First Support on Ginger and OMAP TI
[linux-ginger.git] / drivers / media / dvb / frontends / dib8000.c
blob852c790d09d97b06762ea6688bc54febebbf54fb
1 /*
2 * Linux-DVB Driver for DiBcom's DiB8000 chip (ISDB-T).
4 * Copyright (C) 2009 DiBcom (http://www.dibcom.fr/)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 */
10 #include <linux/kernel.h>
11 #include <linux/i2c.h>
12 #include "dvb_math.h"
14 #include "dvb_frontend.h"
16 #include "dib8000.h"
18 #define LAYER_ALL -1
19 #define LAYER_A 1
20 #define LAYER_B 2
21 #define LAYER_C 3
23 #define FE_CALLBACK_TIME_NEVER 0xffffffff
25 static int debug;
26 module_param(debug, int, 0644);
27 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
29 #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0)
31 enum frontend_tune_state {
32 CT_AGC_START = 20,
33 CT_AGC_STEP_0,
34 CT_AGC_STEP_1,
35 CT_AGC_STEP_2,
36 CT_AGC_STEP_3,
37 CT_AGC_STEP_4,
38 CT_AGC_STOP,
40 CT_DEMOD_START = 30,
43 #define FE_STATUS_TUNE_FAILED 0
45 struct i2c_device {
46 struct i2c_adapter *adap;
47 u8 addr;
50 struct dib8000_state {
51 struct dvb_frontend fe;
52 struct dib8000_config cfg;
54 struct i2c_device i2c;
56 struct dibx000_i2c_master i2c_master;
58 u16 wbd_ref;
60 u8 current_band;
61 u32 current_bandwidth;
62 struct dibx000_agc_config *current_agc;
63 u32 timf;
64 u32 timf_default;
66 u8 div_force_off:1;
67 u8 div_state:1;
68 u16 div_sync_wait;
70 u8 agc_state;
71 u8 differential_constellation;
72 u8 diversity_onoff;
74 s16 ber_monitored_layer;
75 u16 gpio_dir;
76 u16 gpio_val;
78 u16 revision;
79 u8 isdbt_cfg_loaded;
80 enum frontend_tune_state tune_state;
81 u32 status;
84 enum dib8000_power_mode {
85 DIB8000M_POWER_ALL = 0,
86 DIB8000M_POWER_INTERFACE_ONLY,
89 static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
91 u8 wb[2] = { reg >> 8, reg & 0xff };
92 u8 rb[2];
93 struct i2c_msg msg[2] = {
94 {.addr = i2c->addr >> 1,.flags = 0,.buf = wb,.len = 2},
95 {.addr = i2c->addr >> 1,.flags = I2C_M_RD,.buf = rb,.len = 2},
98 if (i2c_transfer(i2c->adap, msg, 2) != 2)
99 dprintk("i2c read error on %d", reg);
101 return (rb[0] << 8) | rb[1];
104 static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
106 return dib8000_i2c_read16(&state->i2c, reg);
109 static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
111 u16 rw[2];
113 rw[0] = dib8000_read_word(state, reg + 0);
114 rw[1] = dib8000_read_word(state, reg + 1);
116 return ((rw[0] << 16) | (rw[1]));
119 static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
121 u8 b[4] = {
122 (reg >> 8) & 0xff, reg & 0xff,
123 (val >> 8) & 0xff, val & 0xff,
125 struct i2c_msg msg = {
126 .addr = i2c->addr >> 1,.flags = 0,.buf = b,.len = 4
128 return i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
131 static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
133 return dib8000_i2c_write16(&state->i2c, reg, val);
136 const int16_t coeff_2k_sb_1seg_dqpsk[8] = {
137 (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
138 (920 << 5) | 0x09
141 const int16_t coeff_2k_sb_1seg[8] = {
142 (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
145 const int16_t coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
146 (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
147 (-931 << 5) | 0x0f
150 const int16_t coeff_2k_sb_3seg_0dqpsk[8] = {
151 (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
152 (982 << 5) | 0x0c
155 const int16_t coeff_2k_sb_3seg_1dqpsk[8] = {
156 (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
157 (-720 << 5) | 0x0d
160 const int16_t coeff_2k_sb_3seg[8] = {
161 (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
162 (-610 << 5) | 0x0a
165 const int16_t coeff_4k_sb_1seg_dqpsk[8] = {
166 (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
167 (-922 << 5) | 0x0d
170 const int16_t coeff_4k_sb_1seg[8] = {
171 (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
172 (-655 << 5) | 0x0a
175 const int16_t coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
176 (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
177 (-958 << 5) | 0x13
180 const int16_t coeff_4k_sb_3seg_0dqpsk[8] = {
181 (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
182 (-568 << 5) | 0x0f
185 const int16_t coeff_4k_sb_3seg_1dqpsk[8] = {
186 (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
187 (-848 << 5) | 0x13
190 const int16_t coeff_4k_sb_3seg[8] = {
191 (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
192 (-869 << 5) | 0x13
195 const int16_t coeff_8k_sb_1seg_dqpsk[8] = {
196 (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
197 (-598 << 5) | 0x10
200 const int16_t coeff_8k_sb_1seg[8] = {
201 (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
202 (585 << 5) | 0x0f
205 const int16_t coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
206 (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
207 (0 << 5) | 0x14
210 const int16_t coeff_8k_sb_3seg_0dqpsk[8] = {
211 (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
212 (-877 << 5) | 0x15
215 const int16_t coeff_8k_sb_3seg_1dqpsk[8] = {
216 (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
217 (-921 << 5) | 0x14
220 const int16_t coeff_8k_sb_3seg[8] = {
221 (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
222 (690 << 5) | 0x14
225 const int16_t ana_fe_coeff_3seg[24] = {
226 81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
229 const int16_t ana_fe_coeff_1seg[24] = {
230 249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
233 const int16_t ana_fe_coeff_13seg[24] = {
234 396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
237 static u16 fft_to_mode(struct dib8000_state *state)
239 u16 mode;
240 switch (state->fe.dtv_property_cache.transmission_mode) {
241 case TRANSMISSION_MODE_2K:
242 mode = 1;
243 break;
244 case TRANSMISSION_MODE_4K:
245 mode = 2;
246 break;
247 default:
248 case TRANSMISSION_MODE_AUTO:
249 case TRANSMISSION_MODE_8K:
250 mode = 3;
251 break;
253 return mode;
256 static void dib8000_set_acquisition_mode(struct dib8000_state *state)
258 u16 nud = dib8000_read_word(state, 298);
259 nud |= (1 << 3) | (1 << 0);
260 dprintk("acquisition mode activated");
261 dib8000_write_word(state, 298, nud);
264 static int dib8000_set_output_mode(struct dib8000_state *state, int mode)
266 u16 outreg, fifo_threshold, smo_mode, sram = 0x0205; /* by default SDRAM deintlv is enabled */
268 outreg = 0;
269 fifo_threshold = 1792;
270 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
272 dprintk("-I- Setting output mode for demod %p to %d", &state->fe, mode);
274 switch (mode) {
275 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
276 outreg = (1 << 10); /* 0x0400 */
277 break;
278 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
279 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
280 break;
281 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
282 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
283 break;
284 case OUTMODE_DIVERSITY:
285 if (state->cfg.hostbus_diversity) {
286 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
287 sram &= 0xfdff;
288 } else
289 sram |= 0x0c00;
290 break;
291 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
292 smo_mode |= (3 << 1);
293 fifo_threshold = 512;
294 outreg = (1 << 10) | (5 << 6);
295 break;
296 case OUTMODE_HIGH_Z: // disable
297 outreg = 0;
298 break;
300 case OUTMODE_ANALOG_ADC:
301 outreg = (1 << 10) | (3 << 6);
302 dib8000_set_acquisition_mode(state);
303 break;
305 default:
306 dprintk("Unhandled output_mode passed to be set for demod %p", &state->fe);
307 return -EINVAL;
310 if (state->cfg.output_mpeg2_in_188_bytes)
311 smo_mode |= (1 << 5);
313 dib8000_write_word(state, 299, smo_mode);
314 dib8000_write_word(state, 300, fifo_threshold); /* synchronous fread */
315 dib8000_write_word(state, 1286, outreg);
316 dib8000_write_word(state, 1291, sram);
318 return 0;
321 static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff)
323 struct dib8000_state *state = fe->demodulator_priv;
324 u16 sync_wait = dib8000_read_word(state, 273) & 0xfff0;
326 if (!state->differential_constellation) {
327 dib8000_write_word(state, 272, 1 << 9); //dvsy_off_lmod4 = 1
328 dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2); // sync_enable = 1; comb_mode = 2
329 } else {
330 dib8000_write_word(state, 272, 0); //dvsy_off_lmod4 = 0
331 dib8000_write_word(state, 273, sync_wait); // sync_enable = 0; comb_mode = 0
333 state->diversity_onoff = onoff;
335 switch (onoff) {
336 case 0: /* only use the internal way - not the diversity input */
337 dib8000_write_word(state, 270, 1);
338 dib8000_write_word(state, 271, 0);
339 break;
340 case 1: /* both ways */
341 dib8000_write_word(state, 270, 6);
342 dib8000_write_word(state, 271, 6);
343 break;
344 case 2: /* only the diversity input */
345 dib8000_write_word(state, 270, 0);
346 dib8000_write_word(state, 271, 1);
347 break;
349 return 0;
352 static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_power_mode mode)
354 /* by default everything is going to be powered off */
355 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
356 reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3, reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
358 /* now, depending on the requested mode, we power on */
359 switch (mode) {
360 /* power up everything in the demod */
361 case DIB8000M_POWER_ALL:
362 reg_774 = 0x0000;
363 reg_775 = 0x0000;
364 reg_776 = 0x0000;
365 reg_900 &= 0xfffc;
366 reg_1280 &= 0x00ff;
367 break;
368 case DIB8000M_POWER_INTERFACE_ONLY:
369 reg_1280 &= 0x00ff;
370 break;
373 dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x", reg_774, reg_775, reg_776, reg_900, reg_1280);
374 dib8000_write_word(state, 774, reg_774);
375 dib8000_write_word(state, 775, reg_775);
376 dib8000_write_word(state, 776, reg_776);
377 dib8000_write_word(state, 900, reg_900);
378 dib8000_write_word(state, 1280, reg_1280);
381 static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no)
383 int ret = 0;
384 u16 reg_907 = dib8000_read_word(state, 907), reg_908 = dib8000_read_word(state, 908);
386 switch (no) {
387 case DIBX000_SLOW_ADC_ON:
388 reg_908 |= (1 << 1) | (1 << 0);
389 ret |= dib8000_write_word(state, 908, reg_908);
390 reg_908 &= ~(1 << 1);
391 break;
393 case DIBX000_SLOW_ADC_OFF:
394 reg_908 |= (1 << 1) | (1 << 0);
395 break;
397 case DIBX000_ADC_ON:
398 reg_907 &= 0x0fff;
399 reg_908 &= 0x0003;
400 break;
402 case DIBX000_ADC_OFF: // leave the VBG voltage on
403 reg_907 |= (1 << 14) | (1 << 13) | (1 << 12);
404 reg_908 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
405 break;
407 case DIBX000_VBG_ENABLE:
408 reg_907 &= ~(1 << 15);
409 break;
411 case DIBX000_VBG_DISABLE:
412 reg_907 |= (1 << 15);
413 break;
415 default:
416 break;
419 ret |= dib8000_write_word(state, 907, reg_907);
420 ret |= dib8000_write_word(state, 908, reg_908);
422 return ret;
425 static int dib8000_set_bandwidth(struct dib8000_state *state, u32 bw)
427 u32 timf;
429 if (bw == 0)
430 bw = 6000;
432 if (state->timf == 0) {
433 dprintk("using default timf");
434 timf = state->timf_default;
435 } else {
436 dprintk("using updated timf");
437 timf = state->timf;
440 dib8000_write_word(state, 29, (u16) ((timf >> 16) & 0xffff));
441 dib8000_write_word(state, 30, (u16) ((timf) & 0xffff));
443 return 0;
446 static int dib8000_sad_calib(struct dib8000_state *state)
448 /* internal */
449 dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
450 dib8000_write_word(state, 924, 776); // 0.625*3.3 / 4096
452 /* do the calibration */
453 dib8000_write_word(state, 923, (1 << 0));
454 dib8000_write_word(state, 923, (0 << 0));
456 msleep(1);
457 return 0;
460 int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
462 struct dib8000_state *state = fe->demodulator_priv;
463 if (value > 4095)
464 value = 4095;
465 state->wbd_ref = value;
466 return dib8000_write_word(state, 106, value);
469 EXPORT_SYMBOL(dib8000_set_wbd_ref);
470 static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
472 dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25);
473 dib8000_write_word(state, 23, (u16) (((bw->internal * 1000) >> 16) & 0xffff)); /* P_sec_len */
474 dib8000_write_word(state, 24, (u16) ((bw->internal * 1000) & 0xffff));
475 dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff));
476 dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff));
477 dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003));
479 dib8000_write_word(state, 922, bw->sad_cfg);
482 static void dib8000_reset_pll(struct dib8000_state *state)
484 const struct dibx000_bandwidth_config *pll = state->cfg.pll;
485 u16 clk_cfg1;
487 // clk_cfg0
488 dib8000_write_word(state, 901, (pll->pll_prediv << 8) | (pll->pll_ratio << 0));
490 // clk_cfg1
491 clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
492 (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) | (pll->pll_range << 1) | (pll->pll_reset << 0);
494 dib8000_write_word(state, 902, clk_cfg1);
495 clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
496 dib8000_write_word(state, 902, clk_cfg1);
498 dprintk("clk_cfg1: 0x%04x", clk_cfg1); /* 0x507 1 0 1 000 0 0 11 1 */
500 /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
501 if (state->cfg.pll->ADClkSrc == 0)
502 dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
503 else if (state->cfg.refclksel != 0)
504 dib8000_write_word(state, 904,
505 (0 << 15) | (1 << 12) | ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) | (pll->
506 ADClkSrc << 7) | (0 << 1));
507 else
508 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
510 dib8000_reset_pll_common(state, pll);
513 static int dib8000_reset_gpio(struct dib8000_state *st)
515 /* reset the GPIOs */
516 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
517 dib8000_write_word(st, 1030, st->cfg.gpio_val);
519 /* TODO 782 is P_gpio_od */
521 dib8000_write_word(st, 1032, st->cfg.gpio_pwm_pos);
523 dib8000_write_word(st, 1037, st->cfg.pwm_freq_div);
524 return 0;
527 static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val)
529 st->cfg.gpio_dir = dib8000_read_word(st, 1029);
530 st->cfg.gpio_dir &= ~(1 << num); /* reset the direction bit */
531 st->cfg.gpio_dir |= (dir & 0x1) << num; /* set the new direction */
532 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
534 st->cfg.gpio_val = dib8000_read_word(st, 1030);
535 st->cfg.gpio_val &= ~(1 << num); /* reset the direction bit */
536 st->cfg.gpio_val |= (val & 0x01) << num; /* set the new value */
537 dib8000_write_word(st, 1030, st->cfg.gpio_val);
539 dprintk("gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val);
541 return 0;
544 int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
546 struct dib8000_state *state = fe->demodulator_priv;
547 return dib8000_cfg_gpio(state, num, dir, val);
550 EXPORT_SYMBOL(dib8000_set_gpio);
551 static const u16 dib8000_defaults[] = {
552 /* auto search configuration - lock0 by default waiting
553 * for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */
554 3, 7,
555 0x0004,
556 0x0400,
557 0x0814,
559 12, 11,
560 0x001b,
561 0x7740,
562 0x005b,
563 0x8d80,
564 0x01c9,
565 0xc380,
566 0x0000,
567 0x0080,
568 0x0000,
569 0x0090,
570 0x0001,
571 0xd4c0,
573 /*1, 32,
574 0x6680 // P_corm_thres Lock algorithms configuration */
576 11, 80, /* set ADC level to -16 */
577 (1 << 13) - 825 - 117,
578 (1 << 13) - 837 - 117,
579 (1 << 13) - 811 - 117,
580 (1 << 13) - 766 - 117,
581 (1 << 13) - 737 - 117,
582 (1 << 13) - 693 - 117,
583 (1 << 13) - 648 - 117,
584 (1 << 13) - 619 - 117,
585 (1 << 13) - 575 - 117,
586 (1 << 13) - 531 - 117,
587 (1 << 13) - 501 - 117,
589 4, 108,
595 1, 175,
596 0x0410,
597 1, 179,
598 8192, // P_fft_nb_to_cut
600 6, 181,
601 0x2800, // P_coff_corthres_ ( 2k 4k 8k ) 0x2800
602 0x2800,
603 0x2800,
604 0x2800, // P_coff_cpilthres_ ( 2k 4k 8k ) 0x2800
605 0x2800,
606 0x2800,
608 2, 193,
609 0x0666, // P_pha3_thres
610 0x0000, // P_cti_use_cpe, P_cti_use_prog
612 2, 205,
613 0x200f, // P_cspu_regul, P_cspu_win_cut
614 0x000f, // P_des_shift_work
616 5, 215,
617 0x023d, // P_adp_regul_cnt
618 0x00a4, // P_adp_noise_cnt
619 0x00a4, // P_adp_regul_ext
620 0x7ff0, // P_adp_noise_ext
621 0x3ccc, // P_adp_fil
623 1, 230,
624 0x0000, // P_2d_byp_ti_num
626 1, 263,
627 0x800, //P_equal_thres_wgn
629 1, 268,
630 (2 << 9) | 39, // P_equal_ctrl_synchro, P_equal_speedmode
632 1, 270,
633 0x0001, // P_div_lock0_wait
634 1, 285,
635 0x0020, //p_fec_
636 1, 299,
637 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
639 1, 338,
640 (1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1
641 (1 << 10) | // P_ctrl_pre_freq_mode_sat=1
642 (0 << 9) | // P_ctrl_pre_freq_inh=0
643 (3 << 5) | // P_ctrl_pre_freq_step=3
644 (1 << 0), // P_pre_freq_win_len=1
646 1, 903,
647 (0 << 4) | 2, // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW)
652 static u16 dib8000_identify(struct i2c_device *client)
654 u16 value;
656 //because of glitches sometimes
657 value = dib8000_i2c_read16(client, 896);
659 if ((value = dib8000_i2c_read16(client, 896)) != 0x01b3) {
660 dprintk("wrong Vendor ID (read=0x%x)", value);
661 return 0;
664 value = dib8000_i2c_read16(client, 897);
665 if (value != 0x8000 && value != 0x8001 && value != 0x8002) {
666 dprintk("wrong Device ID (%x)", value);
667 return 0;
670 switch (value) {
671 case 0x8000:
672 dprintk("found DiB8000A");
673 break;
674 case 0x8001:
675 dprintk("found DiB8000B");
676 break;
677 case 0x8002:
678 dprintk("found DiB8000C");
679 break;
681 return value;
684 static int dib8000_reset(struct dvb_frontend *fe)
686 struct dib8000_state *state = fe->demodulator_priv;
688 dib8000_write_word(state, 1287, 0x0003); /* sram lead in, rdy */
690 if ((state->revision = dib8000_identify(&state->i2c)) == 0)
691 return -EINVAL;
693 if (state->revision == 0x8000)
694 dprintk("error : dib8000 MA not supported");
696 dibx000_reset_i2c_master(&state->i2c_master);
698 dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
700 /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
701 dib8000_set_adc_state(state, DIBX000_VBG_ENABLE);
703 /* restart all parts */
704 dib8000_write_word(state, 770, 0xffff);
705 dib8000_write_word(state, 771, 0xffff);
706 dib8000_write_word(state, 772, 0xfffc);
707 dib8000_write_word(state, 898, 0x000c); // sad
708 dib8000_write_word(state, 1280, 0x004d);
709 dib8000_write_word(state, 1281, 0x000c);
711 dib8000_write_word(state, 770, 0x0000);
712 dib8000_write_word(state, 771, 0x0000);
713 dib8000_write_word(state, 772, 0x0000);
714 dib8000_write_word(state, 898, 0x0004); // sad
715 dib8000_write_word(state, 1280, 0x0000);
716 dib8000_write_word(state, 1281, 0x0000);
718 /* drives */
719 if (state->cfg.drives)
720 dib8000_write_word(state, 906, state->cfg.drives);
721 else {
722 dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.");
723 dib8000_write_word(state, 906, 0x2d98); // min drive SDRAM - not optimal - adjust
726 dib8000_reset_pll(state);
728 if (dib8000_reset_gpio(state) != 0)
729 dprintk("GPIO reset was not successful.");
731 if (dib8000_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
732 dprintk("OUTPUT_MODE could not be resetted.");
734 state->current_agc = NULL;
736 // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
737 /* P_iqc_ca2 = 0; P_iqc_impnc_on = 0; P_iqc_mode = 0; */
738 if (state->cfg.pll->ifreq == 0)
739 dib8000_write_word(state, 40, 0x0755); /* P_iqc_corr_inh = 0 enable IQcorr block */
740 else
741 dib8000_write_word(state, 40, 0x1f55); /* P_iqc_corr_inh = 1 disable IQcorr block */
744 u16 l = 0, r;
745 const u16 *n;
746 n = dib8000_defaults;
747 l = *n++;
748 while (l) {
749 r = *n++;
750 do {
751 dib8000_write_word(state, r, *n++);
752 r++;
753 } while (--l);
754 l = *n++;
757 state->isdbt_cfg_loaded = 0;
759 //div_cfg override for special configs
760 if (state->cfg.div_cfg != 0)
761 dib8000_write_word(state, 903, state->cfg.div_cfg);
763 /* unforce divstr regardless whether i2c enumeration was done or not */
764 dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1));
766 dib8000_set_bandwidth(state, 6000);
768 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
769 dib8000_sad_calib(state);
770 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
772 dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY);
774 return 0;
777 static void dib8000_restart_agc(struct dib8000_state *state)
779 // P_restart_iqc & P_restart_agc
780 dib8000_write_word(state, 770, 0x0a00);
781 dib8000_write_word(state, 770, 0x0000);
784 static int dib8000_update_lna(struct dib8000_state *state)
786 u16 dyn_gain;
788 if (state->cfg.update_lna) {
789 // read dyn_gain here (because it is demod-dependent and not tuner)
790 dyn_gain = dib8000_read_word(state, 390);
792 if (state->cfg.update_lna(&state->fe, dyn_gain)) { // LNA has changed
793 dib8000_restart_agc(state);
794 return 1;
797 return 0;
800 static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
802 struct dibx000_agc_config *agc = NULL;
803 int i;
804 if (state->current_band == band && state->current_agc != NULL)
805 return 0;
806 state->current_band = band;
808 for (i = 0; i < state->cfg.agc_config_count; i++)
809 if (state->cfg.agc[i].band_caps & band) {
810 agc = &state->cfg.agc[i];
811 break;
814 if (agc == NULL) {
815 dprintk("no valid AGC configuration found for band 0x%02x", band);
816 return -EINVAL;
819 state->current_agc = agc;
821 /* AGC */
822 dib8000_write_word(state, 76, agc->setup);
823 dib8000_write_word(state, 77, agc->inv_gain);
824 dib8000_write_word(state, 78, agc->time_stabiliz);
825 dib8000_write_word(state, 101, (agc->alpha_level << 12) | agc->thlock);
827 // Demod AGC loop configuration
828 dib8000_write_word(state, 102, (agc->alpha_mant << 5) | agc->alpha_exp);
829 dib8000_write_word(state, 103, (agc->beta_mant << 6) | agc->beta_exp);
831 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
832 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
834 /* AGC continued */
835 if (state->wbd_ref != 0)
836 dib8000_write_word(state, 106, state->wbd_ref);
837 else // use default
838 dib8000_write_word(state, 106, agc->wbd_ref);
839 dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
840 dib8000_write_word(state, 108, agc->agc1_max);
841 dib8000_write_word(state, 109, agc->agc1_min);
842 dib8000_write_word(state, 110, agc->agc2_max);
843 dib8000_write_word(state, 111, agc->agc2_min);
844 dib8000_write_word(state, 112, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
845 dib8000_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
846 dib8000_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
847 dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
849 dib8000_write_word(state, 75, agc->agc1_pt3);
850 dib8000_write_word(state, 923, (dib8000_read_word(state, 923) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2)); /*LB : 929 -> 923 */
852 return 0;
855 static int dib8000_agc_soft_split(struct dib8000_state *state)
857 u16 agc, split_offset;
859 if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
860 return FE_CALLBACK_TIME_NEVER;
862 // n_agc_global
863 agc = dib8000_read_word(state, 390);
865 if (agc > state->current_agc->split.min_thres)
866 split_offset = state->current_agc->split.min;
867 else if (agc < state->current_agc->split.max_thres)
868 split_offset = state->current_agc->split.max;
869 else
870 split_offset = state->current_agc->split.max *
871 (agc - state->current_agc->split.min_thres) / (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
873 dprintk("AGC split_offset: %d", split_offset);
875 // P_agc_force_split and P_agc_split_offset
876 dib8000_write_word(state, 107, (dib8000_read_word(state, 107) & 0xff00) | split_offset);
877 return 5000;
880 static int dib8000_agc_startup(struct dvb_frontend *fe)
882 struct dib8000_state *state = fe->demodulator_priv;
883 enum frontend_tune_state *tune_state = &state->tune_state;
885 int ret = 0;
887 switch (*tune_state) {
888 case CT_AGC_START:
889 // set power-up level: interf+analog+AGC
891 dib8000_set_adc_state(state, DIBX000_ADC_ON);
893 if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) {
894 *tune_state = CT_AGC_STOP;
895 state->status = FE_STATUS_TUNE_FAILED;
896 break;
899 ret = 70;
900 *tune_state = CT_AGC_STEP_0;
901 break;
903 case CT_AGC_STEP_0:
904 //AGC initialization
905 if (state->cfg.agc_control)
906 state->cfg.agc_control(&state->fe, 1);
908 dib8000_restart_agc(state);
910 // wait AGC rough lock time
911 ret = 50;
912 *tune_state = CT_AGC_STEP_1;
913 break;
915 case CT_AGC_STEP_1:
916 // wait AGC accurate lock time
917 ret = 70;
919 if (dib8000_update_lna(state))
920 // wait only AGC rough lock time
921 ret = 50;
922 else
923 *tune_state = CT_AGC_STEP_2;
924 break;
926 case CT_AGC_STEP_2:
927 dib8000_agc_soft_split(state);
929 if (state->cfg.agc_control)
930 state->cfg.agc_control(&state->fe, 0);
932 *tune_state = CT_AGC_STOP;
933 break;
934 default:
935 ret = dib8000_agc_soft_split(state);
936 break;
938 return ret;
942 static void dib8000_update_timf(struct dib8000_state *state)
944 u32 timf = state->timf = dib8000_read32(state, 435);
946 dib8000_write_word(state, 29, (u16) (timf >> 16));
947 dib8000_write_word(state, 30, (u16) (timf & 0xffff));
948 dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
951 static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
953 u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
954 u8 guard, crate, constellation, timeI;
955 u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
956 u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled
957 const s16 *ncoeff, *ana_fe;
958 u16 tmcc_pow = 0;
959 u16 coff_pow = 0x2800;
960 u16 init_prbs = 0xfff;
961 u16 ana_gain = 0;
962 u16 adc_target_16dB[11] = {
963 (1 << 13) - 825 - 117,
964 (1 << 13) - 837 - 117,
965 (1 << 13) - 811 - 117,
966 (1 << 13) - 766 - 117,
967 (1 << 13) - 737 - 117,
968 (1 << 13) - 693 - 117,
969 (1 << 13) - 648 - 117,
970 (1 << 13) - 619 - 117,
971 (1 << 13) - 575 - 117,
972 (1 << 13) - 531 - 117,
973 (1 << 13) - 501 - 117
976 if (state->ber_monitored_layer != LAYER_ALL)
977 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
978 else
979 dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
981 i = dib8000_read_word(state, 26) & 1; // P_dds_invspec
982 dib8000_write_word(state, 26, state->fe.dtv_property_cache.inversion ^ i);
984 if (state->fe.dtv_property_cache.isdbt_sb_mode) {
985 //compute new dds_freq for the seg and adjust prbs
986 int seg_offset =
987 state->fe.dtv_property_cache.isdbt_sb_segment_idx - (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) -
988 (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2);
989 int clk = state->cfg.pll->internal;
990 u32 segtodds = ((u32) (430 << 23) / clk) << 3; // segtodds = SegBW / Fclk * pow(2,26)
991 int dds_offset = seg_offset * segtodds;
992 int new_dds, sub_channel;
993 if ((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0) // if even
994 dds_offset -= (int)(segtodds / 2);
996 if (state->cfg.pll->ifreq == 0) {
997 if ((state->fe.dtv_property_cache.inversion ^ i) == 0) {
998 dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
999 new_dds = dds_offset;
1000 } else
1001 new_dds = dds_offset;
1003 // We shift tuning frequency if the wanted segment is :
1004 // - the segment of center frequency with an odd total number of segments
1005 // - the segment to the left of center frequency with an even total number of segments
1006 // - the segment to the right of center frequency with an even total number of segments
1007 if ((state->fe.dtv_property_cache.delivery_system == SYS_ISDBT) && (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
1009 (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2)
1010 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx ==
1011 ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1012 || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1013 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx == (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2)))
1014 || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1015 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx ==
1016 ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1017 )) {
1018 new_dds -= ((u32) (850 << 22) / clk) << 4; // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26)
1020 } else {
1021 if ((state->fe.dtv_property_cache.inversion ^ i) == 0)
1022 new_dds = state->cfg.pll->ifreq - dds_offset;
1023 else
1024 new_dds = state->cfg.pll->ifreq + dds_offset;
1026 dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff));
1027 dib8000_write_word(state, 28, (u16) (new_dds & 0xffff));
1028 if (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) // if odd
1029 sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3;
1030 else // if even
1031 sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3;
1032 sub_channel -= 6;
1034 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K
1035 || state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) {
1036 dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); //adp_pass =1
1037 dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); //pha3_force_pha_shift = 1
1038 } else {
1039 dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); //adp_pass =0
1040 dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0
1043 switch (state->fe.dtv_property_cache.transmission_mode) {
1044 case TRANSMISSION_MODE_2K:
1045 switch (sub_channel) {
1046 case -6:
1047 init_prbs = 0x0;
1048 break; // 41, 0, 1
1049 case -5:
1050 init_prbs = 0x423;
1051 break; // 02~04
1052 case -4:
1053 init_prbs = 0x9;
1054 break; // 05~07
1055 case -3:
1056 init_prbs = 0x5C7;
1057 break; // 08~10
1058 case -2:
1059 init_prbs = 0x7A6;
1060 break; // 11~13
1061 case -1:
1062 init_prbs = 0x3D8;
1063 break; // 14~16
1064 case 0:
1065 init_prbs = 0x527;
1066 break; // 17~19
1067 case 1:
1068 init_prbs = 0x7FF;
1069 break; // 20~22
1070 case 2:
1071 init_prbs = 0x79B;
1072 break; // 23~25
1073 case 3:
1074 init_prbs = 0x3D6;
1075 break; // 26~28
1076 case 4:
1077 init_prbs = 0x3A2;
1078 break; // 29~31
1079 case 5:
1080 init_prbs = 0x53B;
1081 break; // 32~34
1082 case 6:
1083 init_prbs = 0x2F4;
1084 break; // 35~37
1085 default:
1086 case 7:
1087 init_prbs = 0x213;
1088 break; // 38~40
1090 break;
1092 case TRANSMISSION_MODE_4K:
1093 switch (sub_channel) {
1094 case -6:
1095 init_prbs = 0x0;
1096 break; // 41, 0, 1
1097 case -5:
1098 init_prbs = 0x208;
1099 break; // 02~04
1100 case -4:
1101 init_prbs = 0xC3;
1102 break; // 05~07
1103 case -3:
1104 init_prbs = 0x7B9;
1105 break; // 08~10
1106 case -2:
1107 init_prbs = 0x423;
1108 break; // 11~13
1109 case -1:
1110 init_prbs = 0x5C7;
1111 break; // 14~16
1112 case 0:
1113 init_prbs = 0x3D8;
1114 break; // 17~19
1115 case 1:
1116 init_prbs = 0x7FF;
1117 break; // 20~22
1118 case 2:
1119 init_prbs = 0x3D6;
1120 break; // 23~25
1121 case 3:
1122 init_prbs = 0x53B;
1123 break; // 26~28
1124 case 4:
1125 init_prbs = 0x213;
1126 break; // 29~31
1127 case 5:
1128 init_prbs = 0x29;
1129 break; // 32~34
1130 case 6:
1131 init_prbs = 0xD0;
1132 break; // 35~37
1133 default:
1134 case 7:
1135 init_prbs = 0x48E;
1136 break; // 38~40
1138 break;
1140 default:
1141 case TRANSMISSION_MODE_8K:
1142 switch (sub_channel) {
1143 case -6:
1144 init_prbs = 0x0;
1145 break; // 41, 0, 1
1146 case -5:
1147 init_prbs = 0x740;
1148 break; // 02~04
1149 case -4:
1150 init_prbs = 0x069;
1151 break; // 05~07
1152 case -3:
1153 init_prbs = 0x7DD;
1154 break; // 08~10
1155 case -2:
1156 init_prbs = 0x208;
1157 break; // 11~13
1158 case -1:
1159 init_prbs = 0x7B9;
1160 break; // 14~16
1161 case 0:
1162 init_prbs = 0x5C7;
1163 break; // 17~19
1164 case 1:
1165 init_prbs = 0x7FF;
1166 break; // 20~22
1167 case 2:
1168 init_prbs = 0x53B;
1169 break; // 23~25
1170 case 3:
1171 init_prbs = 0x29;
1172 break; // 26~28
1173 case 4:
1174 init_prbs = 0x48E;
1175 break; // 29~31
1176 case 5:
1177 init_prbs = 0x4C4;
1178 break; // 32~34
1179 case 6:
1180 init_prbs = 0x367;
1181 break; // 33~37
1182 default:
1183 case 7:
1184 init_prbs = 0x684;
1185 break; // 38~40
1187 break;
1189 } else { // if not state->fe.dtv_property_cache.isdbt_sb_mode
1190 dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff));
1191 dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff));
1192 dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003));
1194 /*P_mode == ?? */
1195 dib8000_write_word(state, 10, (seq << 4));
1196 // dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000);
1198 switch (state->fe.dtv_property_cache.guard_interval) {
1199 case GUARD_INTERVAL_1_32:
1200 guard = 0;
1201 break;
1202 case GUARD_INTERVAL_1_16:
1203 guard = 1;
1204 break;
1205 case GUARD_INTERVAL_1_8:
1206 guard = 2;
1207 break;
1208 case GUARD_INTERVAL_1_4:
1209 default:
1210 guard = 3;
1211 break;
1214 dib8000_write_word(state, 1, (init_prbs << 2) | (guard & 0x3)); // ADDR 1
1216 max_constellation = DQPSK;
1217 for (i = 0; i < 3; i++) {
1218 switch (state->fe.dtv_property_cache.layer[i].modulation) {
1219 case DQPSK:
1220 constellation = 0;
1221 break;
1222 case QPSK:
1223 constellation = 1;
1224 break;
1225 case QAM_16:
1226 constellation = 2;
1227 break;
1228 case QAM_64:
1229 default:
1230 constellation = 3;
1231 break;
1234 switch (state->fe.dtv_property_cache.layer[i].fec) {
1235 case FEC_1_2:
1236 crate = 1;
1237 break;
1238 case FEC_2_3:
1239 crate = 2;
1240 break;
1241 case FEC_3_4:
1242 crate = 3;
1243 break;
1244 case FEC_5_6:
1245 crate = 5;
1246 break;
1247 case FEC_7_8:
1248 default:
1249 crate = 7;
1250 break;
1253 if ((state->fe.dtv_property_cache.layer[i].interleaving > 0) &&
1254 ((state->fe.dtv_property_cache.layer[i].interleaving <= 3) ||
1255 (state->fe.dtv_property_cache.layer[i].interleaving == 4 && state->fe.dtv_property_cache.isdbt_sb_mode == 1))
1257 timeI = state->fe.dtv_property_cache.layer[i].interleaving;
1258 else
1259 timeI = 0;
1260 dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe.dtv_property_cache.layer[i].segment_count & 0xf) << 6) |
1261 (crate << 3) | timeI);
1262 if (state->fe.dtv_property_cache.layer[i].segment_count > 0) {
1263 switch (max_constellation) {
1264 case DQPSK:
1265 case QPSK:
1266 if (state->fe.dtv_property_cache.layer[i].modulation == QAM_16 ||
1267 state->fe.dtv_property_cache.layer[i].modulation == QAM_64)
1268 max_constellation = state->fe.dtv_property_cache.layer[i].modulation;
1269 break;
1270 case QAM_16:
1271 if (state->fe.dtv_property_cache.layer[i].modulation == QAM_64)
1272 max_constellation = state->fe.dtv_property_cache.layer[i].modulation;
1273 break;
1278 mode = fft_to_mode(state);
1280 //dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/
1282 dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) |
1283 ((state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe.dtv_property_cache.
1284 isdbt_sb_mode & 1) << 4));
1286 dprintk("mode = %d ; guard = %d", mode, state->fe.dtv_property_cache.guard_interval);
1288 /* signal optimization parameter */
1290 if (state->fe.dtv_property_cache.isdbt_partial_reception) {
1291 seg_diff_mask = (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0];
1292 for (i = 1; i < 3; i++)
1293 nbseg_diff +=
1294 (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count;
1295 for (i = 0; i < nbseg_diff; i++)
1296 seg_diff_mask |= 1 << permu_seg[i + 1];
1297 } else {
1298 for (i = 0; i < 3; i++)
1299 nbseg_diff +=
1300 (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count;
1301 for (i = 0; i < nbseg_diff; i++)
1302 seg_diff_mask |= 1 << permu_seg[i];
1304 dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask);
1306 state->differential_constellation = (seg_diff_mask != 0);
1307 dib8000_set_diversity_in(&state->fe, state->diversity_onoff);
1309 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb
1310 if (state->fe.dtv_property_cache.isdbt_partial_reception == 1) // 3-segments
1311 seg_mask13 = 0x00E0;
1312 else // 1-segment
1313 seg_mask13 = 0x0040;
1314 } else
1315 seg_mask13 = 0x1fff;
1317 // WRITE: Mode & Diff mask
1318 dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask);
1320 if ((seg_diff_mask) || (state->fe.dtv_property_cache.isdbt_sb_mode))
1321 dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
1322 else
1323 dib8000_write_word(state, 268, (2 << 9) | 39); //init value
1325 // ---- SMALL ----
1326 // P_small_seg_diff
1327 dib8000_write_word(state, 352, seg_diff_mask); // ADDR 352
1329 dib8000_write_word(state, 353, seg_mask13); // ADDR 353
1331 /* // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */
1332 // dib8000_write_word(state, 351, (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5 );
1334 // ---- SMALL ----
1335 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1336 switch (state->fe.dtv_property_cache.transmission_mode) {
1337 case TRANSMISSION_MODE_2K:
1338 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg
1339 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK
1340 ncoeff = coeff_2k_sb_1seg_dqpsk;
1341 else // QPSK or QAM
1342 ncoeff = coeff_2k_sb_1seg;
1343 } else { // 3-segments
1344 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment
1345 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments
1346 ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
1347 else // QPSK or QAM on external segments
1348 ncoeff = coeff_2k_sb_3seg_0dqpsk;
1349 } else { // QPSK or QAM on central segment
1350 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments
1351 ncoeff = coeff_2k_sb_3seg_1dqpsk;
1352 else // QPSK or QAM on external segments
1353 ncoeff = coeff_2k_sb_3seg;
1356 break;
1358 case TRANSMISSION_MODE_4K:
1359 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg
1360 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK
1361 ncoeff = coeff_4k_sb_1seg_dqpsk;
1362 else // QPSK or QAM
1363 ncoeff = coeff_4k_sb_1seg;
1364 } else { // 3-segments
1365 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment
1366 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
1367 ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
1368 } else { // QPSK or QAM on external segments
1369 ncoeff = coeff_4k_sb_3seg_0dqpsk;
1371 } else { // QPSK or QAM on central segment
1372 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
1373 ncoeff = coeff_4k_sb_3seg_1dqpsk;
1374 } else // QPSK or QAM on external segments
1375 ncoeff = coeff_4k_sb_3seg;
1378 break;
1380 case TRANSMISSION_MODE_AUTO:
1381 case TRANSMISSION_MODE_8K:
1382 default:
1383 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg
1384 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK
1385 ncoeff = coeff_8k_sb_1seg_dqpsk;
1386 else // QPSK or QAM
1387 ncoeff = coeff_8k_sb_1seg;
1388 } else { // 3-segments
1389 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment
1390 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
1391 ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
1392 } else { // QPSK or QAM on external segments
1393 ncoeff = coeff_8k_sb_3seg_0dqpsk;
1395 } else { // QPSK or QAM on central segment
1396 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
1397 ncoeff = coeff_8k_sb_3seg_1dqpsk;
1398 } else // QPSK or QAM on external segments
1399 ncoeff = coeff_8k_sb_3seg;
1402 break;
1405 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
1406 for (i = 0; i < 8; i++)
1407 dib8000_write_word(state, 343 + i, ncoeff[i]);
1409 // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5
1410 dib8000_write_word(state, 351,
1411 (state->fe.dtv_property_cache.isdbt_sb_mode << 9) | (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5);
1413 // ---- COFF ----
1414 // Carloff, the most robust
1415 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // Sound Broadcasting mode - use both TMCC and AC pilots
1417 // P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64
1418 // P_coff_narrow_band=1, P_coff_square_val=1, P_coff_one_seg=~partial_rcpt, P_coff_use_tmcc=1, P_coff_use_ac=1
1419 dib8000_write_word(state, 187,
1420 (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 2)
1421 | 0x3);
1423 /* // P_small_coef_ext_enable = 1 */
1424 /* dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */
1426 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // Sound Broadcasting mode 1 seg
1428 // P_coff_winlen=63, P_coff_thres_lock=15, P_coff_one_seg_width= (P_mode == 3) , P_coff_one_seg_sym= (P_mode-1)
1429 if (mode == 3)
1430 dib8000_write_word(state, 180, 0x1fcf | ((mode - 1) << 14));
1431 else
1432 dib8000_write_word(state, 180, 0x0fcf | ((mode - 1) << 14));
1433 // P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1,
1434 // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4
1435 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
1436 // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
1437 dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
1438 // P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
1439 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1441 // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
1442 dib8000_write_word(state, 181, 300);
1443 dib8000_write_word(state, 182, 150);
1444 dib8000_write_word(state, 183, 80);
1445 dib8000_write_word(state, 184, 300);
1446 dib8000_write_word(state, 185, 150);
1447 dib8000_write_word(state, 186, 80);
1448 } else { // Sound Broadcasting mode 3 seg
1449 // P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15
1450 /* if (mode == 3) */
1451 /* dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */
1452 /* else */
1453 /* dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */
1454 dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
1456 // P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1,
1457 // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4
1458 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
1459 // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
1460 dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
1461 //P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
1462 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1464 // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
1465 dib8000_write_word(state, 181, 350);
1466 dib8000_write_word(state, 182, 300);
1467 dib8000_write_word(state, 183, 250);
1468 dib8000_write_word(state, 184, 350);
1469 dib8000_write_word(state, 185, 300);
1470 dib8000_write_word(state, 186, 250);
1473 } else if (state->isdbt_cfg_loaded == 0) { // if not Sound Broadcasting mode : put default values for 13 segments
1474 dib8000_write_word(state, 180, (16 << 6) | 9);
1475 dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2);
1476 coff_pow = 0x2800;
1477 for (i = 0; i < 6; i++)
1478 dib8000_write_word(state, 181 + i, coff_pow);
1480 // P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1,
1481 // P_ctrl_pre_freq_mode_sat=1, P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 3, P_pre_freq_win_len=1
1482 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1);
1484 // P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6
1485 dib8000_write_word(state, 340, (8 << 6) | (6 << 0));
1486 // P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1
1487 dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1489 // ---- FFT ----
1490 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 && state->fe.dtv_property_cache.isdbt_partial_reception == 0) // 1-seg
1491 dib8000_write_word(state, 178, 64); // P_fft_powrange=64
1492 else
1493 dib8000_write_word(state, 178, 32); // P_fft_powrange=32
1495 /* make the cpil_coff_lock more robust but slower p_coff_winlen
1496 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
1498 /* if ( ( nbseg_diff>0)&&(nbseg_diff<13))
1499 dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */
1501 dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask); /* P_lmod4_seg_inh */
1502 dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask); /* P_pha3_seg_inh */
1503 dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask); /* P_tac_seg_inh */
1504 if ((!state->fe.dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0))
1505 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */
1506 else
1507 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask); /* P_equal_noise_seg_inh */
1508 dib8000_write_word(state, 287, ~seg_mask13 | 0x1000); /* P_tmcc_seg_inh */
1509 //dib8000_write_word(state, 288, ~seg_mask13 | seg_diff_mask); /* P_tmcc_seg_eq_inh */
1510 if (!autosearching)
1511 dib8000_write_word(state, 288, (~seg_mask13 | seg_diff_mask) & 0x1fff); /* P_tmcc_seg_eq_inh */
1512 else
1513 dib8000_write_word(state, 288, 0x1fff); //disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels.
1514 dprintk("287 = %X (%d)", ~seg_mask13 | 0x1000, ~seg_mask13 | 0x1000);
1516 dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask)); /* P_des_seg_enabled */
1518 /* offset loop parameters */
1519 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1520 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg
1521 /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1522 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40);
1524 else // Sound Broadcasting mode 3 seg
1525 /* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1526 dib8000_write_word(state, 32, ((10 - mode) << 12) | (6 << 8) | 0x60);
1527 } else
1528 // TODO in 13 seg, timf_alpha can always be the same or not ?
1529 /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
1530 dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80);
1532 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1533 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg
1534 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (11-P_mode) */
1535 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode));
1537 else // Sound Broadcasting mode 3 seg
1538 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (10-P_mode) */
1539 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (9 - mode));
1540 } else
1541 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = 9 */
1542 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode));
1544 /* P_dvsy_sync_wait - reuse mode */
1545 switch (state->fe.dtv_property_cache.transmission_mode) {
1546 case TRANSMISSION_MODE_8K:
1547 mode = 256;
1548 break;
1549 case TRANSMISSION_MODE_4K:
1550 mode = 128;
1551 break;
1552 default:
1553 case TRANSMISSION_MODE_2K:
1554 mode = 64;
1555 break;
1557 if (state->cfg.diversity_delay == 0)
1558 mode = (mode * (1 << (guard)) * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo
1559 else
1560 mode = (mode * (1 << (guard)) * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for DVSY-fifo
1561 mode <<= 4;
1562 dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | mode);
1564 /* channel estimation fine configuration */
1565 switch (max_constellation) {
1566 case QAM_64:
1567 ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
1568 coeff[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
1569 coeff[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
1570 coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1571 coeff[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
1572 //if (!state->cfg.hostbus_diversity) //if diversity, we should prehaps use the configuration of the max_constallation -1
1573 break;
1574 case QAM_16:
1575 ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
1576 coeff[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
1577 coeff[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
1578 coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1579 coeff[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
1580 //if (!((state->cfg.hostbus_diversity) && (max_constellation == QAM_16)))
1581 break;
1582 default:
1583 ana_gain = 0; // 0 : goes along with ADC target at -22dB to keep good mobile performance and lock at sensitivity level
1584 coeff[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
1585 coeff[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
1586 coeff[2] = 0x0333; /* P_adp_regul_ext 0.1 */
1587 coeff[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
1588 break;
1590 for (mode = 0; mode < 4; mode++)
1591 dib8000_write_word(state, 215 + mode, coeff[mode]);
1593 // update ana_gain depending on max constellation
1594 dib8000_write_word(state, 116, ana_gain);
1595 // update ADC target depending on ana_gain
1596 if (ana_gain) { // set -16dB ADC target for ana_gain=-1
1597 for (i = 0; i < 10; i++)
1598 dib8000_write_word(state, 80 + i, adc_target_16dB[i]);
1599 } else { // set -22dB ADC target for ana_gain=0
1600 for (i = 0; i < 10; i++)
1601 dib8000_write_word(state, 80 + i, adc_target_16dB[i] - 355);
1604 // ---- ANA_FE ----
1605 if (state->fe.dtv_property_cache.isdbt_sb_mode) {
1606 if (state->fe.dtv_property_cache.isdbt_partial_reception == 1) // 3-segments
1607 ana_fe = ana_fe_coeff_3seg;
1608 else // 1-segment
1609 ana_fe = ana_fe_coeff_1seg;
1610 } else
1611 ana_fe = ana_fe_coeff_13seg;
1613 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0)
1614 for (mode = 0; mode < 24; mode++)
1615 dib8000_write_word(state, 117 + mode, ana_fe[mode]);
1617 // ---- CHAN_BLK ----
1618 for (i = 0; i < 13; i++) {
1619 if ((((~seg_diff_mask) >> i) & 1) == 1) {
1620 P_cfr_left_edge += (1 << i) * ((i == 0) || ((((seg_mask13 & (~seg_diff_mask)) >> (i - 1)) & 1) == 0));
1621 P_cfr_right_edge += (1 << i) * ((i == 12) || ((((seg_mask13 & (~seg_diff_mask)) >> (i + 1)) & 1) == 0));
1624 dib8000_write_word(state, 222, P_cfr_left_edge); // P_cfr_left_edge
1625 dib8000_write_word(state, 223, P_cfr_right_edge); // P_cfr_right_edge
1626 // "P_cspu_left_edge" not used => do not care
1627 // "P_cspu_right_edge" not used => do not care
1629 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb
1630 dib8000_write_word(state, 228, 1); // P_2d_mode_byp=1
1631 dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); // P_cspu_win_cut = 0
1632 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0 // 1-segment
1633 && state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) {
1634 //dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0
1635 dib8000_write_word(state, 265, 15); // P_equal_noise_sel = 15
1637 } else if (state->isdbt_cfg_loaded == 0) {
1638 dib8000_write_word(state, 228, 0); // default value
1639 dib8000_write_word(state, 265, 31); // default value
1640 dib8000_write_word(state, 205, 0x200f); // init value
1642 // ---- TMCC ----
1643 for (i = 0; i < 3; i++)
1644 tmcc_pow +=
1645 (((state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe.dtv_property_cache.layer[i].segment_count);
1646 // Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9);
1647 // Threshold is set at 1/4 of max power.
1648 tmcc_pow *= (1 << (9 - 2));
1650 dib8000_write_word(state, 290, tmcc_pow); // P_tmcc_dec_thres_2k
1651 dib8000_write_word(state, 291, tmcc_pow); // P_tmcc_dec_thres_4k
1652 dib8000_write_word(state, 292, tmcc_pow); // P_tmcc_dec_thres_8k
1653 //dib8000_write_word(state, 287, (1 << 13) | 0x1000 );
1654 // ---- PHA3 ----
1656 if (state->isdbt_cfg_loaded == 0)
1657 dib8000_write_word(state, 250, 3285); /*p_2d_hspeed_thr0 */
1659 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
1660 state->isdbt_cfg_loaded = 0;
1661 else
1662 state->isdbt_cfg_loaded = 1;
1666 static int dib8000_autosearch_start(struct dvb_frontend *fe)
1668 u8 factor;
1669 u32 value;
1670 struct dib8000_state *state = fe->demodulator_priv;
1672 int slist = 0;
1674 state->fe.dtv_property_cache.inversion = 0;
1675 if (!state->fe.dtv_property_cache.isdbt_sb_mode)
1676 state->fe.dtv_property_cache.layer[0].segment_count = 13;
1677 state->fe.dtv_property_cache.layer[0].modulation = QAM_64;
1678 state->fe.dtv_property_cache.layer[0].fec = FEC_2_3;
1679 state->fe.dtv_property_cache.layer[0].interleaving = 0;
1681 //choose the right list, in sb, always do everything
1682 if (state->fe.dtv_property_cache.isdbt_sb_mode) {
1683 state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1684 state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1685 slist = 7;
1686 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));
1687 } else {
1688 if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) {
1689 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1690 slist = 7;
1691 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 to have autosearch start ok with mode2
1692 } else
1693 slist = 3;
1694 } else {
1695 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1696 slist = 2;
1697 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
1698 } else
1699 slist = 0;
1702 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO)
1703 state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1704 if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO)
1705 state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1707 dprintk("using list for autosearch : %d", slist);
1708 dib8000_set_channel(state, (unsigned char)slist, 1);
1709 //dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
1711 factor = 1;
1713 //set lock_mask values
1714 dib8000_write_word(state, 6, 0x4);
1715 dib8000_write_word(state, 7, 0x8);
1716 dib8000_write_word(state, 8, 0x1000);
1718 //set lock_mask wait time values
1719 value = 50 * state->cfg.pll->internal * factor;
1720 dib8000_write_word(state, 11, (u16) ((value >> 16) & 0xffff)); // lock0 wait time
1721 dib8000_write_word(state, 12, (u16) (value & 0xffff)); // lock0 wait time
1722 value = 100 * state->cfg.pll->internal * factor;
1723 dib8000_write_word(state, 13, (u16) ((value >> 16) & 0xffff)); // lock1 wait time
1724 dib8000_write_word(state, 14, (u16) (value & 0xffff)); // lock1 wait time
1725 value = 1000 * state->cfg.pll->internal * factor;
1726 dib8000_write_word(state, 15, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
1727 dib8000_write_word(state, 16, (u16) (value & 0xffff)); // lock2 wait time
1729 value = dib8000_read_word(state, 0);
1730 dib8000_write_word(state, 0, (u16) ((1 << 15) | value));
1731 dib8000_read_word(state, 1284); // reset the INT. n_irq_pending
1732 dib8000_write_word(state, 0, (u16) value);
1736 return 0;
1739 static int dib8000_autosearch_irq(struct dvb_frontend *fe)
1741 struct dib8000_state *state = fe->demodulator_priv;
1742 u16 irq_pending = dib8000_read_word(state, 1284);
1744 if (irq_pending & 0x1) { // failed
1745 dprintk("dib8000_autosearch_irq failed");
1746 return 1;
1749 if (irq_pending & 0x2) { // succeeded
1750 dprintk("dib8000_autosearch_irq succeeded");
1751 return 2;
1754 return 0; // still pending
1757 static int dib8000_tune(struct dvb_frontend *fe)
1759 struct dib8000_state *state = fe->demodulator_priv;
1760 int ret = 0;
1761 u16 value, mode = fft_to_mode(state);
1763 // we are already tuned - just resuming from suspend
1764 if (state == NULL)
1765 return -EINVAL;
1767 dib8000_set_bandwidth(state, state->fe.dtv_property_cache.bandwidth_hz / 1000);
1768 dib8000_set_channel(state, 0, 0);
1770 // restart demod
1771 ret |= dib8000_write_word(state, 770, 0x4000);
1772 ret |= dib8000_write_word(state, 770, 0x0000);
1773 msleep(45);
1775 /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3 */
1776 /* ret |= dib8000_write_word(state, 29, (0 << 9) | (4 << 5) | (0 << 4) | (3 << 0) ); workaround inh_isi stays at 1 */
1778 // never achieved a lock before - wait for timfreq to update
1779 if (state->timf == 0) {
1780 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1781 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg
1782 msleep(300);
1783 else // Sound Broadcasting mode 3 seg
1784 msleep(500);
1785 } else // 13 seg
1786 msleep(200);
1788 //dump_reg(state);
1789 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1790 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // Sound Broadcasting mode 1 seg
1792 /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40 alpha to check on board */
1793 dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40);
1794 //dib8000_write_word(state, 32, (8 << 12) | (6 << 8) | 0x80);
1796 /* P_ctrl_sfreq_step= (12-P_mode) P_ctrl_sfreq_inh =0 P_ctrl_pha_off_max */
1797 ret |= dib8000_write_word(state, 37, (12 - mode) | ((5 + mode) << 5));
1799 } else { // Sound Broadcasting mode 3 seg
1801 /* P_timf_alpha = (12-P_mode) , P_corm_alpha=6, P_corm_thres=0x60 alpha to check on board */
1802 dib8000_write_word(state, 32, ((12 - mode) << 12) | (6 << 8) | 0x60);
1804 ret |= dib8000_write_word(state, 37, (11 - mode) | ((5 + mode) << 5));
1807 } else { // 13 seg
1808 /* P_timf_alpha = 8 , P_corm_alpha=6, P_corm_thres=0x80 alpha to check on board */
1809 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x80);
1811 ret |= dib8000_write_word(state, 37, (10 - mode) | ((5 + mode) << 5));
1815 // we achieved a coff_cpil_lock - it's time to update the timf
1816 if ((dib8000_read_word(state, 568) >> 11) & 0x1)
1817 dib8000_update_timf(state);
1819 //now that tune is finished, lock0 should lock on fec_mpeg to output this lock on MP_LOCK. It's changed in autosearch start
1820 dib8000_write_word(state, 6, 0x200);
1822 if (state->revision == 0x8002) {
1823 value = dib8000_read_word(state, 903);
1824 dib8000_write_word(state, 903, value & ~(1 << 3));
1825 msleep(1);
1826 dib8000_write_word(state, 903, value | (1 << 3));
1829 return ret;
1832 static int dib8000_wakeup(struct dvb_frontend *fe)
1834 struct dib8000_state *state = fe->demodulator_priv;
1836 dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
1837 dib8000_set_adc_state(state, DIBX000_ADC_ON);
1838 if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
1839 dprintk("could not start Slow ADC");
1841 return 0;
1844 static int dib8000_sleep(struct dvb_frontend *fe)
1846 struct dib8000_state *st = fe->demodulator_priv;
1847 if (1) {
1848 dib8000_set_output_mode(st, OUTMODE_HIGH_Z);
1849 dib8000_set_power_mode(st, DIB8000M_POWER_INTERFACE_ONLY);
1850 return dib8000_set_adc_state(st, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(st, DIBX000_ADC_OFF);
1851 } else {
1853 return 0;
1857 static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1859 struct dib8000_state *state = fe->demodulator_priv;
1860 u16 i, val = 0;
1862 fe->dtv_property_cache.bandwidth_hz = 6000000;
1864 fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1;
1866 val = dib8000_read_word(state, 570);
1867 fe->dtv_property_cache.inversion = (val & 0x40) >> 6;
1868 switch ((val & 0x30) >> 4) {
1869 case 1:
1870 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
1871 break;
1872 case 3:
1873 default:
1874 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1875 break;
1878 switch (val & 0x3) {
1879 case 0:
1880 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
1881 dprintk("dib8000_get_frontend GI = 1/32 ");
1882 break;
1883 case 1:
1884 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
1885 dprintk("dib8000_get_frontend GI = 1/16 ");
1886 break;
1887 case 2:
1888 dprintk("dib8000_get_frontend GI = 1/8 ");
1889 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1890 break;
1891 case 3:
1892 dprintk("dib8000_get_frontend GI = 1/4 ");
1893 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
1894 break;
1897 val = dib8000_read_word(state, 505);
1898 fe->dtv_property_cache.isdbt_partial_reception = val & 1;
1899 dprintk("dib8000_get_frontend : partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception);
1901 for (i = 0; i < 3; i++) {
1902 val = dib8000_read_word(state, 493 + i);
1903 fe->dtv_property_cache.layer[i].segment_count = val & 0x0F;
1904 dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count);
1906 val = dib8000_read_word(state, 499 + i);
1907 fe->dtv_property_cache.layer[i].interleaving = val & 0x3;
1908 dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ", i, fe->dtv_property_cache.layer[i].interleaving);
1910 val = dib8000_read_word(state, 481 + i);
1911 switch (val & 0x7) {
1912 case 1:
1913 fe->dtv_property_cache.layer[i].fec = FEC_1_2;
1914 dprintk("dib8000_get_frontend : Layer %d Code Rate = 1/2 ", i);
1915 break;
1916 case 2:
1917 fe->dtv_property_cache.layer[i].fec = FEC_2_3;
1918 dprintk("dib8000_get_frontend : Layer %d Code Rate = 2/3 ", i);
1919 break;
1920 case 3:
1921 fe->dtv_property_cache.layer[i].fec = FEC_3_4;
1922 dprintk("dib8000_get_frontend : Layer %d Code Rate = 3/4 ", i);
1923 break;
1924 case 5:
1925 fe->dtv_property_cache.layer[i].fec = FEC_5_6;
1926 dprintk("dib8000_get_frontend : Layer %d Code Rate = 5/6 ", i);
1927 break;
1928 default:
1929 fe->dtv_property_cache.layer[i].fec = FEC_7_8;
1930 dprintk("dib8000_get_frontend : Layer %d Code Rate = 7/8 ", i);
1931 break;
1934 val = dib8000_read_word(state, 487 + i);
1935 switch (val & 0x3) {
1936 case 0:
1937 dprintk("dib8000_get_frontend : Layer %d DQPSK ", i);
1938 fe->dtv_property_cache.layer[i].modulation = DQPSK;
1939 break;
1940 case 1:
1941 fe->dtv_property_cache.layer[i].modulation = QPSK;
1942 dprintk("dib8000_get_frontend : Layer %d QPSK ", i);
1943 break;
1944 case 2:
1945 fe->dtv_property_cache.layer[i].modulation = QAM_16;
1946 dprintk("dib8000_get_frontend : Layer %d QAM16 ", i);
1947 break;
1948 case 3:
1949 default:
1950 dprintk("dib8000_get_frontend : Layer %d QAM64 ", i);
1951 fe->dtv_property_cache.layer[i].modulation = QAM_64;
1952 break;
1955 return 0;
1958 static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1960 struct dib8000_state *state = fe->demodulator_priv;
1961 int time, ret;
1963 dib8000_set_output_mode(state, OUTMODE_HIGH_Z);
1965 if (fe->ops.tuner_ops.set_params)
1966 fe->ops.tuner_ops.set_params(fe, fep);
1968 /* start up the AGC */
1969 state->tune_state = CT_AGC_START;
1970 do {
1971 time = dib8000_agc_startup(fe);
1972 if (time != FE_CALLBACK_TIME_NEVER)
1973 msleep(time / 10);
1974 else
1975 break;
1976 } while (state->tune_state != CT_AGC_STOP);
1978 if (state->fe.dtv_property_cache.frequency == 0) {
1979 dprintk("dib8000: must at least specify frequency ");
1980 return 0;
1983 if (state->fe.dtv_property_cache.bandwidth_hz == 0) {
1984 dprintk("dib8000: no bandwidth specified, set to default ");
1985 state->fe.dtv_property_cache.bandwidth_hz = 6000000;
1988 state->tune_state = CT_DEMOD_START;
1990 if ((state->fe.dtv_property_cache.delivery_system != SYS_ISDBT) ||
1991 (state->fe.dtv_property_cache.inversion == INVERSION_AUTO) ||
1992 (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) ||
1993 (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) ||
1994 (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) &&
1995 (state->fe.dtv_property_cache.layer[0].segment_count != 0xff) &&
1996 (state->fe.dtv_property_cache.layer[0].segment_count != 0) &&
1997 ((state->fe.dtv_property_cache.layer[0].modulation == QAM_AUTO) ||
1998 (state->fe.dtv_property_cache.layer[0].fec == FEC_AUTO))) ||
1999 (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) &&
2000 (state->fe.dtv_property_cache.layer[1].segment_count != 0xff) &&
2001 (state->fe.dtv_property_cache.layer[1].segment_count != 0) &&
2002 ((state->fe.dtv_property_cache.layer[1].modulation == QAM_AUTO) ||
2003 (state->fe.dtv_property_cache.layer[1].fec == FEC_AUTO))) ||
2004 (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) &&
2005 (state->fe.dtv_property_cache.layer[2].segment_count != 0xff) &&
2006 (state->fe.dtv_property_cache.layer[2].segment_count != 0) &&
2007 ((state->fe.dtv_property_cache.layer[2].modulation == QAM_AUTO) ||
2008 (state->fe.dtv_property_cache.layer[2].fec == FEC_AUTO))) ||
2009 (((state->fe.dtv_property_cache.layer[0].segment_count == 0) ||
2010 ((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) &&
2011 ((state->fe.dtv_property_cache.layer[1].segment_count == 0) ||
2012 ((state->fe.dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) &&
2013 ((state->fe.dtv_property_cache.layer[2].segment_count == 0) || ((state->fe.dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) {
2014 int i = 800, found;
2016 dib8000_set_bandwidth(state, fe->dtv_property_cache.bandwidth_hz / 1000);
2017 dib8000_autosearch_start(fe);
2018 do {
2019 msleep(10);
2020 found = dib8000_autosearch_irq(fe);
2021 } while (found == 0 && i--);
2023 dprintk("Frequency %d Hz, autosearch returns: %d", fep->frequency, found);
2025 if (found == 0 || found == 1)
2026 return 0; // no channel found
2028 dib8000_get_frontend(fe, fep);
2031 ret = dib8000_tune(fe);
2033 /* make this a config parameter */
2034 dib8000_set_output_mode(state, state->cfg.output_mode);
2036 return ret;
2039 static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
2041 struct dib8000_state *state = fe->demodulator_priv;
2042 u16 lock = dib8000_read_word(state, 568);
2044 *stat = 0;
2046 if ((lock >> 14) & 1) // AGC
2047 *stat |= FE_HAS_SIGNAL;
2049 if ((lock >> 8) & 1) // Equal
2050 *stat |= FE_HAS_CARRIER;
2052 if ((lock >> 3) & 1) // TMCC_SYNC
2053 *stat |= FE_HAS_SYNC;
2055 if ((lock >> 5) & 7) // FEC MPEG
2056 *stat |= FE_HAS_LOCK;
2058 lock = dib8000_read_word(state, 554); // Viterbi Layer A
2059 if (lock & 0x01)
2060 *stat |= FE_HAS_VITERBI;
2062 lock = dib8000_read_word(state, 555); // Viterbi Layer B
2063 if (lock & 0x01)
2064 *stat |= FE_HAS_VITERBI;
2066 lock = dib8000_read_word(state, 556); // Viterbi Layer C
2067 if (lock & 0x01)
2068 *stat |= FE_HAS_VITERBI;
2070 return 0;
2073 static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber)
2075 struct dib8000_state *state = fe->demodulator_priv;
2076 *ber = (dib8000_read_word(state, 560) << 16) | dib8000_read_word(state, 561); // 13 segments
2077 return 0;
2080 static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
2082 struct dib8000_state *state = fe->demodulator_priv;
2083 *unc = dib8000_read_word(state, 565); // packet error on 13 seg
2084 return 0;
2087 static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2089 struct dib8000_state *state = fe->demodulator_priv;
2090 u16 val = dib8000_read_word(state, 390);
2091 *strength = 65535 - val;
2092 return 0;
2095 static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
2097 struct dib8000_state *state = fe->demodulator_priv;
2098 u16 val;
2099 s32 signal_mant, signal_exp, noise_mant, noise_exp;
2100 u32 result = 0;
2102 val = dib8000_read_word(state, 542);
2103 noise_mant = (val >> 6) & 0xff;
2104 noise_exp = (val & 0x3f);
2106 val = dib8000_read_word(state, 543);
2107 signal_mant = (val >> 6) & 0xff;
2108 signal_exp = (val & 0x3f);
2110 if ((noise_exp & 0x20) != 0)
2111 noise_exp -= 0x40;
2112 if ((signal_exp & 0x20) != 0)
2113 signal_exp -= 0x40;
2115 if (signal_mant != 0)
2116 result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
2117 else
2118 result = intlog10(2) * 10 * signal_exp - 100;
2119 if (noise_mant != 0)
2120 result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
2121 else
2122 result -= intlog10(2) * 10 * noise_exp - 100;
2124 *snr = result / (1 << 24);
2125 return 0;
2128 int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
2130 int k = 0;
2131 u8 new_addr = 0;
2132 struct i2c_device client = {.adap = host };
2134 for (k = no_of_demods - 1; k >= 0; k--) {
2135 /* designated i2c address */
2136 new_addr = first_addr + (k << 1);
2138 client.addr = new_addr;
2139 dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */
2140 if (dib8000_identify(&client) == 0) {
2141 dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */
2142 client.addr = default_addr;
2143 if (dib8000_identify(&client) == 0) {
2144 dprintk("#%d: not identified", k);
2145 return -EINVAL;
2149 /* start diversity to pull_down div_str - just for i2c-enumeration */
2150 dib8000_i2c_write16(&client, 1286, (1 << 10) | (4 << 6));
2152 /* set new i2c address and force divstart */
2153 dib8000_i2c_write16(&client, 1285, (new_addr << 2) | 0x2);
2154 client.addr = new_addr;
2155 dib8000_identify(&client);
2157 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
2160 for (k = 0; k < no_of_demods; k++) {
2161 new_addr = first_addr | (k << 1);
2162 client.addr = new_addr;
2164 // unforce divstr
2165 dib8000_i2c_write16(&client, 1285, new_addr << 2);
2167 /* deactivate div - it was just for i2c-enumeration */
2168 dib8000_i2c_write16(&client, 1286, 0);
2171 return 0;
2174 EXPORT_SYMBOL(dib8000_i2c_enumeration);
2175 static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
2177 tune->min_delay_ms = 1000;
2178 tune->step_size = 0;
2179 tune->max_drift = 0;
2180 return 0;
2183 static void dib8000_release(struct dvb_frontend *fe)
2185 struct dib8000_state *st = fe->demodulator_priv;
2186 dibx000_exit_i2c_master(&st->i2c_master);
2187 kfree(st);
2190 struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
2192 struct dib8000_state *st = fe->demodulator_priv;
2193 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
2196 EXPORT_SYMBOL(dib8000_get_i2c_master);
2198 static const struct dvb_frontend_ops dib8000_ops = {
2199 .info = {
2200 .name = "DiBcom 8000 ISDB-T",
2201 .type = FE_OFDM,
2202 .frequency_min = 44250000,
2203 .frequency_max = 867250000,
2204 .frequency_stepsize = 62500,
2205 .caps = FE_CAN_INVERSION_AUTO |
2206 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2207 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2208 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2209 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2212 .release = dib8000_release,
2214 .init = dib8000_wakeup,
2215 .sleep = dib8000_sleep,
2217 .set_frontend = dib8000_set_frontend,
2218 .get_tune_settings = dib8000_fe_get_tune_settings,
2219 .get_frontend = dib8000_get_frontend,
2221 .read_status = dib8000_read_status,
2222 .read_ber = dib8000_read_ber,
2223 .read_signal_strength = dib8000_read_signal_strength,
2224 .read_snr = dib8000_read_snr,
2225 .read_ucblocks = dib8000_read_unc_blocks,
2228 struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
2230 struct dvb_frontend *fe;
2231 struct dib8000_state *state;
2233 dprintk("dib8000_attach");
2235 state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL);
2236 if (state == NULL)
2237 return NULL;
2239 memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
2240 state->i2c.adap = i2c_adap;
2241 state->i2c.addr = i2c_addr;
2242 state->gpio_val = cfg->gpio_val;
2243 state->gpio_dir = cfg->gpio_dir;
2245 /* Ensure the output mode remains at the previous default if it's
2246 * not specifically set by the caller.
2248 if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2249 state->cfg.output_mode = OUTMODE_MPEG2_FIFO;
2251 fe = &state->fe;
2252 fe->demodulator_priv = state;
2253 memcpy(&state->fe.ops, &dib8000_ops, sizeof(struct dvb_frontend_ops));
2255 state->timf_default = cfg->pll->timf;
2257 if (dib8000_identify(&state->i2c) == 0)
2258 goto error;
2260 dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr);
2262 dib8000_reset(fe);
2264 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5)); /* ber_rs_len = 3 */
2266 return fe;
2268 error:
2269 kfree(state);
2270 return NULL;
2273 EXPORT_SYMBOL(dib8000_attach);
2275 MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@dibcom.fr, " "Patrick Boettcher <pboettcher@dibcom.fr>");
2276 MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator");
2277 MODULE_LICENSE("GPL");