Merge branch 'for-3.11' of git://linux-nfs.org/~bfields/linux
[linux-2.6.git] / drivers / media / dvb-frontends / dib8000.c
blob90536147bf0458c444a59e176b79ddff09471f4f
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 <linux/mutex.h>
15 #include "dvb_math.h"
17 #include "dvb_frontend.h"
19 #include "dib8000.h"
21 #define LAYER_ALL -1
22 #define LAYER_A 1
23 #define LAYER_B 2
24 #define LAYER_C 3
26 #define MAX_NUMBER_OF_FRONTENDS 6
27 /* #define DIB8000_AGC_FREEZE */
29 static int debug;
30 module_param(debug, int, 0644);
31 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
33 #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0)
35 struct i2c_device {
36 struct i2c_adapter *adap;
37 u8 addr;
38 u8 *i2c_write_buffer;
39 u8 *i2c_read_buffer;
40 struct mutex *i2c_buffer_lock;
43 enum param_loop_step {
44 LOOP_TUNE_1,
45 LOOP_TUNE_2
48 enum dib8000_autosearch_step {
49 AS_START = 0,
50 AS_SEARCHING_FFT,
51 AS_SEARCHING_GUARD,
52 AS_DONE = 100,
55 enum timeout_mode {
56 SYMBOL_DEPENDENT_OFF = 0,
57 SYMBOL_DEPENDENT_ON,
60 struct dib8000_state {
61 struct dib8000_config cfg;
63 struct i2c_device i2c;
65 struct dibx000_i2c_master i2c_master;
67 u16 wbd_ref;
69 u8 current_band;
70 u32 current_bandwidth;
71 struct dibx000_agc_config *current_agc;
72 u32 timf;
73 u32 timf_default;
75 u8 div_force_off:1;
76 u8 div_state:1;
77 u16 div_sync_wait;
79 u8 agc_state;
80 u8 differential_constellation;
81 u8 diversity_onoff;
83 s16 ber_monitored_layer;
84 u16 gpio_dir;
85 u16 gpio_val;
87 u16 revision;
88 u8 isdbt_cfg_loaded;
89 enum frontend_tune_state tune_state;
90 s32 status;
92 struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
94 /* for the I2C transfer */
95 struct i2c_msg msg[2];
96 u8 i2c_write_buffer[4];
97 u8 i2c_read_buffer[2];
98 struct mutex i2c_buffer_lock;
99 u8 input_mode_mpeg;
101 u16 tuner_enable;
102 struct i2c_adapter dib8096p_tuner_adap;
103 u16 current_demod_bw;
105 u16 seg_mask;
106 u16 seg_diff_mask;
107 u16 mode;
108 u8 layer_b_nb_seg;
109 u8 layer_c_nb_seg;
111 u8 channel_parameters_set;
112 u16 autosearch_state;
113 u16 found_nfft;
114 u16 found_guard;
115 u8 subchannel;
116 u8 symbol_duration;
117 u32 timeout;
118 u8 longest_intlv_layer;
119 u16 output_mode;
121 #ifdef DIB8000_AGC_FREEZE
122 u16 agc1_max;
123 u16 agc1_min;
124 u16 agc2_max;
125 u16 agc2_min;
126 #endif
129 enum dib8000_power_mode {
130 DIB8000_POWER_ALL = 0,
131 DIB8000_POWER_INTERFACE_ONLY,
134 static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
136 u16 ret;
137 struct i2c_msg msg[2] = {
138 {.addr = i2c->addr >> 1, .flags = 0, .len = 2},
139 {.addr = i2c->addr >> 1, .flags = I2C_M_RD, .len = 2},
142 if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) {
143 dprintk("could not acquire lock");
144 return 0;
147 msg[0].buf = i2c->i2c_write_buffer;
148 msg[0].buf[0] = reg >> 8;
149 msg[0].buf[1] = reg & 0xff;
150 msg[1].buf = i2c->i2c_read_buffer;
152 if (i2c_transfer(i2c->adap, msg, 2) != 2)
153 dprintk("i2c read error on %d", reg);
155 ret = (msg[1].buf[0] << 8) | msg[1].buf[1];
156 mutex_unlock(i2c->i2c_buffer_lock);
157 return ret;
160 static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
162 u16 ret;
164 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
165 dprintk("could not acquire lock");
166 return 0;
169 state->i2c_write_buffer[0] = reg >> 8;
170 state->i2c_write_buffer[1] = reg & 0xff;
172 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
173 state->msg[0].addr = state->i2c.addr >> 1;
174 state->msg[0].flags = 0;
175 state->msg[0].buf = state->i2c_write_buffer;
176 state->msg[0].len = 2;
177 state->msg[1].addr = state->i2c.addr >> 1;
178 state->msg[1].flags = I2C_M_RD;
179 state->msg[1].buf = state->i2c_read_buffer;
180 state->msg[1].len = 2;
182 if (i2c_transfer(state->i2c.adap, state->msg, 2) != 2)
183 dprintk("i2c read error on %d", reg);
185 ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
186 mutex_unlock(&state->i2c_buffer_lock);
188 return ret;
191 static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
193 u16 rw[2];
195 rw[0] = dib8000_read_word(state, reg + 0);
196 rw[1] = dib8000_read_word(state, reg + 1);
198 return ((rw[0] << 16) | (rw[1]));
201 static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
203 struct i2c_msg msg = {.addr = i2c->addr >> 1, .flags = 0, .len = 4};
204 int ret = 0;
206 if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) {
207 dprintk("could not acquire lock");
208 return -EINVAL;
211 msg.buf = i2c->i2c_write_buffer;
212 msg.buf[0] = (reg >> 8) & 0xff;
213 msg.buf[1] = reg & 0xff;
214 msg.buf[2] = (val >> 8) & 0xff;
215 msg.buf[3] = val & 0xff;
217 ret = i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
218 mutex_unlock(i2c->i2c_buffer_lock);
220 return ret;
223 static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
225 int ret;
227 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
228 dprintk("could not acquire lock");
229 return -EINVAL;
232 state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
233 state->i2c_write_buffer[1] = reg & 0xff;
234 state->i2c_write_buffer[2] = (val >> 8) & 0xff;
235 state->i2c_write_buffer[3] = val & 0xff;
237 memset(&state->msg[0], 0, sizeof(struct i2c_msg));
238 state->msg[0].addr = state->i2c.addr >> 1;
239 state->msg[0].flags = 0;
240 state->msg[0].buf = state->i2c_write_buffer;
241 state->msg[0].len = 4;
243 ret = (i2c_transfer(state->i2c.adap, state->msg, 1) != 1 ?
244 -EREMOTEIO : 0);
245 mutex_unlock(&state->i2c_buffer_lock);
247 return ret;
250 static const s16 coeff_2k_sb_1seg_dqpsk[8] = {
251 (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
252 (920 << 5) | 0x09
255 static const s16 coeff_2k_sb_1seg[8] = {
256 (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
259 static const s16 coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
260 (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
261 (-931 << 5) | 0x0f
264 static const s16 coeff_2k_sb_3seg_0dqpsk[8] = {
265 (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
266 (982 << 5) | 0x0c
269 static const s16 coeff_2k_sb_3seg_1dqpsk[8] = {
270 (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
271 (-720 << 5) | 0x0d
274 static const s16 coeff_2k_sb_3seg[8] = {
275 (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
276 (-610 << 5) | 0x0a
279 static const s16 coeff_4k_sb_1seg_dqpsk[8] = {
280 (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
281 (-922 << 5) | 0x0d
284 static const s16 coeff_4k_sb_1seg[8] = {
285 (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
286 (-655 << 5) | 0x0a
289 static const s16 coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
290 (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
291 (-958 << 5) | 0x13
294 static const s16 coeff_4k_sb_3seg_0dqpsk[8] = {
295 (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
296 (-568 << 5) | 0x0f
299 static const s16 coeff_4k_sb_3seg_1dqpsk[8] = {
300 (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
301 (-848 << 5) | 0x13
304 static const s16 coeff_4k_sb_3seg[8] = {
305 (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
306 (-869 << 5) | 0x13
309 static const s16 coeff_8k_sb_1seg_dqpsk[8] = {
310 (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
311 (-598 << 5) | 0x10
314 static const s16 coeff_8k_sb_1seg[8] = {
315 (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
316 (585 << 5) | 0x0f
319 static const s16 coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
320 (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
321 (0 << 5) | 0x14
324 static const s16 coeff_8k_sb_3seg_0dqpsk[8] = {
325 (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
326 (-877 << 5) | 0x15
329 static const s16 coeff_8k_sb_3seg_1dqpsk[8] = {
330 (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
331 (-921 << 5) | 0x14
334 static const s16 coeff_8k_sb_3seg[8] = {
335 (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
336 (690 << 5) | 0x14
339 static const s16 ana_fe_coeff_3seg[24] = {
340 81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
343 static const s16 ana_fe_coeff_1seg[24] = {
344 249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
347 static const s16 ana_fe_coeff_13seg[24] = {
348 396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
351 static u16 fft_to_mode(struct dib8000_state *state)
353 u16 mode;
354 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
355 case TRANSMISSION_MODE_2K:
356 mode = 1;
357 break;
358 case TRANSMISSION_MODE_4K:
359 mode = 2;
360 break;
361 default:
362 case TRANSMISSION_MODE_AUTO:
363 case TRANSMISSION_MODE_8K:
364 mode = 3;
365 break;
367 return mode;
370 static void dib8000_set_acquisition_mode(struct dib8000_state *state)
372 u16 nud = dib8000_read_word(state, 298);
373 nud |= (1 << 3) | (1 << 0);
374 dprintk("acquisition mode activated");
375 dib8000_write_word(state, 298, nud);
377 static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode)
379 struct dib8000_state *state = fe->demodulator_priv;
380 u16 outreg, fifo_threshold, smo_mode, sram = 0x0205; /* by default SDRAM deintlv is enabled */
382 state->output_mode = mode;
383 outreg = 0;
384 fifo_threshold = 1792;
385 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
387 dprintk("-I- Setting output mode for demod %p to %d",
388 &state->fe[0], mode);
390 switch (mode) {
391 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
392 outreg = (1 << 10); /* 0x0400 */
393 break;
394 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
395 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
396 break;
397 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
398 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
399 break;
400 case OUTMODE_DIVERSITY:
401 if (state->cfg.hostbus_diversity) {
402 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
403 sram &= 0xfdff;
404 } else
405 sram |= 0x0c00;
406 break;
407 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
408 smo_mode |= (3 << 1);
409 fifo_threshold = 512;
410 outreg = (1 << 10) | (5 << 6);
411 break;
412 case OUTMODE_HIGH_Z: // disable
413 outreg = 0;
414 break;
416 case OUTMODE_ANALOG_ADC:
417 outreg = (1 << 10) | (3 << 6);
418 dib8000_set_acquisition_mode(state);
419 break;
421 default:
422 dprintk("Unhandled output_mode passed to be set for demod %p",
423 &state->fe[0]);
424 return -EINVAL;
427 if (state->cfg.output_mpeg2_in_188_bytes)
428 smo_mode |= (1 << 5);
430 dib8000_write_word(state, 299, smo_mode);
431 dib8000_write_word(state, 300, fifo_threshold); /* synchronous fread */
432 dib8000_write_word(state, 1286, outreg);
433 dib8000_write_word(state, 1291, sram);
435 return 0;
438 static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff)
440 struct dib8000_state *state = fe->demodulator_priv;
441 u16 tmp, sync_wait = dib8000_read_word(state, 273) & 0xfff0;
443 dprintk("set diversity input to %i", onoff);
444 if (!state->differential_constellation) {
445 dib8000_write_word(state, 272, 1 << 9); //dvsy_off_lmod4 = 1
446 dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2); // sync_enable = 1; comb_mode = 2
447 } else {
448 dib8000_write_word(state, 272, 0); //dvsy_off_lmod4 = 0
449 dib8000_write_word(state, 273, sync_wait); // sync_enable = 0; comb_mode = 0
451 state->diversity_onoff = onoff;
453 switch (onoff) {
454 case 0: /* only use the internal way - not the diversity input */
455 dib8000_write_word(state, 270, 1);
456 dib8000_write_word(state, 271, 0);
457 break;
458 case 1: /* both ways */
459 dib8000_write_word(state, 270, 6);
460 dib8000_write_word(state, 271, 6);
461 break;
462 case 2: /* only the diversity input */
463 dib8000_write_word(state, 270, 0);
464 dib8000_write_word(state, 271, 1);
465 break;
468 if (state->revision == 0x8002) {
469 tmp = dib8000_read_word(state, 903);
470 dib8000_write_word(state, 903, tmp & ~(1 << 3));
471 msleep(30);
472 dib8000_write_word(state, 903, tmp | (1 << 3));
474 return 0;
477 static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_power_mode mode)
479 /* by default everything is going to be powered off */
480 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
481 reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3,
482 reg_1280;
484 if (state->revision != 0x8090)
485 reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
486 else
487 reg_1280 = (dib8000_read_word(state, 1280) & 0x707f) | 0x8f80;
489 /* now, depending on the requested mode, we power on */
490 switch (mode) {
491 /* power up everything in the demod */
492 case DIB8000_POWER_ALL:
493 reg_774 = 0x0000;
494 reg_775 = 0x0000;
495 reg_776 = 0x0000;
496 reg_900 &= 0xfffc;
497 if (state->revision != 0x8090)
498 reg_1280 &= 0x00ff;
499 else
500 reg_1280 &= 0x707f;
501 break;
502 case DIB8000_POWER_INTERFACE_ONLY:
503 if (state->revision != 0x8090)
504 reg_1280 &= 0x00ff;
505 else
506 reg_1280 &= 0xfa7b;
507 break;
510 dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x", reg_774, reg_775, reg_776, reg_900, reg_1280);
511 dib8000_write_word(state, 774, reg_774);
512 dib8000_write_word(state, 775, reg_775);
513 dib8000_write_word(state, 776, reg_776);
514 dib8000_write_word(state, 900, reg_900);
515 dib8000_write_word(state, 1280, reg_1280);
518 static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no)
520 int ret = 0;
521 u16 reg, reg_907 = dib8000_read_word(state, 907);
522 u16 reg_908 = dib8000_read_word(state, 908);
524 switch (no) {
525 case DIBX000_SLOW_ADC_ON:
526 if (state->revision != 0x8090) {
527 reg_908 |= (1 << 1) | (1 << 0);
528 ret |= dib8000_write_word(state, 908, reg_908);
529 reg_908 &= ~(1 << 1);
530 } else {
531 reg = dib8000_read_word(state, 1925);
532 /* en_slowAdc = 1 & reset_sladc = 1 */
533 dib8000_write_word(state, 1925, reg |
534 (1<<4) | (1<<2));
536 /* read acces to make it works... strange ... */
537 reg = dib8000_read_word(state, 1925);
538 msleep(20);
539 /* en_slowAdc = 1 & reset_sladc = 0 */
540 dib8000_write_word(state, 1925, reg & ~(1<<4));
542 reg = dib8000_read_word(state, 921) & ~((0x3 << 14)
543 | (0x3 << 12));
544 /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ;
545 (Vin2 = Vcm) */
546 dib8000_write_word(state, 921, reg | (1 << 14)
547 | (3 << 12));
549 break;
551 case DIBX000_SLOW_ADC_OFF:
552 if (state->revision == 0x8090) {
553 reg = dib8000_read_word(state, 1925);
554 /* reset_sladc = 1 en_slowAdc = 0 */
555 dib8000_write_word(state, 1925,
556 (reg & ~(1<<2)) | (1<<4));
558 reg_908 |= (1 << 1) | (1 << 0);
559 break;
561 case DIBX000_ADC_ON:
562 reg_907 &= 0x0fff;
563 reg_908 &= 0x0003;
564 break;
566 case DIBX000_ADC_OFF: // leave the VBG voltage on
567 reg_907 |= (1 << 14) | (1 << 13) | (1 << 12);
568 reg_908 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
569 break;
571 case DIBX000_VBG_ENABLE:
572 reg_907 &= ~(1 << 15);
573 break;
575 case DIBX000_VBG_DISABLE:
576 reg_907 |= (1 << 15);
577 break;
579 default:
580 break;
583 ret |= dib8000_write_word(state, 907, reg_907);
584 ret |= dib8000_write_word(state, 908, reg_908);
586 return ret;
589 static int dib8000_set_bandwidth(struct dvb_frontend *fe, u32 bw)
591 struct dib8000_state *state = fe->demodulator_priv;
592 u32 timf;
594 if (bw == 0)
595 bw = 6000;
597 if (state->timf == 0) {
598 dprintk("using default timf");
599 timf = state->timf_default;
600 } else {
601 dprintk("using updated timf");
602 timf = state->timf;
605 dib8000_write_word(state, 29, (u16) ((timf >> 16) & 0xffff));
606 dib8000_write_word(state, 30, (u16) ((timf) & 0xffff));
608 return 0;
611 static int dib8000_sad_calib(struct dib8000_state *state)
613 u8 sad_sel = 3;
615 if (state->revision == 0x8090) {
616 dib8000_write_word(state, 922, (sad_sel << 2));
617 dib8000_write_word(state, 923, 2048);
619 dib8000_write_word(state, 922, (sad_sel << 2) | 0x1);
620 dib8000_write_word(state, 922, (sad_sel << 2));
621 } else {
622 /* internal */
623 dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
624 dib8000_write_word(state, 924, 776);
626 /* do the calibration */
627 dib8000_write_word(state, 923, (1 << 0));
628 dib8000_write_word(state, 923, (0 << 0));
631 msleep(1);
632 return 0;
635 int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
637 struct dib8000_state *state = fe->demodulator_priv;
638 if (value > 4095)
639 value = 4095;
640 state->wbd_ref = value;
641 return dib8000_write_word(state, 106, value);
643 EXPORT_SYMBOL(dib8000_set_wbd_ref);
645 static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
647 dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25);
648 if (state->revision != 0x8090) {
649 dib8000_write_word(state, 23,
650 (u16) (((bw->internal * 1000) >> 16) & 0xffff));
651 dib8000_write_word(state, 24,
652 (u16) ((bw->internal * 1000) & 0xffff));
653 } else {
654 dib8000_write_word(state, 23, (u16) (((bw->internal / 2 * 1000) >> 16) & 0xffff));
655 dib8000_write_word(state, 24,
656 (u16) ((bw->internal / 2 * 1000) & 0xffff));
658 dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff));
659 dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff));
660 dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003));
662 if (state->revision != 0x8090)
663 dib8000_write_word(state, 922, bw->sad_cfg);
666 static void dib8000_reset_pll(struct dib8000_state *state)
668 const struct dibx000_bandwidth_config *pll = state->cfg.pll;
669 u16 clk_cfg1, reg;
671 if (state->revision != 0x8090) {
672 dib8000_write_word(state, 901,
673 (pll->pll_prediv << 8) | (pll->pll_ratio << 0));
675 clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
676 (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) |
677 (1 << 3) | (pll->pll_range << 1) |
678 (pll->pll_reset << 0);
680 dib8000_write_word(state, 902, clk_cfg1);
681 clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
682 dib8000_write_word(state, 902, clk_cfg1);
684 dprintk("clk_cfg1: 0x%04x", clk_cfg1);
686 /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
687 if (state->cfg.pll->ADClkSrc == 0)
688 dib8000_write_word(state, 904,
689 (0 << 15) | (0 << 12) | (0 << 10) |
690 (pll->modulo << 8) |
691 (pll->ADClkSrc << 7) | (0 << 1));
692 else if (state->cfg.refclksel != 0)
693 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
694 ((state->cfg.refclksel & 0x3) << 10) |
695 (pll->modulo << 8) |
696 (pll->ADClkSrc << 7) | (0 << 1));
697 else
698 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
699 (3 << 10) | (pll->modulo << 8) |
700 (pll->ADClkSrc << 7) | (0 << 1));
701 } else {
702 dib8000_write_word(state, 1856, (!pll->pll_reset<<13) |
703 (pll->pll_range<<12) | (pll->pll_ratio<<6) |
704 (pll->pll_prediv));
706 reg = dib8000_read_word(state, 1857);
707 dib8000_write_word(state, 1857, reg|(!pll->pll_bypass<<15));
709 reg = dib8000_read_word(state, 1858); /* Force clk out pll /2 */
710 dib8000_write_word(state, 1858, reg | 1);
712 dib8000_write_word(state, 904, (pll->modulo << 8));
715 dib8000_reset_pll_common(state, pll);
718 int dib8000_update_pll(struct dvb_frontend *fe,
719 struct dibx000_bandwidth_config *pll, u32 bw, u8 ratio)
721 struct dib8000_state *state = fe->demodulator_priv;
722 u16 reg_1857, reg_1856 = dib8000_read_word(state, 1856);
723 u8 loopdiv, prediv, oldprediv = state->cfg.pll->pll_prediv ;
724 u32 internal, xtal;
726 /* get back old values */
727 prediv = reg_1856 & 0x3f;
728 loopdiv = (reg_1856 >> 6) & 0x3f;
730 if ((pll == NULL) || (pll->pll_prediv == prediv &&
731 pll->pll_ratio == loopdiv))
732 return -EINVAL;
734 dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, pll->pll_prediv, loopdiv, pll->pll_ratio);
735 if (state->revision == 0x8090) {
736 reg_1856 &= 0xf000;
737 reg_1857 = dib8000_read_word(state, 1857);
738 /* disable PLL */
739 dib8000_write_word(state, 1857, reg_1857 & ~(1 << 15));
741 dib8000_write_word(state, 1856, reg_1856 |
742 ((pll->pll_ratio & 0x3f) << 6) |
743 (pll->pll_prediv & 0x3f));
745 /* write new system clk into P_sec_len */
746 internal = dib8000_read32(state, 23) / 1000;
747 dprintk("Old Internal = %d", internal);
748 xtal = 2 * (internal / loopdiv) * prediv;
749 internal = 1000 * (xtal/pll->pll_prediv) * pll->pll_ratio;
750 dprintk("Xtal = %d , New Fmem = %d New Fdemod = %d, New Fsampling = %d", xtal, internal/1000, internal/2000, internal/8000);
751 dprintk("New Internal = %d", internal);
753 dib8000_write_word(state, 23,
754 (u16) (((internal / 2) >> 16) & 0xffff));
755 dib8000_write_word(state, 24, (u16) ((internal / 2) & 0xffff));
756 /* enable PLL */
757 dib8000_write_word(state, 1857, reg_1857 | (1 << 15));
759 while (((dib8000_read_word(state, 1856)>>15)&0x1) != 1)
760 dprintk("Waiting for PLL to lock");
762 /* verify */
763 reg_1856 = dib8000_read_word(state, 1856);
764 dprintk("PLL Updated with prediv = %d and loopdiv = %d",
765 reg_1856&0x3f, (reg_1856>>6)&0x3f);
766 } else {
767 if (bw != state->current_demod_bw) {
768 /** Bandwidth change => force PLL update **/
769 dprintk("PLL: Bandwidth Change %d MHz -> %d MHz (prediv: %d->%d)", state->current_demod_bw / 1000, bw / 1000, oldprediv, state->cfg.pll->pll_prediv);
771 if (state->cfg.pll->pll_prediv != oldprediv) {
772 /** Full PLL change only if prediv is changed **/
774 /** full update => bypass and reconfigure **/
775 dprintk("PLL: New Setting for %d MHz Bandwidth (prediv: %d, ratio: %d)", bw/1000, state->cfg.pll->pll_prediv, state->cfg.pll->pll_ratio);
776 dib8000_write_word(state, 902, dib8000_read_word(state, 902) | (1<<3)); /* bypass PLL */
777 dib8000_reset_pll(state);
778 dib8000_write_word(state, 898, 0x0004); /* sad */
779 } else
780 ratio = state->cfg.pll->pll_ratio;
782 state->current_demod_bw = bw;
785 if (ratio != 0) {
786 /** ratio update => only change ratio **/
787 dprintk("PLL: Update ratio (prediv: %d, ratio: %d)", state->cfg.pll->pll_prediv, ratio);
788 dib8000_write_word(state, 901, (state->cfg.pll->pll_prediv << 8) | (ratio << 0)); /* only the PLL ratio is updated. */
792 return 0;
794 EXPORT_SYMBOL(dib8000_update_pll);
797 static int dib8000_reset_gpio(struct dib8000_state *st)
799 /* reset the GPIOs */
800 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
801 dib8000_write_word(st, 1030, st->cfg.gpio_val);
803 /* TODO 782 is P_gpio_od */
805 dib8000_write_word(st, 1032, st->cfg.gpio_pwm_pos);
807 dib8000_write_word(st, 1037, st->cfg.pwm_freq_div);
808 return 0;
811 static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val)
813 st->cfg.gpio_dir = dib8000_read_word(st, 1029);
814 st->cfg.gpio_dir &= ~(1 << num); /* reset the direction bit */
815 st->cfg.gpio_dir |= (dir & 0x1) << num; /* set the new direction */
816 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
818 st->cfg.gpio_val = dib8000_read_word(st, 1030);
819 st->cfg.gpio_val &= ~(1 << num); /* reset the direction bit */
820 st->cfg.gpio_val |= (val & 0x01) << num; /* set the new value */
821 dib8000_write_word(st, 1030, st->cfg.gpio_val);
823 dprintk("gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val);
825 return 0;
828 int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
830 struct dib8000_state *state = fe->demodulator_priv;
831 return dib8000_cfg_gpio(state, num, dir, val);
834 EXPORT_SYMBOL(dib8000_set_gpio);
835 static const u16 dib8000_defaults[] = {
836 /* auto search configuration - lock0 by default waiting
837 * for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */
838 3, 7,
839 0x0004,
840 0x0400,
841 0x0814,
843 12, 11,
844 0x001b,
845 0x7740,
846 0x005b,
847 0x8d80,
848 0x01c9,
849 0xc380,
850 0x0000,
851 0x0080,
852 0x0000,
853 0x0090,
854 0x0001,
855 0xd4c0,
857 /*1, 32,
858 0x6680 // P_corm_thres Lock algorithms configuration */
860 11, 80, /* set ADC level to -16 */
861 (1 << 13) - 825 - 117,
862 (1 << 13) - 837 - 117,
863 (1 << 13) - 811 - 117,
864 (1 << 13) - 766 - 117,
865 (1 << 13) - 737 - 117,
866 (1 << 13) - 693 - 117,
867 (1 << 13) - 648 - 117,
868 (1 << 13) - 619 - 117,
869 (1 << 13) - 575 - 117,
870 (1 << 13) - 531 - 117,
871 (1 << 13) - 501 - 117,
873 4, 108,
879 1, 175,
880 0x0410,
881 1, 179,
882 8192, // P_fft_nb_to_cut
884 6, 181,
885 0x2800, // P_coff_corthres_ ( 2k 4k 8k ) 0x2800
886 0x2800,
887 0x2800,
888 0x2800, // P_coff_cpilthres_ ( 2k 4k 8k ) 0x2800
889 0x2800,
890 0x2800,
892 2, 193,
893 0x0666, // P_pha3_thres
894 0x0000, // P_cti_use_cpe, P_cti_use_prog
896 2, 205,
897 0x200f, // P_cspu_regul, P_cspu_win_cut
898 0x000f, // P_des_shift_work
900 5, 215,
901 0x023d, // P_adp_regul_cnt
902 0x00a4, // P_adp_noise_cnt
903 0x00a4, // P_adp_regul_ext
904 0x7ff0, // P_adp_noise_ext
905 0x3ccc, // P_adp_fil
907 1, 230,
908 0x0000, // P_2d_byp_ti_num
910 1, 263,
911 0x800, //P_equal_thres_wgn
913 1, 268,
914 (2 << 9) | 39, // P_equal_ctrl_synchro, P_equal_speedmode
916 1, 270,
917 0x0001, // P_div_lock0_wait
918 1, 285,
919 0x0020, //p_fec_
920 1, 299,
921 0x0062, /* P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard */
923 1, 338,
924 (1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1
925 (1 << 10) |
926 (0 << 9) | /* P_ctrl_pre_freq_inh=0 */
927 (3 << 5) | /* P_ctrl_pre_freq_step=3 */
928 (1 << 0), /* P_pre_freq_win_len=1 */
933 static u16 dib8000_identify(struct i2c_device *client)
935 u16 value;
937 //because of glitches sometimes
938 value = dib8000_i2c_read16(client, 896);
940 if ((value = dib8000_i2c_read16(client, 896)) != 0x01b3) {
941 dprintk("wrong Vendor ID (read=0x%x)", value);
942 return 0;
945 value = dib8000_i2c_read16(client, 897);
946 if (value != 0x8000 && value != 0x8001 &&
947 value != 0x8002 && value != 0x8090) {
948 dprintk("wrong Device ID (%x)", value);
949 return 0;
952 switch (value) {
953 case 0x8000:
954 dprintk("found DiB8000A");
955 break;
956 case 0x8001:
957 dprintk("found DiB8000B");
958 break;
959 case 0x8002:
960 dprintk("found DiB8000C");
961 break;
962 case 0x8090:
963 dprintk("found DiB8096P");
964 break;
966 return value;
969 static int dib8000_reset(struct dvb_frontend *fe)
971 struct dib8000_state *state = fe->demodulator_priv;
973 if ((state->revision = dib8000_identify(&state->i2c)) == 0)
974 return -EINVAL;
976 /* sram lead in, rdy */
977 if (state->revision != 0x8090)
978 dib8000_write_word(state, 1287, 0x0003);
980 if (state->revision == 0x8000)
981 dprintk("error : dib8000 MA not supported");
983 dibx000_reset_i2c_master(&state->i2c_master);
985 dib8000_set_power_mode(state, DIB8000_POWER_ALL);
987 /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
988 dib8000_set_adc_state(state, DIBX000_ADC_OFF);
990 /* restart all parts */
991 dib8000_write_word(state, 770, 0xffff);
992 dib8000_write_word(state, 771, 0xffff);
993 dib8000_write_word(state, 772, 0xfffc);
994 if (state->revision == 0x8090)
995 dib8000_write_word(state, 1280, 0x0045);
996 else
997 dib8000_write_word(state, 1280, 0x004d);
998 dib8000_write_word(state, 1281, 0x000c);
1000 dib8000_write_word(state, 770, 0x0000);
1001 dib8000_write_word(state, 771, 0x0000);
1002 dib8000_write_word(state, 772, 0x0000);
1003 dib8000_write_word(state, 898, 0x0004); // sad
1004 dib8000_write_word(state, 1280, 0x0000);
1005 dib8000_write_word(state, 1281, 0x0000);
1007 /* drives */
1008 if (state->revision != 0x8090) {
1009 if (state->cfg.drives)
1010 dib8000_write_word(state, 906, state->cfg.drives);
1011 else {
1012 dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.");
1013 /* min drive SDRAM - not optimal - adjust */
1014 dib8000_write_word(state, 906, 0x2d98);
1018 dib8000_reset_pll(state);
1019 if (state->revision != 0x8090)
1020 dib8000_write_word(state, 898, 0x0004);
1022 if (dib8000_reset_gpio(state) != 0)
1023 dprintk("GPIO reset was not successful.");
1025 if ((state->revision != 0x8090) &&
1026 (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0))
1027 dprintk("OUTPUT_MODE could not be resetted.");
1029 state->current_agc = NULL;
1031 // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
1032 /* P_iqc_ca2 = 0; P_iqc_impnc_on = 0; P_iqc_mode = 0; */
1033 if (state->cfg.pll->ifreq == 0)
1034 dib8000_write_word(state, 40, 0x0755); /* P_iqc_corr_inh = 0 enable IQcorr block */
1035 else
1036 dib8000_write_word(state, 40, 0x1f55); /* P_iqc_corr_inh = 1 disable IQcorr block */
1039 u16 l = 0, r;
1040 const u16 *n;
1041 n = dib8000_defaults;
1042 l = *n++;
1043 while (l) {
1044 r = *n++;
1045 do {
1046 dib8000_write_word(state, r, *n++);
1047 r++;
1048 } while (--l);
1049 l = *n++;
1053 state->isdbt_cfg_loaded = 0;
1055 //div_cfg override for special configs
1056 if ((state->revision != 8090) && (state->cfg.div_cfg != 0))
1057 dib8000_write_word(state, 903, state->cfg.div_cfg);
1059 /* unforce divstr regardless whether i2c enumeration was done or not */
1060 dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1));
1062 dib8000_set_bandwidth(fe, 6000);
1064 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
1065 dib8000_sad_calib(state);
1066 if (state->revision != 0x8090)
1067 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
1069 /* ber_rs_len = 3 */
1070 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5));
1072 dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY);
1074 return 0;
1077 static void dib8000_restart_agc(struct dib8000_state *state)
1079 // P_restart_iqc & P_restart_agc
1080 dib8000_write_word(state, 770, 0x0a00);
1081 dib8000_write_word(state, 770, 0x0000);
1084 static int dib8000_update_lna(struct dib8000_state *state)
1086 u16 dyn_gain;
1088 if (state->cfg.update_lna) {
1089 // read dyn_gain here (because it is demod-dependent and not tuner)
1090 dyn_gain = dib8000_read_word(state, 390);
1092 if (state->cfg.update_lna(state->fe[0], dyn_gain)) {
1093 dib8000_restart_agc(state);
1094 return 1;
1097 return 0;
1100 static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
1102 struct dibx000_agc_config *agc = NULL;
1103 int i;
1104 u16 reg;
1106 if (state->current_band == band && state->current_agc != NULL)
1107 return 0;
1108 state->current_band = band;
1110 for (i = 0; i < state->cfg.agc_config_count; i++)
1111 if (state->cfg.agc[i].band_caps & band) {
1112 agc = &state->cfg.agc[i];
1113 break;
1116 if (agc == NULL) {
1117 dprintk("no valid AGC configuration found for band 0x%02x", band);
1118 return -EINVAL;
1121 state->current_agc = agc;
1123 /* AGC */
1124 dib8000_write_word(state, 76, agc->setup);
1125 dib8000_write_word(state, 77, agc->inv_gain);
1126 dib8000_write_word(state, 78, agc->time_stabiliz);
1127 dib8000_write_word(state, 101, (agc->alpha_level << 12) | agc->thlock);
1129 // Demod AGC loop configuration
1130 dib8000_write_word(state, 102, (agc->alpha_mant << 5) | agc->alpha_exp);
1131 dib8000_write_word(state, 103, (agc->beta_mant << 6) | agc->beta_exp);
1133 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
1134 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
1136 /* AGC continued */
1137 if (state->wbd_ref != 0)
1138 dib8000_write_word(state, 106, state->wbd_ref);
1139 else // use default
1140 dib8000_write_word(state, 106, agc->wbd_ref);
1142 if (state->revision == 0x8090) {
1143 reg = dib8000_read_word(state, 922) & (0x3 << 2);
1144 dib8000_write_word(state, 922, reg | (agc->wbd_sel << 2));
1147 dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
1148 dib8000_write_word(state, 108, agc->agc1_max);
1149 dib8000_write_word(state, 109, agc->agc1_min);
1150 dib8000_write_word(state, 110, agc->agc2_max);
1151 dib8000_write_word(state, 111, agc->agc2_min);
1152 dib8000_write_word(state, 112, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
1153 dib8000_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
1154 dib8000_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
1155 dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
1157 dib8000_write_word(state, 75, agc->agc1_pt3);
1158 if (state->revision != 0x8090)
1159 dib8000_write_word(state, 923,
1160 (dib8000_read_word(state, 923) & 0xffe3) |
1161 (agc->wbd_inv << 4) | (agc->wbd_sel << 2));
1163 return 0;
1166 void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
1168 struct dib8000_state *state = fe->demodulator_priv;
1169 dib8000_set_adc_state(state, DIBX000_ADC_ON);
1170 dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000)));
1172 EXPORT_SYMBOL(dib8000_pwm_agc_reset);
1174 static int dib8000_agc_soft_split(struct dib8000_state *state)
1176 u16 agc, split_offset;
1178 if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
1179 return FE_CALLBACK_TIME_NEVER;
1181 // n_agc_global
1182 agc = dib8000_read_word(state, 390);
1184 if (agc > state->current_agc->split.min_thres)
1185 split_offset = state->current_agc->split.min;
1186 else if (agc < state->current_agc->split.max_thres)
1187 split_offset = state->current_agc->split.max;
1188 else
1189 split_offset = state->current_agc->split.max *
1190 (agc - state->current_agc->split.min_thres) /
1191 (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
1193 dprintk("AGC split_offset: %d", split_offset);
1195 // P_agc_force_split and P_agc_split_offset
1196 dib8000_write_word(state, 107, (dib8000_read_word(state, 107) & 0xff00) | split_offset);
1197 return 5000;
1200 static int dib8000_agc_startup(struct dvb_frontend *fe)
1202 struct dib8000_state *state = fe->demodulator_priv;
1203 enum frontend_tune_state *tune_state = &state->tune_state;
1204 int ret = 0;
1205 u16 reg, upd_demod_gain_period = 0x8000;
1207 switch (*tune_state) {
1208 case CT_AGC_START:
1209 // set power-up level: interf+analog+AGC
1211 if (state->revision != 0x8090)
1212 dib8000_set_adc_state(state, DIBX000_ADC_ON);
1213 else {
1214 dib8000_set_power_mode(state, DIB8000_POWER_ALL);
1216 reg = dib8000_read_word(state, 1947)&0xff00;
1217 dib8000_write_word(state, 1946,
1218 upd_demod_gain_period & 0xFFFF);
1219 /* bit 14 = enDemodGain */
1220 dib8000_write_word(state, 1947, reg | (1<<14) |
1221 ((upd_demod_gain_period >> 16) & 0xFF));
1223 /* enable adc i & q */
1224 reg = dib8000_read_word(state, 1920);
1225 dib8000_write_word(state, 1920, (reg | 0x3) &
1226 (~(1 << 7)));
1229 if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) {
1230 *tune_state = CT_AGC_STOP;
1231 state->status = FE_STATUS_TUNE_FAILED;
1232 break;
1235 ret = 70;
1236 *tune_state = CT_AGC_STEP_0;
1237 break;
1239 case CT_AGC_STEP_0:
1240 //AGC initialization
1241 if (state->cfg.agc_control)
1242 state->cfg.agc_control(fe, 1);
1244 dib8000_restart_agc(state);
1246 // wait AGC rough lock time
1247 ret = 50;
1248 *tune_state = CT_AGC_STEP_1;
1249 break;
1251 case CT_AGC_STEP_1:
1252 // wait AGC accurate lock time
1253 ret = 70;
1255 if (dib8000_update_lna(state))
1256 // wait only AGC rough lock time
1257 ret = 50;
1258 else
1259 *tune_state = CT_AGC_STEP_2;
1260 break;
1262 case CT_AGC_STEP_2:
1263 dib8000_agc_soft_split(state);
1265 if (state->cfg.agc_control)
1266 state->cfg.agc_control(fe, 0);
1268 *tune_state = CT_AGC_STOP;
1269 break;
1270 default:
1271 ret = dib8000_agc_soft_split(state);
1272 break;
1274 return ret;
1278 static void dib8096p_host_bus_drive(struct dib8000_state *state, u8 drive)
1280 u16 reg;
1282 drive &= 0x7;
1284 /* drive host bus 2, 3, 4 */
1285 reg = dib8000_read_word(state, 1798) &
1286 ~(0x7 | (0x7 << 6) | (0x7 << 12));
1287 reg |= (drive<<12) | (drive<<6) | drive;
1288 dib8000_write_word(state, 1798, reg);
1290 /* drive host bus 5,6 */
1291 reg = dib8000_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
1292 reg |= (drive<<8) | (drive<<2);
1293 dib8000_write_word(state, 1799, reg);
1295 /* drive host bus 7, 8, 9 */
1296 reg = dib8000_read_word(state, 1800) &
1297 ~(0x7 | (0x7 << 6) | (0x7 << 12));
1298 reg |= (drive<<12) | (drive<<6) | drive;
1299 dib8000_write_word(state, 1800, reg);
1301 /* drive host bus 10, 11 */
1302 reg = dib8000_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
1303 reg |= (drive<<8) | (drive<<2);
1304 dib8000_write_word(state, 1801, reg);
1306 /* drive host bus 12, 13, 14 */
1307 reg = dib8000_read_word(state, 1802) &
1308 ~(0x7 | (0x7 << 6) | (0x7 << 12));
1309 reg |= (drive<<12) | (drive<<6) | drive;
1310 dib8000_write_word(state, 1802, reg);
1313 static u32 dib8096p_calcSyncFreq(u32 P_Kin, u32 P_Kout,
1314 u32 insertExtSynchro, u32 syncSize)
1316 u32 quantif = 3;
1317 u32 nom = (insertExtSynchro * P_Kin+syncSize);
1318 u32 denom = P_Kout;
1319 u32 syncFreq = ((nom << quantif) / denom);
1321 if ((syncFreq & ((1 << quantif) - 1)) != 0)
1322 syncFreq = (syncFreq >> quantif) + 1;
1323 else
1324 syncFreq = (syncFreq >> quantif);
1326 if (syncFreq != 0)
1327 syncFreq = syncFreq - 1;
1329 return syncFreq;
1332 static void dib8096p_cfg_DibTx(struct dib8000_state *state, u32 P_Kin,
1333 u32 P_Kout, u32 insertExtSynchro, u32 synchroMode,
1334 u32 syncWord, u32 syncSize)
1336 dprintk("Configure DibStream Tx");
1338 dib8000_write_word(state, 1615, 1);
1339 dib8000_write_word(state, 1603, P_Kin);
1340 dib8000_write_word(state, 1605, P_Kout);
1341 dib8000_write_word(state, 1606, insertExtSynchro);
1342 dib8000_write_word(state, 1608, synchroMode);
1343 dib8000_write_word(state, 1609, (syncWord >> 16) & 0xffff);
1344 dib8000_write_word(state, 1610, syncWord & 0xffff);
1345 dib8000_write_word(state, 1612, syncSize);
1346 dib8000_write_word(state, 1615, 0);
1349 static void dib8096p_cfg_DibRx(struct dib8000_state *state, u32 P_Kin,
1350 u32 P_Kout, u32 synchroMode, u32 insertExtSynchro,
1351 u32 syncWord, u32 syncSize, u32 dataOutRate)
1353 u32 syncFreq;
1355 dprintk("Configure DibStream Rx synchroMode = %d", synchroMode);
1357 if ((P_Kin != 0) && (P_Kout != 0)) {
1358 syncFreq = dib8096p_calcSyncFreq(P_Kin, P_Kout,
1359 insertExtSynchro, syncSize);
1360 dib8000_write_word(state, 1542, syncFreq);
1363 dib8000_write_word(state, 1554, 1);
1364 dib8000_write_word(state, 1536, P_Kin);
1365 dib8000_write_word(state, 1537, P_Kout);
1366 dib8000_write_word(state, 1539, synchroMode);
1367 dib8000_write_word(state, 1540, (syncWord >> 16) & 0xffff);
1368 dib8000_write_word(state, 1541, syncWord & 0xffff);
1369 dib8000_write_word(state, 1543, syncSize);
1370 dib8000_write_word(state, 1544, dataOutRate);
1371 dib8000_write_word(state, 1554, 0);
1374 static void dib8096p_enMpegMux(struct dib8000_state *state, int onoff)
1376 u16 reg_1287;
1378 reg_1287 = dib8000_read_word(state, 1287);
1380 switch (onoff) {
1381 case 1:
1382 reg_1287 &= ~(1 << 8);
1383 break;
1384 case 0:
1385 reg_1287 |= (1 << 8);
1386 break;
1389 dib8000_write_word(state, 1287, reg_1287);
1392 static void dib8096p_configMpegMux(struct dib8000_state *state,
1393 u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
1395 u16 reg_1287;
1397 dprintk("Enable Mpeg mux");
1399 dib8096p_enMpegMux(state, 0);
1401 /* If the input mode is MPEG do not divide the serial clock */
1402 if ((enSerialMode == 1) && (state->input_mode_mpeg == 1))
1403 enSerialClkDiv2 = 0;
1405 reg_1287 = ((pulseWidth & 0x1f) << 3) |
1406 ((enSerialMode & 0x1) << 2) | (enSerialClkDiv2 & 0x1);
1407 dib8000_write_word(state, 1287, reg_1287);
1409 dib8096p_enMpegMux(state, 1);
1412 static void dib8096p_setDibTxMux(struct dib8000_state *state, int mode)
1414 u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 7);
1416 switch (mode) {
1417 case MPEG_ON_DIBTX:
1418 dprintk("SET MPEG ON DIBSTREAM TX");
1419 dib8096p_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
1420 reg_1288 |= (1 << 9); break;
1421 case DIV_ON_DIBTX:
1422 dprintk("SET DIV_OUT ON DIBSTREAM TX");
1423 dib8096p_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
1424 reg_1288 |= (1 << 8); break;
1425 case ADC_ON_DIBTX:
1426 dprintk("SET ADC_OUT ON DIBSTREAM TX");
1427 dib8096p_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
1428 reg_1288 |= (1 << 7); break;
1429 default:
1430 break;
1432 dib8000_write_word(state, 1288, reg_1288);
1435 static void dib8096p_setHostBusMux(struct dib8000_state *state, int mode)
1437 u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 4);
1439 switch (mode) {
1440 case DEMOUT_ON_HOSTBUS:
1441 dprintk("SET DEM OUT OLD INTERF ON HOST BUS");
1442 dib8096p_enMpegMux(state, 0);
1443 reg_1288 |= (1 << 6);
1444 break;
1445 case DIBTX_ON_HOSTBUS:
1446 dprintk("SET DIBSTREAM TX ON HOST BUS");
1447 dib8096p_enMpegMux(state, 0);
1448 reg_1288 |= (1 << 5);
1449 break;
1450 case MPEG_ON_HOSTBUS:
1451 dprintk("SET MPEG MUX ON HOST BUS");
1452 reg_1288 |= (1 << 4);
1453 break;
1454 default:
1455 break;
1457 dib8000_write_word(state, 1288, reg_1288);
1460 static int dib8096p_set_diversity_in(struct dvb_frontend *fe, int onoff)
1462 struct dib8000_state *state = fe->demodulator_priv;
1463 u16 reg_1287;
1465 switch (onoff) {
1466 case 0: /* only use the internal way - not the diversity input */
1467 dprintk("%s mode OFF : by default Enable Mpeg INPUT",
1468 __func__);
1469 /* outputRate = 8 */
1470 dib8096p_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0);
1472 /* Do not divide the serial clock of MPEG MUX in
1473 SERIAL MODE in case input mode MPEG is used */
1474 reg_1287 = dib8000_read_word(state, 1287);
1475 /* enSerialClkDiv2 == 1 ? */
1476 if ((reg_1287 & 0x1) == 1) {
1477 /* force enSerialClkDiv2 = 0 */
1478 reg_1287 &= ~0x1;
1479 dib8000_write_word(state, 1287, reg_1287);
1481 state->input_mode_mpeg = 1;
1482 break;
1483 case 1: /* both ways */
1484 case 2: /* only the diversity input */
1485 dprintk("%s ON : Enable diversity INPUT", __func__);
1486 dib8096p_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
1487 state->input_mode_mpeg = 0;
1488 break;
1491 dib8000_set_diversity_in(state->fe[0], onoff);
1492 return 0;
1495 static int dib8096p_set_output_mode(struct dvb_frontend *fe, int mode)
1497 struct dib8000_state *state = fe->demodulator_priv;
1498 u16 outreg, smo_mode, fifo_threshold;
1499 u8 prefer_mpeg_mux_use = 1;
1500 int ret = 0;
1502 state->output_mode = mode;
1503 dib8096p_host_bus_drive(state, 1);
1505 fifo_threshold = 1792;
1506 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
1507 outreg = dib8000_read_word(state, 1286) &
1508 ~((1 << 10) | (0x7 << 6) | (1 << 1));
1510 switch (mode) {
1511 case OUTMODE_HIGH_Z:
1512 outreg = 0;
1513 break;
1515 case OUTMODE_MPEG2_SERIAL:
1516 if (prefer_mpeg_mux_use) {
1517 dprintk("dib8096P setting output mode TS_SERIAL using Mpeg Mux");
1518 dib8096p_configMpegMux(state, 3, 1, 1);
1519 dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS);
1520 } else {/* Use Smooth block */
1521 dprintk("dib8096P setting output mode TS_SERIAL using Smooth bloc");
1522 dib8096p_setHostBusMux(state,
1523 DEMOUT_ON_HOSTBUS);
1524 outreg |= (2 << 6) | (0 << 1);
1526 break;
1528 case OUTMODE_MPEG2_PAR_GATED_CLK:
1529 if (prefer_mpeg_mux_use) {
1530 dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Mpeg Mux");
1531 dib8096p_configMpegMux(state, 2, 0, 0);
1532 dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS);
1533 } else { /* Use Smooth block */
1534 dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Smooth block");
1535 dib8096p_setHostBusMux(state,
1536 DEMOUT_ON_HOSTBUS);
1537 outreg |= (0 << 6);
1539 break;
1541 case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */
1542 dprintk("dib8096P setting output mode TS_PARALLEL_CONT using Smooth block");
1543 dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
1544 outreg |= (1 << 6);
1545 break;
1547 case OUTMODE_MPEG2_FIFO:
1548 /* Using Smooth block because not supported
1549 by new Mpeg Mux bloc */
1550 dprintk("dib8096P setting output mode TS_FIFO using Smooth block");
1551 dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
1552 outreg |= (5 << 6);
1553 smo_mode |= (3 << 1);
1554 fifo_threshold = 512;
1555 break;
1557 case OUTMODE_DIVERSITY:
1558 dprintk("dib8096P setting output mode MODE_DIVERSITY");
1559 dib8096p_setDibTxMux(state, DIV_ON_DIBTX);
1560 dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
1561 break;
1563 case OUTMODE_ANALOG_ADC:
1564 dprintk("dib8096P setting output mode MODE_ANALOG_ADC");
1565 dib8096p_setDibTxMux(state, ADC_ON_DIBTX);
1566 dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
1567 break;
1570 if (mode != OUTMODE_HIGH_Z)
1571 outreg |= (1<<10);
1573 dprintk("output_mpeg2_in_188_bytes = %d",
1574 state->cfg.output_mpeg2_in_188_bytes);
1575 if (state->cfg.output_mpeg2_in_188_bytes)
1576 smo_mode |= (1 << 5);
1578 ret |= dib8000_write_word(state, 299, smo_mode);
1579 /* synchronous fread */
1580 ret |= dib8000_write_word(state, 299 + 1, fifo_threshold);
1581 ret |= dib8000_write_word(state, 1286, outreg);
1583 return ret;
1586 static int map_addr_to_serpar_number(struct i2c_msg *msg)
1588 if (msg->buf[0] <= 15)
1589 msg->buf[0] -= 1;
1590 else if (msg->buf[0] == 17)
1591 msg->buf[0] = 15;
1592 else if (msg->buf[0] == 16)
1593 msg->buf[0] = 17;
1594 else if (msg->buf[0] == 19)
1595 msg->buf[0] = 16;
1596 else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
1597 msg->buf[0] -= 3;
1598 else if (msg->buf[0] == 28)
1599 msg->buf[0] = 23;
1600 else if (msg->buf[0] == 99)
1601 msg->buf[0] = 99;
1602 else
1603 return -EINVAL;
1604 return 0;
1607 static int dib8096p_tuner_write_serpar(struct i2c_adapter *i2c_adap,
1608 struct i2c_msg msg[], int num)
1610 struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1611 u8 n_overflow = 1;
1612 u16 i = 1000;
1613 u16 serpar_num = msg[0].buf[0];
1615 while (n_overflow == 1 && i) {
1616 n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1;
1617 i--;
1618 if (i == 0)
1619 dprintk("Tuner ITF: write busy (overflow)");
1621 dib8000_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
1622 dib8000_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
1624 return num;
1627 static int dib8096p_tuner_read_serpar(struct i2c_adapter *i2c_adap,
1628 struct i2c_msg msg[], int num)
1630 struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1631 u8 n_overflow = 1, n_empty = 1;
1632 u16 i = 1000;
1633 u16 serpar_num = msg[0].buf[0];
1634 u16 read_word;
1636 while (n_overflow == 1 && i) {
1637 n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1;
1638 i--;
1639 if (i == 0)
1640 dprintk("TunerITF: read busy (overflow)");
1642 dib8000_write_word(state, 1985, (0<<6) | (serpar_num&0x3f));
1644 i = 1000;
1645 while (n_empty == 1 && i) {
1646 n_empty = dib8000_read_word(state, 1984)&0x1;
1647 i--;
1648 if (i == 0)
1649 dprintk("TunerITF: read busy (empty)");
1652 read_word = dib8000_read_word(state, 1987);
1653 msg[1].buf[0] = (read_word >> 8) & 0xff;
1654 msg[1].buf[1] = (read_word) & 0xff;
1656 return num;
1659 static int dib8096p_tuner_rw_serpar(struct i2c_adapter *i2c_adap,
1660 struct i2c_msg msg[], int num)
1662 if (map_addr_to_serpar_number(&msg[0]) == 0) {
1663 if (num == 1) /* write */
1664 return dib8096p_tuner_write_serpar(i2c_adap, msg, 1);
1665 else /* read */
1666 return dib8096p_tuner_read_serpar(i2c_adap, msg, 2);
1668 return num;
1671 static int dib8096p_rw_on_apb(struct i2c_adapter *i2c_adap,
1672 struct i2c_msg msg[], int num, u16 apb_address)
1674 struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1675 u16 word;
1677 if (num == 1) { /* write */
1678 dib8000_write_word(state, apb_address,
1679 ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
1680 } else {
1681 word = dib8000_read_word(state, apb_address);
1682 msg[1].buf[0] = (word >> 8) & 0xff;
1683 msg[1].buf[1] = (word) & 0xff;
1685 return num;
1688 static int dib8096p_tuner_xfer(struct i2c_adapter *i2c_adap,
1689 struct i2c_msg msg[], int num)
1691 struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1692 u16 apb_address = 0, word;
1693 int i = 0;
1695 switch (msg[0].buf[0]) {
1696 case 0x12:
1697 apb_address = 1920;
1698 break;
1699 case 0x14:
1700 apb_address = 1921;
1701 break;
1702 case 0x24:
1703 apb_address = 1922;
1704 break;
1705 case 0x1a:
1706 apb_address = 1923;
1707 break;
1708 case 0x22:
1709 apb_address = 1924;
1710 break;
1711 case 0x33:
1712 apb_address = 1926;
1713 break;
1714 case 0x34:
1715 apb_address = 1927;
1716 break;
1717 case 0x35:
1718 apb_address = 1928;
1719 break;
1720 case 0x36:
1721 apb_address = 1929;
1722 break;
1723 case 0x37:
1724 apb_address = 1930;
1725 break;
1726 case 0x38:
1727 apb_address = 1931;
1728 break;
1729 case 0x39:
1730 apb_address = 1932;
1731 break;
1732 case 0x2a:
1733 apb_address = 1935;
1734 break;
1735 case 0x2b:
1736 apb_address = 1936;
1737 break;
1738 case 0x2c:
1739 apb_address = 1937;
1740 break;
1741 case 0x2d:
1742 apb_address = 1938;
1743 break;
1744 case 0x2e:
1745 apb_address = 1939;
1746 break;
1747 case 0x2f:
1748 apb_address = 1940;
1749 break;
1750 case 0x30:
1751 apb_address = 1941;
1752 break;
1753 case 0x31:
1754 apb_address = 1942;
1755 break;
1756 case 0x32:
1757 apb_address = 1943;
1758 break;
1759 case 0x3e:
1760 apb_address = 1944;
1761 break;
1762 case 0x3f:
1763 apb_address = 1945;
1764 break;
1765 case 0x40:
1766 apb_address = 1948;
1767 break;
1768 case 0x25:
1769 apb_address = 936;
1770 break;
1771 case 0x26:
1772 apb_address = 937;
1773 break;
1774 case 0x27:
1775 apb_address = 938;
1776 break;
1777 case 0x28:
1778 apb_address = 939;
1779 break;
1780 case 0x1d:
1781 /* get sad sel request */
1782 i = ((dib8000_read_word(state, 921) >> 12)&0x3);
1783 word = dib8000_read_word(state, 924+i);
1784 msg[1].buf[0] = (word >> 8) & 0xff;
1785 msg[1].buf[1] = (word) & 0xff;
1786 return num;
1787 case 0x1f:
1788 if (num == 1) { /* write */
1789 word = (u16) ((msg[0].buf[1] << 8) |
1790 msg[0].buf[2]);
1791 /* in the VGAMODE Sel are located on bit 0/1 */
1792 word &= 0x3;
1793 word = (dib8000_read_word(state, 921) &
1794 ~(3<<12)) | (word<<12);
1795 /* Set the proper input */
1796 dib8000_write_word(state, 921, word);
1797 return num;
1801 if (apb_address != 0) /* R/W acces via APB */
1802 return dib8096p_rw_on_apb(i2c_adap, msg, num, apb_address);
1803 else /* R/W access via SERPAR */
1804 return dib8096p_tuner_rw_serpar(i2c_adap, msg, num);
1806 return 0;
1809 static u32 dib8096p_i2c_func(struct i2c_adapter *adapter)
1811 return I2C_FUNC_I2C;
1814 static struct i2c_algorithm dib8096p_tuner_xfer_algo = {
1815 .master_xfer = dib8096p_tuner_xfer,
1816 .functionality = dib8096p_i2c_func,
1819 struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe)
1821 struct dib8000_state *st = fe->demodulator_priv;
1822 return &st->dib8096p_tuner_adap;
1824 EXPORT_SYMBOL(dib8096p_get_i2c_tuner);
1826 int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff)
1828 struct dib8000_state *state = fe->demodulator_priv;
1829 u16 en_cur_state;
1831 dprintk("sleep dib8096p: %d", onoff);
1833 en_cur_state = dib8000_read_word(state, 1922);
1835 /* LNAs and MIX are ON and therefore it is a valid configuration */
1836 if (en_cur_state > 0xff)
1837 state->tuner_enable = en_cur_state ;
1839 if (onoff)
1840 en_cur_state &= 0x00ff;
1841 else {
1842 if (state->tuner_enable != 0)
1843 en_cur_state = state->tuner_enable;
1846 dib8000_write_word(state, 1922, en_cur_state);
1848 return 0;
1850 EXPORT_SYMBOL(dib8096p_tuner_sleep);
1852 static const s32 lut_1000ln_mant[] =
1854 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600
1857 s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
1859 struct dib8000_state *state = fe->demodulator_priv;
1860 u32 ix = 0, tmp_val = 0, exp = 0, mant = 0;
1861 s32 val;
1863 val = dib8000_read32(state, 384);
1864 if (mode) {
1865 tmp_val = val;
1866 while (tmp_val >>= 1)
1867 exp++;
1868 mant = (val * 1000 / (1<<exp));
1869 ix = (u8)((mant-1000)/100); /* index of the LUT */
1870 val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908);
1871 val = (val*256)/1000;
1873 return val;
1875 EXPORT_SYMBOL(dib8000_get_adc_power);
1877 int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ)
1879 struct dib8000_state *state = fe->demodulator_priv;
1880 int val = 0;
1882 switch (IQ) {
1883 case 1:
1884 val = dib8000_read_word(state, 403);
1885 break;
1886 case 0:
1887 val = dib8000_read_word(state, 404);
1888 break;
1890 if (val & 0x200)
1891 val -= 1024;
1893 return val;
1895 EXPORT_SYMBOL(dib8090p_get_dc_power);
1897 static void dib8000_update_timf(struct dib8000_state *state)
1899 u32 timf = state->timf = dib8000_read32(state, 435);
1901 dib8000_write_word(state, 29, (u16) (timf >> 16));
1902 dib8000_write_word(state, 30, (u16) (timf & 0xffff));
1903 dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
1906 u32 dib8000_ctrl_timf(struct dvb_frontend *fe, uint8_t op, uint32_t timf)
1908 struct dib8000_state *state = fe->demodulator_priv;
1910 switch (op) {
1911 case DEMOD_TIMF_SET:
1912 state->timf = timf;
1913 break;
1914 case DEMOD_TIMF_UPDATE:
1915 dib8000_update_timf(state);
1916 break;
1917 case DEMOD_TIMF_GET:
1918 break;
1920 dib8000_set_bandwidth(state->fe[0], 6000);
1922 return state->timf;
1924 EXPORT_SYMBOL(dib8000_ctrl_timf);
1926 static const u16 adc_target_16dB[11] = {
1927 (1 << 13) - 825 - 117,
1928 (1 << 13) - 837 - 117,
1929 (1 << 13) - 811 - 117,
1930 (1 << 13) - 766 - 117,
1931 (1 << 13) - 737 - 117,
1932 (1 << 13) - 693 - 117,
1933 (1 << 13) - 648 - 117,
1934 (1 << 13) - 619 - 117,
1935 (1 << 13) - 575 - 117,
1936 (1 << 13) - 531 - 117,
1937 (1 << 13) - 501 - 117
1939 static const u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
1941 static u16 dib8000_set_layer(struct dib8000_state *state, u8 layer_index, u16 max_constellation)
1943 u8 cr, constellation, time_intlv;
1944 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
1946 switch (c->layer[layer_index].modulation) {
1947 case DQPSK:
1948 constellation = 0;
1949 break;
1950 case QPSK:
1951 constellation = 1;
1952 break;
1953 case QAM_16:
1954 constellation = 2;
1955 break;
1956 case QAM_64:
1957 default:
1958 constellation = 3;
1959 break;
1962 switch (c->layer[layer_index].fec) {
1963 case FEC_1_2:
1964 cr = 1;
1965 break;
1966 case FEC_2_3:
1967 cr = 2;
1968 break;
1969 case FEC_3_4:
1970 cr = 3;
1971 break;
1972 case FEC_5_6:
1973 cr = 5;
1974 break;
1975 case FEC_7_8:
1976 default:
1977 cr = 7;
1978 break;
1981 if ((c->layer[layer_index].interleaving > 0) && ((c->layer[layer_index].interleaving <= 3) || (c->layer[layer_index].interleaving == 4 && c->isdbt_sb_mode == 1)))
1982 time_intlv = c->layer[layer_index].interleaving;
1983 else
1984 time_intlv = 0;
1986 dib8000_write_word(state, 2 + layer_index, (constellation << 10) | ((c->layer[layer_index].segment_count & 0xf) << 6) | (cr << 3) | time_intlv);
1987 if (c->layer[layer_index].segment_count > 0) {
1988 switch (max_constellation) {
1989 case DQPSK:
1990 case QPSK:
1991 if (c->layer[layer_index].modulation == QAM_16 || c->layer[layer_index].modulation == QAM_64)
1992 max_constellation = c->layer[layer_index].modulation;
1993 break;
1994 case QAM_16:
1995 if (c->layer[layer_index].modulation == QAM_64)
1996 max_constellation = c->layer[layer_index].modulation;
1997 break;
2001 return max_constellation;
2004 static const u16 adp_Q64[4] = {0x0148, 0xfff0, 0x00a4, 0xfff8}; /* P_adp_regul_cnt 0.04, P_adp_noise_cnt -0.002, P_adp_regul_ext 0.02, P_adp_noise_ext -0.001 */
2005 static const u16 adp_Q16[4] = {0x023d, 0xffdf, 0x00a4, 0xfff0}; /* P_adp_regul_cnt 0.07, P_adp_noise_cnt -0.004, P_adp_regul_ext 0.02, P_adp_noise_ext -0.002 */
2006 static const u16 adp_Qdefault[4] = {0x099a, 0xffae, 0x0333, 0xfff8}; /* P_adp_regul_cnt 0.3, P_adp_noise_cnt -0.01, P_adp_regul_ext 0.1, P_adp_noise_ext -0.002 */
2007 static u16 dib8000_adp_fine_tune(struct dib8000_state *state, u16 max_constellation)
2009 u16 i, ana_gain = 0;
2010 const u16 *adp;
2012 /* channel estimation fine configuration */
2013 switch (max_constellation) {
2014 case QAM_64:
2015 ana_gain = 0x7;
2016 adp = &adp_Q64[0];
2017 break;
2018 case QAM_16:
2019 ana_gain = 0x7;
2020 adp = &adp_Q16[0];
2021 break;
2022 default:
2023 ana_gain = 0;
2024 adp = &adp_Qdefault[0];
2025 break;
2028 for (i = 0; i < 4; i++)
2029 dib8000_write_word(state, 215 + i, adp[i]);
2031 return ana_gain;
2034 static void dib8000_update_ana_gain(struct dib8000_state *state, u16 ana_gain)
2036 u16 i;
2038 dib8000_write_word(state, 116, ana_gain);
2040 /* update ADC target depending on ana_gain */
2041 if (ana_gain) { /* set -16dB ADC target for ana_gain=-1 */
2042 for (i = 0; i < 10; i++)
2043 dib8000_write_word(state, 80 + i, adc_target_16dB[i]);
2044 } else { /* set -22dB ADC target for ana_gain=0 */
2045 for (i = 0; i < 10; i++)
2046 dib8000_write_word(state, 80 + i, adc_target_16dB[i] - 355);
2050 static void dib8000_load_ana_fe_coefs(struct dib8000_state *state, const s16 *ana_fe)
2052 u16 mode = 0;
2054 if (state->isdbt_cfg_loaded == 0)
2055 for (mode = 0; mode < 24; mode++)
2056 dib8000_write_word(state, 117 + mode, ana_fe[mode]);
2059 static const u16 lut_prbs_2k[14] = {
2060 0, 0x423, 0x009, 0x5C7, 0x7A6, 0x3D8, 0x527, 0x7FF, 0x79B, 0x3D6, 0x3A2, 0x53B, 0x2F4, 0x213
2062 static const u16 lut_prbs_4k[14] = {
2063 0, 0x208, 0x0C3, 0x7B9, 0x423, 0x5C7, 0x3D8, 0x7FF, 0x3D6, 0x53B, 0x213, 0x029, 0x0D0, 0x48E
2065 static const u16 lut_prbs_8k[14] = {
2066 0, 0x740, 0x069, 0x7DD, 0x208, 0x7B9, 0x5C7, 0x7FF, 0x53B, 0x029, 0x48E, 0x4C4, 0x367, 0x684
2069 static u16 dib8000_get_init_prbs(struct dib8000_state *state, u16 subchannel)
2071 int sub_channel_prbs_group = 0;
2073 sub_channel_prbs_group = (subchannel / 3) + 1;
2074 dprintk("sub_channel_prbs_group = %d , subchannel =%d prbs = 0x%04x", sub_channel_prbs_group, subchannel, lut_prbs_8k[sub_channel_prbs_group]);
2076 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
2077 case TRANSMISSION_MODE_2K:
2078 return lut_prbs_2k[sub_channel_prbs_group];
2079 case TRANSMISSION_MODE_4K:
2080 return lut_prbs_4k[sub_channel_prbs_group];
2081 default:
2082 case TRANSMISSION_MODE_8K:
2083 return lut_prbs_8k[sub_channel_prbs_group];
2087 static void dib8000_set_13seg_channel(struct dib8000_state *state)
2089 u16 i;
2090 u16 coff_pow = 0x2800;
2092 state->seg_mask = 0x1fff; /* All 13 segments enabled */
2094 /* ---- COFF ---- Carloff, the most robust --- */
2095 if (state->isdbt_cfg_loaded == 0) { /* if not Sound Broadcasting mode : put default values for 13 segments */
2096 dib8000_write_word(state, 180, (16 << 6) | 9);
2097 dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2);
2098 coff_pow = 0x2800;
2099 for (i = 0; i < 6; i++)
2100 dib8000_write_word(state, 181+i, coff_pow);
2102 /* P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1 */
2103 /* 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 */
2104 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1);
2106 /* P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6 */
2107 dib8000_write_word(state, 340, (8 << 6) | (6 << 0));
2108 /* P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1 */
2109 dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
2111 dib8000_write_word(state, 228, 0); /* default value */
2112 dib8000_write_word(state, 265, 31); /* default value */
2113 dib8000_write_word(state, 205, 0x200f); /* init value */
2117 * make the cpil_coff_lock more robust but slower p_coff_winlen
2118 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
2121 if (state->cfg.pll->ifreq == 0)
2122 dib8000_write_word(state, 266, ~state->seg_mask | state->seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */
2124 dib8000_load_ana_fe_coefs(state, ana_fe_coeff_13seg);
2127 static void dib8000_set_subchannel_prbs(struct dib8000_state *state, u16 init_prbs)
2129 u16 reg_1;
2131 reg_1 = dib8000_read_word(state, 1);
2132 dib8000_write_word(state, 1, (init_prbs << 2) | (reg_1 & 0x3)); /* ADDR 1 */
2135 static void dib8000_small_fine_tune(struct dib8000_state *state)
2137 u16 i;
2138 const s16 *ncoeff;
2139 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2141 dib8000_write_word(state, 352, state->seg_diff_mask);
2142 dib8000_write_word(state, 353, state->seg_mask);
2144 /* P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5 */
2145 dib8000_write_word(state, 351, (c->isdbt_sb_mode << 9) | (c->isdbt_sb_mode << 8) | (13 << 4) | 5);
2147 if (c->isdbt_sb_mode) {
2148 /* ---- SMALL ---- */
2149 switch (c->transmission_mode) {
2150 case TRANSMISSION_MODE_2K:
2151 if (c->isdbt_partial_reception == 0) { /* 1-seg */
2152 if (c->layer[0].modulation == DQPSK) /* DQPSK */
2153 ncoeff = coeff_2k_sb_1seg_dqpsk;
2154 else /* QPSK or QAM */
2155 ncoeff = coeff_2k_sb_1seg;
2156 } else { /* 3-segments */
2157 if (c->layer[0].modulation == DQPSK) { /* DQPSK on central segment */
2158 if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
2159 ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
2160 else /* QPSK or QAM on external segments */
2161 ncoeff = coeff_2k_sb_3seg_0dqpsk;
2162 } else { /* QPSK or QAM on central segment */
2163 if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
2164 ncoeff = coeff_2k_sb_3seg_1dqpsk;
2165 else /* QPSK or QAM on external segments */
2166 ncoeff = coeff_2k_sb_3seg;
2169 break;
2170 case TRANSMISSION_MODE_4K:
2171 if (c->isdbt_partial_reception == 0) { /* 1-seg */
2172 if (c->layer[0].modulation == DQPSK) /* DQPSK */
2173 ncoeff = coeff_4k_sb_1seg_dqpsk;
2174 else /* QPSK or QAM */
2175 ncoeff = coeff_4k_sb_1seg;
2176 } else { /* 3-segments */
2177 if (c->layer[0].modulation == DQPSK) { /* DQPSK on central segment */
2178 if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
2179 ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
2180 else /* QPSK or QAM on external segments */
2181 ncoeff = coeff_4k_sb_3seg_0dqpsk;
2182 } else { /* QPSK or QAM on central segment */
2183 if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
2184 ncoeff = coeff_4k_sb_3seg_1dqpsk;
2185 else /* QPSK or QAM on external segments */
2186 ncoeff = coeff_4k_sb_3seg;
2189 break;
2190 case TRANSMISSION_MODE_AUTO:
2191 case TRANSMISSION_MODE_8K:
2192 default:
2193 if (c->isdbt_partial_reception == 0) { /* 1-seg */
2194 if (c->layer[0].modulation == DQPSK) /* DQPSK */
2195 ncoeff = coeff_8k_sb_1seg_dqpsk;
2196 else /* QPSK or QAM */
2197 ncoeff = coeff_8k_sb_1seg;
2198 } else { /* 3-segments */
2199 if (c->layer[0].modulation == DQPSK) { /* DQPSK on central segment */
2200 if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
2201 ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
2202 else /* QPSK or QAM on external segments */
2203 ncoeff = coeff_8k_sb_3seg_0dqpsk;
2204 } else { /* QPSK or QAM on central segment */
2205 if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
2206 ncoeff = coeff_8k_sb_3seg_1dqpsk;
2207 else /* QPSK or QAM on external segments */
2208 ncoeff = coeff_8k_sb_3seg;
2211 break;
2214 for (i = 0; i < 8; i++)
2215 dib8000_write_word(state, 343 + i, ncoeff[i]);
2219 static const u16 coff_thres_1seg[3] = {300, 150, 80};
2220 static const u16 coff_thres_3seg[3] = {350, 300, 250};
2221 static void dib8000_set_sb_channel(struct dib8000_state *state)
2223 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2224 const u16 *coff;
2225 u16 i;
2227 if (c->transmission_mode == TRANSMISSION_MODE_2K || c->transmission_mode == TRANSMISSION_MODE_4K) {
2228 dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); /* adp_pass =1 */
2229 dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); /* pha3_force_pha_shift = 1 */
2230 } else {
2231 dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); /* adp_pass =0 */
2232 dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); /* pha3_force_pha_shift = 0 */
2235 if (c->isdbt_partial_reception == 1) /* 3-segments */
2236 state->seg_mask = 0x00E0;
2237 else /* 1-segment */
2238 state->seg_mask = 0x0040;
2240 dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
2242 /* ---- COFF ---- Carloff, the most robust --- */
2243 /* P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64, 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 */
2244 dib8000_write_word(state, 187, (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~c->isdbt_partial_reception & 1) << 2) | 0x3);
2246 dib8000_write_word(state, 340, (16 << 6) | (8 << 0)); /* P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8 */
2247 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));/* P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1 */
2249 /* Sound Broadcasting mode 1 seg */
2250 if (c->isdbt_partial_reception == 0) {
2251 /* 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) */
2252 if (state->mode == 3)
2253 dib8000_write_word(state, 180, 0x1fcf | ((state->mode - 1) << 14));
2254 else
2255 dib8000_write_word(state, 180, 0x0fcf | ((state->mode - 1) << 14));
2257 /* P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1, P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4 */
2258 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
2259 coff = &coff_thres_1seg[0];
2260 } else { /* Sound Broadcasting mode 3 seg */
2261 dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
2262 /* P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1, P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4 */
2263 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
2264 coff = &coff_thres_3seg[0];
2267 dib8000_write_word(state, 228, 1); /* P_2d_mode_byp=1 */
2268 dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); /* P_cspu_win_cut = 0 */
2270 if (c->isdbt_partial_reception == 0 && c->transmission_mode == TRANSMISSION_MODE_2K)
2271 dib8000_write_word(state, 265, 15); /* P_equal_noise_sel = 15 */
2273 /* Write COFF thres */
2274 for (i = 0 ; i < 3; i++) {
2275 dib8000_write_word(state, 181+i, coff[i]);
2276 dib8000_write_word(state, 184+i, coff[i]);
2280 * make the cpil_coff_lock more robust but slower p_coff_winlen
2281 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
2284 dib8000_write_word(state, 266, ~state->seg_mask | state->seg_diff_mask); /* P_equal_noise_seg_inh */
2286 if (c->isdbt_partial_reception == 0)
2287 dib8000_write_word(state, 178, 64); /* P_fft_powrange = 64 */
2288 else
2289 dib8000_write_word(state, 178, 32); /* P_fft_powrange = 32 */
2292 static void dib8000_set_isdbt_common_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
2294 u16 p_cfr_left_edge = 0, p_cfr_right_edge = 0;
2295 u16 tmcc_pow = 0, ana_gain = 0, tmp = 0, i = 0, nbseg_diff = 0 ;
2296 u16 max_constellation = DQPSK;
2297 int init_prbs;
2298 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2300 /* P_mode */
2301 dib8000_write_word(state, 10, (seq << 4));
2303 /* init mode */
2304 state->mode = fft_to_mode(state);
2306 /* set guard */
2307 tmp = dib8000_read_word(state, 1);
2308 dib8000_write_word(state, 1, (tmp&0xfffc) | (c->guard_interval & 0x3));
2310 dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) | ((c->isdbt_partial_reception & 1) << 5) | ((c->isdbt_sb_mode & 1) << 4));
2312 /* signal optimization parameter */
2313 if (c->isdbt_partial_reception) {
2314 state->seg_diff_mask = (c->layer[0].modulation == DQPSK) << permu_seg[0];
2315 for (i = 1; i < 3; i++)
2316 nbseg_diff += (c->layer[i].modulation == DQPSK) * c->layer[i].segment_count;
2317 for (i = 0; i < nbseg_diff; i++)
2318 state->seg_diff_mask |= 1 << permu_seg[i+1];
2319 } else {
2320 for (i = 0; i < 3; i++)
2321 nbseg_diff += (c->layer[i].modulation == DQPSK) * c->layer[i].segment_count;
2322 for (i = 0; i < nbseg_diff; i++)
2323 state->seg_diff_mask |= 1 << permu_seg[i];
2326 if (state->seg_diff_mask)
2327 dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
2328 else
2329 dib8000_write_word(state, 268, (2 << 9) | 39); /*init value */
2331 for (i = 0; i < 3; i++)
2332 max_constellation = dib8000_set_layer(state, i, max_constellation);
2333 if (autosearching == 0) {
2334 state->layer_b_nb_seg = c->layer[1].segment_count;
2335 state->layer_c_nb_seg = c->layer[2].segment_count;
2338 /* WRITE: Mode & Diff mask */
2339 dib8000_write_word(state, 0, (state->mode << 13) | state->seg_diff_mask);
2341 state->differential_constellation = (state->seg_diff_mask != 0);
2343 /* channel estimation fine configuration */
2344 ana_gain = dib8000_adp_fine_tune(state, max_constellation);
2346 /* update ana_gain depending on max constellation */
2347 dib8000_update_ana_gain(state, ana_gain);
2349 /* ---- ANA_FE ---- */
2350 if (c->isdbt_partial_reception) /* 3-segments */
2351 dib8000_load_ana_fe_coefs(state, ana_fe_coeff_3seg);
2352 else
2353 dib8000_load_ana_fe_coefs(state, ana_fe_coeff_1seg); /* 1-segment */
2355 /* TSB or ISDBT ? apply it now */
2356 if (c->isdbt_sb_mode) {
2357 dib8000_set_sb_channel(state);
2358 if (c->isdbt_sb_subchannel < 14)
2359 init_prbs = dib8000_get_init_prbs(state, c->isdbt_sb_subchannel);
2360 else
2361 init_prbs = 0;
2362 } else {
2363 dib8000_set_13seg_channel(state);
2364 init_prbs = 0xfff;
2367 /* SMALL */
2368 dib8000_small_fine_tune(state);
2370 dib8000_set_subchannel_prbs(state, init_prbs);
2372 /* ---- CHAN_BLK ---- */
2373 for (i = 0; i < 13; i++) {
2374 if ((((~state->seg_diff_mask) >> i) & 1) == 1) {
2375 p_cfr_left_edge += (1 << i) * ((i == 0) || ((((state->seg_mask & (~state->seg_diff_mask)) >> (i - 1)) & 1) == 0));
2376 p_cfr_right_edge += (1 << i) * ((i == 12) || ((((state->seg_mask & (~state->seg_diff_mask)) >> (i + 1)) & 1) == 0));
2379 dib8000_write_word(state, 222, p_cfr_left_edge); /* p_cfr_left_edge */
2380 dib8000_write_word(state, 223, p_cfr_right_edge); /* p_cfr_right_edge */
2381 /* "P_cspu_left_edge" & "P_cspu_right_edge" not used => do not care */
2383 dib8000_write_word(state, 189, ~state->seg_mask | state->seg_diff_mask); /* P_lmod4_seg_inh */
2384 dib8000_write_word(state, 192, ~state->seg_mask | state->seg_diff_mask); /* P_pha3_seg_inh */
2385 dib8000_write_word(state, 225, ~state->seg_mask | state->seg_diff_mask); /* P_tac_seg_inh */
2387 if (!autosearching)
2388 dib8000_write_word(state, 288, (~state->seg_mask | state->seg_diff_mask) & 0x1fff); /* P_tmcc_seg_eq_inh */
2389 else
2390 dib8000_write_word(state, 288, 0x1fff); /*disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels. */
2392 dib8000_write_word(state, 211, state->seg_mask & (~state->seg_diff_mask)); /* P_des_seg_enabled */
2393 dib8000_write_word(state, 287, ~state->seg_mask | 0x1000); /* P_tmcc_seg_inh */
2395 dib8000_write_word(state, 178, 32); /* P_fft_powrange = 32 */
2397 /* ---- TMCC ---- */
2398 for (i = 0; i < 3; i++)
2399 tmcc_pow += (((c->layer[i].modulation == DQPSK) * 4 + 1) * c->layer[i].segment_count) ;
2401 /* Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9); */
2402 /* Threshold is set at 1/4 of max power. */
2403 tmcc_pow *= (1 << (9-2));
2404 dib8000_write_word(state, 290, tmcc_pow); /* P_tmcc_dec_thres_2k */
2405 dib8000_write_word(state, 291, tmcc_pow); /* P_tmcc_dec_thres_4k */
2406 dib8000_write_word(state, 292, tmcc_pow); /* P_tmcc_dec_thres_8k */
2407 /*dib8000_write_word(state, 287, (1 << 13) | 0x1000 ); */
2409 /* ---- PHA3 ---- */
2410 if (state->isdbt_cfg_loaded == 0)
2411 dib8000_write_word(state, 250, 3285); /* p_2d_hspeed_thr0 */
2413 state->isdbt_cfg_loaded = 0;
2416 static u32 dib8000_wait_lock(struct dib8000_state *state, u32 internal,
2417 u32 wait0_ms, u32 wait1_ms, u32 wait2_ms)
2419 u32 value = 0; /* P_search_end0 wait time */
2420 u16 reg = 11; /* P_search_end0 start addr */
2422 for (reg = 11; reg < 16; reg += 2) {
2423 if (reg == 11) {
2424 if (state->revision == 0x8090)
2425 value = internal * wait1_ms;
2426 else
2427 value = internal * wait0_ms;
2428 } else if (reg == 13)
2429 value = internal * wait1_ms;
2430 else if (reg == 15)
2431 value = internal * wait2_ms;
2432 dib8000_write_word(state, reg, (u16)((value >> 16) & 0xffff));
2433 dib8000_write_word(state, (reg + 1), (u16)(value & 0xffff));
2435 return value;
2438 static int dib8000_autosearch_start(struct dvb_frontend *fe)
2440 struct dib8000_state *state = fe->demodulator_priv;
2441 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2442 u8 slist = 0;
2443 u32 value, internal = state->cfg.pll->internal;
2445 if (state->revision == 0x8090)
2446 internal = dib8000_read32(state, 23) / 1000;
2448 if (state->autosearch_state == AS_SEARCHING_FFT) {
2449 dib8000_write_word(state, 37, 0x0065); /* P_ctrl_pha_off_max default values */
2450 dib8000_write_word(state, 116, 0x0000); /* P_ana_gain to 0 */
2452 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x1fff) | (0 << 13) | (1 << 15)); /* P_mode = 0, P_restart_search=1 */
2453 dib8000_write_word(state, 1, (dib8000_read_word(state, 1) & 0xfffc) | 0); /* P_guard = 0 */
2454 dib8000_write_word(state, 6, 0); /* P_lock0_mask = 0 */
2455 dib8000_write_word(state, 7, 0); /* P_lock1_mask = 0 */
2456 dib8000_write_word(state, 8, 0); /* P_lock2_mask = 0 */
2457 dib8000_write_word(state, 10, (dib8000_read_word(state, 10) & 0x200) | (16 << 4) | (0 << 0)); /* P_search_list=16, P_search_maxtrial=0 */
2459 if (state->revision == 0x8090)
2460 value = dib8000_wait_lock(state, internal, 10, 10, 10); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2461 else
2462 value = dib8000_wait_lock(state, internal, 20, 20, 20); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2464 dib8000_write_word(state, 17, 0);
2465 dib8000_write_word(state, 18, 200); /* P_search_rstst = 200 */
2466 dib8000_write_word(state, 19, 0);
2467 dib8000_write_word(state, 20, 400); /* P_search_rstend = 400 */
2468 dib8000_write_word(state, 21, (value >> 16) & 0xffff); /* P_search_checkst */
2469 dib8000_write_word(state, 22, value & 0xffff);
2471 if (state->revision == 0x8090)
2472 dib8000_write_word(state, 32, (dib8000_read_word(state, 32) & 0xf0ff) | (0 << 8)); /* P_corm_alpha = 0 */
2473 else
2474 dib8000_write_word(state, 32, (dib8000_read_word(state, 32) & 0xf0ff) | (9 << 8)); /* P_corm_alpha = 3 */
2475 dib8000_write_word(state, 355, 2); /* P_search_param_max = 2 */
2477 /* P_search_param_select = (1 | 1<<4 | 1 << 8) */
2478 dib8000_write_word(state, 356, 0);
2479 dib8000_write_word(state, 357, 0x111);
2481 dib8000_write_word(state, 770, (dib8000_read_word(state, 770) & 0xdfff) | (1 << 13)); /* P_restart_ccg = 1 */
2482 dib8000_write_word(state, 770, (dib8000_read_word(state, 770) & 0xdfff) | (0 << 13)); /* P_restart_ccg = 0 */
2483 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x7ff) | (0 << 15) | (1 << 13)); /* P_restart_search = 0; */
2484 } else if (state->autosearch_state == AS_SEARCHING_GUARD) {
2485 c->transmission_mode = TRANSMISSION_MODE_8K;
2486 c->guard_interval = GUARD_INTERVAL_1_8;
2487 c->inversion = 0;
2488 c->layer[0].modulation = QAM_64;
2489 c->layer[0].fec = FEC_2_3;
2490 c->layer[0].interleaving = 0;
2491 c->layer[0].segment_count = 13;
2493 slist = 16;
2494 c->transmission_mode = state->found_nfft;
2496 dib8000_set_isdbt_common_channel(state, slist, 1);
2498 /* set lock_mask values */
2499 dib8000_write_word(state, 6, 0x4);
2500 if (state->revision == 0x8090)
2501 dib8000_write_word(state, 7, ((1 << 12) | (1 << 11) | (1 << 10)));/* tmcc_dec_lock, tmcc_sync_lock, tmcc_data_lock, tmcc_bch_uncor */
2502 else
2503 dib8000_write_word(state, 7, 0x8);
2504 dib8000_write_word(state, 8, 0x1000);
2506 /* set lock_mask wait time values */
2507 if (state->revision == 0x8090)
2508 dib8000_wait_lock(state, internal, 50, 100, 1000); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2509 else
2510 dib8000_wait_lock(state, internal, 50, 200, 1000); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2512 dib8000_write_word(state, 355, 3); /* P_search_param_max = 3 */
2514 /* P_search_param_select = 0xf; look for the 4 different guard intervals */
2515 dib8000_write_word(state, 356, 0);
2516 dib8000_write_word(state, 357, 0xf);
2518 value = dib8000_read_word(state, 0);
2519 dib8000_write_word(state, 0, (u16)((1 << 15) | value));
2520 dib8000_read_word(state, 1284); /* reset the INT. n_irq_pending */
2521 dib8000_write_word(state, 0, (u16)value);
2522 } else {
2523 c->inversion = 0;
2524 c->layer[0].modulation = QAM_64;
2525 c->layer[0].fec = FEC_2_3;
2526 c->layer[0].interleaving = 0;
2527 c->layer[0].segment_count = 13;
2528 if (!c->isdbt_sb_mode)
2529 c->layer[0].segment_count = 13;
2531 /* choose the right list, in sb, always do everything */
2532 if (c->isdbt_sb_mode) {
2533 slist = 7;
2534 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));
2535 } else {
2536 if (c->guard_interval == GUARD_INTERVAL_AUTO) {
2537 if (c->transmission_mode == TRANSMISSION_MODE_AUTO) {
2538 c->transmission_mode = TRANSMISSION_MODE_8K;
2539 c->guard_interval = GUARD_INTERVAL_1_8;
2540 slist = 7;
2541 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); /* P_mode = 1 to have autosearch start ok with mode2 */
2542 } else {
2543 c->guard_interval = GUARD_INTERVAL_1_8;
2544 slist = 3;
2546 } else {
2547 if (c->transmission_mode == TRANSMISSION_MODE_AUTO) {
2548 c->transmission_mode = TRANSMISSION_MODE_8K;
2549 slist = 2;
2550 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); /* P_mode = 1 */
2551 } else
2552 slist = 0;
2555 dprintk("Using list for autosearch : %d", slist);
2557 dib8000_set_isdbt_common_channel(state, slist, 1);
2559 /* set lock_mask values */
2560 dib8000_write_word(state, 6, 0x4);
2561 if (state->revision == 0x8090)
2562 dib8000_write_word(state, 7, (1 << 12) | (1 << 11) | (1 << 10));
2563 else
2564 dib8000_write_word(state, 7, 0x8);
2565 dib8000_write_word(state, 8, 0x1000);
2567 /* set lock_mask wait time values */
2568 if (state->revision == 0x8090)
2569 dib8000_wait_lock(state, internal, 50, 200, 1000); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2570 else
2571 dib8000_wait_lock(state, internal, 50, 100, 1000); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2573 value = dib8000_read_word(state, 0);
2574 dib8000_write_word(state, 0, (u16)((1 << 15) | value));
2575 dib8000_read_word(state, 1284); /* reset the INT. n_irq_pending */
2576 dib8000_write_word(state, 0, (u16)value);
2578 return 0;
2581 static int dib8000_autosearch_irq(struct dvb_frontend *fe)
2583 struct dib8000_state *state = fe->demodulator_priv;
2584 u16 irq_pending = dib8000_read_word(state, 1284);
2586 if (state->autosearch_state == AS_SEARCHING_FFT) {
2587 if (irq_pending & 0x1) {
2588 dprintk("dib8000_autosearch_irq: max correlation result available");
2589 return 3;
2591 } else {
2592 if (irq_pending & 0x1) { /* failed */
2593 dprintk("dib8000_autosearch_irq failed");
2594 return 1;
2597 if (irq_pending & 0x2) { /* succeeded */
2598 dprintk("dib8000_autosearch_irq succeeded");
2599 return 2;
2603 return 0; // still pending
2606 static void dib8000_viterbi_state(struct dib8000_state *state, u8 onoff)
2608 u16 tmp;
2610 tmp = dib8000_read_word(state, 771);
2611 if (onoff) /* start P_restart_chd : channel_decoder */
2612 dib8000_write_word(state, 771, tmp & 0xfffd);
2613 else /* stop P_restart_chd : channel_decoder */
2614 dib8000_write_word(state, 771, tmp | (1<<1));
2617 static void dib8000_set_dds(struct dib8000_state *state, s32 offset_khz)
2619 s16 unit_khz_dds_val;
2620 u32 abs_offset_khz = ABS(offset_khz);
2621 u32 dds = state->cfg.pll->ifreq & 0x1ffffff;
2622 u8 invert = !!(state->cfg.pll->ifreq & (1 << 25));
2623 u8 ratio;
2625 if (state->revision == 0x8090) {
2626 ratio = 4;
2627 unit_khz_dds_val = (1<<26) / (dib8000_read32(state, 23) / 1000);
2628 if (offset_khz < 0)
2629 dds = (1 << 26) - (abs_offset_khz * unit_khz_dds_val);
2630 else
2631 dds = (abs_offset_khz * unit_khz_dds_val);
2633 if (invert)
2634 dds = (1<<26) - dds;
2635 } else {
2636 ratio = 2;
2637 unit_khz_dds_val = (u16) (67108864 / state->cfg.pll->internal);
2639 if (offset_khz < 0)
2640 unit_khz_dds_val *= -1;
2642 /* IF tuner */
2643 if (invert)
2644 dds -= abs_offset_khz * unit_khz_dds_val;
2645 else
2646 dds += abs_offset_khz * unit_khz_dds_val;
2649 dprintk("setting a DDS frequency offset of %c%dkHz", invert ? '-' : ' ', dds / unit_khz_dds_val);
2651 if (abs_offset_khz <= (state->cfg.pll->internal / ratio)) {
2652 /* Max dds offset is the half of the demod freq */
2653 dib8000_write_word(state, 26, invert);
2654 dib8000_write_word(state, 27, (u16)(dds >> 16) & 0x1ff);
2655 dib8000_write_word(state, 28, (u16)(dds & 0xffff));
2659 static void dib8000_set_frequency_offset(struct dib8000_state *state)
2661 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2662 int i;
2663 u32 current_rf;
2664 int total_dds_offset_khz;
2666 if (state->fe[0]->ops.tuner_ops.get_frequency)
2667 state->fe[0]->ops.tuner_ops.get_frequency(state->fe[0], &current_rf);
2668 else
2669 current_rf = c->frequency;
2670 current_rf /= 1000;
2671 total_dds_offset_khz = (int)current_rf - (int)c->frequency / 1000;
2673 if (c->isdbt_sb_mode) {
2674 state->subchannel = c->isdbt_sb_subchannel;
2676 i = dib8000_read_word(state, 26) & 1; /* P_dds_invspec */
2677 dib8000_write_word(state, 26, c->inversion ^ i);
2679 if (state->cfg.pll->ifreq == 0) { /* low if tuner */
2680 if ((c->inversion ^ i) == 0)
2681 dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
2682 } else {
2683 if ((c->inversion ^ i) == 0)
2684 total_dds_offset_khz *= -1;
2688 dprintk("%dkhz tuner offset (frequency = %dHz & current_rf = %dHz) total_dds_offset_hz = %d", c->frequency - current_rf, c->frequency, current_rf, total_dds_offset_khz);
2690 /* apply dds offset now */
2691 dib8000_set_dds(state, total_dds_offset_khz);
2694 static u16 LUT_isdbt_symbol_duration[4] = { 26, 101, 63 };
2696 static u32 dib8000_get_symbol_duration(struct dib8000_state *state)
2698 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2699 u16 i;
2701 switch (c->transmission_mode) {
2702 case TRANSMISSION_MODE_2K:
2703 i = 0;
2704 break;
2705 case TRANSMISSION_MODE_4K:
2706 i = 2;
2707 break;
2708 default:
2709 case TRANSMISSION_MODE_AUTO:
2710 case TRANSMISSION_MODE_8K:
2711 i = 1;
2712 break;
2715 return (LUT_isdbt_symbol_duration[i] / (c->bandwidth_hz / 1000)) + 1;
2718 static void dib8000_set_isdbt_loop_params(struct dib8000_state *state, enum param_loop_step loop_step)
2720 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2721 u16 reg_32 = 0, reg_37 = 0;
2723 switch (loop_step) {
2724 case LOOP_TUNE_1:
2725 if (c->isdbt_sb_mode) {
2726 if (c->isdbt_partial_reception == 0) {
2727 reg_32 = ((11 - state->mode) << 12) | (6 << 8) | 0x40; /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x40 */
2728 reg_37 = (3 << 5) | (0 << 4) | (10 - state->mode); /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (10-P_mode) */
2729 } else { /* Sound Broadcasting mode 3 seg */
2730 reg_32 = ((10 - state->mode) << 12) | (6 << 8) | 0x60; /* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x60 */
2731 reg_37 = (3 << 5) | (0 << 4) | (9 - state->mode); /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (9-P_mode) */
2733 } else { /* 13-seg start conf offset loop parameters */
2734 reg_32 = ((9 - state->mode) << 12) | (6 << 8) | 0x80; /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
2735 reg_37 = (3 << 5) | (0 << 4) | (8 - state->mode); /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = 9 */
2737 break;
2738 case LOOP_TUNE_2:
2739 if (c->isdbt_sb_mode) {
2740 if (c->isdbt_partial_reception == 0) { /* Sound Broadcasting mode 1 seg */
2741 reg_32 = ((13-state->mode) << 12) | (6 << 8) | 0x40; /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40*/
2742 reg_37 = (12-state->mode) | ((5 + state->mode) << 5);
2743 } else { /* Sound Broadcasting mode 3 seg */
2744 reg_32 = ((12-state->mode) << 12) | (6 << 8) | 0x60; /* P_timf_alpha = (12-P_mode) , P_corm_alpha=6, P_corm_thres=0x60 */
2745 reg_37 = (11-state->mode) | ((5 + state->mode) << 5);
2747 } else { /* 13 seg */
2748 reg_32 = ((11-state->mode) << 12) | (6 << 8) | 0x80; /* P_timf_alpha = 8 , P_corm_alpha=6, P_corm_thres=0x80 */
2749 reg_37 = ((5+state->mode) << 5) | (10 - state->mode);
2751 break;
2753 dib8000_write_word(state, 32, reg_32);
2754 dib8000_write_word(state, 37, reg_37);
2757 static void dib8000_demod_restart(struct dib8000_state *state)
2759 dib8000_write_word(state, 770, 0x4000);
2760 dib8000_write_word(state, 770, 0x0000);
2761 return;
2764 static void dib8000_set_sync_wait(struct dib8000_state *state)
2766 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2767 u16 sync_wait = 64;
2769 /* P_dvsy_sync_wait - reuse mode */
2770 switch (c->transmission_mode) {
2771 case TRANSMISSION_MODE_8K:
2772 sync_wait = 256;
2773 break;
2774 case TRANSMISSION_MODE_4K:
2775 sync_wait = 128;
2776 break;
2777 default:
2778 case TRANSMISSION_MODE_2K:
2779 sync_wait = 64;
2780 break;
2783 if (state->cfg.diversity_delay == 0)
2784 sync_wait = (sync_wait * (1 << (c->guard_interval)) * 3) / 2 + 48; /* add 50% SFN margin + compensate for one DVSY-fifo */
2785 else
2786 sync_wait = (sync_wait * (1 << (c->guard_interval)) * 3) / 2 + state->cfg.diversity_delay; /* add 50% SFN margin + compensate for DVSY-fifo */
2788 dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | (sync_wait << 4));
2791 static u32 dib8000_get_timeout(struct dib8000_state *state, u32 delay, enum timeout_mode mode)
2793 if (mode == SYMBOL_DEPENDENT_ON)
2794 return systime() + (delay * state->symbol_duration);
2795 else
2796 return systime() + delay;
2799 static s32 dib8000_get_status(struct dvb_frontend *fe)
2801 struct dib8000_state *state = fe->demodulator_priv;
2802 return state->status;
2805 enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
2807 struct dib8000_state *state = fe->demodulator_priv;
2808 return state->tune_state;
2810 EXPORT_SYMBOL(dib8000_get_tune_state);
2812 int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
2814 struct dib8000_state *state = fe->demodulator_priv;
2816 state->tune_state = tune_state;
2817 return 0;
2819 EXPORT_SYMBOL(dib8000_set_tune_state);
2821 static int dib8000_tune_restart_from_demod(struct dvb_frontend *fe)
2823 struct dib8000_state *state = fe->demodulator_priv;
2825 state->status = FE_STATUS_TUNE_PENDING;
2826 state->tune_state = CT_DEMOD_START;
2827 return 0;
2830 static u16 dib8000_read_lock(struct dvb_frontend *fe)
2832 struct dib8000_state *state = fe->demodulator_priv;
2834 if (state->revision == 0x8090)
2835 return dib8000_read_word(state, 570);
2836 return dib8000_read_word(state, 568);
2839 static int dib8090p_init_sdram(struct dib8000_state *state)
2841 u16 reg = 0;
2842 dprintk("init sdram");
2844 reg = dib8000_read_word(state, 274) & 0xfff0;
2845 dib8000_write_word(state, 274, reg | 0x7); /* P_dintlv_delay_ram = 7 because of MobileSdram */
2847 dib8000_write_word(state, 1803, (7 << 2));
2849 reg = dib8000_read_word(state, 1280);
2850 dib8000_write_word(state, 1280, reg | (1 << 2)); /* force restart P_restart_sdram */
2851 dib8000_write_word(state, 1280, reg); /* release restart P_restart_sdram */
2853 return 0;
2856 static int dib8000_tune(struct dvb_frontend *fe)
2858 struct dib8000_state *state = fe->demodulator_priv;
2859 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2860 enum frontend_tune_state *tune_state = &state->tune_state;
2862 u16 locks, deeper_interleaver = 0, i;
2863 int ret = 1; /* 1 symbol duration (in 100us unit) delay most of the time */
2865 u32 *timeout = &state->timeout;
2866 u32 now = systime();
2867 #ifdef DIB8000_AGC_FREEZE
2868 u16 agc1, agc2;
2869 #endif
2871 u32 corm[4] = {0, 0, 0, 0};
2872 u8 find_index, max_value;
2874 #if 0
2875 if (*tune_state < CT_DEMOD_STOP)
2876 dprintk("IN: context status = %d, TUNE_STATE %d autosearch step = %u systime = %u", state->channel_parameters_set, *tune_state, state->autosearch_state, now);
2877 #endif
2879 switch (*tune_state) {
2880 case CT_DEMOD_START: /* 30 */
2881 if (state->revision == 0x8090)
2882 dib8090p_init_sdram(state);
2883 state->status = FE_STATUS_TUNE_PENDING;
2884 if ((c->delivery_system != SYS_ISDBT) ||
2885 (c->inversion == INVERSION_AUTO) ||
2886 (c->transmission_mode == TRANSMISSION_MODE_AUTO) ||
2887 (c->guard_interval == GUARD_INTERVAL_AUTO) ||
2888 (((c->isdbt_layer_enabled & (1 << 0)) != 0) &&
2889 (c->layer[0].segment_count != 0xff) &&
2890 (c->layer[0].segment_count != 0) &&
2891 ((c->layer[0].modulation == QAM_AUTO) ||
2892 (c->layer[0].fec == FEC_AUTO))) ||
2893 (((c->isdbt_layer_enabled & (1 << 1)) != 0) &&
2894 (c->layer[1].segment_count != 0xff) &&
2895 (c->layer[1].segment_count != 0) &&
2896 ((c->layer[1].modulation == QAM_AUTO) ||
2897 (c->layer[1].fec == FEC_AUTO))) ||
2898 (((c->isdbt_layer_enabled & (1 << 2)) != 0) &&
2899 (c->layer[2].segment_count != 0xff) &&
2900 (c->layer[2].segment_count != 0) &&
2901 ((c->layer[2].modulation == QAM_AUTO) ||
2902 (c->layer[2].fec == FEC_AUTO))) ||
2903 (((c->layer[0].segment_count == 0) ||
2904 ((c->isdbt_layer_enabled & (1 << 0)) == 0)) &&
2905 ((c->layer[1].segment_count == 0) ||
2906 ((c->isdbt_layer_enabled & (2 << 0)) == 0)) &&
2907 ((c->layer[2].segment_count == 0) || ((c->isdbt_layer_enabled & (3 << 0)) == 0))))
2908 state->channel_parameters_set = 0; /* auto search */
2909 else
2910 state->channel_parameters_set = 1; /* channel parameters are known */
2912 dib8000_viterbi_state(state, 0); /* force chan dec in restart */
2914 /* Layer monit */
2915 dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
2917 dib8000_set_frequency_offset(state);
2918 dib8000_set_bandwidth(fe, c->bandwidth_hz / 1000);
2920 if (state->channel_parameters_set == 0) { /* The channel struct is unknown, search it ! */
2921 #ifdef DIB8000_AGC_FREEZE
2922 if (state->revision != 0x8090) {
2923 state->agc1_max = dib8000_read_word(state, 108);
2924 state->agc1_min = dib8000_read_word(state, 109);
2925 state->agc2_max = dib8000_read_word(state, 110);
2926 state->agc2_min = dib8000_read_word(state, 111);
2927 agc1 = dib8000_read_word(state, 388);
2928 agc2 = dib8000_read_word(state, 389);
2929 dib8000_write_word(state, 108, agc1);
2930 dib8000_write_word(state, 109, agc1);
2931 dib8000_write_word(state, 110, agc2);
2932 dib8000_write_word(state, 111, agc2);
2934 #endif
2935 state->autosearch_state = AS_SEARCHING_FFT;
2936 state->found_nfft = TRANSMISSION_MODE_AUTO;
2937 state->found_guard = GUARD_INTERVAL_AUTO;
2938 *tune_state = CT_DEMOD_SEARCH_NEXT;
2939 } else { /* we already know the channel struct so TUNE only ! */
2940 state->autosearch_state = AS_DONE;
2941 *tune_state = CT_DEMOD_STEP_3;
2943 state->symbol_duration = dib8000_get_symbol_duration(state);
2944 break;
2946 case CT_DEMOD_SEARCH_NEXT: /* 51 */
2947 dib8000_autosearch_start(fe);
2948 if (state->revision == 0x8090)
2949 ret = 50;
2950 else
2951 ret = 15;
2952 *tune_state = CT_DEMOD_STEP_1;
2953 break;
2955 case CT_DEMOD_STEP_1: /* 31 */
2956 switch (dib8000_autosearch_irq(fe)) {
2957 case 1: /* fail */
2958 state->status = FE_STATUS_TUNE_FAILED;
2959 state->autosearch_state = AS_DONE;
2960 *tune_state = CT_DEMOD_STOP; /* else we are done here */
2961 break;
2962 case 2: /* Succes */
2963 state->status = FE_STATUS_FFT_SUCCESS; /* signal to the upper layer, that there was a channel found and the parameters can be read */
2964 *tune_state = CT_DEMOD_STEP_3;
2965 if (state->autosearch_state == AS_SEARCHING_GUARD)
2966 *tune_state = CT_DEMOD_STEP_2;
2967 else
2968 state->autosearch_state = AS_DONE;
2969 break;
2970 case 3: /* Autosearch FFT max correlation endded */
2971 *tune_state = CT_DEMOD_STEP_2;
2972 break;
2974 break;
2976 case CT_DEMOD_STEP_2:
2977 switch (state->autosearch_state) {
2978 case AS_SEARCHING_FFT:
2979 /* searching for the correct FFT */
2980 if (state->revision == 0x8090) {
2981 corm[2] = (dib8000_read_word(state, 596) << 16) | (dib8000_read_word(state, 597));
2982 corm[1] = (dib8000_read_word(state, 598) << 16) | (dib8000_read_word(state, 599));
2983 corm[0] = (dib8000_read_word(state, 600) << 16) | (dib8000_read_word(state, 601));
2984 } else {
2985 corm[2] = (dib8000_read_word(state, 594) << 16) | (dib8000_read_word(state, 595));
2986 corm[1] = (dib8000_read_word(state, 596) << 16) | (dib8000_read_word(state, 597));
2987 corm[0] = (dib8000_read_word(state, 598) << 16) | (dib8000_read_word(state, 599));
2989 /* dprintk("corm fft: %u %u %u", corm[0], corm[1], corm[2]); */
2991 max_value = 0;
2992 for (find_index = 1 ; find_index < 3 ; find_index++) {
2993 if (corm[max_value] < corm[find_index])
2994 max_value = find_index ;
2997 switch (max_value) {
2998 case 0:
2999 state->found_nfft = TRANSMISSION_MODE_2K;
3000 break;
3001 case 1:
3002 state->found_nfft = TRANSMISSION_MODE_4K;
3003 break;
3004 case 2:
3005 default:
3006 state->found_nfft = TRANSMISSION_MODE_8K;
3007 break;
3009 /* dprintk("Autosearch FFT has found Mode %d", max_value + 1); */
3011 *tune_state = CT_DEMOD_SEARCH_NEXT;
3012 state->autosearch_state = AS_SEARCHING_GUARD;
3013 if (state->revision == 0x8090)
3014 ret = 50;
3015 else
3016 ret = 10;
3017 break;
3018 case AS_SEARCHING_GUARD:
3019 /* searching for the correct guard interval */
3020 if (state->revision == 0x8090)
3021 state->found_guard = dib8000_read_word(state, 572) & 0x3;
3022 else
3023 state->found_guard = dib8000_read_word(state, 570) & 0x3;
3024 /* dprintk("guard interval found=%i", state->found_guard); */
3026 *tune_state = CT_DEMOD_STEP_3;
3027 break;
3028 default:
3029 /* the demod should never be in this state */
3030 state->status = FE_STATUS_TUNE_FAILED;
3031 state->autosearch_state = AS_DONE;
3032 *tune_state = CT_DEMOD_STOP; /* else we are done here */
3033 break;
3035 break;
3037 case CT_DEMOD_STEP_3: /* 33 */
3038 state->symbol_duration = dib8000_get_symbol_duration(state);
3039 dib8000_set_isdbt_loop_params(state, LOOP_TUNE_1);
3040 dib8000_set_isdbt_common_channel(state, 0, 0);/* setting the known channel parameters here */
3041 *tune_state = CT_DEMOD_STEP_4;
3042 break;
3044 case CT_DEMOD_STEP_4: /* (34) */
3045 dib8000_demod_restart(state);
3047 dib8000_set_sync_wait(state);
3048 dib8000_set_diversity_in(state->fe[0], state->diversity_onoff);
3050 locks = (dib8000_read_word(state, 180) >> 6) & 0x3f; /* P_coff_winlen ? */
3051 /* coff should lock over P_coff_winlen ofdm symbols : give 3 times this lenght to lock */
3052 *timeout = dib8000_get_timeout(state, 2 * locks, SYMBOL_DEPENDENT_ON);
3053 *tune_state = CT_DEMOD_STEP_5;
3054 break;
3056 case CT_DEMOD_STEP_5: /* (35) */
3057 locks = dib8000_read_lock(fe);
3058 if (locks & (0x3 << 11)) { /* coff-lock and off_cpil_lock achieved */
3059 dib8000_update_timf(state); /* we achieved a coff_cpil_lock - it's time to update the timf */
3060 if (!state->differential_constellation) {
3061 /* 2 times lmod4_win_len + 10 symbols (pipe delay after coff + nb to compute a 1st correlation) */
3062 *timeout = dib8000_get_timeout(state, (20 * ((dib8000_read_word(state, 188)>>5)&0x1f)), SYMBOL_DEPENDENT_ON);
3063 *tune_state = CT_DEMOD_STEP_7;
3064 } else {
3065 *tune_state = CT_DEMOD_STEP_8;
3067 } else if (now > *timeout) {
3068 *tune_state = CT_DEMOD_STEP_6; /* goto check for diversity input connection */
3070 break;
3072 case CT_DEMOD_STEP_6: /* (36) if there is an input (diversity) */
3073 if ((state->fe[1] != NULL) && (state->output_mode != OUTMODE_DIVERSITY)) {
3074 /* if there is a diversity fe in input and this fe is has not already failled : wait here until this this fe has succedeed or failled */
3075 if (dib8000_get_status(state->fe[1]) <= FE_STATUS_STD_SUCCESS) /* Something is locked on the input fe */
3076 *tune_state = CT_DEMOD_STEP_8; /* go for mpeg */
3077 else if (dib8000_get_status(state->fe[1]) >= FE_STATUS_TUNE_TIME_TOO_SHORT) { /* fe in input failled also, break the current one */
3078 *tune_state = CT_DEMOD_STOP; /* else we are done here ; step 8 will close the loops and exit */
3079 dib8000_viterbi_state(state, 1); /* start viterbi chandec */
3080 dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2);
3081 state->status = FE_STATUS_TUNE_FAILED;
3083 } else {
3084 dib8000_viterbi_state(state, 1); /* start viterbi chandec */
3085 dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2);
3086 *tune_state = CT_DEMOD_STOP; /* else we are done here ; step 8 will close the loops and exit */
3087 state->status = FE_STATUS_TUNE_FAILED;
3089 break;
3091 case CT_DEMOD_STEP_7: /* 37 */
3092 locks = dib8000_read_lock(fe);
3093 if (locks & (1<<10)) { /* lmod4_lock */
3094 ret = 14; /* wait for 14 symbols */
3095 *tune_state = CT_DEMOD_STEP_8;
3096 } else if (now > *timeout)
3097 *tune_state = CT_DEMOD_STEP_6; /* goto check for diversity input connection */
3098 break;
3100 case CT_DEMOD_STEP_8: /* 38 */
3101 dib8000_viterbi_state(state, 1); /* start viterbi chandec */
3102 dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2);
3104 /* mpeg will never lock on this condition because init_prbs is not set : search for it !*/
3105 if (c->isdbt_sb_mode
3106 && c->isdbt_sb_subchannel < 14
3107 && !state->differential_constellation) {
3108 state->subchannel = 0;
3109 *tune_state = CT_DEMOD_STEP_11;
3110 } else {
3111 *tune_state = CT_DEMOD_STEP_9;
3112 state->status = FE_STATUS_LOCKED;
3114 break;
3116 case CT_DEMOD_STEP_9: /* 39 */
3117 if ((state->revision == 0x8090) || ((dib8000_read_word(state, 1291) >> 9) & 0x1)) { /* fe capable of deinterleaving : esram */
3118 /* defines timeout for mpeg lock depending on interleaver lenght of longest layer */
3119 for (i = 0; i < 3; i++) {
3120 if (c->layer[i].interleaving >= deeper_interleaver) {
3121 dprintk("layer%i: time interleaver = %d ", i, c->layer[i].interleaving);
3122 if (c->layer[i].segment_count > 0) { /* valid layer */
3123 deeper_interleaver = c->layer[0].interleaving;
3124 state->longest_intlv_layer = i;
3129 if (deeper_interleaver == 0)
3130 locks = 2; /* locks is the tmp local variable name */
3131 else if (deeper_interleaver == 3)
3132 locks = 8;
3133 else
3134 locks = 2 * deeper_interleaver;
3136 if (state->diversity_onoff != 0) /* because of diversity sync */
3137 locks *= 2;
3139 *timeout = now + (2000 * locks); /* give the mpeg lock 800ms if sram is present */
3140 dprintk("Deeper interleaver mode = %d on layer %d : timeout mult factor = %d => will use timeout = %d", deeper_interleaver, state->longest_intlv_layer, locks, *timeout);
3142 *tune_state = CT_DEMOD_STEP_10;
3143 } else
3144 *tune_state = CT_DEMOD_STOP;
3145 break;
3147 case CT_DEMOD_STEP_10: /* 40 */
3148 locks = dib8000_read_lock(fe);
3149 if (locks&(1<<(7-state->longest_intlv_layer))) { /* mpeg lock : check the longest one */
3150 dprintk("Mpeg locks [ L0 : %d | L1 : %d | L2 : %d ]", (locks>>7)&0x1, (locks>>6)&0x1, (locks>>5)&0x1);
3151 if (c->isdbt_sb_mode
3152 && c->isdbt_sb_subchannel < 14
3153 && !state->differential_constellation)
3154 /* signal to the upper layer, that there was a channel found and the parameters can be read */
3155 state->status = FE_STATUS_DEMOD_SUCCESS;
3156 else
3157 state->status = FE_STATUS_DATA_LOCKED;
3158 *tune_state = CT_DEMOD_STOP;
3159 } else if (now > *timeout) {
3160 if (c->isdbt_sb_mode
3161 && c->isdbt_sb_subchannel < 14
3162 && !state->differential_constellation) { /* continue to try init prbs autosearch */
3163 state->subchannel += 3;
3164 *tune_state = CT_DEMOD_STEP_11;
3165 } else { /* we are done mpeg of the longest interleaver xas not locking but let's try if an other layer has locked in the same time */
3166 if (locks & (0x7<<5)) {
3167 dprintk("Mpeg locks [ L0 : %d | L1 : %d | L2 : %d ]", (locks>>7)&0x1, (locks>>6)&0x1, (locks>>5)&0x1);
3168 state->status = FE_STATUS_DATA_LOCKED;
3169 } else
3170 state->status = FE_STATUS_TUNE_FAILED;
3171 *tune_state = CT_DEMOD_STOP;
3174 break;
3176 case CT_DEMOD_STEP_11: /* 41 : init prbs autosearch */
3177 if (state->subchannel <= 41) {
3178 dib8000_set_subchannel_prbs(state, dib8000_get_init_prbs(state, state->subchannel));
3179 *tune_state = CT_DEMOD_STEP_9;
3180 } else {
3181 *tune_state = CT_DEMOD_STOP;
3182 state->status = FE_STATUS_TUNE_FAILED;
3184 break;
3186 default:
3187 break;
3190 /* tuning is finished - cleanup the demod */
3191 switch (*tune_state) {
3192 case CT_DEMOD_STOP: /* (42) */
3193 #ifdef DIB8000_AGC_FREEZE
3194 if ((state->revision != 0x8090) && (state->agc1_max != 0)) {
3195 dib8000_write_word(state, 108, state->agc1_max);
3196 dib8000_write_word(state, 109, state->agc1_min);
3197 dib8000_write_word(state, 110, state->agc2_max);
3198 dib8000_write_word(state, 111, state->agc2_min);
3199 state->agc1_max = 0;
3200 state->agc1_min = 0;
3201 state->agc2_max = 0;
3202 state->agc2_min = 0;
3204 #endif
3205 ret = FE_CALLBACK_TIME_NEVER;
3206 break;
3207 default:
3208 break;
3211 if ((ret > 0) && (*tune_state > CT_DEMOD_STEP_3))
3212 return ret * state->symbol_duration;
3213 if ((ret > 0) && (ret < state->symbol_duration))
3214 return state->symbol_duration; /* at least one symbol */
3215 return ret;
3218 static int dib8000_wakeup(struct dvb_frontend *fe)
3220 struct dib8000_state *state = fe->demodulator_priv;
3221 u8 index_frontend;
3222 int ret;
3224 dib8000_set_power_mode(state, DIB8000_POWER_ALL);
3225 dib8000_set_adc_state(state, DIBX000_ADC_ON);
3226 if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
3227 dprintk("could not start Slow ADC");
3229 if (state->revision == 0x8090)
3230 dib8000_sad_calib(state);
3232 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3233 ret = state->fe[index_frontend]->ops.init(state->fe[index_frontend]);
3234 if (ret < 0)
3235 return ret;
3238 return 0;
3241 static int dib8000_sleep(struct dvb_frontend *fe)
3243 struct dib8000_state *state = fe->demodulator_priv;
3244 u8 index_frontend;
3245 int ret;
3247 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3248 ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
3249 if (ret < 0)
3250 return ret;
3253 if (state->revision != 0x8090)
3254 dib8000_set_output_mode(fe, OUTMODE_HIGH_Z);
3255 dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY);
3256 return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF);
3259 static int dib8000_get_frontend(struct dvb_frontend *fe)
3261 struct dib8000_state *state = fe->demodulator_priv;
3262 u16 i, val = 0;
3263 fe_status_t stat;
3264 u8 index_frontend, sub_index_frontend;
3266 fe->dtv_property_cache.bandwidth_hz = 6000000;
3268 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3269 state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
3270 if (stat&FE_HAS_SYNC) {
3271 dprintk("TMCC lock on the slave%i", index_frontend);
3272 /* synchronize the cache with the other frontends */
3273 state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend]);
3274 for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL); sub_index_frontend++) {
3275 if (sub_index_frontend != index_frontend) {
3276 state->fe[sub_index_frontend]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode;
3277 state->fe[sub_index_frontend]->dtv_property_cache.inversion = state->fe[index_frontend]->dtv_property_cache.inversion;
3278 state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode = state->fe[index_frontend]->dtv_property_cache.transmission_mode;
3279 state->fe[sub_index_frontend]->dtv_property_cache.guard_interval = state->fe[index_frontend]->dtv_property_cache.guard_interval;
3280 state->fe[sub_index_frontend]->dtv_property_cache.isdbt_partial_reception = state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception;
3281 for (i = 0; i < 3; i++) {
3282 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].segment_count = state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count;
3283 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].interleaving = state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving;
3284 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].fec = state->fe[index_frontend]->dtv_property_cache.layer[i].fec;
3285 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].modulation = state->fe[index_frontend]->dtv_property_cache.layer[i].modulation;
3289 return 0;
3293 fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1;
3295 if (state->revision == 0x8090)
3296 val = dib8000_read_word(state, 572);
3297 else
3298 val = dib8000_read_word(state, 570);
3299 fe->dtv_property_cache.inversion = (val & 0x40) >> 6;
3300 switch ((val & 0x30) >> 4) {
3301 case 1:
3302 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
3303 break;
3304 case 3:
3305 default:
3306 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
3307 break;
3310 switch (val & 0x3) {
3311 case 0:
3312 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
3313 dprintk("dib8000_get_frontend GI = 1/32 ");
3314 break;
3315 case 1:
3316 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
3317 dprintk("dib8000_get_frontend GI = 1/16 ");
3318 break;
3319 case 2:
3320 dprintk("dib8000_get_frontend GI = 1/8 ");
3321 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
3322 break;
3323 case 3:
3324 dprintk("dib8000_get_frontend GI = 1/4 ");
3325 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
3326 break;
3329 val = dib8000_read_word(state, 505);
3330 fe->dtv_property_cache.isdbt_partial_reception = val & 1;
3331 dprintk("dib8000_get_frontend : partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception);
3333 for (i = 0; i < 3; i++) {
3334 val = dib8000_read_word(state, 493 + i);
3335 fe->dtv_property_cache.layer[i].segment_count = val & 0x0F;
3336 dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count);
3338 val = dib8000_read_word(state, 499 + i);
3339 fe->dtv_property_cache.layer[i].interleaving = val & 0x3;
3340 dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ", i, fe->dtv_property_cache.layer[i].interleaving);
3342 val = dib8000_read_word(state, 481 + i);
3343 switch (val & 0x7) {
3344 case 1:
3345 fe->dtv_property_cache.layer[i].fec = FEC_1_2;
3346 dprintk("dib8000_get_frontend : Layer %d Code Rate = 1/2 ", i);
3347 break;
3348 case 2:
3349 fe->dtv_property_cache.layer[i].fec = FEC_2_3;
3350 dprintk("dib8000_get_frontend : Layer %d Code Rate = 2/3 ", i);
3351 break;
3352 case 3:
3353 fe->dtv_property_cache.layer[i].fec = FEC_3_4;
3354 dprintk("dib8000_get_frontend : Layer %d Code Rate = 3/4 ", i);
3355 break;
3356 case 5:
3357 fe->dtv_property_cache.layer[i].fec = FEC_5_6;
3358 dprintk("dib8000_get_frontend : Layer %d Code Rate = 5/6 ", i);
3359 break;
3360 default:
3361 fe->dtv_property_cache.layer[i].fec = FEC_7_8;
3362 dprintk("dib8000_get_frontend : Layer %d Code Rate = 7/8 ", i);
3363 break;
3366 val = dib8000_read_word(state, 487 + i);
3367 switch (val & 0x3) {
3368 case 0:
3369 dprintk("dib8000_get_frontend : Layer %d DQPSK ", i);
3370 fe->dtv_property_cache.layer[i].modulation = DQPSK;
3371 break;
3372 case 1:
3373 fe->dtv_property_cache.layer[i].modulation = QPSK;
3374 dprintk("dib8000_get_frontend : Layer %d QPSK ", i);
3375 break;
3376 case 2:
3377 fe->dtv_property_cache.layer[i].modulation = QAM_16;
3378 dprintk("dib8000_get_frontend : Layer %d QAM16 ", i);
3379 break;
3380 case 3:
3381 default:
3382 dprintk("dib8000_get_frontend : Layer %d QAM64 ", i);
3383 fe->dtv_property_cache.layer[i].modulation = QAM_64;
3384 break;
3388 /* synchronize the cache with the other frontends */
3389 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3390 state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode = fe->dtv_property_cache.isdbt_sb_mode;
3391 state->fe[index_frontend]->dtv_property_cache.inversion = fe->dtv_property_cache.inversion;
3392 state->fe[index_frontend]->dtv_property_cache.transmission_mode = fe->dtv_property_cache.transmission_mode;
3393 state->fe[index_frontend]->dtv_property_cache.guard_interval = fe->dtv_property_cache.guard_interval;
3394 state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception = fe->dtv_property_cache.isdbt_partial_reception;
3395 for (i = 0; i < 3; i++) {
3396 state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count = fe->dtv_property_cache.layer[i].segment_count;
3397 state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving = fe->dtv_property_cache.layer[i].interleaving;
3398 state->fe[index_frontend]->dtv_property_cache.layer[i].fec = fe->dtv_property_cache.layer[i].fec;
3399 state->fe[index_frontend]->dtv_property_cache.layer[i].modulation = fe->dtv_property_cache.layer[i].modulation;
3402 return 0;
3405 static int dib8000_set_frontend(struct dvb_frontend *fe)
3407 struct dib8000_state *state = fe->demodulator_priv;
3408 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
3409 int l, i, active, time, time_slave = FE_CALLBACK_TIME_NEVER;
3410 u8 exit_condition, index_frontend;
3411 u32 delay, callback_time;
3413 if (c->frequency == 0) {
3414 dprintk("dib8000: must at least specify frequency ");
3415 return 0;
3418 if (c->bandwidth_hz == 0) {
3419 dprintk("dib8000: no bandwidth specified, set to default ");
3420 c->bandwidth_hz = 6000000;
3423 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3424 /* synchronization of the cache */
3425 state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT;
3426 memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));
3428 /* set output mode and diversity input */
3429 if (state->revision != 0x8090) {
3430 dib8000_set_diversity_in(state->fe[index_frontend], 1);
3431 if (index_frontend != 0)
3432 dib8000_set_output_mode(state->fe[index_frontend],
3433 OUTMODE_DIVERSITY);
3434 else
3435 dib8000_set_output_mode(state->fe[0], OUTMODE_HIGH_Z);
3436 } else {
3437 dib8096p_set_diversity_in(state->fe[index_frontend], 1);
3438 if (index_frontend != 0)
3439 dib8096p_set_output_mode(state->fe[index_frontend],
3440 OUTMODE_DIVERSITY);
3441 else
3442 dib8096p_set_output_mode(state->fe[0], OUTMODE_HIGH_Z);
3445 /* tune the tuner */
3446 if (state->fe[index_frontend]->ops.tuner_ops.set_params)
3447 state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend]);
3449 dib8000_set_tune_state(state->fe[index_frontend], CT_AGC_START);
3452 /* turn off the diversity of the last chip */
3453 if (state->revision != 0x8090)
3454 dib8000_set_diversity_in(state->fe[index_frontend - 1], 0);
3455 else
3456 dib8096p_set_diversity_in(state->fe[index_frontend - 1], 0);
3458 /* start up the AGC */
3459 do {
3460 time = dib8000_agc_startup(state->fe[0]);
3461 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3462 time_slave = dib8000_agc_startup(state->fe[index_frontend]);
3463 if (time == FE_CALLBACK_TIME_NEVER)
3464 time = time_slave;
3465 else if ((time_slave != FE_CALLBACK_TIME_NEVER) && (time_slave > time))
3466 time = time_slave;
3468 if (time != FE_CALLBACK_TIME_NEVER)
3469 msleep(time / 10);
3470 else
3471 break;
3472 exit_condition = 1;
3473 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3474 if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_AGC_STOP) {
3475 exit_condition = 0;
3476 break;
3479 } while (exit_condition == 0);
3481 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
3482 dib8000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
3484 active = 1;
3485 do {
3486 callback_time = FE_CALLBACK_TIME_NEVER;
3487 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3488 delay = dib8000_tune(state->fe[index_frontend]);
3489 if (delay != FE_CALLBACK_TIME_NEVER)
3490 delay += systime();
3492 /* we are in autosearch */
3493 if (state->channel_parameters_set == 0) { /* searching */
3494 if ((dib8000_get_status(state->fe[index_frontend]) == FE_STATUS_DEMOD_SUCCESS) || (dib8000_get_status(state->fe[index_frontend]) == FE_STATUS_FFT_SUCCESS)) {
3495 dprintk("autosearch succeeded on fe%i", index_frontend);
3496 dib8000_get_frontend(state->fe[index_frontend]); /* we read the channel parameters from the frontend which was successful */
3497 state->channel_parameters_set = 1;
3499 for (l = 0; (l < MAX_NUMBER_OF_FRONTENDS) && (state->fe[l] != NULL); l++) {
3500 if (l != index_frontend) { /* and for all frontend except the successful one */
3501 dib8000_tune_restart_from_demod(state->fe[l]);
3503 state->fe[l]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode;
3504 state->fe[l]->dtv_property_cache.inversion = state->fe[index_frontend]->dtv_property_cache.inversion;
3505 state->fe[l]->dtv_property_cache.transmission_mode = state->fe[index_frontend]->dtv_property_cache.transmission_mode;
3506 state->fe[l]->dtv_property_cache.guard_interval = state->fe[index_frontend]->dtv_property_cache.guard_interval;
3507 state->fe[l]->dtv_property_cache.isdbt_partial_reception = state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception;
3508 for (i = 0; i < 3; i++) {
3509 state->fe[l]->dtv_property_cache.layer[i].segment_count = state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count;
3510 state->fe[l]->dtv_property_cache.layer[i].interleaving = state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving;
3511 state->fe[l]->dtv_property_cache.layer[i].fec = state->fe[index_frontend]->dtv_property_cache.layer[i].fec;
3512 state->fe[l]->dtv_property_cache.layer[i].modulation = state->fe[index_frontend]->dtv_property_cache.layer[i].modulation;
3519 if (delay < callback_time)
3520 callback_time = delay;
3522 /* tuning is done when the master frontend is done (failed or success) */
3523 if (dib8000_get_status(state->fe[0]) == FE_STATUS_TUNE_FAILED ||
3524 dib8000_get_status(state->fe[0]) == FE_STATUS_LOCKED ||
3525 dib8000_get_status(state->fe[0]) == FE_STATUS_DATA_LOCKED) {
3526 active = 0;
3527 /* we need to wait for all frontends to be finished */
3528 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3529 if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_DEMOD_STOP)
3530 active = 1;
3532 if (active == 0)
3533 dprintk("tuning done with status %d", dib8000_get_status(state->fe[0]));
3536 if ((active == 1) && (callback_time == FE_CALLBACK_TIME_NEVER)) {
3537 dprintk("strange callback time something went wrong");
3538 active = 0;
3541 while ((active == 1) && (systime() < callback_time))
3542 msleep(100);
3543 } while (active);
3545 /* set output mode */
3546 if (state->revision != 0x8090)
3547 dib8000_set_output_mode(state->fe[0], state->cfg.output_mode);
3548 else {
3549 dib8096p_set_output_mode(state->fe[0], state->cfg.output_mode);
3550 if (state->cfg.enMpegOutput == 0) {
3551 dib8096p_setDibTxMux(state, MPEG_ON_DIBTX);
3552 dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
3556 return 0;
3559 static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
3561 struct dib8000_state *state = fe->demodulator_priv;
3562 u16 lock_slave = 0, lock;
3563 u8 index_frontend;
3565 lock = dib8000_read_lock(fe);
3566 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
3567 lock_slave |= dib8000_read_lock(state->fe[index_frontend]);
3569 *stat = 0;
3571 if (((lock >> 13) & 1) || ((lock_slave >> 13) & 1))
3572 *stat |= FE_HAS_SIGNAL;
3574 if (((lock >> 8) & 1) || ((lock_slave >> 8) & 1)) /* Equal */
3575 *stat |= FE_HAS_CARRIER;
3577 if ((((lock >> 1) & 0xf) == 0xf) || (((lock_slave >> 1) & 0xf) == 0xf)) /* TMCC_SYNC */
3578 *stat |= FE_HAS_SYNC;
3580 if ((((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) && ((lock >> 5) & 7)) /* FEC MPEG */
3581 *stat |= FE_HAS_LOCK;
3583 if (((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) {
3584 lock = dib8000_read_word(state, 554); /* Viterbi Layer A */
3585 if (lock & 0x01)
3586 *stat |= FE_HAS_VITERBI;
3588 lock = dib8000_read_word(state, 555); /* Viterbi Layer B */
3589 if (lock & 0x01)
3590 *stat |= FE_HAS_VITERBI;
3592 lock = dib8000_read_word(state, 556); /* Viterbi Layer C */
3593 if (lock & 0x01)
3594 *stat |= FE_HAS_VITERBI;
3597 return 0;
3600 static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber)
3602 struct dib8000_state *state = fe->demodulator_priv;
3604 /* 13 segments */
3605 if (state->revision == 0x8090)
3606 *ber = (dib8000_read_word(state, 562) << 16) |
3607 dib8000_read_word(state, 563);
3608 else
3609 *ber = (dib8000_read_word(state, 560) << 16) |
3610 dib8000_read_word(state, 561);
3611 return 0;
3614 static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
3616 struct dib8000_state *state = fe->demodulator_priv;
3618 /* packet error on 13 seg */
3619 if (state->revision == 0x8090)
3620 *unc = dib8000_read_word(state, 567);
3621 else
3622 *unc = dib8000_read_word(state, 565);
3623 return 0;
3626 static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
3628 struct dib8000_state *state = fe->demodulator_priv;
3629 u8 index_frontend;
3630 u16 val;
3632 *strength = 0;
3633 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3634 state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
3635 if (val > 65535 - *strength)
3636 *strength = 65535;
3637 else
3638 *strength += val;
3641 val = 65535 - dib8000_read_word(state, 390);
3642 if (val > 65535 - *strength)
3643 *strength = 65535;
3644 else
3645 *strength += val;
3646 return 0;
3649 static u32 dib8000_get_snr(struct dvb_frontend *fe)
3651 struct dib8000_state *state = fe->demodulator_priv;
3652 u32 n, s, exp;
3653 u16 val;
3655 if (state->revision != 0x8090)
3656 val = dib8000_read_word(state, 542);
3657 else
3658 val = dib8000_read_word(state, 544);
3659 n = (val >> 6) & 0xff;
3660 exp = (val & 0x3f);
3661 if ((exp & 0x20) != 0)
3662 exp -= 0x40;
3663 n <<= exp+16;
3665 if (state->revision != 0x8090)
3666 val = dib8000_read_word(state, 543);
3667 else
3668 val = dib8000_read_word(state, 545);
3669 s = (val >> 6) & 0xff;
3670 exp = (val & 0x3f);
3671 if ((exp & 0x20) != 0)
3672 exp -= 0x40;
3673 s <<= exp+16;
3675 if (n > 0) {
3676 u32 t = (s/n) << 16;
3677 return t + ((s << 16) - n*t) / n;
3679 return 0xffffffff;
3682 static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
3684 struct dib8000_state *state = fe->demodulator_priv;
3685 u8 index_frontend;
3686 u32 snr_master;
3688 snr_master = dib8000_get_snr(fe);
3689 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
3690 snr_master += dib8000_get_snr(state->fe[index_frontend]);
3692 if ((snr_master >> 16) != 0) {
3693 snr_master = 10*intlog10(snr_master>>16);
3694 *snr = snr_master / ((1 << 24) / 10);
3696 else
3697 *snr = 0;
3699 return 0;
3702 int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
3704 struct dib8000_state *state = fe->demodulator_priv;
3705 u8 index_frontend = 1;
3707 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
3708 index_frontend++;
3709 if (index_frontend < MAX_NUMBER_OF_FRONTENDS) {
3710 dprintk("set slave fe %p to index %i", fe_slave, index_frontend);
3711 state->fe[index_frontend] = fe_slave;
3712 return 0;
3715 dprintk("too many slave frontend");
3716 return -ENOMEM;
3718 EXPORT_SYMBOL(dib8000_set_slave_frontend);
3720 int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
3722 struct dib8000_state *state = fe->demodulator_priv;
3723 u8 index_frontend = 1;
3725 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
3726 index_frontend++;
3727 if (index_frontend != 1) {
3728 dprintk("remove slave fe %p (index %i)", state->fe[index_frontend-1], index_frontend-1);
3729 state->fe[index_frontend] = NULL;
3730 return 0;
3733 dprintk("no frontend to be removed");
3734 return -ENODEV;
3736 EXPORT_SYMBOL(dib8000_remove_slave_frontend);
3738 struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
3740 struct dib8000_state *state = fe->demodulator_priv;
3742 if (slave_index >= MAX_NUMBER_OF_FRONTENDS)
3743 return NULL;
3744 return state->fe[slave_index];
3746 EXPORT_SYMBOL(dib8000_get_slave_frontend);
3749 int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods,
3750 u8 default_addr, u8 first_addr, u8 is_dib8096p)
3752 int k = 0, ret = 0;
3753 u8 new_addr = 0;
3754 struct i2c_device client = {.adap = host };
3756 client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
3757 if (!client.i2c_write_buffer) {
3758 dprintk("%s: not enough memory", __func__);
3759 return -ENOMEM;
3761 client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
3762 if (!client.i2c_read_buffer) {
3763 dprintk("%s: not enough memory", __func__);
3764 ret = -ENOMEM;
3765 goto error_memory_read;
3767 client.i2c_buffer_lock = kzalloc(sizeof(struct mutex), GFP_KERNEL);
3768 if (!client.i2c_buffer_lock) {
3769 dprintk("%s: not enough memory", __func__);
3770 ret = -ENOMEM;
3771 goto error_memory_lock;
3773 mutex_init(client.i2c_buffer_lock);
3775 for (k = no_of_demods - 1; k >= 0; k--) {
3776 /* designated i2c address */
3777 new_addr = first_addr + (k << 1);
3779 client.addr = new_addr;
3780 if (!is_dib8096p)
3781 dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */
3782 if (dib8000_identify(&client) == 0) {
3783 /* sram lead in, rdy */
3784 if (!is_dib8096p)
3785 dib8000_i2c_write16(&client, 1287, 0x0003);
3786 client.addr = default_addr;
3787 if (dib8000_identify(&client) == 0) {
3788 dprintk("#%d: not identified", k);
3789 ret = -EINVAL;
3790 goto error;
3794 /* start diversity to pull_down div_str - just for i2c-enumeration */
3795 dib8000_i2c_write16(&client, 1286, (1 << 10) | (4 << 6));
3797 /* set new i2c address and force divstart */
3798 dib8000_i2c_write16(&client, 1285, (new_addr << 2) | 0x2);
3799 client.addr = new_addr;
3800 dib8000_identify(&client);
3802 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
3805 for (k = 0; k < no_of_demods; k++) {
3806 new_addr = first_addr | (k << 1);
3807 client.addr = new_addr;
3809 // unforce divstr
3810 dib8000_i2c_write16(&client, 1285, new_addr << 2);
3812 /* deactivate div - it was just for i2c-enumeration */
3813 dib8000_i2c_write16(&client, 1286, 0);
3816 error:
3817 kfree(client.i2c_buffer_lock);
3818 error_memory_lock:
3819 kfree(client.i2c_read_buffer);
3820 error_memory_read:
3821 kfree(client.i2c_write_buffer);
3823 return ret;
3826 EXPORT_SYMBOL(dib8000_i2c_enumeration);
3827 static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
3829 tune->min_delay_ms = 1000;
3830 tune->step_size = 0;
3831 tune->max_drift = 0;
3832 return 0;
3835 static void dib8000_release(struct dvb_frontend *fe)
3837 struct dib8000_state *st = fe->demodulator_priv;
3838 u8 index_frontend;
3840 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++)
3841 dvb_frontend_detach(st->fe[index_frontend]);
3843 dibx000_exit_i2c_master(&st->i2c_master);
3844 i2c_del_adapter(&st->dib8096p_tuner_adap);
3845 kfree(st->fe[0]);
3846 kfree(st);
3849 struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
3851 struct dib8000_state *st = fe->demodulator_priv;
3852 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
3855 EXPORT_SYMBOL(dib8000_get_i2c_master);
3857 int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
3859 struct dib8000_state *st = fe->demodulator_priv;
3860 u16 val = dib8000_read_word(st, 299) & 0xffef;
3861 val |= (onoff & 0x1) << 4;
3863 dprintk("pid filter enabled %d", onoff);
3864 return dib8000_write_word(st, 299, val);
3866 EXPORT_SYMBOL(dib8000_pid_filter_ctrl);
3868 int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
3870 struct dib8000_state *st = fe->demodulator_priv;
3871 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
3872 return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0);
3874 EXPORT_SYMBOL(dib8000_pid_filter);
3876 static const struct dvb_frontend_ops dib8000_ops = {
3877 .delsys = { SYS_ISDBT },
3878 .info = {
3879 .name = "DiBcom 8000 ISDB-T",
3880 .frequency_min = 44250000,
3881 .frequency_max = 867250000,
3882 .frequency_stepsize = 62500,
3883 .caps = FE_CAN_INVERSION_AUTO |
3884 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
3885 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
3886 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
3887 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
3890 .release = dib8000_release,
3892 .init = dib8000_wakeup,
3893 .sleep = dib8000_sleep,
3895 .set_frontend = dib8000_set_frontend,
3896 .get_tune_settings = dib8000_fe_get_tune_settings,
3897 .get_frontend = dib8000_get_frontend,
3899 .read_status = dib8000_read_status,
3900 .read_ber = dib8000_read_ber,
3901 .read_signal_strength = dib8000_read_signal_strength,
3902 .read_snr = dib8000_read_snr,
3903 .read_ucblocks = dib8000_read_unc_blocks,
3906 struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
3908 struct dvb_frontend *fe;
3909 struct dib8000_state *state;
3911 dprintk("dib8000_attach");
3913 state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL);
3914 if (state == NULL)
3915 return NULL;
3916 fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);
3917 if (fe == NULL)
3918 goto error;
3920 memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
3921 state->i2c.adap = i2c_adap;
3922 state->i2c.addr = i2c_addr;
3923 state->i2c.i2c_write_buffer = state->i2c_write_buffer;
3924 state->i2c.i2c_read_buffer = state->i2c_read_buffer;
3925 mutex_init(&state->i2c_buffer_lock);
3926 state->i2c.i2c_buffer_lock = &state->i2c_buffer_lock;
3927 state->gpio_val = cfg->gpio_val;
3928 state->gpio_dir = cfg->gpio_dir;
3930 /* Ensure the output mode remains at the previous default if it's
3931 * not specifically set by the caller.
3933 if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
3934 state->cfg.output_mode = OUTMODE_MPEG2_FIFO;
3936 state->fe[0] = fe;
3937 fe->demodulator_priv = state;
3938 memcpy(&state->fe[0]->ops, &dib8000_ops, sizeof(struct dvb_frontend_ops));
3940 state->timf_default = cfg->pll->timf;
3942 if (dib8000_identify(&state->i2c) == 0)
3943 goto error;
3945 dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr);
3947 /* init 8096p tuner adapter */
3948 strncpy(state->dib8096p_tuner_adap.name, "DiB8096P tuner interface",
3949 sizeof(state->dib8096p_tuner_adap.name));
3950 state->dib8096p_tuner_adap.algo = &dib8096p_tuner_xfer_algo;
3951 state->dib8096p_tuner_adap.algo_data = NULL;
3952 state->dib8096p_tuner_adap.dev.parent = state->i2c.adap->dev.parent;
3953 i2c_set_adapdata(&state->dib8096p_tuner_adap, state);
3954 i2c_add_adapter(&state->dib8096p_tuner_adap);
3956 dib8000_reset(fe);
3958 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5)); /* ber_rs_len = 3 */
3959 state->current_demod_bw = 6000;
3961 return fe;
3963 error:
3964 kfree(state);
3965 return NULL;
3968 EXPORT_SYMBOL(dib8000_attach);
3970 MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@dibcom.fr, " "Patrick Boettcher <pboettcher@dibcom.fr>");
3971 MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator");
3972 MODULE_LICENSE("GPL");