Staging: strip: delete the driver
[linux/fpc-iii.git] / drivers / media / dvb / frontends / dib8000.c
blobdf17b91b3250b45596619a6a752d63061f4c8a45
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/slab.h>
12 #include <linux/i2c.h>
13 #include "dvb_math.h"
15 #include "dvb_frontend.h"
17 #include "dib8000.h"
19 #define LAYER_ALL -1
20 #define LAYER_A 1
21 #define LAYER_B 2
22 #define LAYER_C 3
24 #define FE_CALLBACK_TIME_NEVER 0xffffffff
26 static int debug;
27 module_param(debug, int, 0644);
28 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
30 #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0)
32 #define FE_STATUS_TUNE_FAILED 0
34 struct i2c_device {
35 struct i2c_adapter *adap;
36 u8 addr;
39 struct dib8000_state {
40 struct dvb_frontend fe;
41 struct dib8000_config cfg;
43 struct i2c_device i2c;
45 struct dibx000_i2c_master i2c_master;
47 u16 wbd_ref;
49 u8 current_band;
50 u32 current_bandwidth;
51 struct dibx000_agc_config *current_agc;
52 u32 timf;
53 u32 timf_default;
55 u8 div_force_off:1;
56 u8 div_state:1;
57 u16 div_sync_wait;
59 u8 agc_state;
60 u8 differential_constellation;
61 u8 diversity_onoff;
63 s16 ber_monitored_layer;
64 u16 gpio_dir;
65 u16 gpio_val;
67 u16 revision;
68 u8 isdbt_cfg_loaded;
69 enum frontend_tune_state tune_state;
70 u32 status;
73 enum dib8000_power_mode {
74 DIB8000M_POWER_ALL = 0,
75 DIB8000M_POWER_INTERFACE_ONLY,
78 static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
80 u8 wb[2] = { reg >> 8, reg & 0xff };
81 u8 rb[2];
82 struct i2c_msg msg[2] = {
83 {.addr = i2c->addr >> 1,.flags = 0,.buf = wb,.len = 2},
84 {.addr = i2c->addr >> 1,.flags = I2C_M_RD,.buf = rb,.len = 2},
87 if (i2c_transfer(i2c->adap, msg, 2) != 2)
88 dprintk("i2c read error on %d", reg);
90 return (rb[0] << 8) | rb[1];
93 static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
95 return dib8000_i2c_read16(&state->i2c, reg);
98 static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
100 u16 rw[2];
102 rw[0] = dib8000_read_word(state, reg + 0);
103 rw[1] = dib8000_read_word(state, reg + 1);
105 return ((rw[0] << 16) | (rw[1]));
108 static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
110 u8 b[4] = {
111 (reg >> 8) & 0xff, reg & 0xff,
112 (val >> 8) & 0xff, val & 0xff,
114 struct i2c_msg msg = {
115 .addr = i2c->addr >> 1,.flags = 0,.buf = b,.len = 4
117 return i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
120 static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
122 return dib8000_i2c_write16(&state->i2c, reg, val);
125 static const int16_t coeff_2k_sb_1seg_dqpsk[8] = {
126 (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
127 (920 << 5) | 0x09
130 static const int16_t coeff_2k_sb_1seg[8] = {
131 (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
134 static const int16_t coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
135 (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
136 (-931 << 5) | 0x0f
139 static const int16_t coeff_2k_sb_3seg_0dqpsk[8] = {
140 (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
141 (982 << 5) | 0x0c
144 static const int16_t coeff_2k_sb_3seg_1dqpsk[8] = {
145 (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
146 (-720 << 5) | 0x0d
149 static const int16_t coeff_2k_sb_3seg[8] = {
150 (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
151 (-610 << 5) | 0x0a
154 static const int16_t coeff_4k_sb_1seg_dqpsk[8] = {
155 (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
156 (-922 << 5) | 0x0d
159 static const int16_t coeff_4k_sb_1seg[8] = {
160 (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
161 (-655 << 5) | 0x0a
164 static const int16_t coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
165 (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
166 (-958 << 5) | 0x13
169 static const int16_t coeff_4k_sb_3seg_0dqpsk[8] = {
170 (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
171 (-568 << 5) | 0x0f
174 static const int16_t coeff_4k_sb_3seg_1dqpsk[8] = {
175 (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
176 (-848 << 5) | 0x13
179 static const int16_t coeff_4k_sb_3seg[8] = {
180 (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
181 (-869 << 5) | 0x13
184 static const int16_t coeff_8k_sb_1seg_dqpsk[8] = {
185 (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
186 (-598 << 5) | 0x10
189 static const int16_t coeff_8k_sb_1seg[8] = {
190 (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
191 (585 << 5) | 0x0f
194 static const int16_t coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
195 (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
196 (0 << 5) | 0x14
199 static const int16_t coeff_8k_sb_3seg_0dqpsk[8] = {
200 (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
201 (-877 << 5) | 0x15
204 static const int16_t coeff_8k_sb_3seg_1dqpsk[8] = {
205 (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
206 (-921 << 5) | 0x14
209 static const int16_t coeff_8k_sb_3seg[8] = {
210 (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
211 (690 << 5) | 0x14
214 static const int16_t ana_fe_coeff_3seg[24] = {
215 81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
218 static const int16_t ana_fe_coeff_1seg[24] = {
219 249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
222 static const int16_t ana_fe_coeff_13seg[24] = {
223 396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
226 static u16 fft_to_mode(struct dib8000_state *state)
228 u16 mode;
229 switch (state->fe.dtv_property_cache.transmission_mode) {
230 case TRANSMISSION_MODE_2K:
231 mode = 1;
232 break;
233 case TRANSMISSION_MODE_4K:
234 mode = 2;
235 break;
236 default:
237 case TRANSMISSION_MODE_AUTO:
238 case TRANSMISSION_MODE_8K:
239 mode = 3;
240 break;
242 return mode;
245 static void dib8000_set_acquisition_mode(struct dib8000_state *state)
247 u16 nud = dib8000_read_word(state, 298);
248 nud |= (1 << 3) | (1 << 0);
249 dprintk("acquisition mode activated");
250 dib8000_write_word(state, 298, nud);
253 static int dib8000_set_output_mode(struct dib8000_state *state, int mode)
255 u16 outreg, fifo_threshold, smo_mode, sram = 0x0205; /* by default SDRAM deintlv is enabled */
257 outreg = 0;
258 fifo_threshold = 1792;
259 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
261 dprintk("-I- Setting output mode for demod %p to %d", &state->fe, mode);
263 switch (mode) {
264 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
265 outreg = (1 << 10); /* 0x0400 */
266 break;
267 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
268 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
269 break;
270 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
271 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
272 break;
273 case OUTMODE_DIVERSITY:
274 if (state->cfg.hostbus_diversity) {
275 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
276 sram &= 0xfdff;
277 } else
278 sram |= 0x0c00;
279 break;
280 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
281 smo_mode |= (3 << 1);
282 fifo_threshold = 512;
283 outreg = (1 << 10) | (5 << 6);
284 break;
285 case OUTMODE_HIGH_Z: // disable
286 outreg = 0;
287 break;
289 case OUTMODE_ANALOG_ADC:
290 outreg = (1 << 10) | (3 << 6);
291 dib8000_set_acquisition_mode(state);
292 break;
294 default:
295 dprintk("Unhandled output_mode passed to be set for demod %p", &state->fe);
296 return -EINVAL;
299 if (state->cfg.output_mpeg2_in_188_bytes)
300 smo_mode |= (1 << 5);
302 dib8000_write_word(state, 299, smo_mode);
303 dib8000_write_word(state, 300, fifo_threshold); /* synchronous fread */
304 dib8000_write_word(state, 1286, outreg);
305 dib8000_write_word(state, 1291, sram);
307 return 0;
310 static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff)
312 struct dib8000_state *state = fe->demodulator_priv;
313 u16 sync_wait = dib8000_read_word(state, 273) & 0xfff0;
315 if (!state->differential_constellation) {
316 dib8000_write_word(state, 272, 1 << 9); //dvsy_off_lmod4 = 1
317 dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2); // sync_enable = 1; comb_mode = 2
318 } else {
319 dib8000_write_word(state, 272, 0); //dvsy_off_lmod4 = 0
320 dib8000_write_word(state, 273, sync_wait); // sync_enable = 0; comb_mode = 0
322 state->diversity_onoff = onoff;
324 switch (onoff) {
325 case 0: /* only use the internal way - not the diversity input */
326 dib8000_write_word(state, 270, 1);
327 dib8000_write_word(state, 271, 0);
328 break;
329 case 1: /* both ways */
330 dib8000_write_word(state, 270, 6);
331 dib8000_write_word(state, 271, 6);
332 break;
333 case 2: /* only the diversity input */
334 dib8000_write_word(state, 270, 0);
335 dib8000_write_word(state, 271, 1);
336 break;
338 return 0;
341 static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_power_mode mode)
343 /* by default everything is going to be powered off */
344 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
345 reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3, reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
347 /* now, depending on the requested mode, we power on */
348 switch (mode) {
349 /* power up everything in the demod */
350 case DIB8000M_POWER_ALL:
351 reg_774 = 0x0000;
352 reg_775 = 0x0000;
353 reg_776 = 0x0000;
354 reg_900 &= 0xfffc;
355 reg_1280 &= 0x00ff;
356 break;
357 case DIB8000M_POWER_INTERFACE_ONLY:
358 reg_1280 &= 0x00ff;
359 break;
362 dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x", reg_774, reg_775, reg_776, reg_900, reg_1280);
363 dib8000_write_word(state, 774, reg_774);
364 dib8000_write_word(state, 775, reg_775);
365 dib8000_write_word(state, 776, reg_776);
366 dib8000_write_word(state, 900, reg_900);
367 dib8000_write_word(state, 1280, reg_1280);
370 static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no)
372 int ret = 0;
373 u16 reg_907 = dib8000_read_word(state, 907), reg_908 = dib8000_read_word(state, 908);
375 switch (no) {
376 case DIBX000_SLOW_ADC_ON:
377 reg_908 |= (1 << 1) | (1 << 0);
378 ret |= dib8000_write_word(state, 908, reg_908);
379 reg_908 &= ~(1 << 1);
380 break;
382 case DIBX000_SLOW_ADC_OFF:
383 reg_908 |= (1 << 1) | (1 << 0);
384 break;
386 case DIBX000_ADC_ON:
387 reg_907 &= 0x0fff;
388 reg_908 &= 0x0003;
389 break;
391 case DIBX000_ADC_OFF: // leave the VBG voltage on
392 reg_907 |= (1 << 14) | (1 << 13) | (1 << 12);
393 reg_908 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
394 break;
396 case DIBX000_VBG_ENABLE:
397 reg_907 &= ~(1 << 15);
398 break;
400 case DIBX000_VBG_DISABLE:
401 reg_907 |= (1 << 15);
402 break;
404 default:
405 break;
408 ret |= dib8000_write_word(state, 907, reg_907);
409 ret |= dib8000_write_word(state, 908, reg_908);
411 return ret;
414 static int dib8000_set_bandwidth(struct dib8000_state *state, u32 bw)
416 u32 timf;
418 if (bw == 0)
419 bw = 6000;
421 if (state->timf == 0) {
422 dprintk("using default timf");
423 timf = state->timf_default;
424 } else {
425 dprintk("using updated timf");
426 timf = state->timf;
429 dib8000_write_word(state, 29, (u16) ((timf >> 16) & 0xffff));
430 dib8000_write_word(state, 30, (u16) ((timf) & 0xffff));
432 return 0;
435 static int dib8000_sad_calib(struct dib8000_state *state)
437 /* internal */
438 dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
439 dib8000_write_word(state, 924, 776); // 0.625*3.3 / 4096
441 /* do the calibration */
442 dib8000_write_word(state, 923, (1 << 0));
443 dib8000_write_word(state, 923, (0 << 0));
445 msleep(1);
446 return 0;
449 int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
451 struct dib8000_state *state = fe->demodulator_priv;
452 if (value > 4095)
453 value = 4095;
454 state->wbd_ref = value;
455 return dib8000_write_word(state, 106, value);
458 EXPORT_SYMBOL(dib8000_set_wbd_ref);
459 static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
461 dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25);
462 dib8000_write_word(state, 23, (u16) (((bw->internal * 1000) >> 16) & 0xffff)); /* P_sec_len */
463 dib8000_write_word(state, 24, (u16) ((bw->internal * 1000) & 0xffff));
464 dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff));
465 dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff));
466 dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003));
468 dib8000_write_word(state, 922, bw->sad_cfg);
471 static void dib8000_reset_pll(struct dib8000_state *state)
473 const struct dibx000_bandwidth_config *pll = state->cfg.pll;
474 u16 clk_cfg1;
476 // clk_cfg0
477 dib8000_write_word(state, 901, (pll->pll_prediv << 8) | (pll->pll_ratio << 0));
479 // clk_cfg1
480 clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
481 (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) | (pll->pll_range << 1) | (pll->pll_reset << 0);
483 dib8000_write_word(state, 902, clk_cfg1);
484 clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
485 dib8000_write_word(state, 902, clk_cfg1);
487 dprintk("clk_cfg1: 0x%04x", clk_cfg1); /* 0x507 1 0 1 000 0 0 11 1 */
489 /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
490 if (state->cfg.pll->ADClkSrc == 0)
491 dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
492 else if (state->cfg.refclksel != 0)
493 dib8000_write_word(state, 904,
494 (0 << 15) | (1 << 12) | ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) | (pll->
495 ADClkSrc << 7) | (0 << 1));
496 else
497 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
499 dib8000_reset_pll_common(state, pll);
502 static int dib8000_reset_gpio(struct dib8000_state *st)
504 /* reset the GPIOs */
505 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
506 dib8000_write_word(st, 1030, st->cfg.gpio_val);
508 /* TODO 782 is P_gpio_od */
510 dib8000_write_word(st, 1032, st->cfg.gpio_pwm_pos);
512 dib8000_write_word(st, 1037, st->cfg.pwm_freq_div);
513 return 0;
516 static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val)
518 st->cfg.gpio_dir = dib8000_read_word(st, 1029);
519 st->cfg.gpio_dir &= ~(1 << num); /* reset the direction bit */
520 st->cfg.gpio_dir |= (dir & 0x1) << num; /* set the new direction */
521 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
523 st->cfg.gpio_val = dib8000_read_word(st, 1030);
524 st->cfg.gpio_val &= ~(1 << num); /* reset the direction bit */
525 st->cfg.gpio_val |= (val & 0x01) << num; /* set the new value */
526 dib8000_write_word(st, 1030, st->cfg.gpio_val);
528 dprintk("gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val);
530 return 0;
533 int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
535 struct dib8000_state *state = fe->demodulator_priv;
536 return dib8000_cfg_gpio(state, num, dir, val);
539 EXPORT_SYMBOL(dib8000_set_gpio);
540 static const u16 dib8000_defaults[] = {
541 /* auto search configuration - lock0 by default waiting
542 * for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */
543 3, 7,
544 0x0004,
545 0x0400,
546 0x0814,
548 12, 11,
549 0x001b,
550 0x7740,
551 0x005b,
552 0x8d80,
553 0x01c9,
554 0xc380,
555 0x0000,
556 0x0080,
557 0x0000,
558 0x0090,
559 0x0001,
560 0xd4c0,
562 /*1, 32,
563 0x6680 // P_corm_thres Lock algorithms configuration */
565 11, 80, /* set ADC level to -16 */
566 (1 << 13) - 825 - 117,
567 (1 << 13) - 837 - 117,
568 (1 << 13) - 811 - 117,
569 (1 << 13) - 766 - 117,
570 (1 << 13) - 737 - 117,
571 (1 << 13) - 693 - 117,
572 (1 << 13) - 648 - 117,
573 (1 << 13) - 619 - 117,
574 (1 << 13) - 575 - 117,
575 (1 << 13) - 531 - 117,
576 (1 << 13) - 501 - 117,
578 4, 108,
584 1, 175,
585 0x0410,
586 1, 179,
587 8192, // P_fft_nb_to_cut
589 6, 181,
590 0x2800, // P_coff_corthres_ ( 2k 4k 8k ) 0x2800
591 0x2800,
592 0x2800,
593 0x2800, // P_coff_cpilthres_ ( 2k 4k 8k ) 0x2800
594 0x2800,
595 0x2800,
597 2, 193,
598 0x0666, // P_pha3_thres
599 0x0000, // P_cti_use_cpe, P_cti_use_prog
601 2, 205,
602 0x200f, // P_cspu_regul, P_cspu_win_cut
603 0x000f, // P_des_shift_work
605 5, 215,
606 0x023d, // P_adp_regul_cnt
607 0x00a4, // P_adp_noise_cnt
608 0x00a4, // P_adp_regul_ext
609 0x7ff0, // P_adp_noise_ext
610 0x3ccc, // P_adp_fil
612 1, 230,
613 0x0000, // P_2d_byp_ti_num
615 1, 263,
616 0x800, //P_equal_thres_wgn
618 1, 268,
619 (2 << 9) | 39, // P_equal_ctrl_synchro, P_equal_speedmode
621 1, 270,
622 0x0001, // P_div_lock0_wait
623 1, 285,
624 0x0020, //p_fec_
625 1, 299,
626 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
628 1, 338,
629 (1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1
630 (1 << 10) | // P_ctrl_pre_freq_mode_sat=1
631 (0 << 9) | // P_ctrl_pre_freq_inh=0
632 (3 << 5) | // P_ctrl_pre_freq_step=3
633 (1 << 0), // P_pre_freq_win_len=1
635 1, 903,
636 (0 << 4) | 2, // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW)
641 static u16 dib8000_identify(struct i2c_device *client)
643 u16 value;
645 //because of glitches sometimes
646 value = dib8000_i2c_read16(client, 896);
648 if ((value = dib8000_i2c_read16(client, 896)) != 0x01b3) {
649 dprintk("wrong Vendor ID (read=0x%x)", value);
650 return 0;
653 value = dib8000_i2c_read16(client, 897);
654 if (value != 0x8000 && value != 0x8001 && value != 0x8002) {
655 dprintk("wrong Device ID (%x)", value);
656 return 0;
659 switch (value) {
660 case 0x8000:
661 dprintk("found DiB8000A");
662 break;
663 case 0x8001:
664 dprintk("found DiB8000B");
665 break;
666 case 0x8002:
667 dprintk("found DiB8000C");
668 break;
670 return value;
673 static int dib8000_reset(struct dvb_frontend *fe)
675 struct dib8000_state *state = fe->demodulator_priv;
677 dib8000_write_word(state, 1287, 0x0003); /* sram lead in, rdy */
679 if ((state->revision = dib8000_identify(&state->i2c)) == 0)
680 return -EINVAL;
682 if (state->revision == 0x8000)
683 dprintk("error : dib8000 MA not supported");
685 dibx000_reset_i2c_master(&state->i2c_master);
687 dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
689 /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
690 dib8000_set_adc_state(state, DIBX000_VBG_ENABLE);
692 /* restart all parts */
693 dib8000_write_word(state, 770, 0xffff);
694 dib8000_write_word(state, 771, 0xffff);
695 dib8000_write_word(state, 772, 0xfffc);
696 dib8000_write_word(state, 898, 0x000c); // sad
697 dib8000_write_word(state, 1280, 0x004d);
698 dib8000_write_word(state, 1281, 0x000c);
700 dib8000_write_word(state, 770, 0x0000);
701 dib8000_write_word(state, 771, 0x0000);
702 dib8000_write_word(state, 772, 0x0000);
703 dib8000_write_word(state, 898, 0x0004); // sad
704 dib8000_write_word(state, 1280, 0x0000);
705 dib8000_write_word(state, 1281, 0x0000);
707 /* drives */
708 if (state->cfg.drives)
709 dib8000_write_word(state, 906, state->cfg.drives);
710 else {
711 dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.");
712 dib8000_write_word(state, 906, 0x2d98); // min drive SDRAM - not optimal - adjust
715 dib8000_reset_pll(state);
717 if (dib8000_reset_gpio(state) != 0)
718 dprintk("GPIO reset was not successful.");
720 if (dib8000_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
721 dprintk("OUTPUT_MODE could not be resetted.");
723 state->current_agc = NULL;
725 // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
726 /* P_iqc_ca2 = 0; P_iqc_impnc_on = 0; P_iqc_mode = 0; */
727 if (state->cfg.pll->ifreq == 0)
728 dib8000_write_word(state, 40, 0x0755); /* P_iqc_corr_inh = 0 enable IQcorr block */
729 else
730 dib8000_write_word(state, 40, 0x1f55); /* P_iqc_corr_inh = 1 disable IQcorr block */
733 u16 l = 0, r;
734 const u16 *n;
735 n = dib8000_defaults;
736 l = *n++;
737 while (l) {
738 r = *n++;
739 do {
740 dib8000_write_word(state, r, *n++);
741 r++;
742 } while (--l);
743 l = *n++;
746 state->isdbt_cfg_loaded = 0;
748 //div_cfg override for special configs
749 if (state->cfg.div_cfg != 0)
750 dib8000_write_word(state, 903, state->cfg.div_cfg);
752 /* unforce divstr regardless whether i2c enumeration was done or not */
753 dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1));
755 dib8000_set_bandwidth(state, 6000);
757 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
758 dib8000_sad_calib(state);
759 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
761 dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY);
763 return 0;
766 static void dib8000_restart_agc(struct dib8000_state *state)
768 // P_restart_iqc & P_restart_agc
769 dib8000_write_word(state, 770, 0x0a00);
770 dib8000_write_word(state, 770, 0x0000);
773 static int dib8000_update_lna(struct dib8000_state *state)
775 u16 dyn_gain;
777 if (state->cfg.update_lna) {
778 // read dyn_gain here (because it is demod-dependent and not tuner)
779 dyn_gain = dib8000_read_word(state, 390);
781 if (state->cfg.update_lna(&state->fe, dyn_gain)) { // LNA has changed
782 dib8000_restart_agc(state);
783 return 1;
786 return 0;
789 static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
791 struct dibx000_agc_config *agc = NULL;
792 int i;
793 if (state->current_band == band && state->current_agc != NULL)
794 return 0;
795 state->current_band = band;
797 for (i = 0; i < state->cfg.agc_config_count; i++)
798 if (state->cfg.agc[i].band_caps & band) {
799 agc = &state->cfg.agc[i];
800 break;
803 if (agc == NULL) {
804 dprintk("no valid AGC configuration found for band 0x%02x", band);
805 return -EINVAL;
808 state->current_agc = agc;
810 /* AGC */
811 dib8000_write_word(state, 76, agc->setup);
812 dib8000_write_word(state, 77, agc->inv_gain);
813 dib8000_write_word(state, 78, agc->time_stabiliz);
814 dib8000_write_word(state, 101, (agc->alpha_level << 12) | agc->thlock);
816 // Demod AGC loop configuration
817 dib8000_write_word(state, 102, (agc->alpha_mant << 5) | agc->alpha_exp);
818 dib8000_write_word(state, 103, (agc->beta_mant << 6) | agc->beta_exp);
820 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
821 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
823 /* AGC continued */
824 if (state->wbd_ref != 0)
825 dib8000_write_word(state, 106, state->wbd_ref);
826 else // use default
827 dib8000_write_word(state, 106, agc->wbd_ref);
828 dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
829 dib8000_write_word(state, 108, agc->agc1_max);
830 dib8000_write_word(state, 109, agc->agc1_min);
831 dib8000_write_word(state, 110, agc->agc2_max);
832 dib8000_write_word(state, 111, agc->agc2_min);
833 dib8000_write_word(state, 112, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
834 dib8000_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
835 dib8000_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
836 dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
838 dib8000_write_word(state, 75, agc->agc1_pt3);
839 dib8000_write_word(state, 923, (dib8000_read_word(state, 923) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2)); /*LB : 929 -> 923 */
841 return 0;
844 void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
846 struct dib8000_state *state = fe->demodulator_priv;
847 dib8000_set_adc_state(state, DIBX000_ADC_ON);
848 dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000)));
850 EXPORT_SYMBOL(dib8000_pwm_agc_reset);
852 static int dib8000_agc_soft_split(struct dib8000_state *state)
854 u16 agc, split_offset;
856 if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
857 return FE_CALLBACK_TIME_NEVER;
859 // n_agc_global
860 agc = dib8000_read_word(state, 390);
862 if (agc > state->current_agc->split.min_thres)
863 split_offset = state->current_agc->split.min;
864 else if (agc < state->current_agc->split.max_thres)
865 split_offset = state->current_agc->split.max;
866 else
867 split_offset = state->current_agc->split.max *
868 (agc - state->current_agc->split.min_thres) / (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
870 dprintk("AGC split_offset: %d", split_offset);
872 // P_agc_force_split and P_agc_split_offset
873 dib8000_write_word(state, 107, (dib8000_read_word(state, 107) & 0xff00) | split_offset);
874 return 5000;
877 static int dib8000_agc_startup(struct dvb_frontend *fe)
879 struct dib8000_state *state = fe->demodulator_priv;
880 enum frontend_tune_state *tune_state = &state->tune_state;
882 int ret = 0;
884 switch (*tune_state) {
885 case CT_AGC_START:
886 // set power-up level: interf+analog+AGC
888 dib8000_set_adc_state(state, DIBX000_ADC_ON);
890 if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) {
891 *tune_state = CT_AGC_STOP;
892 state->status = FE_STATUS_TUNE_FAILED;
893 break;
896 ret = 70;
897 *tune_state = CT_AGC_STEP_0;
898 break;
900 case CT_AGC_STEP_0:
901 //AGC initialization
902 if (state->cfg.agc_control)
903 state->cfg.agc_control(&state->fe, 1);
905 dib8000_restart_agc(state);
907 // wait AGC rough lock time
908 ret = 50;
909 *tune_state = CT_AGC_STEP_1;
910 break;
912 case CT_AGC_STEP_1:
913 // wait AGC accurate lock time
914 ret = 70;
916 if (dib8000_update_lna(state))
917 // wait only AGC rough lock time
918 ret = 50;
919 else
920 *tune_state = CT_AGC_STEP_2;
921 break;
923 case CT_AGC_STEP_2:
924 dib8000_agc_soft_split(state);
926 if (state->cfg.agc_control)
927 state->cfg.agc_control(&state->fe, 0);
929 *tune_state = CT_AGC_STOP;
930 break;
931 default:
932 ret = dib8000_agc_soft_split(state);
933 break;
935 return ret;
939 static const int32_t lut_1000ln_mant[] =
941 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600
944 int32_t dib8000_get_adc_power(struct dvb_frontend *fe, uint8_t mode)
946 struct dib8000_state *state = fe->demodulator_priv;
947 uint32_t ix = 0, tmp_val = 0, exp = 0, mant = 0;
948 int32_t val;
950 val = dib8000_read32(state, 384);
951 /* mode = 1 : ln_agcpower calc using mant-exp conversion and mantis look up table */
952 if (mode) {
953 tmp_val = val;
954 while (tmp_val >>= 1)
955 exp++;
956 mant = (val * 1000 / (1<<exp));
957 ix = (uint8_t)((mant-1000)/100); /* index of the LUT */
958 val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908); /* 1000 * ln(adcpower_real) ; 693 = 1000ln(2) ; 6908 = 1000*ln(1000) ; 20 comes from adc_real = adc_pow_int / 2**20 */
959 val = (val*256)/1000;
961 return val;
963 EXPORT_SYMBOL(dib8000_get_adc_power);
965 static void dib8000_update_timf(struct dib8000_state *state)
967 u32 timf = state->timf = dib8000_read32(state, 435);
969 dib8000_write_word(state, 29, (u16) (timf >> 16));
970 dib8000_write_word(state, 30, (u16) (timf & 0xffff));
971 dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
974 static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
976 u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
977 u8 guard, crate, constellation, timeI;
978 u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
979 u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled
980 const s16 *ncoeff = NULL, *ana_fe;
981 u16 tmcc_pow = 0;
982 u16 coff_pow = 0x2800;
983 u16 init_prbs = 0xfff;
984 u16 ana_gain = 0;
985 u16 adc_target_16dB[11] = {
986 (1 << 13) - 825 - 117,
987 (1 << 13) - 837 - 117,
988 (1 << 13) - 811 - 117,
989 (1 << 13) - 766 - 117,
990 (1 << 13) - 737 - 117,
991 (1 << 13) - 693 - 117,
992 (1 << 13) - 648 - 117,
993 (1 << 13) - 619 - 117,
994 (1 << 13) - 575 - 117,
995 (1 << 13) - 531 - 117,
996 (1 << 13) - 501 - 117
999 if (state->ber_monitored_layer != LAYER_ALL)
1000 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
1001 else
1002 dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
1004 i = dib8000_read_word(state, 26) & 1; // P_dds_invspec
1005 dib8000_write_word(state, 26, state->fe.dtv_property_cache.inversion ^ i);
1007 if (state->fe.dtv_property_cache.isdbt_sb_mode) {
1008 //compute new dds_freq for the seg and adjust prbs
1009 int seg_offset =
1010 state->fe.dtv_property_cache.isdbt_sb_segment_idx - (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) -
1011 (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2);
1012 int clk = state->cfg.pll->internal;
1013 u32 segtodds = ((u32) (430 << 23) / clk) << 3; // segtodds = SegBW / Fclk * pow(2,26)
1014 int dds_offset = seg_offset * segtodds;
1015 int new_dds, sub_channel;
1016 if ((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0) // if even
1017 dds_offset -= (int)(segtodds / 2);
1019 if (state->cfg.pll->ifreq == 0) {
1020 if ((state->fe.dtv_property_cache.inversion ^ i) == 0) {
1021 dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
1022 new_dds = dds_offset;
1023 } else
1024 new_dds = dds_offset;
1026 // We shift tuning frequency if the wanted segment is :
1027 // - the segment of center frequency with an odd total number of segments
1028 // - the segment to the left of center frequency with an even total number of segments
1029 // - the segment to the right of center frequency with an even total number of segments
1030 if ((state->fe.dtv_property_cache.delivery_system == SYS_ISDBT) && (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
1032 (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2)
1033 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx ==
1034 ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1035 || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1036 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx == (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2)))
1037 || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1038 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx ==
1039 ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1040 )) {
1041 new_dds -= ((u32) (850 << 22) / clk) << 4; // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26)
1043 } else {
1044 if ((state->fe.dtv_property_cache.inversion ^ i) == 0)
1045 new_dds = state->cfg.pll->ifreq - dds_offset;
1046 else
1047 new_dds = state->cfg.pll->ifreq + dds_offset;
1049 dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff));
1050 dib8000_write_word(state, 28, (u16) (new_dds & 0xffff));
1051 if (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) // if odd
1052 sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3;
1053 else // if even
1054 sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3;
1055 sub_channel -= 6;
1057 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K
1058 || state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) {
1059 dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); //adp_pass =1
1060 dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); //pha3_force_pha_shift = 1
1061 } else {
1062 dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); //adp_pass =0
1063 dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0
1066 switch (state->fe.dtv_property_cache.transmission_mode) {
1067 case TRANSMISSION_MODE_2K:
1068 switch (sub_channel) {
1069 case -6:
1070 init_prbs = 0x0;
1071 break; // 41, 0, 1
1072 case -5:
1073 init_prbs = 0x423;
1074 break; // 02~04
1075 case -4:
1076 init_prbs = 0x9;
1077 break; // 05~07
1078 case -3:
1079 init_prbs = 0x5C7;
1080 break; // 08~10
1081 case -2:
1082 init_prbs = 0x7A6;
1083 break; // 11~13
1084 case -1:
1085 init_prbs = 0x3D8;
1086 break; // 14~16
1087 case 0:
1088 init_prbs = 0x527;
1089 break; // 17~19
1090 case 1:
1091 init_prbs = 0x7FF;
1092 break; // 20~22
1093 case 2:
1094 init_prbs = 0x79B;
1095 break; // 23~25
1096 case 3:
1097 init_prbs = 0x3D6;
1098 break; // 26~28
1099 case 4:
1100 init_prbs = 0x3A2;
1101 break; // 29~31
1102 case 5:
1103 init_prbs = 0x53B;
1104 break; // 32~34
1105 case 6:
1106 init_prbs = 0x2F4;
1107 break; // 35~37
1108 default:
1109 case 7:
1110 init_prbs = 0x213;
1111 break; // 38~40
1113 break;
1115 case TRANSMISSION_MODE_4K:
1116 switch (sub_channel) {
1117 case -6:
1118 init_prbs = 0x0;
1119 break; // 41, 0, 1
1120 case -5:
1121 init_prbs = 0x208;
1122 break; // 02~04
1123 case -4:
1124 init_prbs = 0xC3;
1125 break; // 05~07
1126 case -3:
1127 init_prbs = 0x7B9;
1128 break; // 08~10
1129 case -2:
1130 init_prbs = 0x423;
1131 break; // 11~13
1132 case -1:
1133 init_prbs = 0x5C7;
1134 break; // 14~16
1135 case 0:
1136 init_prbs = 0x3D8;
1137 break; // 17~19
1138 case 1:
1139 init_prbs = 0x7FF;
1140 break; // 20~22
1141 case 2:
1142 init_prbs = 0x3D6;
1143 break; // 23~25
1144 case 3:
1145 init_prbs = 0x53B;
1146 break; // 26~28
1147 case 4:
1148 init_prbs = 0x213;
1149 break; // 29~31
1150 case 5:
1151 init_prbs = 0x29;
1152 break; // 32~34
1153 case 6:
1154 init_prbs = 0xD0;
1155 break; // 35~37
1156 default:
1157 case 7:
1158 init_prbs = 0x48E;
1159 break; // 38~40
1161 break;
1163 default:
1164 case TRANSMISSION_MODE_8K:
1165 switch (sub_channel) {
1166 case -6:
1167 init_prbs = 0x0;
1168 break; // 41, 0, 1
1169 case -5:
1170 init_prbs = 0x740;
1171 break; // 02~04
1172 case -4:
1173 init_prbs = 0x069;
1174 break; // 05~07
1175 case -3:
1176 init_prbs = 0x7DD;
1177 break; // 08~10
1178 case -2:
1179 init_prbs = 0x208;
1180 break; // 11~13
1181 case -1:
1182 init_prbs = 0x7B9;
1183 break; // 14~16
1184 case 0:
1185 init_prbs = 0x5C7;
1186 break; // 17~19
1187 case 1:
1188 init_prbs = 0x7FF;
1189 break; // 20~22
1190 case 2:
1191 init_prbs = 0x53B;
1192 break; // 23~25
1193 case 3:
1194 init_prbs = 0x29;
1195 break; // 26~28
1196 case 4:
1197 init_prbs = 0x48E;
1198 break; // 29~31
1199 case 5:
1200 init_prbs = 0x4C4;
1201 break; // 32~34
1202 case 6:
1203 init_prbs = 0x367;
1204 break; // 33~37
1205 default:
1206 case 7:
1207 init_prbs = 0x684;
1208 break; // 38~40
1210 break;
1212 } else { // if not state->fe.dtv_property_cache.isdbt_sb_mode
1213 dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff));
1214 dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff));
1215 dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003));
1217 /*P_mode == ?? */
1218 dib8000_write_word(state, 10, (seq << 4));
1219 // dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000);
1221 switch (state->fe.dtv_property_cache.guard_interval) {
1222 case GUARD_INTERVAL_1_32:
1223 guard = 0;
1224 break;
1225 case GUARD_INTERVAL_1_16:
1226 guard = 1;
1227 break;
1228 case GUARD_INTERVAL_1_8:
1229 guard = 2;
1230 break;
1231 case GUARD_INTERVAL_1_4:
1232 default:
1233 guard = 3;
1234 break;
1237 dib8000_write_word(state, 1, (init_prbs << 2) | (guard & 0x3)); // ADDR 1
1239 max_constellation = DQPSK;
1240 for (i = 0; i < 3; i++) {
1241 switch (state->fe.dtv_property_cache.layer[i].modulation) {
1242 case DQPSK:
1243 constellation = 0;
1244 break;
1245 case QPSK:
1246 constellation = 1;
1247 break;
1248 case QAM_16:
1249 constellation = 2;
1250 break;
1251 case QAM_64:
1252 default:
1253 constellation = 3;
1254 break;
1257 switch (state->fe.dtv_property_cache.layer[i].fec) {
1258 case FEC_1_2:
1259 crate = 1;
1260 break;
1261 case FEC_2_3:
1262 crate = 2;
1263 break;
1264 case FEC_3_4:
1265 crate = 3;
1266 break;
1267 case FEC_5_6:
1268 crate = 5;
1269 break;
1270 case FEC_7_8:
1271 default:
1272 crate = 7;
1273 break;
1276 if ((state->fe.dtv_property_cache.layer[i].interleaving > 0) &&
1277 ((state->fe.dtv_property_cache.layer[i].interleaving <= 3) ||
1278 (state->fe.dtv_property_cache.layer[i].interleaving == 4 && state->fe.dtv_property_cache.isdbt_sb_mode == 1))
1280 timeI = state->fe.dtv_property_cache.layer[i].interleaving;
1281 else
1282 timeI = 0;
1283 dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe.dtv_property_cache.layer[i].segment_count & 0xf) << 6) |
1284 (crate << 3) | timeI);
1285 if (state->fe.dtv_property_cache.layer[i].segment_count > 0) {
1286 switch (max_constellation) {
1287 case DQPSK:
1288 case QPSK:
1289 if (state->fe.dtv_property_cache.layer[i].modulation == QAM_16 ||
1290 state->fe.dtv_property_cache.layer[i].modulation == QAM_64)
1291 max_constellation = state->fe.dtv_property_cache.layer[i].modulation;
1292 break;
1293 case QAM_16:
1294 if (state->fe.dtv_property_cache.layer[i].modulation == QAM_64)
1295 max_constellation = state->fe.dtv_property_cache.layer[i].modulation;
1296 break;
1301 mode = fft_to_mode(state);
1303 //dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/
1305 dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) |
1306 ((state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe.dtv_property_cache.
1307 isdbt_sb_mode & 1) << 4));
1309 dprintk("mode = %d ; guard = %d", mode, state->fe.dtv_property_cache.guard_interval);
1311 /* signal optimization parameter */
1313 if (state->fe.dtv_property_cache.isdbt_partial_reception) {
1314 seg_diff_mask = (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0];
1315 for (i = 1; i < 3; i++)
1316 nbseg_diff +=
1317 (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count;
1318 for (i = 0; i < nbseg_diff; i++)
1319 seg_diff_mask |= 1 << permu_seg[i + 1];
1320 } else {
1321 for (i = 0; i < 3; i++)
1322 nbseg_diff +=
1323 (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count;
1324 for (i = 0; i < nbseg_diff; i++)
1325 seg_diff_mask |= 1 << permu_seg[i];
1327 dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask);
1329 state->differential_constellation = (seg_diff_mask != 0);
1330 dib8000_set_diversity_in(&state->fe, state->diversity_onoff);
1332 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb
1333 if (state->fe.dtv_property_cache.isdbt_partial_reception == 1) // 3-segments
1334 seg_mask13 = 0x00E0;
1335 else // 1-segment
1336 seg_mask13 = 0x0040;
1337 } else
1338 seg_mask13 = 0x1fff;
1340 // WRITE: Mode & Diff mask
1341 dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask);
1343 if ((seg_diff_mask) || (state->fe.dtv_property_cache.isdbt_sb_mode))
1344 dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
1345 else
1346 dib8000_write_word(state, 268, (2 << 9) | 39); //init value
1348 // ---- SMALL ----
1349 // P_small_seg_diff
1350 dib8000_write_word(state, 352, seg_diff_mask); // ADDR 352
1352 dib8000_write_word(state, 353, seg_mask13); // ADDR 353
1354 /* // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */
1355 // dib8000_write_word(state, 351, (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5 );
1357 // ---- SMALL ----
1358 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1359 switch (state->fe.dtv_property_cache.transmission_mode) {
1360 case TRANSMISSION_MODE_2K:
1361 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg
1362 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK
1363 ncoeff = coeff_2k_sb_1seg_dqpsk;
1364 else // QPSK or QAM
1365 ncoeff = coeff_2k_sb_1seg;
1366 } else { // 3-segments
1367 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment
1368 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments
1369 ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
1370 else // QPSK or QAM on external segments
1371 ncoeff = coeff_2k_sb_3seg_0dqpsk;
1372 } else { // QPSK or QAM on central segment
1373 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments
1374 ncoeff = coeff_2k_sb_3seg_1dqpsk;
1375 else // QPSK or QAM on external segments
1376 ncoeff = coeff_2k_sb_3seg;
1379 break;
1381 case TRANSMISSION_MODE_4K:
1382 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg
1383 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK
1384 ncoeff = coeff_4k_sb_1seg_dqpsk;
1385 else // QPSK or QAM
1386 ncoeff = coeff_4k_sb_1seg;
1387 } else { // 3-segments
1388 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment
1389 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
1390 ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
1391 } else { // QPSK or QAM on external segments
1392 ncoeff = coeff_4k_sb_3seg_0dqpsk;
1394 } else { // QPSK or QAM on central segment
1395 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
1396 ncoeff = coeff_4k_sb_3seg_1dqpsk;
1397 } else // QPSK or QAM on external segments
1398 ncoeff = coeff_4k_sb_3seg;
1401 break;
1403 case TRANSMISSION_MODE_AUTO:
1404 case TRANSMISSION_MODE_8K:
1405 default:
1406 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg
1407 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK
1408 ncoeff = coeff_8k_sb_1seg_dqpsk;
1409 else // QPSK or QAM
1410 ncoeff = coeff_8k_sb_1seg;
1411 } else { // 3-segments
1412 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment
1413 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
1414 ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
1415 } else { // QPSK or QAM on external segments
1416 ncoeff = coeff_8k_sb_3seg_0dqpsk;
1418 } else { // QPSK or QAM on central segment
1419 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
1420 ncoeff = coeff_8k_sb_3seg_1dqpsk;
1421 } else // QPSK or QAM on external segments
1422 ncoeff = coeff_8k_sb_3seg;
1425 break;
1427 for (i = 0; i < 8; i++)
1428 dib8000_write_word(state, 343 + i, ncoeff[i]);
1431 // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5
1432 dib8000_write_word(state, 351,
1433 (state->fe.dtv_property_cache.isdbt_sb_mode << 9) | (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5);
1435 // ---- COFF ----
1436 // Carloff, the most robust
1437 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // Sound Broadcasting mode - use both TMCC and AC pilots
1439 // P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64
1440 // 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
1441 dib8000_write_word(state, 187,
1442 (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 2)
1443 | 0x3);
1445 /* // P_small_coef_ext_enable = 1 */
1446 /* dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */
1448 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // Sound Broadcasting mode 1 seg
1450 // 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)
1451 if (mode == 3)
1452 dib8000_write_word(state, 180, 0x1fcf | ((mode - 1) << 14));
1453 else
1454 dib8000_write_word(state, 180, 0x0fcf | ((mode - 1) << 14));
1455 // P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1,
1456 // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4
1457 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
1458 // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
1459 dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
1460 // P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
1461 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1463 // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
1464 dib8000_write_word(state, 181, 300);
1465 dib8000_write_word(state, 182, 150);
1466 dib8000_write_word(state, 183, 80);
1467 dib8000_write_word(state, 184, 300);
1468 dib8000_write_word(state, 185, 150);
1469 dib8000_write_word(state, 186, 80);
1470 } else { // Sound Broadcasting mode 3 seg
1471 // P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15
1472 /* if (mode == 3) */
1473 /* dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */
1474 /* else */
1475 /* dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */
1476 dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
1478 // P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1,
1479 // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4
1480 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
1481 // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
1482 dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
1483 //P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
1484 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1486 // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
1487 dib8000_write_word(state, 181, 350);
1488 dib8000_write_word(state, 182, 300);
1489 dib8000_write_word(state, 183, 250);
1490 dib8000_write_word(state, 184, 350);
1491 dib8000_write_word(state, 185, 300);
1492 dib8000_write_word(state, 186, 250);
1495 } else if (state->isdbt_cfg_loaded == 0) { // if not Sound Broadcasting mode : put default values for 13 segments
1496 dib8000_write_word(state, 180, (16 << 6) | 9);
1497 dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2);
1498 coff_pow = 0x2800;
1499 for (i = 0; i < 6; i++)
1500 dib8000_write_word(state, 181 + i, coff_pow);
1502 // P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1,
1503 // 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
1504 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1);
1506 // P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6
1507 dib8000_write_word(state, 340, (8 << 6) | (6 << 0));
1508 // P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1
1509 dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1511 // ---- FFT ----
1512 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 && state->fe.dtv_property_cache.isdbt_partial_reception == 0) // 1-seg
1513 dib8000_write_word(state, 178, 64); // P_fft_powrange=64
1514 else
1515 dib8000_write_word(state, 178, 32); // P_fft_powrange=32
1517 /* make the cpil_coff_lock more robust but slower p_coff_winlen
1518 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
1520 /* if ( ( nbseg_diff>0)&&(nbseg_diff<13))
1521 dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */
1523 dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask); /* P_lmod4_seg_inh */
1524 dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask); /* P_pha3_seg_inh */
1525 dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask); /* P_tac_seg_inh */
1526 if ((!state->fe.dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0))
1527 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */
1528 else
1529 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask); /* P_equal_noise_seg_inh */
1530 dib8000_write_word(state, 287, ~seg_mask13 | 0x1000); /* P_tmcc_seg_inh */
1531 //dib8000_write_word(state, 288, ~seg_mask13 | seg_diff_mask); /* P_tmcc_seg_eq_inh */
1532 if (!autosearching)
1533 dib8000_write_word(state, 288, (~seg_mask13 | seg_diff_mask) & 0x1fff); /* P_tmcc_seg_eq_inh */
1534 else
1535 dib8000_write_word(state, 288, 0x1fff); //disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels.
1536 dprintk("287 = %X (%d)", ~seg_mask13 | 0x1000, ~seg_mask13 | 0x1000);
1538 dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask)); /* P_des_seg_enabled */
1540 /* offset loop parameters */
1541 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1542 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg
1543 /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1544 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40);
1546 else // Sound Broadcasting mode 3 seg
1547 /* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1548 dib8000_write_word(state, 32, ((10 - mode) << 12) | (6 << 8) | 0x60);
1549 } else
1550 // TODO in 13 seg, timf_alpha can always be the same or not ?
1551 /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
1552 dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80);
1554 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1555 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg
1556 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (11-P_mode) */
1557 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode));
1559 else // Sound Broadcasting mode 3 seg
1560 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (10-P_mode) */
1561 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (9 - mode));
1562 } else
1563 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = 9 */
1564 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode));
1566 /* P_dvsy_sync_wait - reuse mode */
1567 switch (state->fe.dtv_property_cache.transmission_mode) {
1568 case TRANSMISSION_MODE_8K:
1569 mode = 256;
1570 break;
1571 case TRANSMISSION_MODE_4K:
1572 mode = 128;
1573 break;
1574 default:
1575 case TRANSMISSION_MODE_2K:
1576 mode = 64;
1577 break;
1579 if (state->cfg.diversity_delay == 0)
1580 mode = (mode * (1 << (guard)) * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo
1581 else
1582 mode = (mode * (1 << (guard)) * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for DVSY-fifo
1583 mode <<= 4;
1584 dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | mode);
1586 /* channel estimation fine configuration */
1587 switch (max_constellation) {
1588 case QAM_64:
1589 ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
1590 coeff[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
1591 coeff[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
1592 coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1593 coeff[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
1594 //if (!state->cfg.hostbus_diversity) //if diversity, we should prehaps use the configuration of the max_constallation -1
1595 break;
1596 case QAM_16:
1597 ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
1598 coeff[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
1599 coeff[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
1600 coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1601 coeff[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
1602 //if (!((state->cfg.hostbus_diversity) && (max_constellation == QAM_16)))
1603 break;
1604 default:
1605 ana_gain = 0; // 0 : goes along with ADC target at -22dB to keep good mobile performance and lock at sensitivity level
1606 coeff[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
1607 coeff[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
1608 coeff[2] = 0x0333; /* P_adp_regul_ext 0.1 */
1609 coeff[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
1610 break;
1612 for (mode = 0; mode < 4; mode++)
1613 dib8000_write_word(state, 215 + mode, coeff[mode]);
1615 // update ana_gain depending on max constellation
1616 dib8000_write_word(state, 116, ana_gain);
1617 // update ADC target depending on ana_gain
1618 if (ana_gain) { // set -16dB ADC target for ana_gain=-1
1619 for (i = 0; i < 10; i++)
1620 dib8000_write_word(state, 80 + i, adc_target_16dB[i]);
1621 } else { // set -22dB ADC target for ana_gain=0
1622 for (i = 0; i < 10; i++)
1623 dib8000_write_word(state, 80 + i, adc_target_16dB[i] - 355);
1626 // ---- ANA_FE ----
1627 if (state->fe.dtv_property_cache.isdbt_sb_mode) {
1628 if (state->fe.dtv_property_cache.isdbt_partial_reception == 1) // 3-segments
1629 ana_fe = ana_fe_coeff_3seg;
1630 else // 1-segment
1631 ana_fe = ana_fe_coeff_1seg;
1632 } else
1633 ana_fe = ana_fe_coeff_13seg;
1635 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0)
1636 for (mode = 0; mode < 24; mode++)
1637 dib8000_write_word(state, 117 + mode, ana_fe[mode]);
1639 // ---- CHAN_BLK ----
1640 for (i = 0; i < 13; i++) {
1641 if ((((~seg_diff_mask) >> i) & 1) == 1) {
1642 P_cfr_left_edge += (1 << i) * ((i == 0) || ((((seg_mask13 & (~seg_diff_mask)) >> (i - 1)) & 1) == 0));
1643 P_cfr_right_edge += (1 << i) * ((i == 12) || ((((seg_mask13 & (~seg_diff_mask)) >> (i + 1)) & 1) == 0));
1646 dib8000_write_word(state, 222, P_cfr_left_edge); // P_cfr_left_edge
1647 dib8000_write_word(state, 223, P_cfr_right_edge); // P_cfr_right_edge
1648 // "P_cspu_left_edge" not used => do not care
1649 // "P_cspu_right_edge" not used => do not care
1651 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb
1652 dib8000_write_word(state, 228, 1); // P_2d_mode_byp=1
1653 dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); // P_cspu_win_cut = 0
1654 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0 // 1-segment
1655 && state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) {
1656 //dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0
1657 dib8000_write_word(state, 265, 15); // P_equal_noise_sel = 15
1659 } else if (state->isdbt_cfg_loaded == 0) {
1660 dib8000_write_word(state, 228, 0); // default value
1661 dib8000_write_word(state, 265, 31); // default value
1662 dib8000_write_word(state, 205, 0x200f); // init value
1664 // ---- TMCC ----
1665 for (i = 0; i < 3; i++)
1666 tmcc_pow +=
1667 (((state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe.dtv_property_cache.layer[i].segment_count);
1668 // Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9);
1669 // Threshold is set at 1/4 of max power.
1670 tmcc_pow *= (1 << (9 - 2));
1672 dib8000_write_word(state, 290, tmcc_pow); // P_tmcc_dec_thres_2k
1673 dib8000_write_word(state, 291, tmcc_pow); // P_tmcc_dec_thres_4k
1674 dib8000_write_word(state, 292, tmcc_pow); // P_tmcc_dec_thres_8k
1675 //dib8000_write_word(state, 287, (1 << 13) | 0x1000 );
1676 // ---- PHA3 ----
1678 if (state->isdbt_cfg_loaded == 0)
1679 dib8000_write_word(state, 250, 3285); /*p_2d_hspeed_thr0 */
1681 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
1682 state->isdbt_cfg_loaded = 0;
1683 else
1684 state->isdbt_cfg_loaded = 1;
1688 static int dib8000_autosearch_start(struct dvb_frontend *fe)
1690 u8 factor;
1691 u32 value;
1692 struct dib8000_state *state = fe->demodulator_priv;
1694 int slist = 0;
1696 state->fe.dtv_property_cache.inversion = 0;
1697 if (!state->fe.dtv_property_cache.isdbt_sb_mode)
1698 state->fe.dtv_property_cache.layer[0].segment_count = 13;
1699 state->fe.dtv_property_cache.layer[0].modulation = QAM_64;
1700 state->fe.dtv_property_cache.layer[0].fec = FEC_2_3;
1701 state->fe.dtv_property_cache.layer[0].interleaving = 0;
1703 //choose the right list, in sb, always do everything
1704 if (state->fe.dtv_property_cache.isdbt_sb_mode) {
1705 state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1706 state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1707 slist = 7;
1708 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));
1709 } else {
1710 if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) {
1711 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1712 slist = 7;
1713 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 to have autosearch start ok with mode2
1714 } else
1715 slist = 3;
1716 } else {
1717 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1718 slist = 2;
1719 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
1720 } else
1721 slist = 0;
1724 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO)
1725 state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1726 if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO)
1727 state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1729 dprintk("using list for autosearch : %d", slist);
1730 dib8000_set_channel(state, (unsigned char)slist, 1);
1731 //dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
1733 factor = 1;
1735 //set lock_mask values
1736 dib8000_write_word(state, 6, 0x4);
1737 dib8000_write_word(state, 7, 0x8);
1738 dib8000_write_word(state, 8, 0x1000);
1740 //set lock_mask wait time values
1741 value = 50 * state->cfg.pll->internal * factor;
1742 dib8000_write_word(state, 11, (u16) ((value >> 16) & 0xffff)); // lock0 wait time
1743 dib8000_write_word(state, 12, (u16) (value & 0xffff)); // lock0 wait time
1744 value = 100 * state->cfg.pll->internal * factor;
1745 dib8000_write_word(state, 13, (u16) ((value >> 16) & 0xffff)); // lock1 wait time
1746 dib8000_write_word(state, 14, (u16) (value & 0xffff)); // lock1 wait time
1747 value = 1000 * state->cfg.pll->internal * factor;
1748 dib8000_write_word(state, 15, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
1749 dib8000_write_word(state, 16, (u16) (value & 0xffff)); // lock2 wait time
1751 value = dib8000_read_word(state, 0);
1752 dib8000_write_word(state, 0, (u16) ((1 << 15) | value));
1753 dib8000_read_word(state, 1284); // reset the INT. n_irq_pending
1754 dib8000_write_word(state, 0, (u16) value);
1758 return 0;
1761 static int dib8000_autosearch_irq(struct dvb_frontend *fe)
1763 struct dib8000_state *state = fe->demodulator_priv;
1764 u16 irq_pending = dib8000_read_word(state, 1284);
1766 if (irq_pending & 0x1) { // failed
1767 dprintk("dib8000_autosearch_irq failed");
1768 return 1;
1771 if (irq_pending & 0x2) { // succeeded
1772 dprintk("dib8000_autosearch_irq succeeded");
1773 return 2;
1776 return 0; // still pending
1779 static int dib8000_tune(struct dvb_frontend *fe)
1781 struct dib8000_state *state = fe->demodulator_priv;
1782 int ret = 0;
1783 u16 value, mode = fft_to_mode(state);
1785 // we are already tuned - just resuming from suspend
1786 if (state == NULL)
1787 return -EINVAL;
1789 dib8000_set_bandwidth(state, state->fe.dtv_property_cache.bandwidth_hz / 1000);
1790 dib8000_set_channel(state, 0, 0);
1792 // restart demod
1793 ret |= dib8000_write_word(state, 770, 0x4000);
1794 ret |= dib8000_write_word(state, 770, 0x0000);
1795 msleep(45);
1797 /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3 */
1798 /* ret |= dib8000_write_word(state, 29, (0 << 9) | (4 << 5) | (0 << 4) | (3 << 0) ); workaround inh_isi stays at 1 */
1800 // never achieved a lock before - wait for timfreq to update
1801 if (state->timf == 0) {
1802 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1803 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg
1804 msleep(300);
1805 else // Sound Broadcasting mode 3 seg
1806 msleep(500);
1807 } else // 13 seg
1808 msleep(200);
1810 //dump_reg(state);
1811 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1812 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // Sound Broadcasting mode 1 seg
1814 /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40 alpha to check on board */
1815 dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40);
1816 //dib8000_write_word(state, 32, (8 << 12) | (6 << 8) | 0x80);
1818 /* P_ctrl_sfreq_step= (12-P_mode) P_ctrl_sfreq_inh =0 P_ctrl_pha_off_max */
1819 ret |= dib8000_write_word(state, 37, (12 - mode) | ((5 + mode) << 5));
1821 } else { // Sound Broadcasting mode 3 seg
1823 /* P_timf_alpha = (12-P_mode) , P_corm_alpha=6, P_corm_thres=0x60 alpha to check on board */
1824 dib8000_write_word(state, 32, ((12 - mode) << 12) | (6 << 8) | 0x60);
1826 ret |= dib8000_write_word(state, 37, (11 - mode) | ((5 + mode) << 5));
1829 } else { // 13 seg
1830 /* P_timf_alpha = 8 , P_corm_alpha=6, P_corm_thres=0x80 alpha to check on board */
1831 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x80);
1833 ret |= dib8000_write_word(state, 37, (10 - mode) | ((5 + mode) << 5));
1837 // we achieved a coff_cpil_lock - it's time to update the timf
1838 if ((dib8000_read_word(state, 568) >> 11) & 0x1)
1839 dib8000_update_timf(state);
1841 //now that tune is finished, lock0 should lock on fec_mpeg to output this lock on MP_LOCK. It's changed in autosearch start
1842 dib8000_write_word(state, 6, 0x200);
1844 if (state->revision == 0x8002) {
1845 value = dib8000_read_word(state, 903);
1846 dib8000_write_word(state, 903, value & ~(1 << 3));
1847 msleep(1);
1848 dib8000_write_word(state, 903, value | (1 << 3));
1851 return ret;
1854 static int dib8000_wakeup(struct dvb_frontend *fe)
1856 struct dib8000_state *state = fe->demodulator_priv;
1858 dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
1859 dib8000_set_adc_state(state, DIBX000_ADC_ON);
1860 if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
1861 dprintk("could not start Slow ADC");
1863 return 0;
1866 static int dib8000_sleep(struct dvb_frontend *fe)
1868 struct dib8000_state *st = fe->demodulator_priv;
1869 if (1) {
1870 dib8000_set_output_mode(st, OUTMODE_HIGH_Z);
1871 dib8000_set_power_mode(st, DIB8000M_POWER_INTERFACE_ONLY);
1872 return dib8000_set_adc_state(st, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(st, DIBX000_ADC_OFF);
1873 } else {
1875 return 0;
1879 enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
1881 struct dib8000_state *state = fe->demodulator_priv;
1882 return state->tune_state;
1884 EXPORT_SYMBOL(dib8000_get_tune_state);
1886 int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
1888 struct dib8000_state *state = fe->demodulator_priv;
1889 state->tune_state = tune_state;
1890 return 0;
1892 EXPORT_SYMBOL(dib8000_set_tune_state);
1897 static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1899 struct dib8000_state *state = fe->demodulator_priv;
1900 u16 i, val = 0;
1902 fe->dtv_property_cache.bandwidth_hz = 6000000;
1904 fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1;
1906 val = dib8000_read_word(state, 570);
1907 fe->dtv_property_cache.inversion = (val & 0x40) >> 6;
1908 switch ((val & 0x30) >> 4) {
1909 case 1:
1910 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
1911 break;
1912 case 3:
1913 default:
1914 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1915 break;
1918 switch (val & 0x3) {
1919 case 0:
1920 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
1921 dprintk("dib8000_get_frontend GI = 1/32 ");
1922 break;
1923 case 1:
1924 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
1925 dprintk("dib8000_get_frontend GI = 1/16 ");
1926 break;
1927 case 2:
1928 dprintk("dib8000_get_frontend GI = 1/8 ");
1929 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1930 break;
1931 case 3:
1932 dprintk("dib8000_get_frontend GI = 1/4 ");
1933 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
1934 break;
1937 val = dib8000_read_word(state, 505);
1938 fe->dtv_property_cache.isdbt_partial_reception = val & 1;
1939 dprintk("dib8000_get_frontend : partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception);
1941 for (i = 0; i < 3; i++) {
1942 val = dib8000_read_word(state, 493 + i);
1943 fe->dtv_property_cache.layer[i].segment_count = val & 0x0F;
1944 dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count);
1946 val = dib8000_read_word(state, 499 + i);
1947 fe->dtv_property_cache.layer[i].interleaving = val & 0x3;
1948 dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ", i, fe->dtv_property_cache.layer[i].interleaving);
1950 val = dib8000_read_word(state, 481 + i);
1951 switch (val & 0x7) {
1952 case 1:
1953 fe->dtv_property_cache.layer[i].fec = FEC_1_2;
1954 dprintk("dib8000_get_frontend : Layer %d Code Rate = 1/2 ", i);
1955 break;
1956 case 2:
1957 fe->dtv_property_cache.layer[i].fec = FEC_2_3;
1958 dprintk("dib8000_get_frontend : Layer %d Code Rate = 2/3 ", i);
1959 break;
1960 case 3:
1961 fe->dtv_property_cache.layer[i].fec = FEC_3_4;
1962 dprintk("dib8000_get_frontend : Layer %d Code Rate = 3/4 ", i);
1963 break;
1964 case 5:
1965 fe->dtv_property_cache.layer[i].fec = FEC_5_6;
1966 dprintk("dib8000_get_frontend : Layer %d Code Rate = 5/6 ", i);
1967 break;
1968 default:
1969 fe->dtv_property_cache.layer[i].fec = FEC_7_8;
1970 dprintk("dib8000_get_frontend : Layer %d Code Rate = 7/8 ", i);
1971 break;
1974 val = dib8000_read_word(state, 487 + i);
1975 switch (val & 0x3) {
1976 case 0:
1977 dprintk("dib8000_get_frontend : Layer %d DQPSK ", i);
1978 fe->dtv_property_cache.layer[i].modulation = DQPSK;
1979 break;
1980 case 1:
1981 fe->dtv_property_cache.layer[i].modulation = QPSK;
1982 dprintk("dib8000_get_frontend : Layer %d QPSK ", i);
1983 break;
1984 case 2:
1985 fe->dtv_property_cache.layer[i].modulation = QAM_16;
1986 dprintk("dib8000_get_frontend : Layer %d QAM16 ", i);
1987 break;
1988 case 3:
1989 default:
1990 dprintk("dib8000_get_frontend : Layer %d QAM64 ", i);
1991 fe->dtv_property_cache.layer[i].modulation = QAM_64;
1992 break;
1995 return 0;
1998 static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
2000 struct dib8000_state *state = fe->demodulator_priv;
2001 int time, ret;
2003 fe->dtv_property_cache.delivery_system = SYS_ISDBT;
2005 dib8000_set_output_mode(state, OUTMODE_HIGH_Z);
2007 if (fe->ops.tuner_ops.set_params)
2008 fe->ops.tuner_ops.set_params(fe, fep);
2010 /* start up the AGC */
2011 state->tune_state = CT_AGC_START;
2012 do {
2013 time = dib8000_agc_startup(fe);
2014 if (time != FE_CALLBACK_TIME_NEVER)
2015 msleep(time / 10);
2016 else
2017 break;
2018 } while (state->tune_state != CT_AGC_STOP);
2020 if (state->fe.dtv_property_cache.frequency == 0) {
2021 dprintk("dib8000: must at least specify frequency ");
2022 return 0;
2025 if (state->fe.dtv_property_cache.bandwidth_hz == 0) {
2026 dprintk("dib8000: no bandwidth specified, set to default ");
2027 state->fe.dtv_property_cache.bandwidth_hz = 6000000;
2030 state->tune_state = CT_DEMOD_START;
2032 if ((state->fe.dtv_property_cache.delivery_system != SYS_ISDBT) ||
2033 (state->fe.dtv_property_cache.inversion == INVERSION_AUTO) ||
2034 (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) ||
2035 (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) ||
2036 (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) &&
2037 (state->fe.dtv_property_cache.layer[0].segment_count != 0xff) &&
2038 (state->fe.dtv_property_cache.layer[0].segment_count != 0) &&
2039 ((state->fe.dtv_property_cache.layer[0].modulation == QAM_AUTO) ||
2040 (state->fe.dtv_property_cache.layer[0].fec == FEC_AUTO))) ||
2041 (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) &&
2042 (state->fe.dtv_property_cache.layer[1].segment_count != 0xff) &&
2043 (state->fe.dtv_property_cache.layer[1].segment_count != 0) &&
2044 ((state->fe.dtv_property_cache.layer[1].modulation == QAM_AUTO) ||
2045 (state->fe.dtv_property_cache.layer[1].fec == FEC_AUTO))) ||
2046 (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) &&
2047 (state->fe.dtv_property_cache.layer[2].segment_count != 0xff) &&
2048 (state->fe.dtv_property_cache.layer[2].segment_count != 0) &&
2049 ((state->fe.dtv_property_cache.layer[2].modulation == QAM_AUTO) ||
2050 (state->fe.dtv_property_cache.layer[2].fec == FEC_AUTO))) ||
2051 (((state->fe.dtv_property_cache.layer[0].segment_count == 0) ||
2052 ((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) &&
2053 ((state->fe.dtv_property_cache.layer[1].segment_count == 0) ||
2054 ((state->fe.dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) &&
2055 ((state->fe.dtv_property_cache.layer[2].segment_count == 0) || ((state->fe.dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) {
2056 int i = 800, found;
2058 dib8000_set_bandwidth(state, fe->dtv_property_cache.bandwidth_hz / 1000);
2059 dib8000_autosearch_start(fe);
2060 do {
2061 msleep(10);
2062 found = dib8000_autosearch_irq(fe);
2063 } while (found == 0 && i--);
2065 dprintk("Frequency %d Hz, autosearch returns: %d", fep->frequency, found);
2067 if (found == 0 || found == 1)
2068 return 0; // no channel found
2070 dib8000_get_frontend(fe, fep);
2073 ret = dib8000_tune(fe);
2075 /* make this a config parameter */
2076 dib8000_set_output_mode(state, state->cfg.output_mode);
2078 return ret;
2081 static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
2083 struct dib8000_state *state = fe->demodulator_priv;
2084 u16 lock = dib8000_read_word(state, 568);
2086 *stat = 0;
2088 if ((lock >> 13) & 1)
2089 *stat |= FE_HAS_SIGNAL;
2091 if ((lock >> 8) & 1) /* Equal */
2092 *stat |= FE_HAS_CARRIER;
2094 if (((lock >> 1) & 0xf) == 0xf) /* TMCC_SYNC */
2095 *stat |= FE_HAS_SYNC;
2097 if (((lock >> 12) & 1) && ((lock >> 5) & 7)) /* FEC MPEG */
2098 *stat |= FE_HAS_LOCK;
2100 if ((lock >> 12) & 1) {
2101 lock = dib8000_read_word(state, 554); /* Viterbi Layer A */
2102 if (lock & 0x01)
2103 *stat |= FE_HAS_VITERBI;
2105 lock = dib8000_read_word(state, 555); /* Viterbi Layer B */
2106 if (lock & 0x01)
2107 *stat |= FE_HAS_VITERBI;
2109 lock = dib8000_read_word(state, 556); /* Viterbi Layer C */
2110 if (lock & 0x01)
2111 *stat |= FE_HAS_VITERBI;
2114 return 0;
2117 static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber)
2119 struct dib8000_state *state = fe->demodulator_priv;
2120 *ber = (dib8000_read_word(state, 560) << 16) | dib8000_read_word(state, 561); // 13 segments
2121 return 0;
2124 static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
2126 struct dib8000_state *state = fe->demodulator_priv;
2127 *unc = dib8000_read_word(state, 565); // packet error on 13 seg
2128 return 0;
2131 static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2133 struct dib8000_state *state = fe->demodulator_priv;
2134 u16 val = dib8000_read_word(state, 390);
2135 *strength = 65535 - val;
2136 return 0;
2139 static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
2141 struct dib8000_state *state = fe->demodulator_priv;
2142 u16 val;
2143 s32 signal_mant, signal_exp, noise_mant, noise_exp;
2144 u32 result = 0;
2146 val = dib8000_read_word(state, 542);
2147 noise_mant = (val >> 6) & 0xff;
2148 noise_exp = (val & 0x3f);
2150 val = dib8000_read_word(state, 543);
2151 signal_mant = (val >> 6) & 0xff;
2152 signal_exp = (val & 0x3f);
2154 if ((noise_exp & 0x20) != 0)
2155 noise_exp -= 0x40;
2156 if ((signal_exp & 0x20) != 0)
2157 signal_exp -= 0x40;
2159 if (signal_mant != 0)
2160 result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
2161 else
2162 result = intlog10(2) * 10 * signal_exp - 100;
2163 if (noise_mant != 0)
2164 result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
2165 else
2166 result -= intlog10(2) * 10 * noise_exp - 100;
2168 *snr = result / ((1 << 24) / 10);
2169 return 0;
2172 int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
2174 int k = 0;
2175 u8 new_addr = 0;
2176 struct i2c_device client = {.adap = host };
2178 for (k = no_of_demods - 1; k >= 0; k--) {
2179 /* designated i2c address */
2180 new_addr = first_addr + (k << 1);
2182 client.addr = new_addr;
2183 dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */
2184 if (dib8000_identify(&client) == 0) {
2185 dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */
2186 client.addr = default_addr;
2187 if (dib8000_identify(&client) == 0) {
2188 dprintk("#%d: not identified", k);
2189 return -EINVAL;
2193 /* start diversity to pull_down div_str - just for i2c-enumeration */
2194 dib8000_i2c_write16(&client, 1286, (1 << 10) | (4 << 6));
2196 /* set new i2c address and force divstart */
2197 dib8000_i2c_write16(&client, 1285, (new_addr << 2) | 0x2);
2198 client.addr = new_addr;
2199 dib8000_identify(&client);
2201 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
2204 for (k = 0; k < no_of_demods; k++) {
2205 new_addr = first_addr | (k << 1);
2206 client.addr = new_addr;
2208 // unforce divstr
2209 dib8000_i2c_write16(&client, 1285, new_addr << 2);
2211 /* deactivate div - it was just for i2c-enumeration */
2212 dib8000_i2c_write16(&client, 1286, 0);
2215 return 0;
2218 EXPORT_SYMBOL(dib8000_i2c_enumeration);
2219 static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
2221 tune->min_delay_ms = 1000;
2222 tune->step_size = 0;
2223 tune->max_drift = 0;
2224 return 0;
2227 static void dib8000_release(struct dvb_frontend *fe)
2229 struct dib8000_state *st = fe->demodulator_priv;
2230 dibx000_exit_i2c_master(&st->i2c_master);
2231 kfree(st);
2234 struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
2236 struct dib8000_state *st = fe->demodulator_priv;
2237 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
2240 EXPORT_SYMBOL(dib8000_get_i2c_master);
2242 int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
2244 struct dib8000_state *st = fe->demodulator_priv;
2245 u16 val = dib8000_read_word(st, 299) & 0xffef;
2246 val |= (onoff & 0x1) << 4;
2248 dprintk("pid filter enabled %d", onoff);
2249 return dib8000_write_word(st, 299, val);
2251 EXPORT_SYMBOL(dib8000_pid_filter_ctrl);
2253 int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
2255 struct dib8000_state *st = fe->demodulator_priv;
2256 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
2257 return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0);
2259 EXPORT_SYMBOL(dib8000_pid_filter);
2261 static const struct dvb_frontend_ops dib8000_ops = {
2262 .info = {
2263 .name = "DiBcom 8000 ISDB-T",
2264 .type = FE_OFDM,
2265 .frequency_min = 44250000,
2266 .frequency_max = 867250000,
2267 .frequency_stepsize = 62500,
2268 .caps = FE_CAN_INVERSION_AUTO |
2269 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2270 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2271 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2272 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2275 .release = dib8000_release,
2277 .init = dib8000_wakeup,
2278 .sleep = dib8000_sleep,
2280 .set_frontend = dib8000_set_frontend,
2281 .get_tune_settings = dib8000_fe_get_tune_settings,
2282 .get_frontend = dib8000_get_frontend,
2284 .read_status = dib8000_read_status,
2285 .read_ber = dib8000_read_ber,
2286 .read_signal_strength = dib8000_read_signal_strength,
2287 .read_snr = dib8000_read_snr,
2288 .read_ucblocks = dib8000_read_unc_blocks,
2291 struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
2293 struct dvb_frontend *fe;
2294 struct dib8000_state *state;
2296 dprintk("dib8000_attach");
2298 state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL);
2299 if (state == NULL)
2300 return NULL;
2302 memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
2303 state->i2c.adap = i2c_adap;
2304 state->i2c.addr = i2c_addr;
2305 state->gpio_val = cfg->gpio_val;
2306 state->gpio_dir = cfg->gpio_dir;
2308 /* Ensure the output mode remains at the previous default if it's
2309 * not specifically set by the caller.
2311 if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2312 state->cfg.output_mode = OUTMODE_MPEG2_FIFO;
2314 fe = &state->fe;
2315 fe->demodulator_priv = state;
2316 memcpy(&state->fe.ops, &dib8000_ops, sizeof(struct dvb_frontend_ops));
2318 state->timf_default = cfg->pll->timf;
2320 if (dib8000_identify(&state->i2c) == 0)
2321 goto error;
2323 dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr);
2325 dib8000_reset(fe);
2327 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5)); /* ber_rs_len = 3 */
2329 return fe;
2331 error:
2332 kfree(state);
2333 return NULL;
2336 EXPORT_SYMBOL(dib8000_attach);
2338 MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@dibcom.fr, " "Patrick Boettcher <pboettcher@dibcom.fr>");
2339 MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator");
2340 MODULE_LICENSE("GPL");