Linux 3.12.39
[linux/fpc-iii.git] / drivers / media / dvb-frontends / dib8000.c
blobccac8467a28ba8b720f5c7b742876d01b6d7d04b
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 state->i2c_write_buffer[0] = reg >> 8;
165 state->i2c_write_buffer[1] = reg & 0xff;
167 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
168 state->msg[0].addr = state->i2c.addr >> 1;
169 state->msg[0].flags = 0;
170 state->msg[0].buf = state->i2c_write_buffer;
171 state->msg[0].len = 2;
172 state->msg[1].addr = state->i2c.addr >> 1;
173 state->msg[1].flags = I2C_M_RD;
174 state->msg[1].buf = state->i2c_read_buffer;
175 state->msg[1].len = 2;
177 if (i2c_transfer(state->i2c.adap, state->msg, 2) != 2)
178 dprintk("i2c read error on %d", reg);
180 ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
182 return ret;
185 static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
187 u16 ret;
189 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
190 dprintk("could not acquire lock");
191 return 0;
194 ret = __dib8000_read_word(state, reg);
196 mutex_unlock(&state->i2c_buffer_lock);
198 return ret;
201 static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
203 u16 rw[2];
205 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
206 dprintk("could not acquire lock");
207 return 0;
210 rw[0] = __dib8000_read_word(state, reg + 0);
211 rw[1] = __dib8000_read_word(state, reg + 1);
213 mutex_unlock(&state->i2c_buffer_lock);
215 return ((rw[0] << 16) | (rw[1]));
218 static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
220 struct i2c_msg msg = {.addr = i2c->addr >> 1, .flags = 0, .len = 4};
221 int ret = 0;
223 if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) {
224 dprintk("could not acquire lock");
225 return -EINVAL;
228 msg.buf = i2c->i2c_write_buffer;
229 msg.buf[0] = (reg >> 8) & 0xff;
230 msg.buf[1] = reg & 0xff;
231 msg.buf[2] = (val >> 8) & 0xff;
232 msg.buf[3] = val & 0xff;
234 ret = i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
235 mutex_unlock(i2c->i2c_buffer_lock);
237 return ret;
240 static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
242 int ret;
244 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
245 dprintk("could not acquire lock");
246 return -EINVAL;
249 state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
250 state->i2c_write_buffer[1] = reg & 0xff;
251 state->i2c_write_buffer[2] = (val >> 8) & 0xff;
252 state->i2c_write_buffer[3] = val & 0xff;
254 memset(&state->msg[0], 0, sizeof(struct i2c_msg));
255 state->msg[0].addr = state->i2c.addr >> 1;
256 state->msg[0].flags = 0;
257 state->msg[0].buf = state->i2c_write_buffer;
258 state->msg[0].len = 4;
260 ret = (i2c_transfer(state->i2c.adap, state->msg, 1) != 1 ?
261 -EREMOTEIO : 0);
262 mutex_unlock(&state->i2c_buffer_lock);
264 return ret;
267 static const s16 coeff_2k_sb_1seg_dqpsk[8] = {
268 (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
269 (920 << 5) | 0x09
272 static const s16 coeff_2k_sb_1seg[8] = {
273 (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
276 static const s16 coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
277 (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
278 (-931 << 5) | 0x0f
281 static const s16 coeff_2k_sb_3seg_0dqpsk[8] = {
282 (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
283 (982 << 5) | 0x0c
286 static const s16 coeff_2k_sb_3seg_1dqpsk[8] = {
287 (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
288 (-720 << 5) | 0x0d
291 static const s16 coeff_2k_sb_3seg[8] = {
292 (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
293 (-610 << 5) | 0x0a
296 static const s16 coeff_4k_sb_1seg_dqpsk[8] = {
297 (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
298 (-922 << 5) | 0x0d
301 static const s16 coeff_4k_sb_1seg[8] = {
302 (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
303 (-655 << 5) | 0x0a
306 static const s16 coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
307 (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
308 (-958 << 5) | 0x13
311 static const s16 coeff_4k_sb_3seg_0dqpsk[8] = {
312 (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
313 (-568 << 5) | 0x0f
316 static const s16 coeff_4k_sb_3seg_1dqpsk[8] = {
317 (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
318 (-848 << 5) | 0x13
321 static const s16 coeff_4k_sb_3seg[8] = {
322 (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
323 (-869 << 5) | 0x13
326 static const s16 coeff_8k_sb_1seg_dqpsk[8] = {
327 (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
328 (-598 << 5) | 0x10
331 static const s16 coeff_8k_sb_1seg[8] = {
332 (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
333 (585 << 5) | 0x0f
336 static const s16 coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
337 (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
338 (0 << 5) | 0x14
341 static const s16 coeff_8k_sb_3seg_0dqpsk[8] = {
342 (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
343 (-877 << 5) | 0x15
346 static const s16 coeff_8k_sb_3seg_1dqpsk[8] = {
347 (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
348 (-921 << 5) | 0x14
351 static const s16 coeff_8k_sb_3seg[8] = {
352 (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
353 (690 << 5) | 0x14
356 static const s16 ana_fe_coeff_3seg[24] = {
357 81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
360 static const s16 ana_fe_coeff_1seg[24] = {
361 249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
364 static const s16 ana_fe_coeff_13seg[24] = {
365 396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
368 static u16 fft_to_mode(struct dib8000_state *state)
370 u16 mode;
371 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
372 case TRANSMISSION_MODE_2K:
373 mode = 1;
374 break;
375 case TRANSMISSION_MODE_4K:
376 mode = 2;
377 break;
378 default:
379 case TRANSMISSION_MODE_AUTO:
380 case TRANSMISSION_MODE_8K:
381 mode = 3;
382 break;
384 return mode;
387 static void dib8000_set_acquisition_mode(struct dib8000_state *state)
389 u16 nud = dib8000_read_word(state, 298);
390 nud |= (1 << 3) | (1 << 0);
391 dprintk("acquisition mode activated");
392 dib8000_write_word(state, 298, nud);
394 static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode)
396 struct dib8000_state *state = fe->demodulator_priv;
397 u16 outreg, fifo_threshold, smo_mode, sram = 0x0205; /* by default SDRAM deintlv is enabled */
399 state->output_mode = mode;
400 outreg = 0;
401 fifo_threshold = 1792;
402 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
404 dprintk("-I- Setting output mode for demod %p to %d",
405 &state->fe[0], mode);
407 switch (mode) {
408 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
409 outreg = (1 << 10); /* 0x0400 */
410 break;
411 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
412 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
413 break;
414 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
415 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
416 break;
417 case OUTMODE_DIVERSITY:
418 if (state->cfg.hostbus_diversity) {
419 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
420 sram &= 0xfdff;
421 } else
422 sram |= 0x0c00;
423 break;
424 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
425 smo_mode |= (3 << 1);
426 fifo_threshold = 512;
427 outreg = (1 << 10) | (5 << 6);
428 break;
429 case OUTMODE_HIGH_Z: // disable
430 outreg = 0;
431 break;
433 case OUTMODE_ANALOG_ADC:
434 outreg = (1 << 10) | (3 << 6);
435 dib8000_set_acquisition_mode(state);
436 break;
438 default:
439 dprintk("Unhandled output_mode passed to be set for demod %p",
440 &state->fe[0]);
441 return -EINVAL;
444 if (state->cfg.output_mpeg2_in_188_bytes)
445 smo_mode |= (1 << 5);
447 dib8000_write_word(state, 299, smo_mode);
448 dib8000_write_word(state, 300, fifo_threshold); /* synchronous fread */
449 dib8000_write_word(state, 1286, outreg);
450 dib8000_write_word(state, 1291, sram);
452 return 0;
455 static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff)
457 struct dib8000_state *state = fe->demodulator_priv;
458 u16 tmp, sync_wait = dib8000_read_word(state, 273) & 0xfff0;
460 dprintk("set diversity input to %i", onoff);
461 if (!state->differential_constellation) {
462 dib8000_write_word(state, 272, 1 << 9); //dvsy_off_lmod4 = 1
463 dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2); // sync_enable = 1; comb_mode = 2
464 } else {
465 dib8000_write_word(state, 272, 0); //dvsy_off_lmod4 = 0
466 dib8000_write_word(state, 273, sync_wait); // sync_enable = 0; comb_mode = 0
468 state->diversity_onoff = onoff;
470 switch (onoff) {
471 case 0: /* only use the internal way - not the diversity input */
472 dib8000_write_word(state, 270, 1);
473 dib8000_write_word(state, 271, 0);
474 break;
475 case 1: /* both ways */
476 dib8000_write_word(state, 270, 6);
477 dib8000_write_word(state, 271, 6);
478 break;
479 case 2: /* only the diversity input */
480 dib8000_write_word(state, 270, 0);
481 dib8000_write_word(state, 271, 1);
482 break;
485 if (state->revision == 0x8002) {
486 tmp = dib8000_read_word(state, 903);
487 dib8000_write_word(state, 903, tmp & ~(1 << 3));
488 msleep(30);
489 dib8000_write_word(state, 903, tmp | (1 << 3));
491 return 0;
494 static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_power_mode mode)
496 /* by default everything is going to be powered off */
497 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
498 reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3,
499 reg_1280;
501 if (state->revision != 0x8090)
502 reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
503 else
504 reg_1280 = (dib8000_read_word(state, 1280) & 0x707f) | 0x8f80;
506 /* now, depending on the requested mode, we power on */
507 switch (mode) {
508 /* power up everything in the demod */
509 case DIB8000_POWER_ALL:
510 reg_774 = 0x0000;
511 reg_775 = 0x0000;
512 reg_776 = 0x0000;
513 reg_900 &= 0xfffc;
514 if (state->revision != 0x8090)
515 reg_1280 &= 0x00ff;
516 else
517 reg_1280 &= 0x707f;
518 break;
519 case DIB8000_POWER_INTERFACE_ONLY:
520 if (state->revision != 0x8090)
521 reg_1280 &= 0x00ff;
522 else
523 reg_1280 &= 0xfa7b;
524 break;
527 dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x", reg_774, reg_775, reg_776, reg_900, reg_1280);
528 dib8000_write_word(state, 774, reg_774);
529 dib8000_write_word(state, 775, reg_775);
530 dib8000_write_word(state, 776, reg_776);
531 dib8000_write_word(state, 900, reg_900);
532 dib8000_write_word(state, 1280, reg_1280);
535 static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no)
537 int ret = 0;
538 u16 reg, reg_907 = dib8000_read_word(state, 907);
539 u16 reg_908 = dib8000_read_word(state, 908);
541 switch (no) {
542 case DIBX000_SLOW_ADC_ON:
543 if (state->revision != 0x8090) {
544 reg_908 |= (1 << 1) | (1 << 0);
545 ret |= dib8000_write_word(state, 908, reg_908);
546 reg_908 &= ~(1 << 1);
547 } else {
548 reg = dib8000_read_word(state, 1925);
549 /* en_slowAdc = 1 & reset_sladc = 1 */
550 dib8000_write_word(state, 1925, reg |
551 (1<<4) | (1<<2));
553 /* read acces to make it works... strange ... */
554 reg = dib8000_read_word(state, 1925);
555 msleep(20);
556 /* en_slowAdc = 1 & reset_sladc = 0 */
557 dib8000_write_word(state, 1925, reg & ~(1<<4));
559 reg = dib8000_read_word(state, 921) & ~((0x3 << 14)
560 | (0x3 << 12));
561 /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ;
562 (Vin2 = Vcm) */
563 dib8000_write_word(state, 921, reg | (1 << 14)
564 | (3 << 12));
566 break;
568 case DIBX000_SLOW_ADC_OFF:
569 if (state->revision == 0x8090) {
570 reg = dib8000_read_word(state, 1925);
571 /* reset_sladc = 1 en_slowAdc = 0 */
572 dib8000_write_word(state, 1925,
573 (reg & ~(1<<2)) | (1<<4));
575 reg_908 |= (1 << 1) | (1 << 0);
576 break;
578 case DIBX000_ADC_ON:
579 reg_907 &= 0x0fff;
580 reg_908 &= 0x0003;
581 break;
583 case DIBX000_ADC_OFF: // leave the VBG voltage on
584 reg_907 |= (1 << 14) | (1 << 13) | (1 << 12);
585 reg_908 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
586 break;
588 case DIBX000_VBG_ENABLE:
589 reg_907 &= ~(1 << 15);
590 break;
592 case DIBX000_VBG_DISABLE:
593 reg_907 |= (1 << 15);
594 break;
596 default:
597 break;
600 ret |= dib8000_write_word(state, 907, reg_907);
601 ret |= dib8000_write_word(state, 908, reg_908);
603 return ret;
606 static int dib8000_set_bandwidth(struct dvb_frontend *fe, u32 bw)
608 struct dib8000_state *state = fe->demodulator_priv;
609 u32 timf;
611 if (bw == 0)
612 bw = 6000;
614 if (state->timf == 0) {
615 dprintk("using default timf");
616 timf = state->timf_default;
617 } else {
618 dprintk("using updated timf");
619 timf = state->timf;
622 dib8000_write_word(state, 29, (u16) ((timf >> 16) & 0xffff));
623 dib8000_write_word(state, 30, (u16) ((timf) & 0xffff));
625 return 0;
628 static int dib8000_sad_calib(struct dib8000_state *state)
630 u8 sad_sel = 3;
632 if (state->revision == 0x8090) {
633 dib8000_write_word(state, 922, (sad_sel << 2));
634 dib8000_write_word(state, 923, 2048);
636 dib8000_write_word(state, 922, (sad_sel << 2) | 0x1);
637 dib8000_write_word(state, 922, (sad_sel << 2));
638 } else {
639 /* internal */
640 dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
641 dib8000_write_word(state, 924, 776);
643 /* do the calibration */
644 dib8000_write_word(state, 923, (1 << 0));
645 dib8000_write_word(state, 923, (0 << 0));
648 msleep(1);
649 return 0;
652 int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
654 struct dib8000_state *state = fe->demodulator_priv;
655 if (value > 4095)
656 value = 4095;
657 state->wbd_ref = value;
658 return dib8000_write_word(state, 106, value);
660 EXPORT_SYMBOL(dib8000_set_wbd_ref);
662 static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
664 dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25);
665 if (state->revision != 0x8090) {
666 dib8000_write_word(state, 23,
667 (u16) (((bw->internal * 1000) >> 16) & 0xffff));
668 dib8000_write_word(state, 24,
669 (u16) ((bw->internal * 1000) & 0xffff));
670 } else {
671 dib8000_write_word(state, 23, (u16) (((bw->internal / 2 * 1000) >> 16) & 0xffff));
672 dib8000_write_word(state, 24,
673 (u16) ((bw->internal / 2 * 1000) & 0xffff));
675 dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff));
676 dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff));
677 dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003));
679 if (state->revision != 0x8090)
680 dib8000_write_word(state, 922, bw->sad_cfg);
683 static void dib8000_reset_pll(struct dib8000_state *state)
685 const struct dibx000_bandwidth_config *pll = state->cfg.pll;
686 u16 clk_cfg1, reg;
688 if (state->revision != 0x8090) {
689 dib8000_write_word(state, 901,
690 (pll->pll_prediv << 8) | (pll->pll_ratio << 0));
692 clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
693 (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) |
694 (1 << 3) | (pll->pll_range << 1) |
695 (pll->pll_reset << 0);
697 dib8000_write_word(state, 902, clk_cfg1);
698 clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
699 dib8000_write_word(state, 902, clk_cfg1);
701 dprintk("clk_cfg1: 0x%04x", clk_cfg1);
703 /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
704 if (state->cfg.pll->ADClkSrc == 0)
705 dib8000_write_word(state, 904,
706 (0 << 15) | (0 << 12) | (0 << 10) |
707 (pll->modulo << 8) |
708 (pll->ADClkSrc << 7) | (0 << 1));
709 else if (state->cfg.refclksel != 0)
710 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
711 ((state->cfg.refclksel & 0x3) << 10) |
712 (pll->modulo << 8) |
713 (pll->ADClkSrc << 7) | (0 << 1));
714 else
715 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
716 (3 << 10) | (pll->modulo << 8) |
717 (pll->ADClkSrc << 7) | (0 << 1));
718 } else {
719 dib8000_write_word(state, 1856, (!pll->pll_reset<<13) |
720 (pll->pll_range<<12) | (pll->pll_ratio<<6) |
721 (pll->pll_prediv));
723 reg = dib8000_read_word(state, 1857);
724 dib8000_write_word(state, 1857, reg|(!pll->pll_bypass<<15));
726 reg = dib8000_read_word(state, 1858); /* Force clk out pll /2 */
727 dib8000_write_word(state, 1858, reg | 1);
729 dib8000_write_word(state, 904, (pll->modulo << 8));
732 dib8000_reset_pll_common(state, pll);
735 int dib8000_update_pll(struct dvb_frontend *fe,
736 struct dibx000_bandwidth_config *pll, u32 bw, u8 ratio)
738 struct dib8000_state *state = fe->demodulator_priv;
739 u16 reg_1857, reg_1856 = dib8000_read_word(state, 1856);
740 u8 loopdiv, prediv, oldprediv = state->cfg.pll->pll_prediv ;
741 u32 internal, xtal;
743 /* get back old values */
744 prediv = reg_1856 & 0x3f;
745 loopdiv = (reg_1856 >> 6) & 0x3f;
747 if ((pll == NULL) || (pll->pll_prediv == prediv &&
748 pll->pll_ratio == loopdiv))
749 return -EINVAL;
751 dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, pll->pll_prediv, loopdiv, pll->pll_ratio);
752 if (state->revision == 0x8090) {
753 reg_1856 &= 0xf000;
754 reg_1857 = dib8000_read_word(state, 1857);
755 /* disable PLL */
756 dib8000_write_word(state, 1857, reg_1857 & ~(1 << 15));
758 dib8000_write_word(state, 1856, reg_1856 |
759 ((pll->pll_ratio & 0x3f) << 6) |
760 (pll->pll_prediv & 0x3f));
762 /* write new system clk into P_sec_len */
763 internal = dib8000_read32(state, 23) / 1000;
764 dprintk("Old Internal = %d", internal);
765 xtal = 2 * (internal / loopdiv) * prediv;
766 internal = 1000 * (xtal/pll->pll_prediv) * pll->pll_ratio;
767 dprintk("Xtal = %d , New Fmem = %d New Fdemod = %d, New Fsampling = %d", xtal, internal/1000, internal/2000, internal/8000);
768 dprintk("New Internal = %d", internal);
770 dib8000_write_word(state, 23,
771 (u16) (((internal / 2) >> 16) & 0xffff));
772 dib8000_write_word(state, 24, (u16) ((internal / 2) & 0xffff));
773 /* enable PLL */
774 dib8000_write_word(state, 1857, reg_1857 | (1 << 15));
776 while (((dib8000_read_word(state, 1856)>>15)&0x1) != 1)
777 dprintk("Waiting for PLL to lock");
779 /* verify */
780 reg_1856 = dib8000_read_word(state, 1856);
781 dprintk("PLL Updated with prediv = %d and loopdiv = %d",
782 reg_1856&0x3f, (reg_1856>>6)&0x3f);
783 } else {
784 if (bw != state->current_demod_bw) {
785 /** Bandwidth change => force PLL update **/
786 dprintk("PLL: Bandwidth Change %d MHz -> %d MHz (prediv: %d->%d)", state->current_demod_bw / 1000, bw / 1000, oldprediv, state->cfg.pll->pll_prediv);
788 if (state->cfg.pll->pll_prediv != oldprediv) {
789 /** Full PLL change only if prediv is changed **/
791 /** full update => bypass and reconfigure **/
792 dprintk("PLL: New Setting for %d MHz Bandwidth (prediv: %d, ratio: %d)", bw/1000, state->cfg.pll->pll_prediv, state->cfg.pll->pll_ratio);
793 dib8000_write_word(state, 902, dib8000_read_word(state, 902) | (1<<3)); /* bypass PLL */
794 dib8000_reset_pll(state);
795 dib8000_write_word(state, 898, 0x0004); /* sad */
796 } else
797 ratio = state->cfg.pll->pll_ratio;
799 state->current_demod_bw = bw;
802 if (ratio != 0) {
803 /** ratio update => only change ratio **/
804 dprintk("PLL: Update ratio (prediv: %d, ratio: %d)", state->cfg.pll->pll_prediv, ratio);
805 dib8000_write_word(state, 901, (state->cfg.pll->pll_prediv << 8) | (ratio << 0)); /* only the PLL ratio is updated. */
809 return 0;
811 EXPORT_SYMBOL(dib8000_update_pll);
814 static int dib8000_reset_gpio(struct dib8000_state *st)
816 /* reset the GPIOs */
817 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
818 dib8000_write_word(st, 1030, st->cfg.gpio_val);
820 /* TODO 782 is P_gpio_od */
822 dib8000_write_word(st, 1032, st->cfg.gpio_pwm_pos);
824 dib8000_write_word(st, 1037, st->cfg.pwm_freq_div);
825 return 0;
828 static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val)
830 st->cfg.gpio_dir = dib8000_read_word(st, 1029);
831 st->cfg.gpio_dir &= ~(1 << num); /* reset the direction bit */
832 st->cfg.gpio_dir |= (dir & 0x1) << num; /* set the new direction */
833 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
835 st->cfg.gpio_val = dib8000_read_word(st, 1030);
836 st->cfg.gpio_val &= ~(1 << num); /* reset the direction bit */
837 st->cfg.gpio_val |= (val & 0x01) << num; /* set the new value */
838 dib8000_write_word(st, 1030, st->cfg.gpio_val);
840 dprintk("gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val);
842 return 0;
845 int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
847 struct dib8000_state *state = fe->demodulator_priv;
848 return dib8000_cfg_gpio(state, num, dir, val);
851 EXPORT_SYMBOL(dib8000_set_gpio);
852 static const u16 dib8000_defaults[] = {
853 /* auto search configuration - lock0 by default waiting
854 * for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */
855 3, 7,
856 0x0004,
857 0x0400,
858 0x0814,
860 12, 11,
861 0x001b,
862 0x7740,
863 0x005b,
864 0x8d80,
865 0x01c9,
866 0xc380,
867 0x0000,
868 0x0080,
869 0x0000,
870 0x0090,
871 0x0001,
872 0xd4c0,
874 /*1, 32,
875 0x6680 // P_corm_thres Lock algorithms configuration */
877 11, 80, /* set ADC level to -16 */
878 (1 << 13) - 825 - 117,
879 (1 << 13) - 837 - 117,
880 (1 << 13) - 811 - 117,
881 (1 << 13) - 766 - 117,
882 (1 << 13) - 737 - 117,
883 (1 << 13) - 693 - 117,
884 (1 << 13) - 648 - 117,
885 (1 << 13) - 619 - 117,
886 (1 << 13) - 575 - 117,
887 (1 << 13) - 531 - 117,
888 (1 << 13) - 501 - 117,
890 4, 108,
896 1, 175,
897 0x0410,
898 1, 179,
899 8192, // P_fft_nb_to_cut
901 6, 181,
902 0x2800, // P_coff_corthres_ ( 2k 4k 8k ) 0x2800
903 0x2800,
904 0x2800,
905 0x2800, // P_coff_cpilthres_ ( 2k 4k 8k ) 0x2800
906 0x2800,
907 0x2800,
909 2, 193,
910 0x0666, // P_pha3_thres
911 0x0000, // P_cti_use_cpe, P_cti_use_prog
913 2, 205,
914 0x200f, // P_cspu_regul, P_cspu_win_cut
915 0x000f, // P_des_shift_work
917 5, 215,
918 0x023d, // P_adp_regul_cnt
919 0x00a4, // P_adp_noise_cnt
920 0x00a4, // P_adp_regul_ext
921 0x7ff0, // P_adp_noise_ext
922 0x3ccc, // P_adp_fil
924 1, 230,
925 0x0000, // P_2d_byp_ti_num
927 1, 263,
928 0x800, //P_equal_thres_wgn
930 1, 268,
931 (2 << 9) | 39, // P_equal_ctrl_synchro, P_equal_speedmode
933 1, 270,
934 0x0001, // P_div_lock0_wait
935 1, 285,
936 0x0020, //p_fec_
937 1, 299,
938 0x0062, /* P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard */
940 1, 338,
941 (1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1
942 (1 << 10) |
943 (0 << 9) | /* P_ctrl_pre_freq_inh=0 */
944 (3 << 5) | /* P_ctrl_pre_freq_step=3 */
945 (1 << 0), /* P_pre_freq_win_len=1 */
950 static u16 dib8000_identify(struct i2c_device *client)
952 u16 value;
954 //because of glitches sometimes
955 value = dib8000_i2c_read16(client, 896);
957 if ((value = dib8000_i2c_read16(client, 896)) != 0x01b3) {
958 dprintk("wrong Vendor ID (read=0x%x)", value);
959 return 0;
962 value = dib8000_i2c_read16(client, 897);
963 if (value != 0x8000 && value != 0x8001 &&
964 value != 0x8002 && value != 0x8090) {
965 dprintk("wrong Device ID (%x)", value);
966 return 0;
969 switch (value) {
970 case 0x8000:
971 dprintk("found DiB8000A");
972 break;
973 case 0x8001:
974 dprintk("found DiB8000B");
975 break;
976 case 0x8002:
977 dprintk("found DiB8000C");
978 break;
979 case 0x8090:
980 dprintk("found DiB8096P");
981 break;
983 return value;
986 static int dib8000_reset(struct dvb_frontend *fe)
988 struct dib8000_state *state = fe->demodulator_priv;
990 if ((state->revision = dib8000_identify(&state->i2c)) == 0)
991 return -EINVAL;
993 /* sram lead in, rdy */
994 if (state->revision != 0x8090)
995 dib8000_write_word(state, 1287, 0x0003);
997 if (state->revision == 0x8000)
998 dprintk("error : dib8000 MA not supported");
1000 dibx000_reset_i2c_master(&state->i2c_master);
1002 dib8000_set_power_mode(state, DIB8000_POWER_ALL);
1004 /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
1005 dib8000_set_adc_state(state, DIBX000_ADC_OFF);
1007 /* restart all parts */
1008 dib8000_write_word(state, 770, 0xffff);
1009 dib8000_write_word(state, 771, 0xffff);
1010 dib8000_write_word(state, 772, 0xfffc);
1011 if (state->revision == 0x8090)
1012 dib8000_write_word(state, 1280, 0x0045);
1013 else
1014 dib8000_write_word(state, 1280, 0x004d);
1015 dib8000_write_word(state, 1281, 0x000c);
1017 dib8000_write_word(state, 770, 0x0000);
1018 dib8000_write_word(state, 771, 0x0000);
1019 dib8000_write_word(state, 772, 0x0000);
1020 dib8000_write_word(state, 898, 0x0004); // sad
1021 dib8000_write_word(state, 1280, 0x0000);
1022 dib8000_write_word(state, 1281, 0x0000);
1024 /* drives */
1025 if (state->revision != 0x8090) {
1026 if (state->cfg.drives)
1027 dib8000_write_word(state, 906, state->cfg.drives);
1028 else {
1029 dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.");
1030 /* min drive SDRAM - not optimal - adjust */
1031 dib8000_write_word(state, 906, 0x2d98);
1035 dib8000_reset_pll(state);
1036 if (state->revision != 0x8090)
1037 dib8000_write_word(state, 898, 0x0004);
1039 if (dib8000_reset_gpio(state) != 0)
1040 dprintk("GPIO reset was not successful.");
1042 if ((state->revision != 0x8090) &&
1043 (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0))
1044 dprintk("OUTPUT_MODE could not be resetted.");
1046 state->current_agc = NULL;
1048 // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
1049 /* P_iqc_ca2 = 0; P_iqc_impnc_on = 0; P_iqc_mode = 0; */
1050 if (state->cfg.pll->ifreq == 0)
1051 dib8000_write_word(state, 40, 0x0755); /* P_iqc_corr_inh = 0 enable IQcorr block */
1052 else
1053 dib8000_write_word(state, 40, 0x1f55); /* P_iqc_corr_inh = 1 disable IQcorr block */
1056 u16 l = 0, r;
1057 const u16 *n;
1058 n = dib8000_defaults;
1059 l = *n++;
1060 while (l) {
1061 r = *n++;
1062 do {
1063 dib8000_write_word(state, r, *n++);
1064 r++;
1065 } while (--l);
1066 l = *n++;
1070 state->isdbt_cfg_loaded = 0;
1072 //div_cfg override for special configs
1073 if ((state->revision != 8090) && (state->cfg.div_cfg != 0))
1074 dib8000_write_word(state, 903, state->cfg.div_cfg);
1076 /* unforce divstr regardless whether i2c enumeration was done or not */
1077 dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1));
1079 dib8000_set_bandwidth(fe, 6000);
1081 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
1082 dib8000_sad_calib(state);
1083 if (state->revision != 0x8090)
1084 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
1086 /* ber_rs_len = 3 */
1087 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5));
1089 dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY);
1091 return 0;
1094 static void dib8000_restart_agc(struct dib8000_state *state)
1096 // P_restart_iqc & P_restart_agc
1097 dib8000_write_word(state, 770, 0x0a00);
1098 dib8000_write_word(state, 770, 0x0000);
1101 static int dib8000_update_lna(struct dib8000_state *state)
1103 u16 dyn_gain;
1105 if (state->cfg.update_lna) {
1106 // read dyn_gain here (because it is demod-dependent and not tuner)
1107 dyn_gain = dib8000_read_word(state, 390);
1109 if (state->cfg.update_lna(state->fe[0], dyn_gain)) {
1110 dib8000_restart_agc(state);
1111 return 1;
1114 return 0;
1117 static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
1119 struct dibx000_agc_config *agc = NULL;
1120 int i;
1121 u16 reg;
1123 if (state->current_band == band && state->current_agc != NULL)
1124 return 0;
1125 state->current_band = band;
1127 for (i = 0; i < state->cfg.agc_config_count; i++)
1128 if (state->cfg.agc[i].band_caps & band) {
1129 agc = &state->cfg.agc[i];
1130 break;
1133 if (agc == NULL) {
1134 dprintk("no valid AGC configuration found for band 0x%02x", band);
1135 return -EINVAL;
1138 state->current_agc = agc;
1140 /* AGC */
1141 dib8000_write_word(state, 76, agc->setup);
1142 dib8000_write_word(state, 77, agc->inv_gain);
1143 dib8000_write_word(state, 78, agc->time_stabiliz);
1144 dib8000_write_word(state, 101, (agc->alpha_level << 12) | agc->thlock);
1146 // Demod AGC loop configuration
1147 dib8000_write_word(state, 102, (agc->alpha_mant << 5) | agc->alpha_exp);
1148 dib8000_write_word(state, 103, (agc->beta_mant << 6) | agc->beta_exp);
1150 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
1151 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
1153 /* AGC continued */
1154 if (state->wbd_ref != 0)
1155 dib8000_write_word(state, 106, state->wbd_ref);
1156 else // use default
1157 dib8000_write_word(state, 106, agc->wbd_ref);
1159 if (state->revision == 0x8090) {
1160 reg = dib8000_read_word(state, 922) & (0x3 << 2);
1161 dib8000_write_word(state, 922, reg | (agc->wbd_sel << 2));
1164 dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
1165 dib8000_write_word(state, 108, agc->agc1_max);
1166 dib8000_write_word(state, 109, agc->agc1_min);
1167 dib8000_write_word(state, 110, agc->agc2_max);
1168 dib8000_write_word(state, 111, agc->agc2_min);
1169 dib8000_write_word(state, 112, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
1170 dib8000_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
1171 dib8000_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
1172 dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
1174 dib8000_write_word(state, 75, agc->agc1_pt3);
1175 if (state->revision != 0x8090)
1176 dib8000_write_word(state, 923,
1177 (dib8000_read_word(state, 923) & 0xffe3) |
1178 (agc->wbd_inv << 4) | (agc->wbd_sel << 2));
1180 return 0;
1183 void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
1185 struct dib8000_state *state = fe->demodulator_priv;
1186 dib8000_set_adc_state(state, DIBX000_ADC_ON);
1187 dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000)));
1189 EXPORT_SYMBOL(dib8000_pwm_agc_reset);
1191 static int dib8000_agc_soft_split(struct dib8000_state *state)
1193 u16 agc, split_offset;
1195 if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
1196 return FE_CALLBACK_TIME_NEVER;
1198 // n_agc_global
1199 agc = dib8000_read_word(state, 390);
1201 if (agc > state->current_agc->split.min_thres)
1202 split_offset = state->current_agc->split.min;
1203 else if (agc < state->current_agc->split.max_thres)
1204 split_offset = state->current_agc->split.max;
1205 else
1206 split_offset = state->current_agc->split.max *
1207 (agc - state->current_agc->split.min_thres) /
1208 (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
1210 dprintk("AGC split_offset: %d", split_offset);
1212 // P_agc_force_split and P_agc_split_offset
1213 dib8000_write_word(state, 107, (dib8000_read_word(state, 107) & 0xff00) | split_offset);
1214 return 5000;
1217 static int dib8000_agc_startup(struct dvb_frontend *fe)
1219 struct dib8000_state *state = fe->demodulator_priv;
1220 enum frontend_tune_state *tune_state = &state->tune_state;
1221 int ret = 0;
1222 u16 reg, upd_demod_gain_period = 0x8000;
1224 switch (*tune_state) {
1225 case CT_AGC_START:
1226 // set power-up level: interf+analog+AGC
1228 if (state->revision != 0x8090)
1229 dib8000_set_adc_state(state, DIBX000_ADC_ON);
1230 else {
1231 dib8000_set_power_mode(state, DIB8000_POWER_ALL);
1233 reg = dib8000_read_word(state, 1947)&0xff00;
1234 dib8000_write_word(state, 1946,
1235 upd_demod_gain_period & 0xFFFF);
1236 /* bit 14 = enDemodGain */
1237 dib8000_write_word(state, 1947, reg | (1<<14) |
1238 ((upd_demod_gain_period >> 16) & 0xFF));
1240 /* enable adc i & q */
1241 reg = dib8000_read_word(state, 1920);
1242 dib8000_write_word(state, 1920, (reg | 0x3) &
1243 (~(1 << 7)));
1246 if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) {
1247 *tune_state = CT_AGC_STOP;
1248 state->status = FE_STATUS_TUNE_FAILED;
1249 break;
1252 ret = 70;
1253 *tune_state = CT_AGC_STEP_0;
1254 break;
1256 case CT_AGC_STEP_0:
1257 //AGC initialization
1258 if (state->cfg.agc_control)
1259 state->cfg.agc_control(fe, 1);
1261 dib8000_restart_agc(state);
1263 // wait AGC rough lock time
1264 ret = 50;
1265 *tune_state = CT_AGC_STEP_1;
1266 break;
1268 case CT_AGC_STEP_1:
1269 // wait AGC accurate lock time
1270 ret = 70;
1272 if (dib8000_update_lna(state))
1273 // wait only AGC rough lock time
1274 ret = 50;
1275 else
1276 *tune_state = CT_AGC_STEP_2;
1277 break;
1279 case CT_AGC_STEP_2:
1280 dib8000_agc_soft_split(state);
1282 if (state->cfg.agc_control)
1283 state->cfg.agc_control(fe, 0);
1285 *tune_state = CT_AGC_STOP;
1286 break;
1287 default:
1288 ret = dib8000_agc_soft_split(state);
1289 break;
1291 return ret;
1295 static void dib8096p_host_bus_drive(struct dib8000_state *state, u8 drive)
1297 u16 reg;
1299 drive &= 0x7;
1301 /* drive host bus 2, 3, 4 */
1302 reg = dib8000_read_word(state, 1798) &
1303 ~(0x7 | (0x7 << 6) | (0x7 << 12));
1304 reg |= (drive<<12) | (drive<<6) | drive;
1305 dib8000_write_word(state, 1798, reg);
1307 /* drive host bus 5,6 */
1308 reg = dib8000_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
1309 reg |= (drive<<8) | (drive<<2);
1310 dib8000_write_word(state, 1799, reg);
1312 /* drive host bus 7, 8, 9 */
1313 reg = dib8000_read_word(state, 1800) &
1314 ~(0x7 | (0x7 << 6) | (0x7 << 12));
1315 reg |= (drive<<12) | (drive<<6) | drive;
1316 dib8000_write_word(state, 1800, reg);
1318 /* drive host bus 10, 11 */
1319 reg = dib8000_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
1320 reg |= (drive<<8) | (drive<<2);
1321 dib8000_write_word(state, 1801, reg);
1323 /* drive host bus 12, 13, 14 */
1324 reg = dib8000_read_word(state, 1802) &
1325 ~(0x7 | (0x7 << 6) | (0x7 << 12));
1326 reg |= (drive<<12) | (drive<<6) | drive;
1327 dib8000_write_word(state, 1802, reg);
1330 static u32 dib8096p_calcSyncFreq(u32 P_Kin, u32 P_Kout,
1331 u32 insertExtSynchro, u32 syncSize)
1333 u32 quantif = 3;
1334 u32 nom = (insertExtSynchro * P_Kin+syncSize);
1335 u32 denom = P_Kout;
1336 u32 syncFreq = ((nom << quantif) / denom);
1338 if ((syncFreq & ((1 << quantif) - 1)) != 0)
1339 syncFreq = (syncFreq >> quantif) + 1;
1340 else
1341 syncFreq = (syncFreq >> quantif);
1343 if (syncFreq != 0)
1344 syncFreq = syncFreq - 1;
1346 return syncFreq;
1349 static void dib8096p_cfg_DibTx(struct dib8000_state *state, u32 P_Kin,
1350 u32 P_Kout, u32 insertExtSynchro, u32 synchroMode,
1351 u32 syncWord, u32 syncSize)
1353 dprintk("Configure DibStream Tx");
1355 dib8000_write_word(state, 1615, 1);
1356 dib8000_write_word(state, 1603, P_Kin);
1357 dib8000_write_word(state, 1605, P_Kout);
1358 dib8000_write_word(state, 1606, insertExtSynchro);
1359 dib8000_write_word(state, 1608, synchroMode);
1360 dib8000_write_word(state, 1609, (syncWord >> 16) & 0xffff);
1361 dib8000_write_word(state, 1610, syncWord & 0xffff);
1362 dib8000_write_word(state, 1612, syncSize);
1363 dib8000_write_word(state, 1615, 0);
1366 static void dib8096p_cfg_DibRx(struct dib8000_state *state, u32 P_Kin,
1367 u32 P_Kout, u32 synchroMode, u32 insertExtSynchro,
1368 u32 syncWord, u32 syncSize, u32 dataOutRate)
1370 u32 syncFreq;
1372 dprintk("Configure DibStream Rx synchroMode = %d", synchroMode);
1374 if ((P_Kin != 0) && (P_Kout != 0)) {
1375 syncFreq = dib8096p_calcSyncFreq(P_Kin, P_Kout,
1376 insertExtSynchro, syncSize);
1377 dib8000_write_word(state, 1542, syncFreq);
1380 dib8000_write_word(state, 1554, 1);
1381 dib8000_write_word(state, 1536, P_Kin);
1382 dib8000_write_word(state, 1537, P_Kout);
1383 dib8000_write_word(state, 1539, synchroMode);
1384 dib8000_write_word(state, 1540, (syncWord >> 16) & 0xffff);
1385 dib8000_write_word(state, 1541, syncWord & 0xffff);
1386 dib8000_write_word(state, 1543, syncSize);
1387 dib8000_write_word(state, 1544, dataOutRate);
1388 dib8000_write_word(state, 1554, 0);
1391 static void dib8096p_enMpegMux(struct dib8000_state *state, int onoff)
1393 u16 reg_1287;
1395 reg_1287 = dib8000_read_word(state, 1287);
1397 switch (onoff) {
1398 case 1:
1399 reg_1287 &= ~(1 << 8);
1400 break;
1401 case 0:
1402 reg_1287 |= (1 << 8);
1403 break;
1406 dib8000_write_word(state, 1287, reg_1287);
1409 static void dib8096p_configMpegMux(struct dib8000_state *state,
1410 u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
1412 u16 reg_1287;
1414 dprintk("Enable Mpeg mux");
1416 dib8096p_enMpegMux(state, 0);
1418 /* If the input mode is MPEG do not divide the serial clock */
1419 if ((enSerialMode == 1) && (state->input_mode_mpeg == 1))
1420 enSerialClkDiv2 = 0;
1422 reg_1287 = ((pulseWidth & 0x1f) << 3) |
1423 ((enSerialMode & 0x1) << 2) | (enSerialClkDiv2 & 0x1);
1424 dib8000_write_word(state, 1287, reg_1287);
1426 dib8096p_enMpegMux(state, 1);
1429 static void dib8096p_setDibTxMux(struct dib8000_state *state, int mode)
1431 u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 7);
1433 switch (mode) {
1434 case MPEG_ON_DIBTX:
1435 dprintk("SET MPEG ON DIBSTREAM TX");
1436 dib8096p_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
1437 reg_1288 |= (1 << 9); break;
1438 case DIV_ON_DIBTX:
1439 dprintk("SET DIV_OUT ON DIBSTREAM TX");
1440 dib8096p_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
1441 reg_1288 |= (1 << 8); break;
1442 case ADC_ON_DIBTX:
1443 dprintk("SET ADC_OUT ON DIBSTREAM TX");
1444 dib8096p_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
1445 reg_1288 |= (1 << 7); break;
1446 default:
1447 break;
1449 dib8000_write_word(state, 1288, reg_1288);
1452 static void dib8096p_setHostBusMux(struct dib8000_state *state, int mode)
1454 u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 4);
1456 switch (mode) {
1457 case DEMOUT_ON_HOSTBUS:
1458 dprintk("SET DEM OUT OLD INTERF ON HOST BUS");
1459 dib8096p_enMpegMux(state, 0);
1460 reg_1288 |= (1 << 6);
1461 break;
1462 case DIBTX_ON_HOSTBUS:
1463 dprintk("SET DIBSTREAM TX ON HOST BUS");
1464 dib8096p_enMpegMux(state, 0);
1465 reg_1288 |= (1 << 5);
1466 break;
1467 case MPEG_ON_HOSTBUS:
1468 dprintk("SET MPEG MUX ON HOST BUS");
1469 reg_1288 |= (1 << 4);
1470 break;
1471 default:
1472 break;
1474 dib8000_write_word(state, 1288, reg_1288);
1477 static int dib8096p_set_diversity_in(struct dvb_frontend *fe, int onoff)
1479 struct dib8000_state *state = fe->demodulator_priv;
1480 u16 reg_1287;
1482 switch (onoff) {
1483 case 0: /* only use the internal way - not the diversity input */
1484 dprintk("%s mode OFF : by default Enable Mpeg INPUT",
1485 __func__);
1486 /* outputRate = 8 */
1487 dib8096p_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0);
1489 /* Do not divide the serial clock of MPEG MUX in
1490 SERIAL MODE in case input mode MPEG is used */
1491 reg_1287 = dib8000_read_word(state, 1287);
1492 /* enSerialClkDiv2 == 1 ? */
1493 if ((reg_1287 & 0x1) == 1) {
1494 /* force enSerialClkDiv2 = 0 */
1495 reg_1287 &= ~0x1;
1496 dib8000_write_word(state, 1287, reg_1287);
1498 state->input_mode_mpeg = 1;
1499 break;
1500 case 1: /* both ways */
1501 case 2: /* only the diversity input */
1502 dprintk("%s ON : Enable diversity INPUT", __func__);
1503 dib8096p_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
1504 state->input_mode_mpeg = 0;
1505 break;
1508 dib8000_set_diversity_in(state->fe[0], onoff);
1509 return 0;
1512 static int dib8096p_set_output_mode(struct dvb_frontend *fe, int mode)
1514 struct dib8000_state *state = fe->demodulator_priv;
1515 u16 outreg, smo_mode, fifo_threshold;
1516 u8 prefer_mpeg_mux_use = 1;
1517 int ret = 0;
1519 state->output_mode = mode;
1520 dib8096p_host_bus_drive(state, 1);
1522 fifo_threshold = 1792;
1523 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
1524 outreg = dib8000_read_word(state, 1286) &
1525 ~((1 << 10) | (0x7 << 6) | (1 << 1));
1527 switch (mode) {
1528 case OUTMODE_HIGH_Z:
1529 outreg = 0;
1530 break;
1532 case OUTMODE_MPEG2_SERIAL:
1533 if (prefer_mpeg_mux_use) {
1534 dprintk("dib8096P setting output mode TS_SERIAL using Mpeg Mux");
1535 dib8096p_configMpegMux(state, 3, 1, 1);
1536 dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS);
1537 } else {/* Use Smooth block */
1538 dprintk("dib8096P setting output mode TS_SERIAL using Smooth bloc");
1539 dib8096p_setHostBusMux(state,
1540 DEMOUT_ON_HOSTBUS);
1541 outreg |= (2 << 6) | (0 << 1);
1543 break;
1545 case OUTMODE_MPEG2_PAR_GATED_CLK:
1546 if (prefer_mpeg_mux_use) {
1547 dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Mpeg Mux");
1548 dib8096p_configMpegMux(state, 2, 0, 0);
1549 dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS);
1550 } else { /* Use Smooth block */
1551 dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Smooth block");
1552 dib8096p_setHostBusMux(state,
1553 DEMOUT_ON_HOSTBUS);
1554 outreg |= (0 << 6);
1556 break;
1558 case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */
1559 dprintk("dib8096P setting output mode TS_PARALLEL_CONT using Smooth block");
1560 dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
1561 outreg |= (1 << 6);
1562 break;
1564 case OUTMODE_MPEG2_FIFO:
1565 /* Using Smooth block because not supported
1566 by new Mpeg Mux bloc */
1567 dprintk("dib8096P setting output mode TS_FIFO using Smooth block");
1568 dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
1569 outreg |= (5 << 6);
1570 smo_mode |= (3 << 1);
1571 fifo_threshold = 512;
1572 break;
1574 case OUTMODE_DIVERSITY:
1575 dprintk("dib8096P setting output mode MODE_DIVERSITY");
1576 dib8096p_setDibTxMux(state, DIV_ON_DIBTX);
1577 dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
1578 break;
1580 case OUTMODE_ANALOG_ADC:
1581 dprintk("dib8096P setting output mode MODE_ANALOG_ADC");
1582 dib8096p_setDibTxMux(state, ADC_ON_DIBTX);
1583 dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
1584 break;
1587 if (mode != OUTMODE_HIGH_Z)
1588 outreg |= (1<<10);
1590 dprintk("output_mpeg2_in_188_bytes = %d",
1591 state->cfg.output_mpeg2_in_188_bytes);
1592 if (state->cfg.output_mpeg2_in_188_bytes)
1593 smo_mode |= (1 << 5);
1595 ret |= dib8000_write_word(state, 299, smo_mode);
1596 /* synchronous fread */
1597 ret |= dib8000_write_word(state, 299 + 1, fifo_threshold);
1598 ret |= dib8000_write_word(state, 1286, outreg);
1600 return ret;
1603 static int map_addr_to_serpar_number(struct i2c_msg *msg)
1605 if (msg->buf[0] <= 15)
1606 msg->buf[0] -= 1;
1607 else if (msg->buf[0] == 17)
1608 msg->buf[0] = 15;
1609 else if (msg->buf[0] == 16)
1610 msg->buf[0] = 17;
1611 else if (msg->buf[0] == 19)
1612 msg->buf[0] = 16;
1613 else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
1614 msg->buf[0] -= 3;
1615 else if (msg->buf[0] == 28)
1616 msg->buf[0] = 23;
1617 else if (msg->buf[0] == 99)
1618 msg->buf[0] = 99;
1619 else
1620 return -EINVAL;
1621 return 0;
1624 static int dib8096p_tuner_write_serpar(struct i2c_adapter *i2c_adap,
1625 struct i2c_msg msg[], int num)
1627 struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1628 u8 n_overflow = 1;
1629 u16 i = 1000;
1630 u16 serpar_num = msg[0].buf[0];
1632 while (n_overflow == 1 && i) {
1633 n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1;
1634 i--;
1635 if (i == 0)
1636 dprintk("Tuner ITF: write busy (overflow)");
1638 dib8000_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
1639 dib8000_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
1641 return num;
1644 static int dib8096p_tuner_read_serpar(struct i2c_adapter *i2c_adap,
1645 struct i2c_msg msg[], int num)
1647 struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1648 u8 n_overflow = 1, n_empty = 1;
1649 u16 i = 1000;
1650 u16 serpar_num = msg[0].buf[0];
1651 u16 read_word;
1653 while (n_overflow == 1 && i) {
1654 n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1;
1655 i--;
1656 if (i == 0)
1657 dprintk("TunerITF: read busy (overflow)");
1659 dib8000_write_word(state, 1985, (0<<6) | (serpar_num&0x3f));
1661 i = 1000;
1662 while (n_empty == 1 && i) {
1663 n_empty = dib8000_read_word(state, 1984)&0x1;
1664 i--;
1665 if (i == 0)
1666 dprintk("TunerITF: read busy (empty)");
1669 read_word = dib8000_read_word(state, 1987);
1670 msg[1].buf[0] = (read_word >> 8) & 0xff;
1671 msg[1].buf[1] = (read_word) & 0xff;
1673 return num;
1676 static int dib8096p_tuner_rw_serpar(struct i2c_adapter *i2c_adap,
1677 struct i2c_msg msg[], int num)
1679 if (map_addr_to_serpar_number(&msg[0]) == 0) {
1680 if (num == 1) /* write */
1681 return dib8096p_tuner_write_serpar(i2c_adap, msg, 1);
1682 else /* read */
1683 return dib8096p_tuner_read_serpar(i2c_adap, msg, 2);
1685 return num;
1688 static int dib8096p_rw_on_apb(struct i2c_adapter *i2c_adap,
1689 struct i2c_msg msg[], int num, u16 apb_address)
1691 struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1692 u16 word;
1694 if (num == 1) { /* write */
1695 dib8000_write_word(state, apb_address,
1696 ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
1697 } else {
1698 word = dib8000_read_word(state, apb_address);
1699 msg[1].buf[0] = (word >> 8) & 0xff;
1700 msg[1].buf[1] = (word) & 0xff;
1702 return num;
1705 static int dib8096p_tuner_xfer(struct i2c_adapter *i2c_adap,
1706 struct i2c_msg msg[], int num)
1708 struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1709 u16 apb_address = 0, word;
1710 int i = 0;
1712 switch (msg[0].buf[0]) {
1713 case 0x12:
1714 apb_address = 1920;
1715 break;
1716 case 0x14:
1717 apb_address = 1921;
1718 break;
1719 case 0x24:
1720 apb_address = 1922;
1721 break;
1722 case 0x1a:
1723 apb_address = 1923;
1724 break;
1725 case 0x22:
1726 apb_address = 1924;
1727 break;
1728 case 0x33:
1729 apb_address = 1926;
1730 break;
1731 case 0x34:
1732 apb_address = 1927;
1733 break;
1734 case 0x35:
1735 apb_address = 1928;
1736 break;
1737 case 0x36:
1738 apb_address = 1929;
1739 break;
1740 case 0x37:
1741 apb_address = 1930;
1742 break;
1743 case 0x38:
1744 apb_address = 1931;
1745 break;
1746 case 0x39:
1747 apb_address = 1932;
1748 break;
1749 case 0x2a:
1750 apb_address = 1935;
1751 break;
1752 case 0x2b:
1753 apb_address = 1936;
1754 break;
1755 case 0x2c:
1756 apb_address = 1937;
1757 break;
1758 case 0x2d:
1759 apb_address = 1938;
1760 break;
1761 case 0x2e:
1762 apb_address = 1939;
1763 break;
1764 case 0x2f:
1765 apb_address = 1940;
1766 break;
1767 case 0x30:
1768 apb_address = 1941;
1769 break;
1770 case 0x31:
1771 apb_address = 1942;
1772 break;
1773 case 0x32:
1774 apb_address = 1943;
1775 break;
1776 case 0x3e:
1777 apb_address = 1944;
1778 break;
1779 case 0x3f:
1780 apb_address = 1945;
1781 break;
1782 case 0x40:
1783 apb_address = 1948;
1784 break;
1785 case 0x25:
1786 apb_address = 936;
1787 break;
1788 case 0x26:
1789 apb_address = 937;
1790 break;
1791 case 0x27:
1792 apb_address = 938;
1793 break;
1794 case 0x28:
1795 apb_address = 939;
1796 break;
1797 case 0x1d:
1798 /* get sad sel request */
1799 i = ((dib8000_read_word(state, 921) >> 12)&0x3);
1800 word = dib8000_read_word(state, 924+i);
1801 msg[1].buf[0] = (word >> 8) & 0xff;
1802 msg[1].buf[1] = (word) & 0xff;
1803 return num;
1804 case 0x1f:
1805 if (num == 1) { /* write */
1806 word = (u16) ((msg[0].buf[1] << 8) |
1807 msg[0].buf[2]);
1808 /* in the VGAMODE Sel are located on bit 0/1 */
1809 word &= 0x3;
1810 word = (dib8000_read_word(state, 921) &
1811 ~(3<<12)) | (word<<12);
1812 /* Set the proper input */
1813 dib8000_write_word(state, 921, word);
1814 return num;
1818 if (apb_address != 0) /* R/W acces via APB */
1819 return dib8096p_rw_on_apb(i2c_adap, msg, num, apb_address);
1820 else /* R/W access via SERPAR */
1821 return dib8096p_tuner_rw_serpar(i2c_adap, msg, num);
1823 return 0;
1826 static u32 dib8096p_i2c_func(struct i2c_adapter *adapter)
1828 return I2C_FUNC_I2C;
1831 static struct i2c_algorithm dib8096p_tuner_xfer_algo = {
1832 .master_xfer = dib8096p_tuner_xfer,
1833 .functionality = dib8096p_i2c_func,
1836 struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe)
1838 struct dib8000_state *st = fe->demodulator_priv;
1839 return &st->dib8096p_tuner_adap;
1841 EXPORT_SYMBOL(dib8096p_get_i2c_tuner);
1843 int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff)
1845 struct dib8000_state *state = fe->demodulator_priv;
1846 u16 en_cur_state;
1848 dprintk("sleep dib8096p: %d", onoff);
1850 en_cur_state = dib8000_read_word(state, 1922);
1852 /* LNAs and MIX are ON and therefore it is a valid configuration */
1853 if (en_cur_state > 0xff)
1854 state->tuner_enable = en_cur_state ;
1856 if (onoff)
1857 en_cur_state &= 0x00ff;
1858 else {
1859 if (state->tuner_enable != 0)
1860 en_cur_state = state->tuner_enable;
1863 dib8000_write_word(state, 1922, en_cur_state);
1865 return 0;
1867 EXPORT_SYMBOL(dib8096p_tuner_sleep);
1869 static const s32 lut_1000ln_mant[] =
1871 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600
1874 s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
1876 struct dib8000_state *state = fe->demodulator_priv;
1877 u32 ix = 0, tmp_val = 0, exp = 0, mant = 0;
1878 s32 val;
1880 val = dib8000_read32(state, 384);
1881 if (mode) {
1882 tmp_val = val;
1883 while (tmp_val >>= 1)
1884 exp++;
1885 mant = (val * 1000 / (1<<exp));
1886 ix = (u8)((mant-1000)/100); /* index of the LUT */
1887 val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908);
1888 val = (val*256)/1000;
1890 return val;
1892 EXPORT_SYMBOL(dib8000_get_adc_power);
1894 int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ)
1896 struct dib8000_state *state = fe->demodulator_priv;
1897 int val = 0;
1899 switch (IQ) {
1900 case 1:
1901 val = dib8000_read_word(state, 403);
1902 break;
1903 case 0:
1904 val = dib8000_read_word(state, 404);
1905 break;
1907 if (val & 0x200)
1908 val -= 1024;
1910 return val;
1912 EXPORT_SYMBOL(dib8090p_get_dc_power);
1914 static void dib8000_update_timf(struct dib8000_state *state)
1916 u32 timf = state->timf = dib8000_read32(state, 435);
1918 dib8000_write_word(state, 29, (u16) (timf >> 16));
1919 dib8000_write_word(state, 30, (u16) (timf & 0xffff));
1920 dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
1923 u32 dib8000_ctrl_timf(struct dvb_frontend *fe, uint8_t op, uint32_t timf)
1925 struct dib8000_state *state = fe->demodulator_priv;
1927 switch (op) {
1928 case DEMOD_TIMF_SET:
1929 state->timf = timf;
1930 break;
1931 case DEMOD_TIMF_UPDATE:
1932 dib8000_update_timf(state);
1933 break;
1934 case DEMOD_TIMF_GET:
1935 break;
1937 dib8000_set_bandwidth(state->fe[0], 6000);
1939 return state->timf;
1941 EXPORT_SYMBOL(dib8000_ctrl_timf);
1943 static const u16 adc_target_16dB[11] = {
1944 (1 << 13) - 825 - 117,
1945 (1 << 13) - 837 - 117,
1946 (1 << 13) - 811 - 117,
1947 (1 << 13) - 766 - 117,
1948 (1 << 13) - 737 - 117,
1949 (1 << 13) - 693 - 117,
1950 (1 << 13) - 648 - 117,
1951 (1 << 13) - 619 - 117,
1952 (1 << 13) - 575 - 117,
1953 (1 << 13) - 531 - 117,
1954 (1 << 13) - 501 - 117
1956 static const u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
1958 static u16 dib8000_set_layer(struct dib8000_state *state, u8 layer_index, u16 max_constellation)
1960 u8 cr, constellation, time_intlv;
1961 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
1963 switch (c->layer[layer_index].modulation) {
1964 case DQPSK:
1965 constellation = 0;
1966 break;
1967 case QPSK:
1968 constellation = 1;
1969 break;
1970 case QAM_16:
1971 constellation = 2;
1972 break;
1973 case QAM_64:
1974 default:
1975 constellation = 3;
1976 break;
1979 switch (c->layer[layer_index].fec) {
1980 case FEC_1_2:
1981 cr = 1;
1982 break;
1983 case FEC_2_3:
1984 cr = 2;
1985 break;
1986 case FEC_3_4:
1987 cr = 3;
1988 break;
1989 case FEC_5_6:
1990 cr = 5;
1991 break;
1992 case FEC_7_8:
1993 default:
1994 cr = 7;
1995 break;
1998 if ((c->layer[layer_index].interleaving > 0) && ((c->layer[layer_index].interleaving <= 3) || (c->layer[layer_index].interleaving == 4 && c->isdbt_sb_mode == 1)))
1999 time_intlv = c->layer[layer_index].interleaving;
2000 else
2001 time_intlv = 0;
2003 dib8000_write_word(state, 2 + layer_index, (constellation << 10) | ((c->layer[layer_index].segment_count & 0xf) << 6) | (cr << 3) | time_intlv);
2004 if (c->layer[layer_index].segment_count > 0) {
2005 switch (max_constellation) {
2006 case DQPSK:
2007 case QPSK:
2008 if (c->layer[layer_index].modulation == QAM_16 || c->layer[layer_index].modulation == QAM_64)
2009 max_constellation = c->layer[layer_index].modulation;
2010 break;
2011 case QAM_16:
2012 if (c->layer[layer_index].modulation == QAM_64)
2013 max_constellation = c->layer[layer_index].modulation;
2014 break;
2018 return max_constellation;
2021 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 */
2022 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 */
2023 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 */
2024 static u16 dib8000_adp_fine_tune(struct dib8000_state *state, u16 max_constellation)
2026 u16 i, ana_gain = 0;
2027 const u16 *adp;
2029 /* channel estimation fine configuration */
2030 switch (max_constellation) {
2031 case QAM_64:
2032 ana_gain = 0x7;
2033 adp = &adp_Q64[0];
2034 break;
2035 case QAM_16:
2036 ana_gain = 0x7;
2037 adp = &adp_Q16[0];
2038 break;
2039 default:
2040 ana_gain = 0;
2041 adp = &adp_Qdefault[0];
2042 break;
2045 for (i = 0; i < 4; i++)
2046 dib8000_write_word(state, 215 + i, adp[i]);
2048 return ana_gain;
2051 static void dib8000_update_ana_gain(struct dib8000_state *state, u16 ana_gain)
2053 u16 i;
2055 dib8000_write_word(state, 116, ana_gain);
2057 /* update ADC target depending on ana_gain */
2058 if (ana_gain) { /* set -16dB ADC target for ana_gain=-1 */
2059 for (i = 0; i < 10; i++)
2060 dib8000_write_word(state, 80 + i, adc_target_16dB[i]);
2061 } else { /* set -22dB ADC target for ana_gain=0 */
2062 for (i = 0; i < 10; i++)
2063 dib8000_write_word(state, 80 + i, adc_target_16dB[i] - 355);
2067 static void dib8000_load_ana_fe_coefs(struct dib8000_state *state, const s16 *ana_fe)
2069 u16 mode = 0;
2071 if (state->isdbt_cfg_loaded == 0)
2072 for (mode = 0; mode < 24; mode++)
2073 dib8000_write_word(state, 117 + mode, ana_fe[mode]);
2076 static const u16 lut_prbs_2k[14] = {
2077 0, 0x423, 0x009, 0x5C7, 0x7A6, 0x3D8, 0x527, 0x7FF, 0x79B, 0x3D6, 0x3A2, 0x53B, 0x2F4, 0x213
2079 static const u16 lut_prbs_4k[14] = {
2080 0, 0x208, 0x0C3, 0x7B9, 0x423, 0x5C7, 0x3D8, 0x7FF, 0x3D6, 0x53B, 0x213, 0x029, 0x0D0, 0x48E
2082 static const u16 lut_prbs_8k[14] = {
2083 0, 0x740, 0x069, 0x7DD, 0x208, 0x7B9, 0x5C7, 0x7FF, 0x53B, 0x029, 0x48E, 0x4C4, 0x367, 0x684
2086 static u16 dib8000_get_init_prbs(struct dib8000_state *state, u16 subchannel)
2088 int sub_channel_prbs_group = 0;
2090 sub_channel_prbs_group = (subchannel / 3) + 1;
2091 dprintk("sub_channel_prbs_group = %d , subchannel =%d prbs = 0x%04x", sub_channel_prbs_group, subchannel, lut_prbs_8k[sub_channel_prbs_group]);
2093 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
2094 case TRANSMISSION_MODE_2K:
2095 return lut_prbs_2k[sub_channel_prbs_group];
2096 case TRANSMISSION_MODE_4K:
2097 return lut_prbs_4k[sub_channel_prbs_group];
2098 default:
2099 case TRANSMISSION_MODE_8K:
2100 return lut_prbs_8k[sub_channel_prbs_group];
2104 static void dib8000_set_13seg_channel(struct dib8000_state *state)
2106 u16 i;
2107 u16 coff_pow = 0x2800;
2109 state->seg_mask = 0x1fff; /* All 13 segments enabled */
2111 /* ---- COFF ---- Carloff, the most robust --- */
2112 if (state->isdbt_cfg_loaded == 0) { /* if not Sound Broadcasting mode : put default values for 13 segments */
2113 dib8000_write_word(state, 180, (16 << 6) | 9);
2114 dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2);
2115 coff_pow = 0x2800;
2116 for (i = 0; i < 6; i++)
2117 dib8000_write_word(state, 181+i, coff_pow);
2119 /* P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1 */
2120 /* 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 */
2121 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1);
2123 /* P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6 */
2124 dib8000_write_word(state, 340, (8 << 6) | (6 << 0));
2125 /* P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1 */
2126 dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
2128 dib8000_write_word(state, 228, 0); /* default value */
2129 dib8000_write_word(state, 265, 31); /* default value */
2130 dib8000_write_word(state, 205, 0x200f); /* init value */
2134 * make the cpil_coff_lock more robust but slower p_coff_winlen
2135 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
2138 if (state->cfg.pll->ifreq == 0)
2139 dib8000_write_word(state, 266, ~state->seg_mask | state->seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */
2141 dib8000_load_ana_fe_coefs(state, ana_fe_coeff_13seg);
2144 static void dib8000_set_subchannel_prbs(struct dib8000_state *state, u16 init_prbs)
2146 u16 reg_1;
2148 reg_1 = dib8000_read_word(state, 1);
2149 dib8000_write_word(state, 1, (init_prbs << 2) | (reg_1 & 0x3)); /* ADDR 1 */
2152 static void dib8000_small_fine_tune(struct dib8000_state *state)
2154 u16 i;
2155 const s16 *ncoeff;
2156 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2158 dib8000_write_word(state, 352, state->seg_diff_mask);
2159 dib8000_write_word(state, 353, state->seg_mask);
2161 /* P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5 */
2162 dib8000_write_word(state, 351, (c->isdbt_sb_mode << 9) | (c->isdbt_sb_mode << 8) | (13 << 4) | 5);
2164 if (c->isdbt_sb_mode) {
2165 /* ---- SMALL ---- */
2166 switch (c->transmission_mode) {
2167 case TRANSMISSION_MODE_2K:
2168 if (c->isdbt_partial_reception == 0) { /* 1-seg */
2169 if (c->layer[0].modulation == DQPSK) /* DQPSK */
2170 ncoeff = coeff_2k_sb_1seg_dqpsk;
2171 else /* QPSK or QAM */
2172 ncoeff = coeff_2k_sb_1seg;
2173 } else { /* 3-segments */
2174 if (c->layer[0].modulation == DQPSK) { /* DQPSK on central segment */
2175 if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
2176 ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
2177 else /* QPSK or QAM on external segments */
2178 ncoeff = coeff_2k_sb_3seg_0dqpsk;
2179 } else { /* QPSK or QAM on central segment */
2180 if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
2181 ncoeff = coeff_2k_sb_3seg_1dqpsk;
2182 else /* QPSK or QAM on external segments */
2183 ncoeff = coeff_2k_sb_3seg;
2186 break;
2187 case TRANSMISSION_MODE_4K:
2188 if (c->isdbt_partial_reception == 0) { /* 1-seg */
2189 if (c->layer[0].modulation == DQPSK) /* DQPSK */
2190 ncoeff = coeff_4k_sb_1seg_dqpsk;
2191 else /* QPSK or QAM */
2192 ncoeff = coeff_4k_sb_1seg;
2193 } else { /* 3-segments */
2194 if (c->layer[0].modulation == DQPSK) { /* DQPSK on central segment */
2195 if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
2196 ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
2197 else /* QPSK or QAM on external segments */
2198 ncoeff = coeff_4k_sb_3seg_0dqpsk;
2199 } else { /* QPSK or QAM on central segment */
2200 if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
2201 ncoeff = coeff_4k_sb_3seg_1dqpsk;
2202 else /* QPSK or QAM on external segments */
2203 ncoeff = coeff_4k_sb_3seg;
2206 break;
2207 case TRANSMISSION_MODE_AUTO:
2208 case TRANSMISSION_MODE_8K:
2209 default:
2210 if (c->isdbt_partial_reception == 0) { /* 1-seg */
2211 if (c->layer[0].modulation == DQPSK) /* DQPSK */
2212 ncoeff = coeff_8k_sb_1seg_dqpsk;
2213 else /* QPSK or QAM */
2214 ncoeff = coeff_8k_sb_1seg;
2215 } else { /* 3-segments */
2216 if (c->layer[0].modulation == DQPSK) { /* DQPSK on central segment */
2217 if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
2218 ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
2219 else /* QPSK or QAM on external segments */
2220 ncoeff = coeff_8k_sb_3seg_0dqpsk;
2221 } else { /* QPSK or QAM on central segment */
2222 if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
2223 ncoeff = coeff_8k_sb_3seg_1dqpsk;
2224 else /* QPSK or QAM on external segments */
2225 ncoeff = coeff_8k_sb_3seg;
2228 break;
2231 for (i = 0; i < 8; i++)
2232 dib8000_write_word(state, 343 + i, ncoeff[i]);
2236 static const u16 coff_thres_1seg[3] = {300, 150, 80};
2237 static const u16 coff_thres_3seg[3] = {350, 300, 250};
2238 static void dib8000_set_sb_channel(struct dib8000_state *state)
2240 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2241 const u16 *coff;
2242 u16 i;
2244 if (c->transmission_mode == TRANSMISSION_MODE_2K || c->transmission_mode == TRANSMISSION_MODE_4K) {
2245 dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); /* adp_pass =1 */
2246 dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); /* pha3_force_pha_shift = 1 */
2247 } else {
2248 dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); /* adp_pass =0 */
2249 dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); /* pha3_force_pha_shift = 0 */
2252 if (c->isdbt_partial_reception == 1) /* 3-segments */
2253 state->seg_mask = 0x00E0;
2254 else /* 1-segment */
2255 state->seg_mask = 0x0040;
2257 dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
2259 /* ---- COFF ---- Carloff, the most robust --- */
2260 /* 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 */
2261 dib8000_write_word(state, 187, (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~c->isdbt_partial_reception & 1) << 2) | 0x3);
2263 dib8000_write_word(state, 340, (16 << 6) | (8 << 0)); /* P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8 */
2264 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 */
2266 /* Sound Broadcasting mode 1 seg */
2267 if (c->isdbt_partial_reception == 0) {
2268 /* 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) */
2269 if (state->mode == 3)
2270 dib8000_write_word(state, 180, 0x1fcf | ((state->mode - 1) << 14));
2271 else
2272 dib8000_write_word(state, 180, 0x0fcf | ((state->mode - 1) << 14));
2274 /* 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 */
2275 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
2276 coff = &coff_thres_1seg[0];
2277 } else { /* Sound Broadcasting mode 3 seg */
2278 dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
2279 /* 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 */
2280 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
2281 coff = &coff_thres_3seg[0];
2284 dib8000_write_word(state, 228, 1); /* P_2d_mode_byp=1 */
2285 dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); /* P_cspu_win_cut = 0 */
2287 if (c->isdbt_partial_reception == 0 && c->transmission_mode == TRANSMISSION_MODE_2K)
2288 dib8000_write_word(state, 265, 15); /* P_equal_noise_sel = 15 */
2290 /* Write COFF thres */
2291 for (i = 0 ; i < 3; i++) {
2292 dib8000_write_word(state, 181+i, coff[i]);
2293 dib8000_write_word(state, 184+i, coff[i]);
2297 * make the cpil_coff_lock more robust but slower p_coff_winlen
2298 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
2301 dib8000_write_word(state, 266, ~state->seg_mask | state->seg_diff_mask); /* P_equal_noise_seg_inh */
2303 if (c->isdbt_partial_reception == 0)
2304 dib8000_write_word(state, 178, 64); /* P_fft_powrange = 64 */
2305 else
2306 dib8000_write_word(state, 178, 32); /* P_fft_powrange = 32 */
2309 static void dib8000_set_isdbt_common_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
2311 u16 p_cfr_left_edge = 0, p_cfr_right_edge = 0;
2312 u16 tmcc_pow = 0, ana_gain = 0, tmp = 0, i = 0, nbseg_diff = 0 ;
2313 u16 max_constellation = DQPSK;
2314 int init_prbs;
2315 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2317 /* P_mode */
2318 dib8000_write_word(state, 10, (seq << 4));
2320 /* init mode */
2321 state->mode = fft_to_mode(state);
2323 /* set guard */
2324 tmp = dib8000_read_word(state, 1);
2325 dib8000_write_word(state, 1, (tmp&0xfffc) | (c->guard_interval & 0x3));
2327 dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) | ((c->isdbt_partial_reception & 1) << 5) | ((c->isdbt_sb_mode & 1) << 4));
2329 /* signal optimization parameter */
2330 if (c->isdbt_partial_reception) {
2331 state->seg_diff_mask = (c->layer[0].modulation == DQPSK) << permu_seg[0];
2332 for (i = 1; i < 3; i++)
2333 nbseg_diff += (c->layer[i].modulation == DQPSK) * c->layer[i].segment_count;
2334 for (i = 0; i < nbseg_diff; i++)
2335 state->seg_diff_mask |= 1 << permu_seg[i+1];
2336 } else {
2337 for (i = 0; i < 3; i++)
2338 nbseg_diff += (c->layer[i].modulation == DQPSK) * c->layer[i].segment_count;
2339 for (i = 0; i < nbseg_diff; i++)
2340 state->seg_diff_mask |= 1 << permu_seg[i];
2343 if (state->seg_diff_mask)
2344 dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
2345 else
2346 dib8000_write_word(state, 268, (2 << 9) | 39); /*init value */
2348 for (i = 0; i < 3; i++)
2349 max_constellation = dib8000_set_layer(state, i, max_constellation);
2350 if (autosearching == 0) {
2351 state->layer_b_nb_seg = c->layer[1].segment_count;
2352 state->layer_c_nb_seg = c->layer[2].segment_count;
2355 /* WRITE: Mode & Diff mask */
2356 dib8000_write_word(state, 0, (state->mode << 13) | state->seg_diff_mask);
2358 state->differential_constellation = (state->seg_diff_mask != 0);
2360 /* channel estimation fine configuration */
2361 ana_gain = dib8000_adp_fine_tune(state, max_constellation);
2363 /* update ana_gain depending on max constellation */
2364 dib8000_update_ana_gain(state, ana_gain);
2366 /* ---- ANA_FE ---- */
2367 if (c->isdbt_partial_reception) /* 3-segments */
2368 dib8000_load_ana_fe_coefs(state, ana_fe_coeff_3seg);
2369 else
2370 dib8000_load_ana_fe_coefs(state, ana_fe_coeff_1seg); /* 1-segment */
2372 /* TSB or ISDBT ? apply it now */
2373 if (c->isdbt_sb_mode) {
2374 dib8000_set_sb_channel(state);
2375 if (c->isdbt_sb_subchannel < 14)
2376 init_prbs = dib8000_get_init_prbs(state, c->isdbt_sb_subchannel);
2377 else
2378 init_prbs = 0;
2379 } else {
2380 dib8000_set_13seg_channel(state);
2381 init_prbs = 0xfff;
2384 /* SMALL */
2385 dib8000_small_fine_tune(state);
2387 dib8000_set_subchannel_prbs(state, init_prbs);
2389 /* ---- CHAN_BLK ---- */
2390 for (i = 0; i < 13; i++) {
2391 if ((((~state->seg_diff_mask) >> i) & 1) == 1) {
2392 p_cfr_left_edge += (1 << i) * ((i == 0) || ((((state->seg_mask & (~state->seg_diff_mask)) >> (i - 1)) & 1) == 0));
2393 p_cfr_right_edge += (1 << i) * ((i == 12) || ((((state->seg_mask & (~state->seg_diff_mask)) >> (i + 1)) & 1) == 0));
2396 dib8000_write_word(state, 222, p_cfr_left_edge); /* p_cfr_left_edge */
2397 dib8000_write_word(state, 223, p_cfr_right_edge); /* p_cfr_right_edge */
2398 /* "P_cspu_left_edge" & "P_cspu_right_edge" not used => do not care */
2400 dib8000_write_word(state, 189, ~state->seg_mask | state->seg_diff_mask); /* P_lmod4_seg_inh */
2401 dib8000_write_word(state, 192, ~state->seg_mask | state->seg_diff_mask); /* P_pha3_seg_inh */
2402 dib8000_write_word(state, 225, ~state->seg_mask | state->seg_diff_mask); /* P_tac_seg_inh */
2404 if (!autosearching)
2405 dib8000_write_word(state, 288, (~state->seg_mask | state->seg_diff_mask) & 0x1fff); /* P_tmcc_seg_eq_inh */
2406 else
2407 dib8000_write_word(state, 288, 0x1fff); /*disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels. */
2409 dib8000_write_word(state, 211, state->seg_mask & (~state->seg_diff_mask)); /* P_des_seg_enabled */
2410 dib8000_write_word(state, 287, ~state->seg_mask | 0x1000); /* P_tmcc_seg_inh */
2412 dib8000_write_word(state, 178, 32); /* P_fft_powrange = 32 */
2414 /* ---- TMCC ---- */
2415 for (i = 0; i < 3; i++)
2416 tmcc_pow += (((c->layer[i].modulation == DQPSK) * 4 + 1) * c->layer[i].segment_count) ;
2418 /* Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9); */
2419 /* Threshold is set at 1/4 of max power. */
2420 tmcc_pow *= (1 << (9-2));
2421 dib8000_write_word(state, 290, tmcc_pow); /* P_tmcc_dec_thres_2k */
2422 dib8000_write_word(state, 291, tmcc_pow); /* P_tmcc_dec_thres_4k */
2423 dib8000_write_word(state, 292, tmcc_pow); /* P_tmcc_dec_thres_8k */
2424 /*dib8000_write_word(state, 287, (1 << 13) | 0x1000 ); */
2426 /* ---- PHA3 ---- */
2427 if (state->isdbt_cfg_loaded == 0)
2428 dib8000_write_word(state, 250, 3285); /* p_2d_hspeed_thr0 */
2430 state->isdbt_cfg_loaded = 0;
2433 static u32 dib8000_wait_lock(struct dib8000_state *state, u32 internal,
2434 u32 wait0_ms, u32 wait1_ms, u32 wait2_ms)
2436 u32 value = 0; /* P_search_end0 wait time */
2437 u16 reg = 11; /* P_search_end0 start addr */
2439 for (reg = 11; reg < 16; reg += 2) {
2440 if (reg == 11) {
2441 if (state->revision == 0x8090)
2442 value = internal * wait1_ms;
2443 else
2444 value = internal * wait0_ms;
2445 } else if (reg == 13)
2446 value = internal * wait1_ms;
2447 else if (reg == 15)
2448 value = internal * wait2_ms;
2449 dib8000_write_word(state, reg, (u16)((value >> 16) & 0xffff));
2450 dib8000_write_word(state, (reg + 1), (u16)(value & 0xffff));
2452 return value;
2455 static int dib8000_autosearch_start(struct dvb_frontend *fe)
2457 struct dib8000_state *state = fe->demodulator_priv;
2458 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2459 u8 slist = 0;
2460 u32 value, internal = state->cfg.pll->internal;
2462 if (state->revision == 0x8090)
2463 internal = dib8000_read32(state, 23) / 1000;
2465 if ((state->revision >= 0x8002) &&
2466 (state->autosearch_state == AS_SEARCHING_FFT)) {
2467 dib8000_write_word(state, 37, 0x0065); /* P_ctrl_pha_off_max default values */
2468 dib8000_write_word(state, 116, 0x0000); /* P_ana_gain to 0 */
2470 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x1fff) | (0 << 13) | (1 << 15)); /* P_mode = 0, P_restart_search=1 */
2471 dib8000_write_word(state, 1, (dib8000_read_word(state, 1) & 0xfffc) | 0); /* P_guard = 0 */
2472 dib8000_write_word(state, 6, 0); /* P_lock0_mask = 0 */
2473 dib8000_write_word(state, 7, 0); /* P_lock1_mask = 0 */
2474 dib8000_write_word(state, 8, 0); /* P_lock2_mask = 0 */
2475 dib8000_write_word(state, 10, (dib8000_read_word(state, 10) & 0x200) | (16 << 4) | (0 << 0)); /* P_search_list=16, P_search_maxtrial=0 */
2477 if (state->revision == 0x8090)
2478 value = dib8000_wait_lock(state, internal, 10, 10, 10); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2479 else
2480 value = dib8000_wait_lock(state, internal, 20, 20, 20); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2482 dib8000_write_word(state, 17, 0);
2483 dib8000_write_word(state, 18, 200); /* P_search_rstst = 200 */
2484 dib8000_write_word(state, 19, 0);
2485 dib8000_write_word(state, 20, 400); /* P_search_rstend = 400 */
2486 dib8000_write_word(state, 21, (value >> 16) & 0xffff); /* P_search_checkst */
2487 dib8000_write_word(state, 22, value & 0xffff);
2489 if (state->revision == 0x8090)
2490 dib8000_write_word(state, 32, (dib8000_read_word(state, 32) & 0xf0ff) | (0 << 8)); /* P_corm_alpha = 0 */
2491 else
2492 dib8000_write_word(state, 32, (dib8000_read_word(state, 32) & 0xf0ff) | (9 << 8)); /* P_corm_alpha = 3 */
2493 dib8000_write_word(state, 355, 2); /* P_search_param_max = 2 */
2495 /* P_search_param_select = (1 | 1<<4 | 1 << 8) */
2496 dib8000_write_word(state, 356, 0);
2497 dib8000_write_word(state, 357, 0x111);
2499 dib8000_write_word(state, 770, (dib8000_read_word(state, 770) & 0xdfff) | (1 << 13)); /* P_restart_ccg = 1 */
2500 dib8000_write_word(state, 770, (dib8000_read_word(state, 770) & 0xdfff) | (0 << 13)); /* P_restart_ccg = 0 */
2501 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x7ff) | (0 << 15) | (1 << 13)); /* P_restart_search = 0; */
2502 } else if ((state->revision >= 0x8002) &&
2503 (state->autosearch_state == AS_SEARCHING_GUARD)) {
2504 c->transmission_mode = TRANSMISSION_MODE_8K;
2505 c->guard_interval = GUARD_INTERVAL_1_8;
2506 c->inversion = 0;
2507 c->layer[0].modulation = QAM_64;
2508 c->layer[0].fec = FEC_2_3;
2509 c->layer[0].interleaving = 0;
2510 c->layer[0].segment_count = 13;
2512 slist = 16;
2513 c->transmission_mode = state->found_nfft;
2515 dib8000_set_isdbt_common_channel(state, slist, 1);
2517 /* set lock_mask values */
2518 dib8000_write_word(state, 6, 0x4);
2519 if (state->revision == 0x8090)
2520 dib8000_write_word(state, 7, ((1 << 12) | (1 << 11) | (1 << 10)));/* tmcc_dec_lock, tmcc_sync_lock, tmcc_data_lock, tmcc_bch_uncor */
2521 else
2522 dib8000_write_word(state, 7, 0x8);
2523 dib8000_write_word(state, 8, 0x1000);
2525 /* set lock_mask wait time values */
2526 if (state->revision == 0x8090)
2527 dib8000_wait_lock(state, internal, 50, 100, 1000); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2528 else
2529 dib8000_wait_lock(state, internal, 50, 200, 1000); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2531 dib8000_write_word(state, 355, 3); /* P_search_param_max = 3 */
2533 /* P_search_param_select = 0xf; look for the 4 different guard intervals */
2534 dib8000_write_word(state, 356, 0);
2535 dib8000_write_word(state, 357, 0xf);
2537 value = dib8000_read_word(state, 0);
2538 dib8000_write_word(state, 0, (u16)((1 << 15) | value));
2539 dib8000_read_word(state, 1284); /* reset the INT. n_irq_pending */
2540 dib8000_write_word(state, 0, (u16)value);
2541 } else {
2542 c->inversion = 0;
2543 c->layer[0].modulation = QAM_64;
2544 c->layer[0].fec = FEC_2_3;
2545 c->layer[0].interleaving = 0;
2546 c->layer[0].segment_count = 13;
2547 if (!c->isdbt_sb_mode)
2548 c->layer[0].segment_count = 13;
2550 /* choose the right list, in sb, always do everything */
2551 if (c->isdbt_sb_mode) {
2552 slist = 7;
2553 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));
2554 } else {
2555 if (c->guard_interval == GUARD_INTERVAL_AUTO) {
2556 if (c->transmission_mode == TRANSMISSION_MODE_AUTO) {
2557 c->transmission_mode = TRANSMISSION_MODE_8K;
2558 c->guard_interval = GUARD_INTERVAL_1_8;
2559 slist = 7;
2560 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); /* P_mode = 1 to have autosearch start ok with mode2 */
2561 } else {
2562 c->guard_interval = GUARD_INTERVAL_1_8;
2563 slist = 3;
2565 } else {
2566 if (c->transmission_mode == TRANSMISSION_MODE_AUTO) {
2567 c->transmission_mode = TRANSMISSION_MODE_8K;
2568 slist = 2;
2569 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); /* P_mode = 1 */
2570 } else
2571 slist = 0;
2574 dprintk("Using list for autosearch : %d", slist);
2576 dib8000_set_isdbt_common_channel(state, slist, 1);
2578 /* set lock_mask values */
2579 dib8000_write_word(state, 6, 0x4);
2580 if (state->revision == 0x8090)
2581 dib8000_write_word(state, 7, (1 << 12) | (1 << 11) | (1 << 10));
2582 else
2583 dib8000_write_word(state, 7, 0x8);
2584 dib8000_write_word(state, 8, 0x1000);
2586 /* set lock_mask wait time values */
2587 if (state->revision == 0x8090)
2588 dib8000_wait_lock(state, internal, 50, 200, 1000); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2589 else
2590 dib8000_wait_lock(state, internal, 50, 100, 1000); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2592 value = dib8000_read_word(state, 0);
2593 dib8000_write_word(state, 0, (u16)((1 << 15) | value));
2594 dib8000_read_word(state, 1284); /* reset the INT. n_irq_pending */
2595 dib8000_write_word(state, 0, (u16)value);
2597 return 0;
2600 static int dib8000_autosearch_irq(struct dvb_frontend *fe)
2602 struct dib8000_state *state = fe->demodulator_priv;
2603 u16 irq_pending = dib8000_read_word(state, 1284);
2605 if ((state->revision >= 0x8002) &&
2606 (state->autosearch_state == AS_SEARCHING_FFT)) {
2607 if (irq_pending & 0x1) {
2608 dprintk("dib8000_autosearch_irq: max correlation result available");
2609 return 3;
2611 } else {
2612 if (irq_pending & 0x1) { /* failed */
2613 dprintk("dib8000_autosearch_irq failed");
2614 return 1;
2617 if (irq_pending & 0x2) { /* succeeded */
2618 dprintk("dib8000_autosearch_irq succeeded");
2619 return 2;
2623 return 0; // still pending
2626 static void dib8000_viterbi_state(struct dib8000_state *state, u8 onoff)
2628 u16 tmp;
2630 tmp = dib8000_read_word(state, 771);
2631 if (onoff) /* start P_restart_chd : channel_decoder */
2632 dib8000_write_word(state, 771, tmp & 0xfffd);
2633 else /* stop P_restart_chd : channel_decoder */
2634 dib8000_write_word(state, 771, tmp | (1<<1));
2637 static void dib8000_set_dds(struct dib8000_state *state, s32 offset_khz)
2639 s16 unit_khz_dds_val;
2640 u32 abs_offset_khz = ABS(offset_khz);
2641 u32 dds = state->cfg.pll->ifreq & 0x1ffffff;
2642 u8 invert = !!(state->cfg.pll->ifreq & (1 << 25));
2643 u8 ratio;
2645 if (state->revision == 0x8090) {
2646 ratio = 4;
2647 unit_khz_dds_val = (1<<26) / (dib8000_read32(state, 23) / 1000);
2648 if (offset_khz < 0)
2649 dds = (1 << 26) - (abs_offset_khz * unit_khz_dds_val);
2650 else
2651 dds = (abs_offset_khz * unit_khz_dds_val);
2653 if (invert)
2654 dds = (1<<26) - dds;
2655 } else {
2656 ratio = 2;
2657 unit_khz_dds_val = (u16) (67108864 / state->cfg.pll->internal);
2659 if (offset_khz < 0)
2660 unit_khz_dds_val *= -1;
2662 /* IF tuner */
2663 if (invert)
2664 dds -= abs_offset_khz * unit_khz_dds_val;
2665 else
2666 dds += abs_offset_khz * unit_khz_dds_val;
2669 dprintk("setting a DDS frequency offset of %c%dkHz", invert ? '-' : ' ', dds / unit_khz_dds_val);
2671 if (abs_offset_khz <= (state->cfg.pll->internal / ratio)) {
2672 /* Max dds offset is the half of the demod freq */
2673 dib8000_write_word(state, 26, invert);
2674 dib8000_write_word(state, 27, (u16)(dds >> 16) & 0x1ff);
2675 dib8000_write_word(state, 28, (u16)(dds & 0xffff));
2679 static void dib8000_set_frequency_offset(struct dib8000_state *state)
2681 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2682 int i;
2683 u32 current_rf;
2684 int total_dds_offset_khz;
2686 if (state->fe[0]->ops.tuner_ops.get_frequency)
2687 state->fe[0]->ops.tuner_ops.get_frequency(state->fe[0], &current_rf);
2688 else
2689 current_rf = c->frequency;
2690 current_rf /= 1000;
2691 total_dds_offset_khz = (int)current_rf - (int)c->frequency / 1000;
2693 if (c->isdbt_sb_mode) {
2694 state->subchannel = c->isdbt_sb_subchannel;
2696 i = dib8000_read_word(state, 26) & 1; /* P_dds_invspec */
2697 dib8000_write_word(state, 26, c->inversion ^ i);
2699 if (state->cfg.pll->ifreq == 0) { /* low if tuner */
2700 if ((c->inversion ^ i) == 0)
2701 dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
2702 } else {
2703 if ((c->inversion ^ i) == 0)
2704 total_dds_offset_khz *= -1;
2708 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);
2710 /* apply dds offset now */
2711 dib8000_set_dds(state, total_dds_offset_khz);
2714 static u16 LUT_isdbt_symbol_duration[4] = { 26, 101, 63 };
2716 static u32 dib8000_get_symbol_duration(struct dib8000_state *state)
2718 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2719 u16 i;
2721 switch (c->transmission_mode) {
2722 case TRANSMISSION_MODE_2K:
2723 i = 0;
2724 break;
2725 case TRANSMISSION_MODE_4K:
2726 i = 2;
2727 break;
2728 default:
2729 case TRANSMISSION_MODE_AUTO:
2730 case TRANSMISSION_MODE_8K:
2731 i = 1;
2732 break;
2735 return (LUT_isdbt_symbol_duration[i] / (c->bandwidth_hz / 1000)) + 1;
2738 static void dib8000_set_isdbt_loop_params(struct dib8000_state *state, enum param_loop_step loop_step)
2740 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2741 u16 reg_32 = 0, reg_37 = 0;
2743 switch (loop_step) {
2744 case LOOP_TUNE_1:
2745 if (c->isdbt_sb_mode) {
2746 if (c->isdbt_partial_reception == 0) {
2747 reg_32 = ((11 - state->mode) << 12) | (6 << 8) | 0x40; /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x40 */
2748 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) */
2749 } else { /* Sound Broadcasting mode 3 seg */
2750 reg_32 = ((10 - state->mode) << 12) | (6 << 8) | 0x60; /* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x60 */
2751 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) */
2753 } else { /* 13-seg start conf offset loop parameters */
2754 reg_32 = ((9 - state->mode) << 12) | (6 << 8) | 0x80; /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
2755 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 */
2757 break;
2758 case LOOP_TUNE_2:
2759 if (c->isdbt_sb_mode) {
2760 if (c->isdbt_partial_reception == 0) { /* Sound Broadcasting mode 1 seg */
2761 reg_32 = ((13-state->mode) << 12) | (6 << 8) | 0x40; /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40*/
2762 reg_37 = (12-state->mode) | ((5 + state->mode) << 5);
2763 } else { /* Sound Broadcasting mode 3 seg */
2764 reg_32 = ((12-state->mode) << 12) | (6 << 8) | 0x60; /* P_timf_alpha = (12-P_mode) , P_corm_alpha=6, P_corm_thres=0x60 */
2765 reg_37 = (11-state->mode) | ((5 + state->mode) << 5);
2767 } else { /* 13 seg */
2768 reg_32 = ((11-state->mode) << 12) | (6 << 8) | 0x80; /* P_timf_alpha = 8 , P_corm_alpha=6, P_corm_thres=0x80 */
2769 reg_37 = ((5+state->mode) << 5) | (10 - state->mode);
2771 break;
2773 dib8000_write_word(state, 32, reg_32);
2774 dib8000_write_word(state, 37, reg_37);
2777 static void dib8000_demod_restart(struct dib8000_state *state)
2779 dib8000_write_word(state, 770, 0x4000);
2780 dib8000_write_word(state, 770, 0x0000);
2781 return;
2784 static void dib8000_set_sync_wait(struct dib8000_state *state)
2786 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2787 u16 sync_wait = 64;
2789 /* P_dvsy_sync_wait - reuse mode */
2790 switch (c->transmission_mode) {
2791 case TRANSMISSION_MODE_8K:
2792 sync_wait = 256;
2793 break;
2794 case TRANSMISSION_MODE_4K:
2795 sync_wait = 128;
2796 break;
2797 default:
2798 case TRANSMISSION_MODE_2K:
2799 sync_wait = 64;
2800 break;
2803 if (state->cfg.diversity_delay == 0)
2804 sync_wait = (sync_wait * (1 << (c->guard_interval)) * 3) / 2 + 48; /* add 50% SFN margin + compensate for one DVSY-fifo */
2805 else
2806 sync_wait = (sync_wait * (1 << (c->guard_interval)) * 3) / 2 + state->cfg.diversity_delay; /* add 50% SFN margin + compensate for DVSY-fifo */
2808 dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | (sync_wait << 4));
2811 static u32 dib8000_get_timeout(struct dib8000_state *state, u32 delay, enum timeout_mode mode)
2813 if (mode == SYMBOL_DEPENDENT_ON)
2814 return systime() + (delay * state->symbol_duration);
2815 else
2816 return systime() + delay;
2819 static s32 dib8000_get_status(struct dvb_frontend *fe)
2821 struct dib8000_state *state = fe->demodulator_priv;
2822 return state->status;
2825 enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
2827 struct dib8000_state *state = fe->demodulator_priv;
2828 return state->tune_state;
2830 EXPORT_SYMBOL(dib8000_get_tune_state);
2832 int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
2834 struct dib8000_state *state = fe->demodulator_priv;
2836 state->tune_state = tune_state;
2837 return 0;
2839 EXPORT_SYMBOL(dib8000_set_tune_state);
2841 static int dib8000_tune_restart_from_demod(struct dvb_frontend *fe)
2843 struct dib8000_state *state = fe->demodulator_priv;
2845 state->status = FE_STATUS_TUNE_PENDING;
2846 state->tune_state = CT_DEMOD_START;
2847 return 0;
2850 static u16 dib8000_read_lock(struct dvb_frontend *fe)
2852 struct dib8000_state *state = fe->demodulator_priv;
2854 if (state->revision == 0x8090)
2855 return dib8000_read_word(state, 570);
2856 return dib8000_read_word(state, 568);
2859 static int dib8090p_init_sdram(struct dib8000_state *state)
2861 u16 reg = 0;
2862 dprintk("init sdram");
2864 reg = dib8000_read_word(state, 274) & 0xfff0;
2865 dib8000_write_word(state, 274, reg | 0x7); /* P_dintlv_delay_ram = 7 because of MobileSdram */
2867 dib8000_write_word(state, 1803, (7 << 2));
2869 reg = dib8000_read_word(state, 1280);
2870 dib8000_write_word(state, 1280, reg | (1 << 2)); /* force restart P_restart_sdram */
2871 dib8000_write_word(state, 1280, reg); /* release restart P_restart_sdram */
2873 return 0;
2876 static int dib8000_tune(struct dvb_frontend *fe)
2878 struct dib8000_state *state = fe->demodulator_priv;
2879 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2880 enum frontend_tune_state *tune_state = &state->tune_state;
2882 u16 locks, deeper_interleaver = 0, i;
2883 int ret = 1; /* 1 symbol duration (in 100us unit) delay most of the time */
2885 u32 *timeout = &state->timeout;
2886 u32 now = systime();
2887 #ifdef DIB8000_AGC_FREEZE
2888 u16 agc1, agc2;
2889 #endif
2891 u32 corm[4] = {0, 0, 0, 0};
2892 u8 find_index, max_value;
2894 #if 0
2895 if (*tune_state < CT_DEMOD_STOP)
2896 dprintk("IN: context status = %d, TUNE_STATE %d autosearch step = %u systime = %u", state->channel_parameters_set, *tune_state, state->autosearch_state, now);
2897 #endif
2899 switch (*tune_state) {
2900 case CT_DEMOD_START: /* 30 */
2901 if (state->revision == 0x8090)
2902 dib8090p_init_sdram(state);
2903 state->status = FE_STATUS_TUNE_PENDING;
2904 if ((c->delivery_system != SYS_ISDBT) ||
2905 (c->inversion == INVERSION_AUTO) ||
2906 (c->transmission_mode == TRANSMISSION_MODE_AUTO) ||
2907 (c->guard_interval == GUARD_INTERVAL_AUTO) ||
2908 (((c->isdbt_layer_enabled & (1 << 0)) != 0) &&
2909 (c->layer[0].segment_count != 0xff) &&
2910 (c->layer[0].segment_count != 0) &&
2911 ((c->layer[0].modulation == QAM_AUTO) ||
2912 (c->layer[0].fec == FEC_AUTO))) ||
2913 (((c->isdbt_layer_enabled & (1 << 1)) != 0) &&
2914 (c->layer[1].segment_count != 0xff) &&
2915 (c->layer[1].segment_count != 0) &&
2916 ((c->layer[1].modulation == QAM_AUTO) ||
2917 (c->layer[1].fec == FEC_AUTO))) ||
2918 (((c->isdbt_layer_enabled & (1 << 2)) != 0) &&
2919 (c->layer[2].segment_count != 0xff) &&
2920 (c->layer[2].segment_count != 0) &&
2921 ((c->layer[2].modulation == QAM_AUTO) ||
2922 (c->layer[2].fec == FEC_AUTO))) ||
2923 (((c->layer[0].segment_count == 0) ||
2924 ((c->isdbt_layer_enabled & (1 << 0)) == 0)) &&
2925 ((c->layer[1].segment_count == 0) ||
2926 ((c->isdbt_layer_enabled & (2 << 0)) == 0)) &&
2927 ((c->layer[2].segment_count == 0) || ((c->isdbt_layer_enabled & (3 << 0)) == 0))))
2928 state->channel_parameters_set = 0; /* auto search */
2929 else
2930 state->channel_parameters_set = 1; /* channel parameters are known */
2932 dib8000_viterbi_state(state, 0); /* force chan dec in restart */
2934 /* Layer monit */
2935 dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
2937 dib8000_set_frequency_offset(state);
2938 dib8000_set_bandwidth(fe, c->bandwidth_hz / 1000);
2940 if (state->channel_parameters_set == 0) { /* The channel struct is unknown, search it ! */
2941 #ifdef DIB8000_AGC_FREEZE
2942 if (state->revision != 0x8090) {
2943 state->agc1_max = dib8000_read_word(state, 108);
2944 state->agc1_min = dib8000_read_word(state, 109);
2945 state->agc2_max = dib8000_read_word(state, 110);
2946 state->agc2_min = dib8000_read_word(state, 111);
2947 agc1 = dib8000_read_word(state, 388);
2948 agc2 = dib8000_read_word(state, 389);
2949 dib8000_write_word(state, 108, agc1);
2950 dib8000_write_word(state, 109, agc1);
2951 dib8000_write_word(state, 110, agc2);
2952 dib8000_write_word(state, 111, agc2);
2954 #endif
2955 state->autosearch_state = AS_SEARCHING_FFT;
2956 state->found_nfft = TRANSMISSION_MODE_AUTO;
2957 state->found_guard = GUARD_INTERVAL_AUTO;
2958 *tune_state = CT_DEMOD_SEARCH_NEXT;
2959 } else { /* we already know the channel struct so TUNE only ! */
2960 state->autosearch_state = AS_DONE;
2961 *tune_state = CT_DEMOD_STEP_3;
2963 state->symbol_duration = dib8000_get_symbol_duration(state);
2964 break;
2966 case CT_DEMOD_SEARCH_NEXT: /* 51 */
2967 dib8000_autosearch_start(fe);
2968 if (state->revision == 0x8090)
2969 ret = 50;
2970 else
2971 ret = 15;
2972 *tune_state = CT_DEMOD_STEP_1;
2973 break;
2975 case CT_DEMOD_STEP_1: /* 31 */
2976 switch (dib8000_autosearch_irq(fe)) {
2977 case 1: /* fail */
2978 state->status = FE_STATUS_TUNE_FAILED;
2979 state->autosearch_state = AS_DONE;
2980 *tune_state = CT_DEMOD_STOP; /* else we are done here */
2981 break;
2982 case 2: /* Succes */
2983 state->status = FE_STATUS_FFT_SUCCESS; /* signal to the upper layer, that there was a channel found and the parameters can be read */
2984 *tune_state = CT_DEMOD_STEP_3;
2985 if (state->autosearch_state == AS_SEARCHING_GUARD)
2986 *tune_state = CT_DEMOD_STEP_2;
2987 else
2988 state->autosearch_state = AS_DONE;
2989 break;
2990 case 3: /* Autosearch FFT max correlation endded */
2991 *tune_state = CT_DEMOD_STEP_2;
2992 break;
2994 break;
2996 case CT_DEMOD_STEP_2:
2997 switch (state->autosearch_state) {
2998 case AS_SEARCHING_FFT:
2999 /* searching for the correct FFT */
3000 if (state->revision == 0x8090) {
3001 corm[2] = (dib8000_read_word(state, 596) << 16) | (dib8000_read_word(state, 597));
3002 corm[1] = (dib8000_read_word(state, 598) << 16) | (dib8000_read_word(state, 599));
3003 corm[0] = (dib8000_read_word(state, 600) << 16) | (dib8000_read_word(state, 601));
3004 } else {
3005 corm[2] = (dib8000_read_word(state, 594) << 16) | (dib8000_read_word(state, 595));
3006 corm[1] = (dib8000_read_word(state, 596) << 16) | (dib8000_read_word(state, 597));
3007 corm[0] = (dib8000_read_word(state, 598) << 16) | (dib8000_read_word(state, 599));
3009 /* dprintk("corm fft: %u %u %u", corm[0], corm[1], corm[2]); */
3011 max_value = 0;
3012 for (find_index = 1 ; find_index < 3 ; find_index++) {
3013 if (corm[max_value] < corm[find_index])
3014 max_value = find_index ;
3017 switch (max_value) {
3018 case 0:
3019 state->found_nfft = TRANSMISSION_MODE_2K;
3020 break;
3021 case 1:
3022 state->found_nfft = TRANSMISSION_MODE_4K;
3023 break;
3024 case 2:
3025 default:
3026 state->found_nfft = TRANSMISSION_MODE_8K;
3027 break;
3029 /* dprintk("Autosearch FFT has found Mode %d", max_value + 1); */
3031 *tune_state = CT_DEMOD_SEARCH_NEXT;
3032 state->autosearch_state = AS_SEARCHING_GUARD;
3033 if (state->revision == 0x8090)
3034 ret = 50;
3035 else
3036 ret = 10;
3037 break;
3038 case AS_SEARCHING_GUARD:
3039 /* searching for the correct guard interval */
3040 if (state->revision == 0x8090)
3041 state->found_guard = dib8000_read_word(state, 572) & 0x3;
3042 else
3043 state->found_guard = dib8000_read_word(state, 570) & 0x3;
3044 /* dprintk("guard interval found=%i", state->found_guard); */
3046 *tune_state = CT_DEMOD_STEP_3;
3047 break;
3048 default:
3049 /* the demod should never be in this state */
3050 state->status = FE_STATUS_TUNE_FAILED;
3051 state->autosearch_state = AS_DONE;
3052 *tune_state = CT_DEMOD_STOP; /* else we are done here */
3053 break;
3055 break;
3057 case CT_DEMOD_STEP_3: /* 33 */
3058 state->symbol_duration = dib8000_get_symbol_duration(state);
3059 dib8000_set_isdbt_loop_params(state, LOOP_TUNE_1);
3060 dib8000_set_isdbt_common_channel(state, 0, 0);/* setting the known channel parameters here */
3061 *tune_state = CT_DEMOD_STEP_4;
3062 break;
3064 case CT_DEMOD_STEP_4: /* (34) */
3065 dib8000_demod_restart(state);
3067 dib8000_set_sync_wait(state);
3068 dib8000_set_diversity_in(state->fe[0], state->diversity_onoff);
3070 locks = (dib8000_read_word(state, 180) >> 6) & 0x3f; /* P_coff_winlen ? */
3071 /* coff should lock over P_coff_winlen ofdm symbols : give 3 times this lenght to lock */
3072 *timeout = dib8000_get_timeout(state, 2 * locks, SYMBOL_DEPENDENT_ON);
3073 *tune_state = CT_DEMOD_STEP_5;
3074 break;
3076 case CT_DEMOD_STEP_5: /* (35) */
3077 locks = dib8000_read_lock(fe);
3078 if (locks & (0x3 << 11)) { /* coff-lock and off_cpil_lock achieved */
3079 dib8000_update_timf(state); /* we achieved a coff_cpil_lock - it's time to update the timf */
3080 if (!state->differential_constellation) {
3081 /* 2 times lmod4_win_len + 10 symbols (pipe delay after coff + nb to compute a 1st correlation) */
3082 *timeout = dib8000_get_timeout(state, (20 * ((dib8000_read_word(state, 188)>>5)&0x1f)), SYMBOL_DEPENDENT_ON);
3083 *tune_state = CT_DEMOD_STEP_7;
3084 } else {
3085 *tune_state = CT_DEMOD_STEP_8;
3087 } else if (now > *timeout) {
3088 *tune_state = CT_DEMOD_STEP_6; /* goto check for diversity input connection */
3090 break;
3092 case CT_DEMOD_STEP_6: /* (36) if there is an input (diversity) */
3093 if ((state->fe[1] != NULL) && (state->output_mode != OUTMODE_DIVERSITY)) {
3094 /* 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 */
3095 if (dib8000_get_status(state->fe[1]) <= FE_STATUS_STD_SUCCESS) /* Something is locked on the input fe */
3096 *tune_state = CT_DEMOD_STEP_8; /* go for mpeg */
3097 else if (dib8000_get_status(state->fe[1]) >= FE_STATUS_TUNE_TIME_TOO_SHORT) { /* fe in input failled also, break the current one */
3098 *tune_state = CT_DEMOD_STOP; /* else we are done here ; step 8 will close the loops and exit */
3099 dib8000_viterbi_state(state, 1); /* start viterbi chandec */
3100 dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2);
3101 state->status = FE_STATUS_TUNE_FAILED;
3103 } else {
3104 dib8000_viterbi_state(state, 1); /* start viterbi chandec */
3105 dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2);
3106 *tune_state = CT_DEMOD_STOP; /* else we are done here ; step 8 will close the loops and exit */
3107 state->status = FE_STATUS_TUNE_FAILED;
3109 break;
3111 case CT_DEMOD_STEP_7: /* 37 */
3112 locks = dib8000_read_lock(fe);
3113 if (locks & (1<<10)) { /* lmod4_lock */
3114 ret = 14; /* wait for 14 symbols */
3115 *tune_state = CT_DEMOD_STEP_8;
3116 } else if (now > *timeout)
3117 *tune_state = CT_DEMOD_STEP_6; /* goto check for diversity input connection */
3118 break;
3120 case CT_DEMOD_STEP_8: /* 38 */
3121 dib8000_viterbi_state(state, 1); /* start viterbi chandec */
3122 dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2);
3124 /* mpeg will never lock on this condition because init_prbs is not set : search for it !*/
3125 if (c->isdbt_sb_mode
3126 && c->isdbt_sb_subchannel < 14
3127 && !state->differential_constellation) {
3128 state->subchannel = 0;
3129 *tune_state = CT_DEMOD_STEP_11;
3130 } else {
3131 *tune_state = CT_DEMOD_STEP_9;
3132 state->status = FE_STATUS_LOCKED;
3134 break;
3136 case CT_DEMOD_STEP_9: /* 39 */
3137 if ((state->revision == 0x8090) || ((dib8000_read_word(state, 1291) >> 9) & 0x1)) { /* fe capable of deinterleaving : esram */
3138 /* defines timeout for mpeg lock depending on interleaver lenght of longest layer */
3139 for (i = 0; i < 3; i++) {
3140 if (c->layer[i].interleaving >= deeper_interleaver) {
3141 dprintk("layer%i: time interleaver = %d ", i, c->layer[i].interleaving);
3142 if (c->layer[i].segment_count > 0) { /* valid layer */
3143 deeper_interleaver = c->layer[0].interleaving;
3144 state->longest_intlv_layer = i;
3149 if (deeper_interleaver == 0)
3150 locks = 2; /* locks is the tmp local variable name */
3151 else if (deeper_interleaver == 3)
3152 locks = 8;
3153 else
3154 locks = 2 * deeper_interleaver;
3156 if (state->diversity_onoff != 0) /* because of diversity sync */
3157 locks *= 2;
3159 *timeout = now + (2000 * locks); /* give the mpeg lock 800ms if sram is present */
3160 dprintk("Deeper interleaver mode = %d on layer %d : timeout mult factor = %d => will use timeout = %d", deeper_interleaver, state->longest_intlv_layer, locks, *timeout);
3162 *tune_state = CT_DEMOD_STEP_10;
3163 } else
3164 *tune_state = CT_DEMOD_STOP;
3165 break;
3167 case CT_DEMOD_STEP_10: /* 40 */
3168 locks = dib8000_read_lock(fe);
3169 if (locks&(1<<(7-state->longest_intlv_layer))) { /* mpeg lock : check the longest one */
3170 dprintk("Mpeg locks [ L0 : %d | L1 : %d | L2 : %d ]", (locks>>7)&0x1, (locks>>6)&0x1, (locks>>5)&0x1);
3171 if (c->isdbt_sb_mode
3172 && c->isdbt_sb_subchannel < 14
3173 && !state->differential_constellation)
3174 /* signal to the upper layer, that there was a channel found and the parameters can be read */
3175 state->status = FE_STATUS_DEMOD_SUCCESS;
3176 else
3177 state->status = FE_STATUS_DATA_LOCKED;
3178 *tune_state = CT_DEMOD_STOP;
3179 } else if (now > *timeout) {
3180 if (c->isdbt_sb_mode
3181 && c->isdbt_sb_subchannel < 14
3182 && !state->differential_constellation) { /* continue to try init prbs autosearch */
3183 state->subchannel += 3;
3184 *tune_state = CT_DEMOD_STEP_11;
3185 } 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 */
3186 if (locks & (0x7<<5)) {
3187 dprintk("Mpeg locks [ L0 : %d | L1 : %d | L2 : %d ]", (locks>>7)&0x1, (locks>>6)&0x1, (locks>>5)&0x1);
3188 state->status = FE_STATUS_DATA_LOCKED;
3189 } else
3190 state->status = FE_STATUS_TUNE_FAILED;
3191 *tune_state = CT_DEMOD_STOP;
3194 break;
3196 case CT_DEMOD_STEP_11: /* 41 : init prbs autosearch */
3197 if (state->subchannel <= 41) {
3198 dib8000_set_subchannel_prbs(state, dib8000_get_init_prbs(state, state->subchannel));
3199 *tune_state = CT_DEMOD_STEP_9;
3200 } else {
3201 *tune_state = CT_DEMOD_STOP;
3202 state->status = FE_STATUS_TUNE_FAILED;
3204 break;
3206 default:
3207 break;
3210 /* tuning is finished - cleanup the demod */
3211 switch (*tune_state) {
3212 case CT_DEMOD_STOP: /* (42) */
3213 #ifdef DIB8000_AGC_FREEZE
3214 if ((state->revision != 0x8090) && (state->agc1_max != 0)) {
3215 dib8000_write_word(state, 108, state->agc1_max);
3216 dib8000_write_word(state, 109, state->agc1_min);
3217 dib8000_write_word(state, 110, state->agc2_max);
3218 dib8000_write_word(state, 111, state->agc2_min);
3219 state->agc1_max = 0;
3220 state->agc1_min = 0;
3221 state->agc2_max = 0;
3222 state->agc2_min = 0;
3224 #endif
3225 ret = FE_CALLBACK_TIME_NEVER;
3226 break;
3227 default:
3228 break;
3231 if ((ret > 0) && (*tune_state > CT_DEMOD_STEP_3))
3232 return ret * state->symbol_duration;
3233 if ((ret > 0) && (ret < state->symbol_duration))
3234 return state->symbol_duration; /* at least one symbol */
3235 return ret;
3238 static int dib8000_wakeup(struct dvb_frontend *fe)
3240 struct dib8000_state *state = fe->demodulator_priv;
3241 u8 index_frontend;
3242 int ret;
3244 dib8000_set_power_mode(state, DIB8000_POWER_ALL);
3245 dib8000_set_adc_state(state, DIBX000_ADC_ON);
3246 if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
3247 dprintk("could not start Slow ADC");
3249 if (state->revision == 0x8090)
3250 dib8000_sad_calib(state);
3252 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3253 ret = state->fe[index_frontend]->ops.init(state->fe[index_frontend]);
3254 if (ret < 0)
3255 return ret;
3258 return 0;
3261 static int dib8000_sleep(struct dvb_frontend *fe)
3263 struct dib8000_state *state = fe->demodulator_priv;
3264 u8 index_frontend;
3265 int ret;
3267 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3268 ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
3269 if (ret < 0)
3270 return ret;
3273 if (state->revision != 0x8090)
3274 dib8000_set_output_mode(fe, OUTMODE_HIGH_Z);
3275 dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY);
3276 return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF);
3279 static int dib8000_get_frontend(struct dvb_frontend *fe)
3281 struct dib8000_state *state = fe->demodulator_priv;
3282 u16 i, val = 0;
3283 fe_status_t stat;
3284 u8 index_frontend, sub_index_frontend;
3286 fe->dtv_property_cache.bandwidth_hz = 6000000;
3288 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3289 state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
3290 if (stat&FE_HAS_SYNC) {
3291 dprintk("TMCC lock on the slave%i", index_frontend);
3292 /* synchronize the cache with the other frontends */
3293 state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend]);
3294 for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL); sub_index_frontend++) {
3295 if (sub_index_frontend != index_frontend) {
3296 state->fe[sub_index_frontend]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode;
3297 state->fe[sub_index_frontend]->dtv_property_cache.inversion = state->fe[index_frontend]->dtv_property_cache.inversion;
3298 state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode = state->fe[index_frontend]->dtv_property_cache.transmission_mode;
3299 state->fe[sub_index_frontend]->dtv_property_cache.guard_interval = state->fe[index_frontend]->dtv_property_cache.guard_interval;
3300 state->fe[sub_index_frontend]->dtv_property_cache.isdbt_partial_reception = state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception;
3301 for (i = 0; i < 3; i++) {
3302 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].segment_count = state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count;
3303 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].interleaving = state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving;
3304 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].fec = state->fe[index_frontend]->dtv_property_cache.layer[i].fec;
3305 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].modulation = state->fe[index_frontend]->dtv_property_cache.layer[i].modulation;
3309 return 0;
3313 fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1;
3315 if (state->revision == 0x8090)
3316 val = dib8000_read_word(state, 572);
3317 else
3318 val = dib8000_read_word(state, 570);
3319 fe->dtv_property_cache.inversion = (val & 0x40) >> 6;
3320 switch ((val & 0x30) >> 4) {
3321 case 1:
3322 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
3323 break;
3324 case 3:
3325 default:
3326 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
3327 break;
3330 switch (val & 0x3) {
3331 case 0:
3332 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
3333 dprintk("dib8000_get_frontend GI = 1/32 ");
3334 break;
3335 case 1:
3336 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
3337 dprintk("dib8000_get_frontend GI = 1/16 ");
3338 break;
3339 case 2:
3340 dprintk("dib8000_get_frontend GI = 1/8 ");
3341 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
3342 break;
3343 case 3:
3344 dprintk("dib8000_get_frontend GI = 1/4 ");
3345 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
3346 break;
3349 val = dib8000_read_word(state, 505);
3350 fe->dtv_property_cache.isdbt_partial_reception = val & 1;
3351 dprintk("dib8000_get_frontend : partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception);
3353 for (i = 0; i < 3; i++) {
3354 val = dib8000_read_word(state, 493 + i);
3355 fe->dtv_property_cache.layer[i].segment_count = val & 0x0F;
3356 dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count);
3358 val = dib8000_read_word(state, 499 + i);
3359 fe->dtv_property_cache.layer[i].interleaving = val & 0x3;
3360 dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ", i, fe->dtv_property_cache.layer[i].interleaving);
3362 val = dib8000_read_word(state, 481 + i);
3363 switch (val & 0x7) {
3364 case 1:
3365 fe->dtv_property_cache.layer[i].fec = FEC_1_2;
3366 dprintk("dib8000_get_frontend : Layer %d Code Rate = 1/2 ", i);
3367 break;
3368 case 2:
3369 fe->dtv_property_cache.layer[i].fec = FEC_2_3;
3370 dprintk("dib8000_get_frontend : Layer %d Code Rate = 2/3 ", i);
3371 break;
3372 case 3:
3373 fe->dtv_property_cache.layer[i].fec = FEC_3_4;
3374 dprintk("dib8000_get_frontend : Layer %d Code Rate = 3/4 ", i);
3375 break;
3376 case 5:
3377 fe->dtv_property_cache.layer[i].fec = FEC_5_6;
3378 dprintk("dib8000_get_frontend : Layer %d Code Rate = 5/6 ", i);
3379 break;
3380 default:
3381 fe->dtv_property_cache.layer[i].fec = FEC_7_8;
3382 dprintk("dib8000_get_frontend : Layer %d Code Rate = 7/8 ", i);
3383 break;
3386 val = dib8000_read_word(state, 487 + i);
3387 switch (val & 0x3) {
3388 case 0:
3389 dprintk("dib8000_get_frontend : Layer %d DQPSK ", i);
3390 fe->dtv_property_cache.layer[i].modulation = DQPSK;
3391 break;
3392 case 1:
3393 fe->dtv_property_cache.layer[i].modulation = QPSK;
3394 dprintk("dib8000_get_frontend : Layer %d QPSK ", i);
3395 break;
3396 case 2:
3397 fe->dtv_property_cache.layer[i].modulation = QAM_16;
3398 dprintk("dib8000_get_frontend : Layer %d QAM16 ", i);
3399 break;
3400 case 3:
3401 default:
3402 dprintk("dib8000_get_frontend : Layer %d QAM64 ", i);
3403 fe->dtv_property_cache.layer[i].modulation = QAM_64;
3404 break;
3408 /* synchronize the cache with the other frontends */
3409 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3410 state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode = fe->dtv_property_cache.isdbt_sb_mode;
3411 state->fe[index_frontend]->dtv_property_cache.inversion = fe->dtv_property_cache.inversion;
3412 state->fe[index_frontend]->dtv_property_cache.transmission_mode = fe->dtv_property_cache.transmission_mode;
3413 state->fe[index_frontend]->dtv_property_cache.guard_interval = fe->dtv_property_cache.guard_interval;
3414 state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception = fe->dtv_property_cache.isdbt_partial_reception;
3415 for (i = 0; i < 3; i++) {
3416 state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count = fe->dtv_property_cache.layer[i].segment_count;
3417 state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving = fe->dtv_property_cache.layer[i].interleaving;
3418 state->fe[index_frontend]->dtv_property_cache.layer[i].fec = fe->dtv_property_cache.layer[i].fec;
3419 state->fe[index_frontend]->dtv_property_cache.layer[i].modulation = fe->dtv_property_cache.layer[i].modulation;
3422 return 0;
3425 static int dib8000_set_frontend(struct dvb_frontend *fe)
3427 struct dib8000_state *state = fe->demodulator_priv;
3428 struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
3429 int l, i, active, time, time_slave = FE_CALLBACK_TIME_NEVER;
3430 u8 exit_condition, index_frontend;
3431 u32 delay, callback_time;
3433 if (c->frequency == 0) {
3434 dprintk("dib8000: must at least specify frequency ");
3435 return 0;
3438 if (c->bandwidth_hz == 0) {
3439 dprintk("dib8000: no bandwidth specified, set to default ");
3440 c->bandwidth_hz = 6000000;
3443 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3444 /* synchronization of the cache */
3445 state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT;
3446 memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));
3448 /* set output mode and diversity input */
3449 if (state->revision != 0x8090) {
3450 dib8000_set_diversity_in(state->fe[index_frontend], 1);
3451 if (index_frontend != 0)
3452 dib8000_set_output_mode(state->fe[index_frontend],
3453 OUTMODE_DIVERSITY);
3454 else
3455 dib8000_set_output_mode(state->fe[0], OUTMODE_HIGH_Z);
3456 } else {
3457 dib8096p_set_diversity_in(state->fe[index_frontend], 1);
3458 if (index_frontend != 0)
3459 dib8096p_set_output_mode(state->fe[index_frontend],
3460 OUTMODE_DIVERSITY);
3461 else
3462 dib8096p_set_output_mode(state->fe[0], OUTMODE_HIGH_Z);
3465 /* tune the tuner */
3466 if (state->fe[index_frontend]->ops.tuner_ops.set_params)
3467 state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend]);
3469 dib8000_set_tune_state(state->fe[index_frontend], CT_AGC_START);
3472 /* turn off the diversity of the last chip */
3473 if (state->revision != 0x8090)
3474 dib8000_set_diversity_in(state->fe[index_frontend - 1], 0);
3475 else
3476 dib8096p_set_diversity_in(state->fe[index_frontend - 1], 0);
3478 /* start up the AGC */
3479 do {
3480 time = dib8000_agc_startup(state->fe[0]);
3481 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3482 time_slave = dib8000_agc_startup(state->fe[index_frontend]);
3483 if (time == FE_CALLBACK_TIME_NEVER)
3484 time = time_slave;
3485 else if ((time_slave != FE_CALLBACK_TIME_NEVER) && (time_slave > time))
3486 time = time_slave;
3488 if (time != FE_CALLBACK_TIME_NEVER)
3489 msleep(time / 10);
3490 else
3491 break;
3492 exit_condition = 1;
3493 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3494 if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_AGC_STOP) {
3495 exit_condition = 0;
3496 break;
3499 } while (exit_condition == 0);
3501 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
3502 dib8000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
3504 active = 1;
3505 do {
3506 callback_time = FE_CALLBACK_TIME_NEVER;
3507 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3508 delay = dib8000_tune(state->fe[index_frontend]);
3509 if (delay != FE_CALLBACK_TIME_NEVER)
3510 delay += systime();
3512 /* we are in autosearch */
3513 if (state->channel_parameters_set == 0) { /* searching */
3514 if ((dib8000_get_status(state->fe[index_frontend]) == FE_STATUS_DEMOD_SUCCESS) || (dib8000_get_status(state->fe[index_frontend]) == FE_STATUS_FFT_SUCCESS)) {
3515 dprintk("autosearch succeeded on fe%i", index_frontend);
3516 dib8000_get_frontend(state->fe[index_frontend]); /* we read the channel parameters from the frontend which was successful */
3517 state->channel_parameters_set = 1;
3519 for (l = 0; (l < MAX_NUMBER_OF_FRONTENDS) && (state->fe[l] != NULL); l++) {
3520 if (l != index_frontend) { /* and for all frontend except the successful one */
3521 dib8000_tune_restart_from_demod(state->fe[l]);
3523 state->fe[l]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode;
3524 state->fe[l]->dtv_property_cache.inversion = state->fe[index_frontend]->dtv_property_cache.inversion;
3525 state->fe[l]->dtv_property_cache.transmission_mode = state->fe[index_frontend]->dtv_property_cache.transmission_mode;
3526 state->fe[l]->dtv_property_cache.guard_interval = state->fe[index_frontend]->dtv_property_cache.guard_interval;
3527 state->fe[l]->dtv_property_cache.isdbt_partial_reception = state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception;
3528 for (i = 0; i < 3; i++) {
3529 state->fe[l]->dtv_property_cache.layer[i].segment_count = state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count;
3530 state->fe[l]->dtv_property_cache.layer[i].interleaving = state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving;
3531 state->fe[l]->dtv_property_cache.layer[i].fec = state->fe[index_frontend]->dtv_property_cache.layer[i].fec;
3532 state->fe[l]->dtv_property_cache.layer[i].modulation = state->fe[index_frontend]->dtv_property_cache.layer[i].modulation;
3539 if (delay < callback_time)
3540 callback_time = delay;
3542 /* tuning is done when the master frontend is done (failed or success) */
3543 if (dib8000_get_status(state->fe[0]) == FE_STATUS_TUNE_FAILED ||
3544 dib8000_get_status(state->fe[0]) == FE_STATUS_LOCKED ||
3545 dib8000_get_status(state->fe[0]) == FE_STATUS_DATA_LOCKED) {
3546 active = 0;
3547 /* we need to wait for all frontends to be finished */
3548 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3549 if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_DEMOD_STOP)
3550 active = 1;
3552 if (active == 0)
3553 dprintk("tuning done with status %d", dib8000_get_status(state->fe[0]));
3556 if ((active == 1) && (callback_time == FE_CALLBACK_TIME_NEVER)) {
3557 dprintk("strange callback time something went wrong");
3558 active = 0;
3561 while ((active == 1) && (systime() < callback_time))
3562 msleep(100);
3563 } while (active);
3565 /* set output mode */
3566 if (state->revision != 0x8090)
3567 dib8000_set_output_mode(state->fe[0], state->cfg.output_mode);
3568 else {
3569 dib8096p_set_output_mode(state->fe[0], state->cfg.output_mode);
3570 if (state->cfg.enMpegOutput == 0) {
3571 dib8096p_setDibTxMux(state, MPEG_ON_DIBTX);
3572 dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
3576 return 0;
3579 static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
3581 struct dib8000_state *state = fe->demodulator_priv;
3582 u16 lock_slave = 0, lock;
3583 u8 index_frontend;
3585 lock = dib8000_read_lock(fe);
3586 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
3587 lock_slave |= dib8000_read_lock(state->fe[index_frontend]);
3589 *stat = 0;
3591 if (((lock >> 13) & 1) || ((lock_slave >> 13) & 1))
3592 *stat |= FE_HAS_SIGNAL;
3594 if (((lock >> 8) & 1) || ((lock_slave >> 8) & 1)) /* Equal */
3595 *stat |= FE_HAS_CARRIER;
3597 if ((((lock >> 1) & 0xf) == 0xf) || (((lock_slave >> 1) & 0xf) == 0xf)) /* TMCC_SYNC */
3598 *stat |= FE_HAS_SYNC;
3600 if ((((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) && ((lock >> 5) & 7)) /* FEC MPEG */
3601 *stat |= FE_HAS_LOCK;
3603 if (((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) {
3604 lock = dib8000_read_word(state, 554); /* Viterbi Layer A */
3605 if (lock & 0x01)
3606 *stat |= FE_HAS_VITERBI;
3608 lock = dib8000_read_word(state, 555); /* Viterbi Layer B */
3609 if (lock & 0x01)
3610 *stat |= FE_HAS_VITERBI;
3612 lock = dib8000_read_word(state, 556); /* Viterbi Layer C */
3613 if (lock & 0x01)
3614 *stat |= FE_HAS_VITERBI;
3617 return 0;
3620 static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber)
3622 struct dib8000_state *state = fe->demodulator_priv;
3624 /* 13 segments */
3625 if (state->revision == 0x8090)
3626 *ber = (dib8000_read_word(state, 562) << 16) |
3627 dib8000_read_word(state, 563);
3628 else
3629 *ber = (dib8000_read_word(state, 560) << 16) |
3630 dib8000_read_word(state, 561);
3631 return 0;
3634 static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
3636 struct dib8000_state *state = fe->demodulator_priv;
3638 /* packet error on 13 seg */
3639 if (state->revision == 0x8090)
3640 *unc = dib8000_read_word(state, 567);
3641 else
3642 *unc = dib8000_read_word(state, 565);
3643 return 0;
3646 static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
3648 struct dib8000_state *state = fe->demodulator_priv;
3649 u8 index_frontend;
3650 u16 val;
3652 *strength = 0;
3653 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3654 state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
3655 if (val > 65535 - *strength)
3656 *strength = 65535;
3657 else
3658 *strength += val;
3661 val = 65535 - dib8000_read_word(state, 390);
3662 if (val > 65535 - *strength)
3663 *strength = 65535;
3664 else
3665 *strength += val;
3666 return 0;
3669 static u32 dib8000_get_snr(struct dvb_frontend *fe)
3671 struct dib8000_state *state = fe->demodulator_priv;
3672 u32 n, s, exp;
3673 u16 val;
3675 if (state->revision != 0x8090)
3676 val = dib8000_read_word(state, 542);
3677 else
3678 val = dib8000_read_word(state, 544);
3679 n = (val >> 6) & 0xff;
3680 exp = (val & 0x3f);
3681 if ((exp & 0x20) != 0)
3682 exp -= 0x40;
3683 n <<= exp+16;
3685 if (state->revision != 0x8090)
3686 val = dib8000_read_word(state, 543);
3687 else
3688 val = dib8000_read_word(state, 545);
3689 s = (val >> 6) & 0xff;
3690 exp = (val & 0x3f);
3691 if ((exp & 0x20) != 0)
3692 exp -= 0x40;
3693 s <<= exp+16;
3695 if (n > 0) {
3696 u32 t = (s/n) << 16;
3697 return t + ((s << 16) - n*t) / n;
3699 return 0xffffffff;
3702 static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
3704 struct dib8000_state *state = fe->demodulator_priv;
3705 u8 index_frontend;
3706 u32 snr_master;
3708 snr_master = dib8000_get_snr(fe);
3709 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
3710 snr_master += dib8000_get_snr(state->fe[index_frontend]);
3712 if ((snr_master >> 16) != 0) {
3713 snr_master = 10*intlog10(snr_master>>16);
3714 *snr = snr_master / ((1 << 24) / 10);
3716 else
3717 *snr = 0;
3719 return 0;
3722 int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
3724 struct dib8000_state *state = fe->demodulator_priv;
3725 u8 index_frontend = 1;
3727 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
3728 index_frontend++;
3729 if (index_frontend < MAX_NUMBER_OF_FRONTENDS) {
3730 dprintk("set slave fe %p to index %i", fe_slave, index_frontend);
3731 state->fe[index_frontend] = fe_slave;
3732 return 0;
3735 dprintk("too many slave frontend");
3736 return -ENOMEM;
3738 EXPORT_SYMBOL(dib8000_set_slave_frontend);
3740 int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
3742 struct dib8000_state *state = fe->demodulator_priv;
3743 u8 index_frontend = 1;
3745 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
3746 index_frontend++;
3747 if (index_frontend != 1) {
3748 dprintk("remove slave fe %p (index %i)", state->fe[index_frontend-1], index_frontend-1);
3749 state->fe[index_frontend] = NULL;
3750 return 0;
3753 dprintk("no frontend to be removed");
3754 return -ENODEV;
3756 EXPORT_SYMBOL(dib8000_remove_slave_frontend);
3758 struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
3760 struct dib8000_state *state = fe->demodulator_priv;
3762 if (slave_index >= MAX_NUMBER_OF_FRONTENDS)
3763 return NULL;
3764 return state->fe[slave_index];
3766 EXPORT_SYMBOL(dib8000_get_slave_frontend);
3769 int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods,
3770 u8 default_addr, u8 first_addr, u8 is_dib8096p)
3772 int k = 0, ret = 0;
3773 u8 new_addr = 0;
3774 struct i2c_device client = {.adap = host };
3776 client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
3777 if (!client.i2c_write_buffer) {
3778 dprintk("%s: not enough memory", __func__);
3779 return -ENOMEM;
3781 client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
3782 if (!client.i2c_read_buffer) {
3783 dprintk("%s: not enough memory", __func__);
3784 ret = -ENOMEM;
3785 goto error_memory_read;
3787 client.i2c_buffer_lock = kzalloc(sizeof(struct mutex), GFP_KERNEL);
3788 if (!client.i2c_buffer_lock) {
3789 dprintk("%s: not enough memory", __func__);
3790 ret = -ENOMEM;
3791 goto error_memory_lock;
3793 mutex_init(client.i2c_buffer_lock);
3795 for (k = no_of_demods - 1; k >= 0; k--) {
3796 /* designated i2c address */
3797 new_addr = first_addr + (k << 1);
3799 client.addr = new_addr;
3800 if (!is_dib8096p)
3801 dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */
3802 if (dib8000_identify(&client) == 0) {
3803 /* sram lead in, rdy */
3804 if (!is_dib8096p)
3805 dib8000_i2c_write16(&client, 1287, 0x0003);
3806 client.addr = default_addr;
3807 if (dib8000_identify(&client) == 0) {
3808 dprintk("#%d: not identified", k);
3809 ret = -EINVAL;
3810 goto error;
3814 /* start diversity to pull_down div_str - just for i2c-enumeration */
3815 dib8000_i2c_write16(&client, 1286, (1 << 10) | (4 << 6));
3817 /* set new i2c address and force divstart */
3818 dib8000_i2c_write16(&client, 1285, (new_addr << 2) | 0x2);
3819 client.addr = new_addr;
3820 dib8000_identify(&client);
3822 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
3825 for (k = 0; k < no_of_demods; k++) {
3826 new_addr = first_addr | (k << 1);
3827 client.addr = new_addr;
3829 // unforce divstr
3830 dib8000_i2c_write16(&client, 1285, new_addr << 2);
3832 /* deactivate div - it was just for i2c-enumeration */
3833 dib8000_i2c_write16(&client, 1286, 0);
3836 error:
3837 kfree(client.i2c_buffer_lock);
3838 error_memory_lock:
3839 kfree(client.i2c_read_buffer);
3840 error_memory_read:
3841 kfree(client.i2c_write_buffer);
3843 return ret;
3846 EXPORT_SYMBOL(dib8000_i2c_enumeration);
3847 static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
3849 tune->min_delay_ms = 1000;
3850 tune->step_size = 0;
3851 tune->max_drift = 0;
3852 return 0;
3855 static void dib8000_release(struct dvb_frontend *fe)
3857 struct dib8000_state *st = fe->demodulator_priv;
3858 u8 index_frontend;
3860 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++)
3861 dvb_frontend_detach(st->fe[index_frontend]);
3863 dibx000_exit_i2c_master(&st->i2c_master);
3864 i2c_del_adapter(&st->dib8096p_tuner_adap);
3865 kfree(st->fe[0]);
3866 kfree(st);
3869 struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
3871 struct dib8000_state *st = fe->demodulator_priv;
3872 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
3875 EXPORT_SYMBOL(dib8000_get_i2c_master);
3877 int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
3879 struct dib8000_state *st = fe->demodulator_priv;
3880 u16 val = dib8000_read_word(st, 299) & 0xffef;
3881 val |= (onoff & 0x1) << 4;
3883 dprintk("pid filter enabled %d", onoff);
3884 return dib8000_write_word(st, 299, val);
3886 EXPORT_SYMBOL(dib8000_pid_filter_ctrl);
3888 int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
3890 struct dib8000_state *st = fe->demodulator_priv;
3891 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
3892 return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0);
3894 EXPORT_SYMBOL(dib8000_pid_filter);
3896 static const struct dvb_frontend_ops dib8000_ops = {
3897 .delsys = { SYS_ISDBT },
3898 .info = {
3899 .name = "DiBcom 8000 ISDB-T",
3900 .frequency_min = 44250000,
3901 .frequency_max = 867250000,
3902 .frequency_stepsize = 62500,
3903 .caps = FE_CAN_INVERSION_AUTO |
3904 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
3905 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
3906 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
3907 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
3910 .release = dib8000_release,
3912 .init = dib8000_wakeup,
3913 .sleep = dib8000_sleep,
3915 .set_frontend = dib8000_set_frontend,
3916 .get_tune_settings = dib8000_fe_get_tune_settings,
3917 .get_frontend = dib8000_get_frontend,
3919 .read_status = dib8000_read_status,
3920 .read_ber = dib8000_read_ber,
3921 .read_signal_strength = dib8000_read_signal_strength,
3922 .read_snr = dib8000_read_snr,
3923 .read_ucblocks = dib8000_read_unc_blocks,
3926 struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
3928 struct dvb_frontend *fe;
3929 struct dib8000_state *state;
3931 dprintk("dib8000_attach");
3933 state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL);
3934 if (state == NULL)
3935 return NULL;
3936 fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);
3937 if (fe == NULL)
3938 goto error;
3940 memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
3941 state->i2c.adap = i2c_adap;
3942 state->i2c.addr = i2c_addr;
3943 state->i2c.i2c_write_buffer = state->i2c_write_buffer;
3944 state->i2c.i2c_read_buffer = state->i2c_read_buffer;
3945 mutex_init(&state->i2c_buffer_lock);
3946 state->i2c.i2c_buffer_lock = &state->i2c_buffer_lock;
3947 state->gpio_val = cfg->gpio_val;
3948 state->gpio_dir = cfg->gpio_dir;
3950 /* Ensure the output mode remains at the previous default if it's
3951 * not specifically set by the caller.
3953 if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
3954 state->cfg.output_mode = OUTMODE_MPEG2_FIFO;
3956 state->fe[0] = fe;
3957 fe->demodulator_priv = state;
3958 memcpy(&state->fe[0]->ops, &dib8000_ops, sizeof(struct dvb_frontend_ops));
3960 state->timf_default = cfg->pll->timf;
3962 if (dib8000_identify(&state->i2c) == 0)
3963 goto error;
3965 dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr);
3967 /* init 8096p tuner adapter */
3968 strncpy(state->dib8096p_tuner_adap.name, "DiB8096P tuner interface",
3969 sizeof(state->dib8096p_tuner_adap.name));
3970 state->dib8096p_tuner_adap.algo = &dib8096p_tuner_xfer_algo;
3971 state->dib8096p_tuner_adap.algo_data = NULL;
3972 state->dib8096p_tuner_adap.dev.parent = state->i2c.adap->dev.parent;
3973 i2c_set_adapdata(&state->dib8096p_tuner_adap, state);
3974 i2c_add_adapter(&state->dib8096p_tuner_adap);
3976 dib8000_reset(fe);
3978 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5)); /* ber_rs_len = 3 */
3979 state->current_demod_bw = 6000;
3981 return fe;
3983 error:
3984 kfree(state);
3985 return NULL;
3988 EXPORT_SYMBOL(dib8000_attach);
3990 MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@dibcom.fr, " "Patrick Boettcher <pboettcher@dibcom.fr>");
3991 MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator");
3992 MODULE_LICENSE("GPL");