FRV: Use generic show_interrupts()
[cris-mirror.git] / drivers / media / dvb / frontends / dib8000.c
blobc1c3e26906e2843b7893fa666c4929cf8442e7e4
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
25 #define MAX_NUMBER_OF_FRONTENDS 6
27 static int debug;
28 module_param(debug, int, 0644);
29 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
31 #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0)
33 #define FE_STATUS_TUNE_FAILED 0
35 struct i2c_device {
36 struct i2c_adapter *adap;
37 u8 addr;
40 struct dib8000_state {
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;
72 struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
75 enum dib8000_power_mode {
76 DIB8000M_POWER_ALL = 0,
77 DIB8000M_POWER_INTERFACE_ONLY,
80 static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
82 u8 wb[2] = { reg >> 8, reg & 0xff };
83 u8 rb[2];
84 struct i2c_msg msg[2] = {
85 {.addr = i2c->addr >> 1,.flags = 0,.buf = wb,.len = 2},
86 {.addr = i2c->addr >> 1,.flags = I2C_M_RD,.buf = rb,.len = 2},
89 if (i2c_transfer(i2c->adap, msg, 2) != 2)
90 dprintk("i2c read error on %d", reg);
92 return (rb[0] << 8) | rb[1];
95 static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
97 return dib8000_i2c_read16(&state->i2c, reg);
100 static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
102 u16 rw[2];
104 rw[0] = dib8000_read_word(state, reg + 0);
105 rw[1] = dib8000_read_word(state, reg + 1);
107 return ((rw[0] << 16) | (rw[1]));
110 static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
112 u8 b[4] = {
113 (reg >> 8) & 0xff, reg & 0xff,
114 (val >> 8) & 0xff, val & 0xff,
116 struct i2c_msg msg = {
117 .addr = i2c->addr >> 1,.flags = 0,.buf = b,.len = 4
119 return i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
122 static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
124 return dib8000_i2c_write16(&state->i2c, reg, val);
127 static const s16 coeff_2k_sb_1seg_dqpsk[8] = {
128 (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
129 (920 << 5) | 0x09
132 static const s16 coeff_2k_sb_1seg[8] = {
133 (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
136 static const s16 coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
137 (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
138 (-931 << 5) | 0x0f
141 static const s16 coeff_2k_sb_3seg_0dqpsk[8] = {
142 (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
143 (982 << 5) | 0x0c
146 static const s16 coeff_2k_sb_3seg_1dqpsk[8] = {
147 (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
148 (-720 << 5) | 0x0d
151 static const s16 coeff_2k_sb_3seg[8] = {
152 (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
153 (-610 << 5) | 0x0a
156 static const s16 coeff_4k_sb_1seg_dqpsk[8] = {
157 (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
158 (-922 << 5) | 0x0d
161 static const s16 coeff_4k_sb_1seg[8] = {
162 (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
163 (-655 << 5) | 0x0a
166 static const s16 coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
167 (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
168 (-958 << 5) | 0x13
171 static const s16 coeff_4k_sb_3seg_0dqpsk[8] = {
172 (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
173 (-568 << 5) | 0x0f
176 static const s16 coeff_4k_sb_3seg_1dqpsk[8] = {
177 (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
178 (-848 << 5) | 0x13
181 static const s16 coeff_4k_sb_3seg[8] = {
182 (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
183 (-869 << 5) | 0x13
186 static const s16 coeff_8k_sb_1seg_dqpsk[8] = {
187 (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
188 (-598 << 5) | 0x10
191 static const s16 coeff_8k_sb_1seg[8] = {
192 (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
193 (585 << 5) | 0x0f
196 static const s16 coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
197 (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
198 (0 << 5) | 0x14
201 static const s16 coeff_8k_sb_3seg_0dqpsk[8] = {
202 (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
203 (-877 << 5) | 0x15
206 static const s16 coeff_8k_sb_3seg_1dqpsk[8] = {
207 (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
208 (-921 << 5) | 0x14
211 static const s16 coeff_8k_sb_3seg[8] = {
212 (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
213 (690 << 5) | 0x14
216 static const s16 ana_fe_coeff_3seg[24] = {
217 81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
220 static const s16 ana_fe_coeff_1seg[24] = {
221 249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
224 static const s16 ana_fe_coeff_13seg[24] = {
225 396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
228 static u16 fft_to_mode(struct dib8000_state *state)
230 u16 mode;
231 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
232 case TRANSMISSION_MODE_2K:
233 mode = 1;
234 break;
235 case TRANSMISSION_MODE_4K:
236 mode = 2;
237 break;
238 default:
239 case TRANSMISSION_MODE_AUTO:
240 case TRANSMISSION_MODE_8K:
241 mode = 3;
242 break;
244 return mode;
247 static void dib8000_set_acquisition_mode(struct dib8000_state *state)
249 u16 nud = dib8000_read_word(state, 298);
250 nud |= (1 << 3) | (1 << 0);
251 dprintk("acquisition mode activated");
252 dib8000_write_word(state, 298, nud);
254 static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode)
256 struct dib8000_state *state = fe->demodulator_priv;
258 u16 outreg, fifo_threshold, smo_mode, sram = 0x0205; /* by default SDRAM deintlv is enabled */
260 outreg = 0;
261 fifo_threshold = 1792;
262 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
264 dprintk("-I- Setting output mode for demod %p to %d",
265 &state->fe[0], mode);
267 switch (mode) {
268 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
269 outreg = (1 << 10); /* 0x0400 */
270 break;
271 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
272 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
273 break;
274 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
275 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
276 break;
277 case OUTMODE_DIVERSITY:
278 if (state->cfg.hostbus_diversity) {
279 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
280 sram &= 0xfdff;
281 } else
282 sram |= 0x0c00;
283 break;
284 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
285 smo_mode |= (3 << 1);
286 fifo_threshold = 512;
287 outreg = (1 << 10) | (5 << 6);
288 break;
289 case OUTMODE_HIGH_Z: // disable
290 outreg = 0;
291 break;
293 case OUTMODE_ANALOG_ADC:
294 outreg = (1 << 10) | (3 << 6);
295 dib8000_set_acquisition_mode(state);
296 break;
298 default:
299 dprintk("Unhandled output_mode passed to be set for demod %p",
300 &state->fe[0]);
301 return -EINVAL;
304 if (state->cfg.output_mpeg2_in_188_bytes)
305 smo_mode |= (1 << 5);
307 dib8000_write_word(state, 299, smo_mode);
308 dib8000_write_word(state, 300, fifo_threshold); /* synchronous fread */
309 dib8000_write_word(state, 1286, outreg);
310 dib8000_write_word(state, 1291, sram);
312 return 0;
315 static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff)
317 struct dib8000_state *state = fe->demodulator_priv;
318 u16 sync_wait = dib8000_read_word(state, 273) & 0xfff0;
320 if (!state->differential_constellation) {
321 dib8000_write_word(state, 272, 1 << 9); //dvsy_off_lmod4 = 1
322 dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2); // sync_enable = 1; comb_mode = 2
323 } else {
324 dib8000_write_word(state, 272, 0); //dvsy_off_lmod4 = 0
325 dib8000_write_word(state, 273, sync_wait); // sync_enable = 0; comb_mode = 0
327 state->diversity_onoff = onoff;
329 switch (onoff) {
330 case 0: /* only use the internal way - not the diversity input */
331 dib8000_write_word(state, 270, 1);
332 dib8000_write_word(state, 271, 0);
333 break;
334 case 1: /* both ways */
335 dib8000_write_word(state, 270, 6);
336 dib8000_write_word(state, 271, 6);
337 break;
338 case 2: /* only the diversity input */
339 dib8000_write_word(state, 270, 0);
340 dib8000_write_word(state, 271, 1);
341 break;
343 return 0;
346 static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_power_mode mode)
348 /* by default everything is going to be powered off */
349 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
350 reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3,
351 reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
353 /* now, depending on the requested mode, we power on */
354 switch (mode) {
355 /* power up everything in the demod */
356 case DIB8000M_POWER_ALL:
357 reg_774 = 0x0000;
358 reg_775 = 0x0000;
359 reg_776 = 0x0000;
360 reg_900 &= 0xfffc;
361 reg_1280 &= 0x00ff;
362 break;
363 case DIB8000M_POWER_INTERFACE_ONLY:
364 reg_1280 &= 0x00ff;
365 break;
368 dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x", reg_774, reg_775, reg_776, reg_900, reg_1280);
369 dib8000_write_word(state, 774, reg_774);
370 dib8000_write_word(state, 775, reg_775);
371 dib8000_write_word(state, 776, reg_776);
372 dib8000_write_word(state, 900, reg_900);
373 dib8000_write_word(state, 1280, reg_1280);
376 static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no)
378 int ret = 0;
379 u16 reg_907 = dib8000_read_word(state, 907), reg_908 = dib8000_read_word(state, 908);
381 switch (no) {
382 case DIBX000_SLOW_ADC_ON:
383 reg_908 |= (1 << 1) | (1 << 0);
384 ret |= dib8000_write_word(state, 908, reg_908);
385 reg_908 &= ~(1 << 1);
386 break;
388 case DIBX000_SLOW_ADC_OFF:
389 reg_908 |= (1 << 1) | (1 << 0);
390 break;
392 case DIBX000_ADC_ON:
393 reg_907 &= 0x0fff;
394 reg_908 &= 0x0003;
395 break;
397 case DIBX000_ADC_OFF: // leave the VBG voltage on
398 reg_907 |= (1 << 14) | (1 << 13) | (1 << 12);
399 reg_908 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
400 break;
402 case DIBX000_VBG_ENABLE:
403 reg_907 &= ~(1 << 15);
404 break;
406 case DIBX000_VBG_DISABLE:
407 reg_907 |= (1 << 15);
408 break;
410 default:
411 break;
414 ret |= dib8000_write_word(state, 907, reg_907);
415 ret |= dib8000_write_word(state, 908, reg_908);
417 return ret;
420 static int dib8000_set_bandwidth(struct dvb_frontend *fe, u32 bw)
422 struct dib8000_state *state = fe->demodulator_priv;
423 u32 timf;
425 if (bw == 0)
426 bw = 6000;
428 if (state->timf == 0) {
429 dprintk("using default timf");
430 timf = state->timf_default;
431 } else {
432 dprintk("using updated timf");
433 timf = state->timf;
436 dib8000_write_word(state, 29, (u16) ((timf >> 16) & 0xffff));
437 dib8000_write_word(state, 30, (u16) ((timf) & 0xffff));
439 return 0;
442 static int dib8000_sad_calib(struct dib8000_state *state)
444 /* internal */
445 dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
446 dib8000_write_word(state, 924, 776); // 0.625*3.3 / 4096
448 /* do the calibration */
449 dib8000_write_word(state, 923, (1 << 0));
450 dib8000_write_word(state, 923, (0 << 0));
452 msleep(1);
453 return 0;
456 int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
458 struct dib8000_state *state = fe->demodulator_priv;
459 if (value > 4095)
460 value = 4095;
461 state->wbd_ref = value;
462 return dib8000_write_word(state, 106, value);
465 EXPORT_SYMBOL(dib8000_set_wbd_ref);
466 static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
468 dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25);
469 dib8000_write_word(state, 23, (u16) (((bw->internal * 1000) >> 16) & 0xffff)); /* P_sec_len */
470 dib8000_write_word(state, 24, (u16) ((bw->internal * 1000) & 0xffff));
471 dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff));
472 dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff));
473 dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003));
475 dib8000_write_word(state, 922, bw->sad_cfg);
478 static void dib8000_reset_pll(struct dib8000_state *state)
480 const struct dibx000_bandwidth_config *pll = state->cfg.pll;
481 u16 clk_cfg1;
483 // clk_cfg0
484 dib8000_write_word(state, 901, (pll->pll_prediv << 8) | (pll->pll_ratio << 0));
486 // clk_cfg1
487 clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
488 (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) |
489 (pll->pll_range << 1) | (pll->pll_reset << 0);
491 dib8000_write_word(state, 902, clk_cfg1);
492 clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
493 dib8000_write_word(state, 902, clk_cfg1);
495 dprintk("clk_cfg1: 0x%04x", clk_cfg1); /* 0x507 1 0 1 000 0 0 11 1 */
497 /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
498 if (state->cfg.pll->ADClkSrc == 0)
499 dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) |
500 (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
501 else if (state->cfg.refclksel != 0)
502 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
503 ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) |
504 (pll->ADClkSrc << 7) | (0 << 1));
505 else
506 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
508 dib8000_reset_pll_common(state, pll);
511 static int dib8000_reset_gpio(struct dib8000_state *st)
513 /* reset the GPIOs */
514 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
515 dib8000_write_word(st, 1030, st->cfg.gpio_val);
517 /* TODO 782 is P_gpio_od */
519 dib8000_write_word(st, 1032, st->cfg.gpio_pwm_pos);
521 dib8000_write_word(st, 1037, st->cfg.pwm_freq_div);
522 return 0;
525 static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val)
527 st->cfg.gpio_dir = dib8000_read_word(st, 1029);
528 st->cfg.gpio_dir &= ~(1 << num); /* reset the direction bit */
529 st->cfg.gpio_dir |= (dir & 0x1) << num; /* set the new direction */
530 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
532 st->cfg.gpio_val = dib8000_read_word(st, 1030);
533 st->cfg.gpio_val &= ~(1 << num); /* reset the direction bit */
534 st->cfg.gpio_val |= (val & 0x01) << num; /* set the new value */
535 dib8000_write_word(st, 1030, st->cfg.gpio_val);
537 dprintk("gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val);
539 return 0;
542 int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
544 struct dib8000_state *state = fe->demodulator_priv;
545 return dib8000_cfg_gpio(state, num, dir, val);
548 EXPORT_SYMBOL(dib8000_set_gpio);
549 static const u16 dib8000_defaults[] = {
550 /* auto search configuration - lock0 by default waiting
551 * for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */
552 3, 7,
553 0x0004,
554 0x0400,
555 0x0814,
557 12, 11,
558 0x001b,
559 0x7740,
560 0x005b,
561 0x8d80,
562 0x01c9,
563 0xc380,
564 0x0000,
565 0x0080,
566 0x0000,
567 0x0090,
568 0x0001,
569 0xd4c0,
571 /*1, 32,
572 0x6680 // P_corm_thres Lock algorithms configuration */
574 11, 80, /* set ADC level to -16 */
575 (1 << 13) - 825 - 117,
576 (1 << 13) - 837 - 117,
577 (1 << 13) - 811 - 117,
578 (1 << 13) - 766 - 117,
579 (1 << 13) - 737 - 117,
580 (1 << 13) - 693 - 117,
581 (1 << 13) - 648 - 117,
582 (1 << 13) - 619 - 117,
583 (1 << 13) - 575 - 117,
584 (1 << 13) - 531 - 117,
585 (1 << 13) - 501 - 117,
587 4, 108,
593 1, 175,
594 0x0410,
595 1, 179,
596 8192, // P_fft_nb_to_cut
598 6, 181,
599 0x2800, // P_coff_corthres_ ( 2k 4k 8k ) 0x2800
600 0x2800,
601 0x2800,
602 0x2800, // P_coff_cpilthres_ ( 2k 4k 8k ) 0x2800
603 0x2800,
604 0x2800,
606 2, 193,
607 0x0666, // P_pha3_thres
608 0x0000, // P_cti_use_cpe, P_cti_use_prog
610 2, 205,
611 0x200f, // P_cspu_regul, P_cspu_win_cut
612 0x000f, // P_des_shift_work
614 5, 215,
615 0x023d, // P_adp_regul_cnt
616 0x00a4, // P_adp_noise_cnt
617 0x00a4, // P_adp_regul_ext
618 0x7ff0, // P_adp_noise_ext
619 0x3ccc, // P_adp_fil
621 1, 230,
622 0x0000, // P_2d_byp_ti_num
624 1, 263,
625 0x800, //P_equal_thres_wgn
627 1, 268,
628 (2 << 9) | 39, // P_equal_ctrl_synchro, P_equal_speedmode
630 1, 270,
631 0x0001, // P_div_lock0_wait
632 1, 285,
633 0x0020, //p_fec_
634 1, 299,
635 0x0062, /* P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard */
637 1, 338,
638 (1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1
639 (1 << 10) |
640 (0 << 9) | /* P_ctrl_pre_freq_inh=0 */
641 (3 << 5) | /* P_ctrl_pre_freq_step=3 */
642 (1 << 0), /* P_pre_freq_win_len=1 */
644 1, 903,
645 (0 << 4) | 2, // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW)
650 static u16 dib8000_identify(struct i2c_device *client)
652 u16 value;
654 //because of glitches sometimes
655 value = dib8000_i2c_read16(client, 896);
657 if ((value = dib8000_i2c_read16(client, 896)) != 0x01b3) {
658 dprintk("wrong Vendor ID (read=0x%x)", value);
659 return 0;
662 value = dib8000_i2c_read16(client, 897);
663 if (value != 0x8000 && value != 0x8001 && value != 0x8002) {
664 dprintk("wrong Device ID (%x)", value);
665 return 0;
668 switch (value) {
669 case 0x8000:
670 dprintk("found DiB8000A");
671 break;
672 case 0x8001:
673 dprintk("found DiB8000B");
674 break;
675 case 0x8002:
676 dprintk("found DiB8000C");
677 break;
679 return value;
682 static int dib8000_reset(struct dvb_frontend *fe)
684 struct dib8000_state *state = fe->demodulator_priv;
686 dib8000_write_word(state, 1287, 0x0003); /* sram lead in, rdy */
688 if ((state->revision = dib8000_identify(&state->i2c)) == 0)
689 return -EINVAL;
691 if (state->revision == 0x8000)
692 dprintk("error : dib8000 MA not supported");
694 dibx000_reset_i2c_master(&state->i2c_master);
696 dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
698 /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
699 dib8000_set_adc_state(state, DIBX000_VBG_ENABLE);
701 /* restart all parts */
702 dib8000_write_word(state, 770, 0xffff);
703 dib8000_write_word(state, 771, 0xffff);
704 dib8000_write_word(state, 772, 0xfffc);
705 dib8000_write_word(state, 898, 0x000c); // sad
706 dib8000_write_word(state, 1280, 0x004d);
707 dib8000_write_word(state, 1281, 0x000c);
709 dib8000_write_word(state, 770, 0x0000);
710 dib8000_write_word(state, 771, 0x0000);
711 dib8000_write_word(state, 772, 0x0000);
712 dib8000_write_word(state, 898, 0x0004); // sad
713 dib8000_write_word(state, 1280, 0x0000);
714 dib8000_write_word(state, 1281, 0x0000);
716 /* drives */
717 if (state->cfg.drives)
718 dib8000_write_word(state, 906, state->cfg.drives);
719 else {
720 dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.");
721 dib8000_write_word(state, 906, 0x2d98); // min drive SDRAM - not optimal - adjust
724 dib8000_reset_pll(state);
726 if (dib8000_reset_gpio(state) != 0)
727 dprintk("GPIO reset was not successful.");
729 if (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0)
730 dprintk("OUTPUT_MODE could not be resetted.");
732 state->current_agc = NULL;
734 // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
735 /* P_iqc_ca2 = 0; P_iqc_impnc_on = 0; P_iqc_mode = 0; */
736 if (state->cfg.pll->ifreq == 0)
737 dib8000_write_word(state, 40, 0x0755); /* P_iqc_corr_inh = 0 enable IQcorr block */
738 else
739 dib8000_write_word(state, 40, 0x1f55); /* P_iqc_corr_inh = 1 disable IQcorr block */
742 u16 l = 0, r;
743 const u16 *n;
744 n = dib8000_defaults;
745 l = *n++;
746 while (l) {
747 r = *n++;
748 do {
749 dib8000_write_word(state, r, *n++);
750 r++;
751 } while (--l);
752 l = *n++;
755 state->isdbt_cfg_loaded = 0;
757 //div_cfg override for special configs
758 if (state->cfg.div_cfg != 0)
759 dib8000_write_word(state, 903, state->cfg.div_cfg);
761 /* unforce divstr regardless whether i2c enumeration was done or not */
762 dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1));
764 dib8000_set_bandwidth(fe, 6000);
766 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
767 dib8000_sad_calib(state);
768 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
770 dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY);
772 return 0;
775 static void dib8000_restart_agc(struct dib8000_state *state)
777 // P_restart_iqc & P_restart_agc
778 dib8000_write_word(state, 770, 0x0a00);
779 dib8000_write_word(state, 770, 0x0000);
782 static int dib8000_update_lna(struct dib8000_state *state)
784 u16 dyn_gain;
786 if (state->cfg.update_lna) {
787 // read dyn_gain here (because it is demod-dependent and not tuner)
788 dyn_gain = dib8000_read_word(state, 390);
790 if (state->cfg.update_lna(state->fe[0], dyn_gain)) {
791 dib8000_restart_agc(state);
792 return 1;
795 return 0;
798 static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
800 struct dibx000_agc_config *agc = NULL;
801 int i;
802 if (state->current_band == band && state->current_agc != NULL)
803 return 0;
804 state->current_band = band;
806 for (i = 0; i < state->cfg.agc_config_count; i++)
807 if (state->cfg.agc[i].band_caps & band) {
808 agc = &state->cfg.agc[i];
809 break;
812 if (agc == NULL) {
813 dprintk("no valid AGC configuration found for band 0x%02x", band);
814 return -EINVAL;
817 state->current_agc = agc;
819 /* AGC */
820 dib8000_write_word(state, 76, agc->setup);
821 dib8000_write_word(state, 77, agc->inv_gain);
822 dib8000_write_word(state, 78, agc->time_stabiliz);
823 dib8000_write_word(state, 101, (agc->alpha_level << 12) | agc->thlock);
825 // Demod AGC loop configuration
826 dib8000_write_word(state, 102, (agc->alpha_mant << 5) | agc->alpha_exp);
827 dib8000_write_word(state, 103, (agc->beta_mant << 6) | agc->beta_exp);
829 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
830 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
832 /* AGC continued */
833 if (state->wbd_ref != 0)
834 dib8000_write_word(state, 106, state->wbd_ref);
835 else // use default
836 dib8000_write_word(state, 106, agc->wbd_ref);
837 dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
838 dib8000_write_word(state, 108, agc->agc1_max);
839 dib8000_write_word(state, 109, agc->agc1_min);
840 dib8000_write_word(state, 110, agc->agc2_max);
841 dib8000_write_word(state, 111, agc->agc2_min);
842 dib8000_write_word(state, 112, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
843 dib8000_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
844 dib8000_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
845 dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
847 dib8000_write_word(state, 75, agc->agc1_pt3);
848 dib8000_write_word(state, 923, (dib8000_read_word(state, 923) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2)); /*LB : 929 -> 923 */
850 return 0;
853 void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
855 struct dib8000_state *state = fe->demodulator_priv;
856 dib8000_set_adc_state(state, DIBX000_ADC_ON);
857 dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000)));
859 EXPORT_SYMBOL(dib8000_pwm_agc_reset);
861 static int dib8000_agc_soft_split(struct dib8000_state *state)
863 u16 agc, split_offset;
865 if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
866 return FE_CALLBACK_TIME_NEVER;
868 // n_agc_global
869 agc = dib8000_read_word(state, 390);
871 if (agc > state->current_agc->split.min_thres)
872 split_offset = state->current_agc->split.min;
873 else if (agc < state->current_agc->split.max_thres)
874 split_offset = state->current_agc->split.max;
875 else
876 split_offset = state->current_agc->split.max *
877 (agc - state->current_agc->split.min_thres) /
878 (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
880 dprintk("AGC split_offset: %d", split_offset);
882 // P_agc_force_split and P_agc_split_offset
883 dib8000_write_word(state, 107, (dib8000_read_word(state, 107) & 0xff00) | split_offset);
884 return 5000;
887 static int dib8000_agc_startup(struct dvb_frontend *fe)
889 struct dib8000_state *state = fe->demodulator_priv;
890 enum frontend_tune_state *tune_state = &state->tune_state;
892 int ret = 0;
894 switch (*tune_state) {
895 case CT_AGC_START:
896 // set power-up level: interf+analog+AGC
898 dib8000_set_adc_state(state, DIBX000_ADC_ON);
900 if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) {
901 *tune_state = CT_AGC_STOP;
902 state->status = FE_STATUS_TUNE_FAILED;
903 break;
906 ret = 70;
907 *tune_state = CT_AGC_STEP_0;
908 break;
910 case CT_AGC_STEP_0:
911 //AGC initialization
912 if (state->cfg.agc_control)
913 state->cfg.agc_control(fe, 1);
915 dib8000_restart_agc(state);
917 // wait AGC rough lock time
918 ret = 50;
919 *tune_state = CT_AGC_STEP_1;
920 break;
922 case CT_AGC_STEP_1:
923 // wait AGC accurate lock time
924 ret = 70;
926 if (dib8000_update_lna(state))
927 // wait only AGC rough lock time
928 ret = 50;
929 else
930 *tune_state = CT_AGC_STEP_2;
931 break;
933 case CT_AGC_STEP_2:
934 dib8000_agc_soft_split(state);
936 if (state->cfg.agc_control)
937 state->cfg.agc_control(fe, 0);
939 *tune_state = CT_AGC_STOP;
940 break;
941 default:
942 ret = dib8000_agc_soft_split(state);
943 break;
945 return ret;
949 static const s32 lut_1000ln_mant[] =
951 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600
954 s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
956 struct dib8000_state *state = fe->demodulator_priv;
957 u32 ix = 0, tmp_val = 0, exp = 0, mant = 0;
958 s32 val;
960 val = dib8000_read32(state, 384);
961 if (mode) {
962 tmp_val = val;
963 while (tmp_val >>= 1)
964 exp++;
965 mant = (val * 1000 / (1<<exp));
966 ix = (u8)((mant-1000)/100); /* index of the LUT */
967 val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908);
968 val = (val*256)/1000;
970 return val;
972 EXPORT_SYMBOL(dib8000_get_adc_power);
974 static void dib8000_update_timf(struct dib8000_state *state)
976 u32 timf = state->timf = dib8000_read32(state, 435);
978 dib8000_write_word(state, 29, (u16) (timf >> 16));
979 dib8000_write_word(state, 30, (u16) (timf & 0xffff));
980 dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
983 static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
985 u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
986 u8 guard, crate, constellation, timeI;
987 u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
988 u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled
989 const s16 *ncoeff = NULL, *ana_fe;
990 u16 tmcc_pow = 0;
991 u16 coff_pow = 0x2800;
992 u16 init_prbs = 0xfff;
993 u16 ana_gain = 0;
994 u16 adc_target_16dB[11] = {
995 (1 << 13) - 825 - 117,
996 (1 << 13) - 837 - 117,
997 (1 << 13) - 811 - 117,
998 (1 << 13) - 766 - 117,
999 (1 << 13) - 737 - 117,
1000 (1 << 13) - 693 - 117,
1001 (1 << 13) - 648 - 117,
1002 (1 << 13) - 619 - 117,
1003 (1 << 13) - 575 - 117,
1004 (1 << 13) - 531 - 117,
1005 (1 << 13) - 501 - 117
1008 if (state->ber_monitored_layer != LAYER_ALL)
1009 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
1010 else
1011 dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
1013 i = dib8000_read_word(state, 26) & 1; // P_dds_invspec
1014 dib8000_write_word(state, 26, state->fe[0]->dtv_property_cache.inversion^i);
1016 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
1017 //compute new dds_freq for the seg and adjust prbs
1018 int seg_offset =
1019 state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx -
1020 (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) -
1021 (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2);
1022 int clk = state->cfg.pll->internal;
1023 u32 segtodds = ((u32) (430 << 23) / clk) << 3; // segtodds = SegBW / Fclk * pow(2,26)
1024 int dds_offset = seg_offset * segtodds;
1025 int new_dds, sub_channel;
1026 if ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1027 dds_offset -= (int)(segtodds / 2);
1029 if (state->cfg.pll->ifreq == 0) {
1030 if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0) {
1031 dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
1032 new_dds = dds_offset;
1033 } else
1034 new_dds = dds_offset;
1036 // We shift tuning frequency if the wanted segment is :
1037 // - the segment of center frequency with an odd total number of segments
1038 // - the segment to the left of center frequency with an even total number of segments
1039 // - the segment to the right of center frequency with an even total number of segments
1040 if ((state->fe[0]->dtv_property_cache.delivery_system == SYS_ISDBT)
1041 && (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)
1042 && (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
1043 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
1044 ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1045 || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1046 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx == (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2)))
1047 || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1048 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
1049 ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1050 )) {
1051 new_dds -= ((u32) (850 << 22) / clk) << 4; // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26)
1053 } else {
1054 if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0)
1055 new_dds = state->cfg.pll->ifreq - dds_offset;
1056 else
1057 new_dds = state->cfg.pll->ifreq + dds_offset;
1059 dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff));
1060 dib8000_write_word(state, 28, (u16) (new_dds & 0xffff));
1061 if (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
1062 sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3;
1063 else
1064 sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3;
1065 sub_channel -= 6;
1067 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K
1068 || state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) {
1069 dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); //adp_pass =1
1070 dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); //pha3_force_pha_shift = 1
1071 } else {
1072 dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); //adp_pass =0
1073 dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0
1076 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1077 case TRANSMISSION_MODE_2K:
1078 switch (sub_channel) {
1079 case -6:
1080 init_prbs = 0x0;
1081 break; // 41, 0, 1
1082 case -5:
1083 init_prbs = 0x423;
1084 break; // 02~04
1085 case -4:
1086 init_prbs = 0x9;
1087 break; // 05~07
1088 case -3:
1089 init_prbs = 0x5C7;
1090 break; // 08~10
1091 case -2:
1092 init_prbs = 0x7A6;
1093 break; // 11~13
1094 case -1:
1095 init_prbs = 0x3D8;
1096 break; // 14~16
1097 case 0:
1098 init_prbs = 0x527;
1099 break; // 17~19
1100 case 1:
1101 init_prbs = 0x7FF;
1102 break; // 20~22
1103 case 2:
1104 init_prbs = 0x79B;
1105 break; // 23~25
1106 case 3:
1107 init_prbs = 0x3D6;
1108 break; // 26~28
1109 case 4:
1110 init_prbs = 0x3A2;
1111 break; // 29~31
1112 case 5:
1113 init_prbs = 0x53B;
1114 break; // 32~34
1115 case 6:
1116 init_prbs = 0x2F4;
1117 break; // 35~37
1118 default:
1119 case 7:
1120 init_prbs = 0x213;
1121 break; // 38~40
1123 break;
1125 case TRANSMISSION_MODE_4K:
1126 switch (sub_channel) {
1127 case -6:
1128 init_prbs = 0x0;
1129 break; // 41, 0, 1
1130 case -5:
1131 init_prbs = 0x208;
1132 break; // 02~04
1133 case -4:
1134 init_prbs = 0xC3;
1135 break; // 05~07
1136 case -3:
1137 init_prbs = 0x7B9;
1138 break; // 08~10
1139 case -2:
1140 init_prbs = 0x423;
1141 break; // 11~13
1142 case -1:
1143 init_prbs = 0x5C7;
1144 break; // 14~16
1145 case 0:
1146 init_prbs = 0x3D8;
1147 break; // 17~19
1148 case 1:
1149 init_prbs = 0x7FF;
1150 break; // 20~22
1151 case 2:
1152 init_prbs = 0x3D6;
1153 break; // 23~25
1154 case 3:
1155 init_prbs = 0x53B;
1156 break; // 26~28
1157 case 4:
1158 init_prbs = 0x213;
1159 break; // 29~31
1160 case 5:
1161 init_prbs = 0x29;
1162 break; // 32~34
1163 case 6:
1164 init_prbs = 0xD0;
1165 break; // 35~37
1166 default:
1167 case 7:
1168 init_prbs = 0x48E;
1169 break; // 38~40
1171 break;
1173 default:
1174 case TRANSMISSION_MODE_8K:
1175 switch (sub_channel) {
1176 case -6:
1177 init_prbs = 0x0;
1178 break; // 41, 0, 1
1179 case -5:
1180 init_prbs = 0x740;
1181 break; // 02~04
1182 case -4:
1183 init_prbs = 0x069;
1184 break; // 05~07
1185 case -3:
1186 init_prbs = 0x7DD;
1187 break; // 08~10
1188 case -2:
1189 init_prbs = 0x208;
1190 break; // 11~13
1191 case -1:
1192 init_prbs = 0x7B9;
1193 break; // 14~16
1194 case 0:
1195 init_prbs = 0x5C7;
1196 break; // 17~19
1197 case 1:
1198 init_prbs = 0x7FF;
1199 break; // 20~22
1200 case 2:
1201 init_prbs = 0x53B;
1202 break; // 23~25
1203 case 3:
1204 init_prbs = 0x29;
1205 break; // 26~28
1206 case 4:
1207 init_prbs = 0x48E;
1208 break; // 29~31
1209 case 5:
1210 init_prbs = 0x4C4;
1211 break; // 32~34
1212 case 6:
1213 init_prbs = 0x367;
1214 break; // 33~37
1215 default:
1216 case 7:
1217 init_prbs = 0x684;
1218 break; // 38~40
1220 break;
1222 } else {
1223 dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff));
1224 dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff));
1225 dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003));
1227 /*P_mode == ?? */
1228 dib8000_write_word(state, 10, (seq << 4));
1229 // dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000);
1231 switch (state->fe[0]->dtv_property_cache.guard_interval) {
1232 case GUARD_INTERVAL_1_32:
1233 guard = 0;
1234 break;
1235 case GUARD_INTERVAL_1_16:
1236 guard = 1;
1237 break;
1238 case GUARD_INTERVAL_1_8:
1239 guard = 2;
1240 break;
1241 case GUARD_INTERVAL_1_4:
1242 default:
1243 guard = 3;
1244 break;
1247 dib8000_write_word(state, 1, (init_prbs << 2) | (guard & 0x3)); // ADDR 1
1249 max_constellation = DQPSK;
1250 for (i = 0; i < 3; i++) {
1251 switch (state->fe[0]->dtv_property_cache.layer[i].modulation) {
1252 case DQPSK:
1253 constellation = 0;
1254 break;
1255 case QPSK:
1256 constellation = 1;
1257 break;
1258 case QAM_16:
1259 constellation = 2;
1260 break;
1261 case QAM_64:
1262 default:
1263 constellation = 3;
1264 break;
1267 switch (state->fe[0]->dtv_property_cache.layer[i].fec) {
1268 case FEC_1_2:
1269 crate = 1;
1270 break;
1271 case FEC_2_3:
1272 crate = 2;
1273 break;
1274 case FEC_3_4:
1275 crate = 3;
1276 break;
1277 case FEC_5_6:
1278 crate = 5;
1279 break;
1280 case FEC_7_8:
1281 default:
1282 crate = 7;
1283 break;
1286 if ((state->fe[0]->dtv_property_cache.layer[i].interleaving > 0) &&
1287 ((state->fe[0]->dtv_property_cache.layer[i].interleaving <= 3) ||
1288 (state->fe[0]->dtv_property_cache.layer[i].interleaving == 4 && state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1))
1290 timeI = state->fe[0]->dtv_property_cache.layer[i].interleaving;
1291 else
1292 timeI = 0;
1293 dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe[0]->dtv_property_cache.layer[i].segment_count & 0xf) << 6) |
1294 (crate << 3) | timeI);
1295 if (state->fe[0]->dtv_property_cache.layer[i].segment_count > 0) {
1296 switch (max_constellation) {
1297 case DQPSK:
1298 case QPSK:
1299 if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_16 ||
1300 state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64)
1301 max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation;
1302 break;
1303 case QAM_16:
1304 if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64)
1305 max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation;
1306 break;
1311 mode = fft_to_mode(state);
1313 //dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/
1315 dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) |
1316 ((state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe[0]->dtv_property_cache.
1317 isdbt_sb_mode & 1) << 4));
1319 dprintk("mode = %d ; guard = %d", mode, state->fe[0]->dtv_property_cache.guard_interval);
1321 /* signal optimization parameter */
1323 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception) {
1324 seg_diff_mask = (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0];
1325 for (i = 1; i < 3; i++)
1326 nbseg_diff +=
1327 (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
1328 for (i = 0; i < nbseg_diff; i++)
1329 seg_diff_mask |= 1 << permu_seg[i + 1];
1330 } else {
1331 for (i = 0; i < 3; i++)
1332 nbseg_diff +=
1333 (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
1334 for (i = 0; i < nbseg_diff; i++)
1335 seg_diff_mask |= 1 << permu_seg[i];
1337 dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask);
1339 state->differential_constellation = (seg_diff_mask != 0);
1340 dib8000_set_diversity_in(state->fe[0], state->diversity_onoff);
1342 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1343 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1)
1344 seg_mask13 = 0x00E0;
1345 else // 1-segment
1346 seg_mask13 = 0x0040;
1347 } else
1348 seg_mask13 = 0x1fff;
1350 // WRITE: Mode & Diff mask
1351 dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask);
1353 if ((seg_diff_mask) || (state->fe[0]->dtv_property_cache.isdbt_sb_mode))
1354 dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
1355 else
1356 dib8000_write_word(state, 268, (2 << 9) | 39); //init value
1358 // ---- SMALL ----
1359 // P_small_seg_diff
1360 dib8000_write_word(state, 352, seg_diff_mask); // ADDR 352
1362 dib8000_write_word(state, 353, seg_mask13); // ADDR 353
1364 /* // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */
1366 // ---- SMALL ----
1367 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1368 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1369 case TRANSMISSION_MODE_2K:
1370 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1371 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
1372 ncoeff = coeff_2k_sb_1seg_dqpsk;
1373 else // QPSK or QAM
1374 ncoeff = coeff_2k_sb_1seg;
1375 } else { // 3-segments
1376 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
1377 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK)
1378 ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
1379 else // QPSK or QAM on external segments
1380 ncoeff = coeff_2k_sb_3seg_0dqpsk;
1381 } else { // QPSK or QAM on central segment
1382 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK)
1383 ncoeff = coeff_2k_sb_3seg_1dqpsk;
1384 else // QPSK or QAM on external segments
1385 ncoeff = coeff_2k_sb_3seg;
1388 break;
1390 case TRANSMISSION_MODE_4K:
1391 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1392 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
1393 ncoeff = coeff_4k_sb_1seg_dqpsk;
1394 else // QPSK or QAM
1395 ncoeff = coeff_4k_sb_1seg;
1396 } else { // 3-segments
1397 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
1398 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1399 ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
1400 } else { // QPSK or QAM on external segments
1401 ncoeff = coeff_4k_sb_3seg_0dqpsk;
1403 } else { // QPSK or QAM on central segment
1404 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1405 ncoeff = coeff_4k_sb_3seg_1dqpsk;
1406 } else // QPSK or QAM on external segments
1407 ncoeff = coeff_4k_sb_3seg;
1410 break;
1412 case TRANSMISSION_MODE_AUTO:
1413 case TRANSMISSION_MODE_8K:
1414 default:
1415 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1416 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
1417 ncoeff = coeff_8k_sb_1seg_dqpsk;
1418 else // QPSK or QAM
1419 ncoeff = coeff_8k_sb_1seg;
1420 } else { // 3-segments
1421 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
1422 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1423 ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
1424 } else { // QPSK or QAM on external segments
1425 ncoeff = coeff_8k_sb_3seg_0dqpsk;
1427 } else { // QPSK or QAM on central segment
1428 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1429 ncoeff = coeff_8k_sb_3seg_1dqpsk;
1430 } else // QPSK or QAM on external segments
1431 ncoeff = coeff_8k_sb_3seg;
1434 break;
1436 for (i = 0; i < 8; i++)
1437 dib8000_write_word(state, 343 + i, ncoeff[i]);
1440 // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5
1441 dib8000_write_word(state, 351,
1442 (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 9) | (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5);
1444 // ---- COFF ----
1445 // Carloff, the most robust
1446 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1448 // P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64
1449 // 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
1450 dib8000_write_word(state, 187,
1451 (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 2)
1452 | 0x3);
1454 /* // P_small_coef_ext_enable = 1 */
1455 /* dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */
1457 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1459 // 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)
1460 if (mode == 3)
1461 dib8000_write_word(state, 180, 0x1fcf | ((mode - 1) << 14));
1462 else
1463 dib8000_write_word(state, 180, 0x0fcf | ((mode - 1) << 14));
1464 // P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1,
1465 // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4
1466 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
1467 // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
1468 dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
1469 // P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
1470 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1472 // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
1473 dib8000_write_word(state, 181, 300);
1474 dib8000_write_word(state, 182, 150);
1475 dib8000_write_word(state, 183, 80);
1476 dib8000_write_word(state, 184, 300);
1477 dib8000_write_word(state, 185, 150);
1478 dib8000_write_word(state, 186, 80);
1479 } else { // Sound Broadcasting mode 3 seg
1480 // P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15
1481 /* if (mode == 3) */
1482 /* dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */
1483 /* else */
1484 /* dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */
1485 dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
1487 // P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1,
1488 // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4
1489 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
1490 // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
1491 dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
1492 //P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
1493 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1495 // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
1496 dib8000_write_word(state, 181, 350);
1497 dib8000_write_word(state, 182, 300);
1498 dib8000_write_word(state, 183, 250);
1499 dib8000_write_word(state, 184, 350);
1500 dib8000_write_word(state, 185, 300);
1501 dib8000_write_word(state, 186, 250);
1504 } else if (state->isdbt_cfg_loaded == 0) { // if not Sound Broadcasting mode : put default values for 13 segments
1505 dib8000_write_word(state, 180, (16 << 6) | 9);
1506 dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2);
1507 coff_pow = 0x2800;
1508 for (i = 0; i < 6; i++)
1509 dib8000_write_word(state, 181 + i, coff_pow);
1511 // P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1,
1512 // 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
1513 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1);
1515 // P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6
1516 dib8000_write_word(state, 340, (8 << 6) | (6 << 0));
1517 // P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1
1518 dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1520 // ---- FFT ----
1521 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 && state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1522 dib8000_write_word(state, 178, 64); // P_fft_powrange=64
1523 else
1524 dib8000_write_word(state, 178, 32); // P_fft_powrange=32
1526 /* make the cpil_coff_lock more robust but slower p_coff_winlen
1527 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
1529 /* if ( ( nbseg_diff>0)&&(nbseg_diff<13))
1530 dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */
1532 dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask); /* P_lmod4_seg_inh */
1533 dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask); /* P_pha3_seg_inh */
1534 dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask); /* P_tac_seg_inh */
1535 if ((!state->fe[0]->dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0))
1536 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */
1537 else
1538 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask); /* P_equal_noise_seg_inh */
1539 dib8000_write_word(state, 287, ~seg_mask13 | 0x1000); /* P_tmcc_seg_inh */
1540 //dib8000_write_word(state, 288, ~seg_mask13 | seg_diff_mask); /* P_tmcc_seg_eq_inh */
1541 if (!autosearching)
1542 dib8000_write_word(state, 288, (~seg_mask13 | seg_diff_mask) & 0x1fff); /* P_tmcc_seg_eq_inh */
1543 else
1544 dib8000_write_word(state, 288, 0x1fff); //disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels.
1545 dprintk("287 = %X (%d)", ~seg_mask13 | 0x1000, ~seg_mask13 | 0x1000);
1547 dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask)); /* P_des_seg_enabled */
1549 /* offset loop parameters */
1550 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1551 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1552 /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1553 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40);
1555 else // Sound Broadcasting mode 3 seg
1556 /* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1557 dib8000_write_word(state, 32, ((10 - mode) << 12) | (6 << 8) | 0x60);
1558 } else
1559 // TODO in 13 seg, timf_alpha can always be the same or not ?
1560 /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
1561 dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80);
1563 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1564 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1565 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (11-P_mode) */
1566 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode));
1568 else // Sound Broadcasting mode 3 seg
1569 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (10-P_mode) */
1570 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (9 - mode));
1571 } else
1572 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = 9 */
1573 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode));
1575 /* P_dvsy_sync_wait - reuse mode */
1576 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1577 case TRANSMISSION_MODE_8K:
1578 mode = 256;
1579 break;
1580 case TRANSMISSION_MODE_4K:
1581 mode = 128;
1582 break;
1583 default:
1584 case TRANSMISSION_MODE_2K:
1585 mode = 64;
1586 break;
1588 if (state->cfg.diversity_delay == 0)
1589 mode = (mode * (1 << (guard)) * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo
1590 else
1591 mode = (mode * (1 << (guard)) * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for DVSY-fifo
1592 mode <<= 4;
1593 dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | mode);
1595 /* channel estimation fine configuration */
1596 switch (max_constellation) {
1597 case QAM_64:
1598 ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
1599 coeff[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
1600 coeff[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
1601 coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1602 coeff[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
1603 //if (!state->cfg.hostbus_diversity) //if diversity, we should prehaps use the configuration of the max_constallation -1
1604 break;
1605 case QAM_16:
1606 ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
1607 coeff[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
1608 coeff[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
1609 coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1610 coeff[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
1611 //if (!((state->cfg.hostbus_diversity) && (max_constellation == QAM_16)))
1612 break;
1613 default:
1614 ana_gain = 0; // 0 : goes along with ADC target at -22dB to keep good mobile performance and lock at sensitivity level
1615 coeff[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
1616 coeff[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
1617 coeff[2] = 0x0333; /* P_adp_regul_ext 0.1 */
1618 coeff[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
1619 break;
1621 for (mode = 0; mode < 4; mode++)
1622 dib8000_write_word(state, 215 + mode, coeff[mode]);
1624 // update ana_gain depending on max constellation
1625 dib8000_write_word(state, 116, ana_gain);
1626 // update ADC target depending on ana_gain
1627 if (ana_gain) { // set -16dB ADC target for ana_gain=-1
1628 for (i = 0; i < 10; i++)
1629 dib8000_write_word(state, 80 + i, adc_target_16dB[i]);
1630 } else { // set -22dB ADC target for ana_gain=0
1631 for (i = 0; i < 10; i++)
1632 dib8000_write_word(state, 80 + i, adc_target_16dB[i] - 355);
1635 // ---- ANA_FE ----
1636 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
1637 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1)
1638 ana_fe = ana_fe_coeff_3seg;
1639 else // 1-segment
1640 ana_fe = ana_fe_coeff_1seg;
1641 } else
1642 ana_fe = ana_fe_coeff_13seg;
1644 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0)
1645 for (mode = 0; mode < 24; mode++)
1646 dib8000_write_word(state, 117 + mode, ana_fe[mode]);
1648 // ---- CHAN_BLK ----
1649 for (i = 0; i < 13; i++) {
1650 if ((((~seg_diff_mask) >> i) & 1) == 1) {
1651 P_cfr_left_edge += (1 << i) * ((i == 0) || ((((seg_mask13 & (~seg_diff_mask)) >> (i - 1)) & 1) == 0));
1652 P_cfr_right_edge += (1 << i) * ((i == 12) || ((((seg_mask13 & (~seg_diff_mask)) >> (i + 1)) & 1) == 0));
1655 dib8000_write_word(state, 222, P_cfr_left_edge); // P_cfr_left_edge
1656 dib8000_write_word(state, 223, P_cfr_right_edge); // P_cfr_right_edge
1657 // "P_cspu_left_edge" not used => do not care
1658 // "P_cspu_right_edge" not used => do not care
1660 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1661 dib8000_write_word(state, 228, 1); // P_2d_mode_byp=1
1662 dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); // P_cspu_win_cut = 0
1663 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0
1664 && state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) {
1665 //dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0
1666 dib8000_write_word(state, 265, 15); // P_equal_noise_sel = 15
1668 } else if (state->isdbt_cfg_loaded == 0) {
1669 dib8000_write_word(state, 228, 0); // default value
1670 dib8000_write_word(state, 265, 31); // default value
1671 dib8000_write_word(state, 205, 0x200f); // init value
1673 // ---- TMCC ----
1674 for (i = 0; i < 3; i++)
1675 tmcc_pow +=
1676 (((state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe[0]->dtv_property_cache.layer[i].segment_count);
1677 // Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9);
1678 // Threshold is set at 1/4 of max power.
1679 tmcc_pow *= (1 << (9 - 2));
1681 dib8000_write_word(state, 290, tmcc_pow); // P_tmcc_dec_thres_2k
1682 dib8000_write_word(state, 291, tmcc_pow); // P_tmcc_dec_thres_4k
1683 dib8000_write_word(state, 292, tmcc_pow); // P_tmcc_dec_thres_8k
1684 //dib8000_write_word(state, 287, (1 << 13) | 0x1000 );
1685 // ---- PHA3 ----
1687 if (state->isdbt_cfg_loaded == 0)
1688 dib8000_write_word(state, 250, 3285); /*p_2d_hspeed_thr0 */
1690 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)
1691 state->isdbt_cfg_loaded = 0;
1692 else
1693 state->isdbt_cfg_loaded = 1;
1697 static int dib8000_autosearch_start(struct dvb_frontend *fe)
1699 u8 factor;
1700 u32 value;
1701 struct dib8000_state *state = fe->demodulator_priv;
1703 int slist = 0;
1705 state->fe[0]->dtv_property_cache.inversion = 0;
1706 if (!state->fe[0]->dtv_property_cache.isdbt_sb_mode)
1707 state->fe[0]->dtv_property_cache.layer[0].segment_count = 13;
1708 state->fe[0]->dtv_property_cache.layer[0].modulation = QAM_64;
1709 state->fe[0]->dtv_property_cache.layer[0].fec = FEC_2_3;
1710 state->fe[0]->dtv_property_cache.layer[0].interleaving = 0;
1712 //choose the right list, in sb, always do everything
1713 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
1714 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1715 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1716 slist = 7;
1717 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));
1718 } else {
1719 if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) {
1720 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1721 slist = 7;
1722 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 to have autosearch start ok with mode2
1723 } else
1724 slist = 3;
1725 } else {
1726 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1727 slist = 2;
1728 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
1729 } else
1730 slist = 0;
1733 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO)
1734 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1735 if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO)
1736 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1738 dprintk("using list for autosearch : %d", slist);
1739 dib8000_set_channel(state, (unsigned char)slist, 1);
1740 //dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
1742 factor = 1;
1744 //set lock_mask values
1745 dib8000_write_word(state, 6, 0x4);
1746 dib8000_write_word(state, 7, 0x8);
1747 dib8000_write_word(state, 8, 0x1000);
1749 //set lock_mask wait time values
1750 value = 50 * state->cfg.pll->internal * factor;
1751 dib8000_write_word(state, 11, (u16) ((value >> 16) & 0xffff)); // lock0 wait time
1752 dib8000_write_word(state, 12, (u16) (value & 0xffff)); // lock0 wait time
1753 value = 100 * state->cfg.pll->internal * factor;
1754 dib8000_write_word(state, 13, (u16) ((value >> 16) & 0xffff)); // lock1 wait time
1755 dib8000_write_word(state, 14, (u16) (value & 0xffff)); // lock1 wait time
1756 value = 1000 * state->cfg.pll->internal * factor;
1757 dib8000_write_word(state, 15, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
1758 dib8000_write_word(state, 16, (u16) (value & 0xffff)); // lock2 wait time
1760 value = dib8000_read_word(state, 0);
1761 dib8000_write_word(state, 0, (u16) ((1 << 15) | value));
1762 dib8000_read_word(state, 1284); // reset the INT. n_irq_pending
1763 dib8000_write_word(state, 0, (u16) value);
1767 return 0;
1770 static int dib8000_autosearch_irq(struct dvb_frontend *fe)
1772 struct dib8000_state *state = fe->demodulator_priv;
1773 u16 irq_pending = dib8000_read_word(state, 1284);
1775 if (irq_pending & 0x1) { // failed
1776 dprintk("dib8000_autosearch_irq failed");
1777 return 1;
1780 if (irq_pending & 0x2) { // succeeded
1781 dprintk("dib8000_autosearch_irq succeeded");
1782 return 2;
1785 return 0; // still pending
1788 static int dib8000_tune(struct dvb_frontend *fe)
1790 struct dib8000_state *state = fe->demodulator_priv;
1791 int ret = 0;
1792 u16 value, mode = fft_to_mode(state);
1794 // we are already tuned - just resuming from suspend
1795 if (state == NULL)
1796 return -EINVAL;
1798 dib8000_set_bandwidth(fe, state->fe[0]->dtv_property_cache.bandwidth_hz / 1000);
1799 dib8000_set_channel(state, 0, 0);
1801 // restart demod
1802 ret |= dib8000_write_word(state, 770, 0x4000);
1803 ret |= dib8000_write_word(state, 770, 0x0000);
1804 msleep(45);
1806 /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3 */
1807 /* ret |= dib8000_write_word(state, 29, (0 << 9) | (4 << 5) | (0 << 4) | (3 << 0) ); workaround inh_isi stays at 1 */
1809 // never achieved a lock before - wait for timfreq to update
1810 if (state->timf == 0) {
1811 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1812 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1813 msleep(300);
1814 else // Sound Broadcasting mode 3 seg
1815 msleep(500);
1816 } else // 13 seg
1817 msleep(200);
1819 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1820 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1822 /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40 alpha to check on board */
1823 dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40);
1824 //dib8000_write_word(state, 32, (8 << 12) | (6 << 8) | 0x80);
1826 /* P_ctrl_sfreq_step= (12-P_mode) P_ctrl_sfreq_inh =0 P_ctrl_pha_off_max */
1827 ret |= dib8000_write_word(state, 37, (12 - mode) | ((5 + mode) << 5));
1829 } else { // Sound Broadcasting mode 3 seg
1831 /* P_timf_alpha = (12-P_mode) , P_corm_alpha=6, P_corm_thres=0x60 alpha to check on board */
1832 dib8000_write_word(state, 32, ((12 - mode) << 12) | (6 << 8) | 0x60);
1834 ret |= dib8000_write_word(state, 37, (11 - mode) | ((5 + mode) << 5));
1837 } else { // 13 seg
1838 /* P_timf_alpha = 8 , P_corm_alpha=6, P_corm_thres=0x80 alpha to check on board */
1839 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x80);
1841 ret |= dib8000_write_word(state, 37, (10 - mode) | ((5 + mode) << 5));
1845 // we achieved a coff_cpil_lock - it's time to update the timf
1846 if ((dib8000_read_word(state, 568) >> 11) & 0x1)
1847 dib8000_update_timf(state);
1849 //now that tune is finished, lock0 should lock on fec_mpeg to output this lock on MP_LOCK. It's changed in autosearch start
1850 dib8000_write_word(state, 6, 0x200);
1852 if (state->revision == 0x8002) {
1853 value = dib8000_read_word(state, 903);
1854 dib8000_write_word(state, 903, value & ~(1 << 3));
1855 msleep(1);
1856 dib8000_write_word(state, 903, value | (1 << 3));
1859 return ret;
1862 static int dib8000_wakeup(struct dvb_frontend *fe)
1864 struct dib8000_state *state = fe->demodulator_priv;
1865 u8 index_frontend;
1866 int ret;
1868 dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
1869 dib8000_set_adc_state(state, DIBX000_ADC_ON);
1870 if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
1871 dprintk("could not start Slow ADC");
1873 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1874 ret = state->fe[index_frontend]->ops.init(state->fe[index_frontend]);
1875 if (ret < 0)
1876 return ret;
1879 return 0;
1882 static int dib8000_sleep(struct dvb_frontend *fe)
1884 struct dib8000_state *state = fe->demodulator_priv;
1885 u8 index_frontend;
1886 int ret;
1888 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1889 ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
1890 if (ret < 0)
1891 return ret;
1894 dib8000_set_output_mode(fe, OUTMODE_HIGH_Z);
1895 dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY);
1896 return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF);
1899 enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
1901 struct dib8000_state *state = fe->demodulator_priv;
1902 return state->tune_state;
1904 EXPORT_SYMBOL(dib8000_get_tune_state);
1906 int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
1908 struct dib8000_state *state = fe->demodulator_priv;
1909 state->tune_state = tune_state;
1910 return 0;
1912 EXPORT_SYMBOL(dib8000_set_tune_state);
1914 static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1916 struct dib8000_state *state = fe->demodulator_priv;
1917 u16 i, val = 0;
1918 fe_status_t stat;
1919 u8 index_frontend, sub_index_frontend;
1921 fe->dtv_property_cache.bandwidth_hz = 6000000;
1923 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1924 state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
1925 if (stat&FE_HAS_SYNC) {
1926 dprintk("TMCC lock on the slave%i", index_frontend);
1927 /* synchronize the cache with the other frontends */
1928 state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend], fep);
1929 for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL); sub_index_frontend++) {
1930 if (sub_index_frontend != index_frontend) {
1931 state->fe[sub_index_frontend]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode;
1932 state->fe[sub_index_frontend]->dtv_property_cache.inversion = state->fe[index_frontend]->dtv_property_cache.inversion;
1933 state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode = state->fe[index_frontend]->dtv_property_cache.transmission_mode;
1934 state->fe[sub_index_frontend]->dtv_property_cache.guard_interval = state->fe[index_frontend]->dtv_property_cache.guard_interval;
1935 state->fe[sub_index_frontend]->dtv_property_cache.isdbt_partial_reception = state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception;
1936 for (i = 0; i < 3; i++) {
1937 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].segment_count = state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count;
1938 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].interleaving = state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving;
1939 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].fec = state->fe[index_frontend]->dtv_property_cache.layer[i].fec;
1940 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].modulation = state->fe[index_frontend]->dtv_property_cache.layer[i].modulation;
1944 return 0;
1948 fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1;
1950 val = dib8000_read_word(state, 570);
1951 fe->dtv_property_cache.inversion = (val & 0x40) >> 6;
1952 switch ((val & 0x30) >> 4) {
1953 case 1:
1954 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
1955 break;
1956 case 3:
1957 default:
1958 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1959 break;
1962 switch (val & 0x3) {
1963 case 0:
1964 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
1965 dprintk("dib8000_get_frontend GI = 1/32 ");
1966 break;
1967 case 1:
1968 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
1969 dprintk("dib8000_get_frontend GI = 1/16 ");
1970 break;
1971 case 2:
1972 dprintk("dib8000_get_frontend GI = 1/8 ");
1973 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1974 break;
1975 case 3:
1976 dprintk("dib8000_get_frontend GI = 1/4 ");
1977 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
1978 break;
1981 val = dib8000_read_word(state, 505);
1982 fe->dtv_property_cache.isdbt_partial_reception = val & 1;
1983 dprintk("dib8000_get_frontend : partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception);
1985 for (i = 0; i < 3; i++) {
1986 val = dib8000_read_word(state, 493 + i);
1987 fe->dtv_property_cache.layer[i].segment_count = val & 0x0F;
1988 dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count);
1990 val = dib8000_read_word(state, 499 + i);
1991 fe->dtv_property_cache.layer[i].interleaving = val & 0x3;
1992 dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ", i, fe->dtv_property_cache.layer[i].interleaving);
1994 val = dib8000_read_word(state, 481 + i);
1995 switch (val & 0x7) {
1996 case 1:
1997 fe->dtv_property_cache.layer[i].fec = FEC_1_2;
1998 dprintk("dib8000_get_frontend : Layer %d Code Rate = 1/2 ", i);
1999 break;
2000 case 2:
2001 fe->dtv_property_cache.layer[i].fec = FEC_2_3;
2002 dprintk("dib8000_get_frontend : Layer %d Code Rate = 2/3 ", i);
2003 break;
2004 case 3:
2005 fe->dtv_property_cache.layer[i].fec = FEC_3_4;
2006 dprintk("dib8000_get_frontend : Layer %d Code Rate = 3/4 ", i);
2007 break;
2008 case 5:
2009 fe->dtv_property_cache.layer[i].fec = FEC_5_6;
2010 dprintk("dib8000_get_frontend : Layer %d Code Rate = 5/6 ", i);
2011 break;
2012 default:
2013 fe->dtv_property_cache.layer[i].fec = FEC_7_8;
2014 dprintk("dib8000_get_frontend : Layer %d Code Rate = 7/8 ", i);
2015 break;
2018 val = dib8000_read_word(state, 487 + i);
2019 switch (val & 0x3) {
2020 case 0:
2021 dprintk("dib8000_get_frontend : Layer %d DQPSK ", i);
2022 fe->dtv_property_cache.layer[i].modulation = DQPSK;
2023 break;
2024 case 1:
2025 fe->dtv_property_cache.layer[i].modulation = QPSK;
2026 dprintk("dib8000_get_frontend : Layer %d QPSK ", i);
2027 break;
2028 case 2:
2029 fe->dtv_property_cache.layer[i].modulation = QAM_16;
2030 dprintk("dib8000_get_frontend : Layer %d QAM16 ", i);
2031 break;
2032 case 3:
2033 default:
2034 dprintk("dib8000_get_frontend : Layer %d QAM64 ", i);
2035 fe->dtv_property_cache.layer[i].modulation = QAM_64;
2036 break;
2040 /* synchronize the cache with the other frontends */
2041 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2042 state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode = fe->dtv_property_cache.isdbt_sb_mode;
2043 state->fe[index_frontend]->dtv_property_cache.inversion = fe->dtv_property_cache.inversion;
2044 state->fe[index_frontend]->dtv_property_cache.transmission_mode = fe->dtv_property_cache.transmission_mode;
2045 state->fe[index_frontend]->dtv_property_cache.guard_interval = fe->dtv_property_cache.guard_interval;
2046 state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception = fe->dtv_property_cache.isdbt_partial_reception;
2047 for (i = 0; i < 3; i++) {
2048 state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count = fe->dtv_property_cache.layer[i].segment_count;
2049 state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving = fe->dtv_property_cache.layer[i].interleaving;
2050 state->fe[index_frontend]->dtv_property_cache.layer[i].fec = fe->dtv_property_cache.layer[i].fec;
2051 state->fe[index_frontend]->dtv_property_cache.layer[i].modulation = fe->dtv_property_cache.layer[i].modulation;
2054 return 0;
2057 static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
2059 struct dib8000_state *state = fe->demodulator_priv;
2060 u8 nbr_pending, exit_condition, index_frontend;
2061 s8 index_frontend_success = -1;
2062 int time, ret;
2063 int time_slave = FE_CALLBACK_TIME_NEVER;
2065 if (state->fe[0]->dtv_property_cache.frequency == 0) {
2066 dprintk("dib8000: must at least specify frequency ");
2067 return 0;
2070 if (state->fe[0]->dtv_property_cache.bandwidth_hz == 0) {
2071 dprintk("dib8000: no bandwidth specified, set to default ");
2072 state->fe[0]->dtv_property_cache.bandwidth_hz = 6000000;
2075 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2076 /* synchronization of the cache */
2077 state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT;
2078 memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));
2080 dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_HIGH_Z);
2081 if (state->fe[index_frontend]->ops.tuner_ops.set_params)
2082 state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend], fep);
2084 dib8000_set_tune_state(state->fe[index_frontend], CT_AGC_START);
2087 /* start up the AGC */
2088 do {
2089 time = dib8000_agc_startup(state->fe[0]);
2090 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2091 time_slave = dib8000_agc_startup(state->fe[index_frontend]);
2092 if (time == FE_CALLBACK_TIME_NEVER)
2093 time = time_slave;
2094 else if ((time_slave != FE_CALLBACK_TIME_NEVER) && (time_slave > time))
2095 time = time_slave;
2097 if (time != FE_CALLBACK_TIME_NEVER)
2098 msleep(time / 10);
2099 else
2100 break;
2101 exit_condition = 1;
2102 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2103 if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_AGC_STOP) {
2104 exit_condition = 0;
2105 break;
2108 } while (exit_condition == 0);
2110 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2111 dib8000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
2113 if ((state->fe[0]->dtv_property_cache.delivery_system != SYS_ISDBT) ||
2114 (state->fe[0]->dtv_property_cache.inversion == INVERSION_AUTO) ||
2115 (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) ||
2116 (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) ||
2117 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) &&
2118 (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0xff) &&
2119 (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0) &&
2120 ((state->fe[0]->dtv_property_cache.layer[0].modulation == QAM_AUTO) ||
2121 (state->fe[0]->dtv_property_cache.layer[0].fec == FEC_AUTO))) ||
2122 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) &&
2123 (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0xff) &&
2124 (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0) &&
2125 ((state->fe[0]->dtv_property_cache.layer[1].modulation == QAM_AUTO) ||
2126 (state->fe[0]->dtv_property_cache.layer[1].fec == FEC_AUTO))) ||
2127 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) &&
2128 (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0xff) &&
2129 (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0) &&
2130 ((state->fe[0]->dtv_property_cache.layer[2].modulation == QAM_AUTO) ||
2131 (state->fe[0]->dtv_property_cache.layer[2].fec == FEC_AUTO))) ||
2132 (((state->fe[0]->dtv_property_cache.layer[0].segment_count == 0) ||
2133 ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) &&
2134 ((state->fe[0]->dtv_property_cache.layer[1].segment_count == 0) ||
2135 ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) &&
2136 ((state->fe[0]->dtv_property_cache.layer[2].segment_count == 0) || ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) {
2137 int i = 80000;
2138 u8 found = 0;
2139 u8 tune_failed = 0;
2141 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2142 dib8000_set_bandwidth(state->fe[index_frontend], fe->dtv_property_cache.bandwidth_hz / 1000);
2143 dib8000_autosearch_start(state->fe[index_frontend]);
2146 do {
2147 msleep(20);
2148 nbr_pending = 0;
2149 exit_condition = 0; /* 0: tune pending; 1: tune failed; 2:tune success */
2150 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2151 if (((tune_failed >> index_frontend) & 0x1) == 0) {
2152 found = dib8000_autosearch_irq(state->fe[index_frontend]);
2153 switch (found) {
2154 case 0: /* tune pending */
2155 nbr_pending++;
2156 break;
2157 case 2:
2158 dprintk("autosearch succeed on the frontend%i", index_frontend);
2159 exit_condition = 2;
2160 index_frontend_success = index_frontend;
2161 break;
2162 default:
2163 dprintk("unhandled autosearch result");
2164 case 1:
2165 dprintk("autosearch failed for the frontend%i", index_frontend);
2166 break;
2171 /* if all tune are done and no success, exit: tune failed */
2172 if ((nbr_pending == 0) && (exit_condition == 0))
2173 exit_condition = 1;
2174 } while ((exit_condition == 0) && i--);
2176 if (exit_condition == 1) { /* tune failed */
2177 dprintk("tune failed");
2178 return 0;
2181 dprintk("tune success on frontend%i", index_frontend_success);
2183 dib8000_get_frontend(fe, fep);
2186 for (index_frontend = 0, ret = 0; (ret >= 0) && (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2187 ret = dib8000_tune(state->fe[index_frontend]);
2189 /* set output mode and diversity input */
2190 dib8000_set_output_mode(state->fe[0], state->cfg.output_mode);
2191 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2192 dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_DIVERSITY);
2193 dib8000_set_diversity_in(state->fe[index_frontend-1], 1);
2196 /* turn off the diversity of the last chip */
2197 dib8000_set_diversity_in(state->fe[index_frontend-1], 0);
2199 return ret;
2202 static u16 dib8000_read_lock(struct dvb_frontend *fe)
2204 struct dib8000_state *state = fe->demodulator_priv;
2206 return dib8000_read_word(state, 568);
2209 static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
2211 struct dib8000_state *state = fe->demodulator_priv;
2212 u16 lock_slave = 0, lock = dib8000_read_word(state, 568);
2213 u8 index_frontend;
2215 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2216 lock_slave |= dib8000_read_lock(state->fe[index_frontend]);
2218 *stat = 0;
2220 if (((lock >> 13) & 1) || ((lock_slave >> 13) & 1))
2221 *stat |= FE_HAS_SIGNAL;
2223 if (((lock >> 8) & 1) || ((lock_slave >> 8) & 1)) /* Equal */
2224 *stat |= FE_HAS_CARRIER;
2226 if ((((lock >> 1) & 0xf) == 0xf) || (((lock_slave >> 1) & 0xf) == 0xf)) /* TMCC_SYNC */
2227 *stat |= FE_HAS_SYNC;
2229 if ((((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) && ((lock >> 5) & 7)) /* FEC MPEG */
2230 *stat |= FE_HAS_LOCK;
2232 if (((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) {
2233 lock = dib8000_read_word(state, 554); /* Viterbi Layer A */
2234 if (lock & 0x01)
2235 *stat |= FE_HAS_VITERBI;
2237 lock = dib8000_read_word(state, 555); /* Viterbi Layer B */
2238 if (lock & 0x01)
2239 *stat |= FE_HAS_VITERBI;
2241 lock = dib8000_read_word(state, 556); /* Viterbi Layer C */
2242 if (lock & 0x01)
2243 *stat |= FE_HAS_VITERBI;
2246 return 0;
2249 static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber)
2251 struct dib8000_state *state = fe->demodulator_priv;
2252 *ber = (dib8000_read_word(state, 560) << 16) | dib8000_read_word(state, 561); // 13 segments
2253 return 0;
2256 static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
2258 struct dib8000_state *state = fe->demodulator_priv;
2259 *unc = dib8000_read_word(state, 565); // packet error on 13 seg
2260 return 0;
2263 static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2265 struct dib8000_state *state = fe->demodulator_priv;
2266 u8 index_frontend;
2267 u16 val;
2269 *strength = 0;
2270 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2271 state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
2272 if (val > 65535 - *strength)
2273 *strength = 65535;
2274 else
2275 *strength += val;
2278 val = 65535 - dib8000_read_word(state, 390);
2279 if (val > 65535 - *strength)
2280 *strength = 65535;
2281 else
2282 *strength += val;
2283 return 0;
2286 static u32 dib8000_get_snr(struct dvb_frontend *fe)
2288 struct dib8000_state *state = fe->demodulator_priv;
2289 u32 n, s, exp;
2290 u16 val;
2292 val = dib8000_read_word(state, 542);
2293 n = (val >> 6) & 0xff;
2294 exp = (val & 0x3f);
2295 if ((exp & 0x20) != 0)
2296 exp -= 0x40;
2297 n <<= exp+16;
2299 val = dib8000_read_word(state, 543);
2300 s = (val >> 6) & 0xff;
2301 exp = (val & 0x3f);
2302 if ((exp & 0x20) != 0)
2303 exp -= 0x40;
2304 s <<= exp+16;
2306 if (n > 0) {
2307 u32 t = (s/n) << 16;
2308 return t + ((s << 16) - n*t) / n;
2310 return 0xffffffff;
2313 static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
2315 struct dib8000_state *state = fe->demodulator_priv;
2316 u8 index_frontend;
2317 u32 snr_master;
2319 snr_master = dib8000_get_snr(fe);
2320 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2321 snr_master += dib8000_get_snr(state->fe[index_frontend]);
2323 if (snr_master != 0) {
2324 snr_master = 10*intlog10(snr_master>>16);
2325 *snr = snr_master / ((1 << 24) / 10);
2327 else
2328 *snr = 0;
2330 return 0;
2333 int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
2335 struct dib8000_state *state = fe->demodulator_priv;
2336 u8 index_frontend = 1;
2338 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
2339 index_frontend++;
2340 if (index_frontend < MAX_NUMBER_OF_FRONTENDS) {
2341 dprintk("set slave fe %p to index %i", fe_slave, index_frontend);
2342 state->fe[index_frontend] = fe_slave;
2343 return 0;
2346 dprintk("too many slave frontend");
2347 return -ENOMEM;
2349 EXPORT_SYMBOL(dib8000_set_slave_frontend);
2351 int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
2353 struct dib8000_state *state = fe->demodulator_priv;
2354 u8 index_frontend = 1;
2356 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
2357 index_frontend++;
2358 if (index_frontend != 1) {
2359 dprintk("remove slave fe %p (index %i)", state->fe[index_frontend-1], index_frontend-1);
2360 state->fe[index_frontend] = NULL;
2361 return 0;
2364 dprintk("no frontend to be removed");
2365 return -ENODEV;
2367 EXPORT_SYMBOL(dib8000_remove_slave_frontend);
2369 struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
2371 struct dib8000_state *state = fe->demodulator_priv;
2373 if (slave_index >= MAX_NUMBER_OF_FRONTENDS)
2374 return NULL;
2375 return state->fe[slave_index];
2377 EXPORT_SYMBOL(dib8000_get_slave_frontend);
2380 int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
2382 int k = 0;
2383 u8 new_addr = 0;
2384 struct i2c_device client = {.adap = host };
2386 for (k = no_of_demods - 1; k >= 0; k--) {
2387 /* designated i2c address */
2388 new_addr = first_addr + (k << 1);
2390 client.addr = new_addr;
2391 dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */
2392 if (dib8000_identify(&client) == 0) {
2393 dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */
2394 client.addr = default_addr;
2395 if (dib8000_identify(&client) == 0) {
2396 dprintk("#%d: not identified", k);
2397 return -EINVAL;
2401 /* start diversity to pull_down div_str - just for i2c-enumeration */
2402 dib8000_i2c_write16(&client, 1286, (1 << 10) | (4 << 6));
2404 /* set new i2c address and force divstart */
2405 dib8000_i2c_write16(&client, 1285, (new_addr << 2) | 0x2);
2406 client.addr = new_addr;
2407 dib8000_identify(&client);
2409 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
2412 for (k = 0; k < no_of_demods; k++) {
2413 new_addr = first_addr | (k << 1);
2414 client.addr = new_addr;
2416 // unforce divstr
2417 dib8000_i2c_write16(&client, 1285, new_addr << 2);
2419 /* deactivate div - it was just for i2c-enumeration */
2420 dib8000_i2c_write16(&client, 1286, 0);
2423 return 0;
2426 EXPORT_SYMBOL(dib8000_i2c_enumeration);
2427 static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
2429 tune->min_delay_ms = 1000;
2430 tune->step_size = 0;
2431 tune->max_drift = 0;
2432 return 0;
2435 static void dib8000_release(struct dvb_frontend *fe)
2437 struct dib8000_state *st = fe->demodulator_priv;
2438 u8 index_frontend;
2440 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++)
2441 dvb_frontend_detach(st->fe[index_frontend]);
2443 dibx000_exit_i2c_master(&st->i2c_master);
2444 kfree(st->fe[0]);
2445 kfree(st);
2448 struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
2450 struct dib8000_state *st = fe->demodulator_priv;
2451 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
2454 EXPORT_SYMBOL(dib8000_get_i2c_master);
2456 int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
2458 struct dib8000_state *st = fe->demodulator_priv;
2459 u16 val = dib8000_read_word(st, 299) & 0xffef;
2460 val |= (onoff & 0x1) << 4;
2462 dprintk("pid filter enabled %d", onoff);
2463 return dib8000_write_word(st, 299, val);
2465 EXPORT_SYMBOL(dib8000_pid_filter_ctrl);
2467 int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
2469 struct dib8000_state *st = fe->demodulator_priv;
2470 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
2471 return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0);
2473 EXPORT_SYMBOL(dib8000_pid_filter);
2475 static const struct dvb_frontend_ops dib8000_ops = {
2476 .info = {
2477 .name = "DiBcom 8000 ISDB-T",
2478 .type = FE_OFDM,
2479 .frequency_min = 44250000,
2480 .frequency_max = 867250000,
2481 .frequency_stepsize = 62500,
2482 .caps = FE_CAN_INVERSION_AUTO |
2483 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2484 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2485 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2486 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2489 .release = dib8000_release,
2491 .init = dib8000_wakeup,
2492 .sleep = dib8000_sleep,
2494 .set_frontend = dib8000_set_frontend,
2495 .get_tune_settings = dib8000_fe_get_tune_settings,
2496 .get_frontend = dib8000_get_frontend,
2498 .read_status = dib8000_read_status,
2499 .read_ber = dib8000_read_ber,
2500 .read_signal_strength = dib8000_read_signal_strength,
2501 .read_snr = dib8000_read_snr,
2502 .read_ucblocks = dib8000_read_unc_blocks,
2505 struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
2507 struct dvb_frontend *fe;
2508 struct dib8000_state *state;
2510 dprintk("dib8000_attach");
2512 state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL);
2513 if (state == NULL)
2514 return NULL;
2515 fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);
2516 if (fe == NULL)
2517 goto error;
2519 memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
2520 state->i2c.adap = i2c_adap;
2521 state->i2c.addr = i2c_addr;
2522 state->gpio_val = cfg->gpio_val;
2523 state->gpio_dir = cfg->gpio_dir;
2525 /* Ensure the output mode remains at the previous default if it's
2526 * not specifically set by the caller.
2528 if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2529 state->cfg.output_mode = OUTMODE_MPEG2_FIFO;
2531 state->fe[0] = fe;
2532 fe->demodulator_priv = state;
2533 memcpy(&state->fe[0]->ops, &dib8000_ops, sizeof(struct dvb_frontend_ops));
2535 state->timf_default = cfg->pll->timf;
2537 if (dib8000_identify(&state->i2c) == 0)
2538 goto error;
2540 dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr);
2542 dib8000_reset(fe);
2544 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5)); /* ber_rs_len = 3 */
2546 return fe;
2548 error:
2549 kfree(state);
2550 return NULL;
2553 EXPORT_SYMBOL(dib8000_attach);
2555 MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@dibcom.fr, " "Patrick Boettcher <pboettcher@dibcom.fr>");
2556 MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator");
2557 MODULE_LICENSE("GPL");