Merge tag 'v3.3.7' into 3.3/master
[zen-stable.git] / drivers / media / dvb / frontends / dib8000.c
blob9ca34f495009dc29f15509f9075986af3247fe48
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 FE_CALLBACK_TIME_NEVER 0xffffffff
27 #define MAX_NUMBER_OF_FRONTENDS 6
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 #define FE_STATUS_TUNE_FAILED 0
37 struct i2c_device {
38 struct i2c_adapter *adap;
39 u8 addr;
40 u8 *i2c_write_buffer;
41 u8 *i2c_read_buffer;
42 struct mutex *i2c_buffer_lock;
45 struct dib8000_state {
46 struct dib8000_config cfg;
48 struct i2c_device i2c;
50 struct dibx000_i2c_master i2c_master;
52 u16 wbd_ref;
54 u8 current_band;
55 u32 current_bandwidth;
56 struct dibx000_agc_config *current_agc;
57 u32 timf;
58 u32 timf_default;
60 u8 div_force_off:1;
61 u8 div_state:1;
62 u16 div_sync_wait;
64 u8 agc_state;
65 u8 differential_constellation;
66 u8 diversity_onoff;
68 s16 ber_monitored_layer;
69 u16 gpio_dir;
70 u16 gpio_val;
72 u16 revision;
73 u8 isdbt_cfg_loaded;
74 enum frontend_tune_state tune_state;
75 u32 status;
77 struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
79 /* for the I2C transfer */
80 struct i2c_msg msg[2];
81 u8 i2c_write_buffer[4];
82 u8 i2c_read_buffer[2];
83 struct mutex i2c_buffer_lock;
84 u8 input_mode_mpeg;
86 u16 tuner_enable;
87 struct i2c_adapter dib8096p_tuner_adap;
90 enum dib8000_power_mode {
91 DIB8000_POWER_ALL = 0,
92 DIB8000_POWER_INTERFACE_ONLY,
95 static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
97 u16 ret;
98 struct i2c_msg msg[2] = {
99 {.addr = i2c->addr >> 1, .flags = 0, .len = 2},
100 {.addr = i2c->addr >> 1, .flags = I2C_M_RD, .len = 2},
103 if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) {
104 dprintk("could not acquire lock");
105 return 0;
108 msg[0].buf = i2c->i2c_write_buffer;
109 msg[0].buf[0] = reg >> 8;
110 msg[0].buf[1] = reg & 0xff;
111 msg[1].buf = i2c->i2c_read_buffer;
113 if (i2c_transfer(i2c->adap, msg, 2) != 2)
114 dprintk("i2c read error on %d", reg);
116 ret = (msg[1].buf[0] << 8) | msg[1].buf[1];
117 mutex_unlock(i2c->i2c_buffer_lock);
118 return ret;
121 static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
123 u16 ret;
125 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
126 dprintk("could not acquire lock");
127 return 0;
130 state->i2c_write_buffer[0] = reg >> 8;
131 state->i2c_write_buffer[1] = reg & 0xff;
133 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
134 state->msg[0].addr = state->i2c.addr >> 1;
135 state->msg[0].flags = 0;
136 state->msg[0].buf = state->i2c_write_buffer;
137 state->msg[0].len = 2;
138 state->msg[1].addr = state->i2c.addr >> 1;
139 state->msg[1].flags = I2C_M_RD;
140 state->msg[1].buf = state->i2c_read_buffer;
141 state->msg[1].len = 2;
143 if (i2c_transfer(state->i2c.adap, state->msg, 2) != 2)
144 dprintk("i2c read error on %d", reg);
146 ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
147 mutex_unlock(&state->i2c_buffer_lock);
149 return ret;
152 static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
154 u16 rw[2];
156 rw[0] = dib8000_read_word(state, reg + 0);
157 rw[1] = dib8000_read_word(state, reg + 1);
159 return ((rw[0] << 16) | (rw[1]));
162 static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
164 struct i2c_msg msg = {.addr = i2c->addr >> 1, .flags = 0, .len = 4};
165 int ret = 0;
167 if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) {
168 dprintk("could not acquire lock");
169 return -EINVAL;
172 msg.buf = i2c->i2c_write_buffer;
173 msg.buf[0] = (reg >> 8) & 0xff;
174 msg.buf[1] = reg & 0xff;
175 msg.buf[2] = (val >> 8) & 0xff;
176 msg.buf[3] = val & 0xff;
178 ret = i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
179 mutex_unlock(i2c->i2c_buffer_lock);
181 return ret;
184 static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
186 int ret;
188 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
189 dprintk("could not acquire lock");
190 return -EINVAL;
193 state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
194 state->i2c_write_buffer[1] = reg & 0xff;
195 state->i2c_write_buffer[2] = (val >> 8) & 0xff;
196 state->i2c_write_buffer[3] = val & 0xff;
198 memset(&state->msg[0], 0, sizeof(struct i2c_msg));
199 state->msg[0].addr = state->i2c.addr >> 1;
200 state->msg[0].flags = 0;
201 state->msg[0].buf = state->i2c_write_buffer;
202 state->msg[0].len = 4;
204 ret = (i2c_transfer(state->i2c.adap, state->msg, 1) != 1 ?
205 -EREMOTEIO : 0);
206 mutex_unlock(&state->i2c_buffer_lock);
208 return ret;
211 static const s16 coeff_2k_sb_1seg_dqpsk[8] = {
212 (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
213 (920 << 5) | 0x09
216 static const s16 coeff_2k_sb_1seg[8] = {
217 (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
220 static const s16 coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
221 (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
222 (-931 << 5) | 0x0f
225 static const s16 coeff_2k_sb_3seg_0dqpsk[8] = {
226 (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
227 (982 << 5) | 0x0c
230 static const s16 coeff_2k_sb_3seg_1dqpsk[8] = {
231 (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
232 (-720 << 5) | 0x0d
235 static const s16 coeff_2k_sb_3seg[8] = {
236 (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
237 (-610 << 5) | 0x0a
240 static const s16 coeff_4k_sb_1seg_dqpsk[8] = {
241 (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
242 (-922 << 5) | 0x0d
245 static const s16 coeff_4k_sb_1seg[8] = {
246 (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
247 (-655 << 5) | 0x0a
250 static const s16 coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
251 (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
252 (-958 << 5) | 0x13
255 static const s16 coeff_4k_sb_3seg_0dqpsk[8] = {
256 (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
257 (-568 << 5) | 0x0f
260 static const s16 coeff_4k_sb_3seg_1dqpsk[8] = {
261 (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
262 (-848 << 5) | 0x13
265 static const s16 coeff_4k_sb_3seg[8] = {
266 (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
267 (-869 << 5) | 0x13
270 static const s16 coeff_8k_sb_1seg_dqpsk[8] = {
271 (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
272 (-598 << 5) | 0x10
275 static const s16 coeff_8k_sb_1seg[8] = {
276 (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
277 (585 << 5) | 0x0f
280 static const s16 coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
281 (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
282 (0 << 5) | 0x14
285 static const s16 coeff_8k_sb_3seg_0dqpsk[8] = {
286 (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
287 (-877 << 5) | 0x15
290 static const s16 coeff_8k_sb_3seg_1dqpsk[8] = {
291 (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
292 (-921 << 5) | 0x14
295 static const s16 coeff_8k_sb_3seg[8] = {
296 (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
297 (690 << 5) | 0x14
300 static const s16 ana_fe_coeff_3seg[24] = {
301 81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
304 static const s16 ana_fe_coeff_1seg[24] = {
305 249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
308 static const s16 ana_fe_coeff_13seg[24] = {
309 396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
312 static u16 fft_to_mode(struct dib8000_state *state)
314 u16 mode;
315 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
316 case TRANSMISSION_MODE_2K:
317 mode = 1;
318 break;
319 case TRANSMISSION_MODE_4K:
320 mode = 2;
321 break;
322 default:
323 case TRANSMISSION_MODE_AUTO:
324 case TRANSMISSION_MODE_8K:
325 mode = 3;
326 break;
328 return mode;
331 static void dib8000_set_acquisition_mode(struct dib8000_state *state)
333 u16 nud = dib8000_read_word(state, 298);
334 nud |= (1 << 3) | (1 << 0);
335 dprintk("acquisition mode activated");
336 dib8000_write_word(state, 298, nud);
338 static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode)
340 struct dib8000_state *state = fe->demodulator_priv;
342 u16 outreg, fifo_threshold, smo_mode, sram = 0x0205; /* by default SDRAM deintlv is enabled */
344 outreg = 0;
345 fifo_threshold = 1792;
346 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
348 dprintk("-I- Setting output mode for demod %p to %d",
349 &state->fe[0], mode);
351 switch (mode) {
352 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
353 outreg = (1 << 10); /* 0x0400 */
354 break;
355 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
356 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
357 break;
358 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
359 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
360 break;
361 case OUTMODE_DIVERSITY:
362 if (state->cfg.hostbus_diversity) {
363 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
364 sram &= 0xfdff;
365 } else
366 sram |= 0x0c00;
367 break;
368 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
369 smo_mode |= (3 << 1);
370 fifo_threshold = 512;
371 outreg = (1 << 10) | (5 << 6);
372 break;
373 case OUTMODE_HIGH_Z: // disable
374 outreg = 0;
375 break;
377 case OUTMODE_ANALOG_ADC:
378 outreg = (1 << 10) | (3 << 6);
379 dib8000_set_acquisition_mode(state);
380 break;
382 default:
383 dprintk("Unhandled output_mode passed to be set for demod %p",
384 &state->fe[0]);
385 return -EINVAL;
388 if (state->cfg.output_mpeg2_in_188_bytes)
389 smo_mode |= (1 << 5);
391 dib8000_write_word(state, 299, smo_mode);
392 dib8000_write_word(state, 300, fifo_threshold); /* synchronous fread */
393 dib8000_write_word(state, 1286, outreg);
394 dib8000_write_word(state, 1291, sram);
396 return 0;
399 static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff)
401 struct dib8000_state *state = fe->demodulator_priv;
402 u16 sync_wait = dib8000_read_word(state, 273) & 0xfff0;
404 if (!state->differential_constellation) {
405 dib8000_write_word(state, 272, 1 << 9); //dvsy_off_lmod4 = 1
406 dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2); // sync_enable = 1; comb_mode = 2
407 } else {
408 dib8000_write_word(state, 272, 0); //dvsy_off_lmod4 = 0
409 dib8000_write_word(state, 273, sync_wait); // sync_enable = 0; comb_mode = 0
411 state->diversity_onoff = onoff;
413 switch (onoff) {
414 case 0: /* only use the internal way - not the diversity input */
415 dib8000_write_word(state, 270, 1);
416 dib8000_write_word(state, 271, 0);
417 break;
418 case 1: /* both ways */
419 dib8000_write_word(state, 270, 6);
420 dib8000_write_word(state, 271, 6);
421 break;
422 case 2: /* only the diversity input */
423 dib8000_write_word(state, 270, 0);
424 dib8000_write_word(state, 271, 1);
425 break;
427 return 0;
430 static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_power_mode mode)
432 /* by default everything is going to be powered off */
433 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
434 reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3,
435 reg_1280;
437 if (state->revision != 0x8090)
438 reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
439 else
440 reg_1280 = (dib8000_read_word(state, 1280) & 0x707f) | 0x8f80;
442 /* now, depending on the requested mode, we power on */
443 switch (mode) {
444 /* power up everything in the demod */
445 case DIB8000_POWER_ALL:
446 reg_774 = 0x0000;
447 reg_775 = 0x0000;
448 reg_776 = 0x0000;
449 reg_900 &= 0xfffc;
450 if (state->revision != 0x8090)
451 reg_1280 &= 0x00ff;
452 else
453 reg_1280 &= 0x707f;
454 break;
455 case DIB8000_POWER_INTERFACE_ONLY:
456 if (state->revision != 0x8090)
457 reg_1280 &= 0x00ff;
458 else
459 reg_1280 &= 0xfa7b;
460 break;
463 dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x", reg_774, reg_775, reg_776, reg_900, reg_1280);
464 dib8000_write_word(state, 774, reg_774);
465 dib8000_write_word(state, 775, reg_775);
466 dib8000_write_word(state, 776, reg_776);
467 dib8000_write_word(state, 900, reg_900);
468 dib8000_write_word(state, 1280, reg_1280);
471 static int dib8000_init_sdram(struct dib8000_state *state)
473 u16 reg = 0;
474 dprintk("Init sdram");
476 reg = dib8000_read_word(state, 274)&0xfff0;
477 /* P_dintlv_delay_ram = 7 because of MobileSdram */
478 dib8000_write_word(state, 274, reg | 0x7);
480 dib8000_write_word(state, 1803, (7<<2));
482 reg = dib8000_read_word(state, 1280);
483 /* force restart P_restart_sdram */
484 dib8000_write_word(state, 1280, reg | (1<<2));
486 /* release restart P_restart_sdram */
487 dib8000_write_word(state, 1280, reg);
489 return 0;
492 static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no)
494 int ret = 0;
495 u16 reg, reg_907 = dib8000_read_word(state, 907);
496 u16 reg_908 = dib8000_read_word(state, 908);
498 switch (no) {
499 case DIBX000_SLOW_ADC_ON:
500 if (state->revision != 0x8090) {
501 reg_908 |= (1 << 1) | (1 << 0);
502 ret |= dib8000_write_word(state, 908, reg_908);
503 reg_908 &= ~(1 << 1);
504 } else {
505 reg = dib8000_read_word(state, 1925);
506 /* en_slowAdc = 1 & reset_sladc = 1 */
507 dib8000_write_word(state, 1925, reg |
508 (1<<4) | (1<<2));
510 /* read acces to make it works... strange ... */
511 reg = dib8000_read_word(state, 1925);
512 msleep(20);
513 /* en_slowAdc = 1 & reset_sladc = 0 */
514 dib8000_write_word(state, 1925, reg & ~(1<<4));
516 reg = dib8000_read_word(state, 921) & ~((0x3 << 14)
517 | (0x3 << 12));
518 /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ;
519 (Vin2 = Vcm) */
520 dib8000_write_word(state, 921, reg | (1 << 14)
521 | (3 << 12));
523 break;
525 case DIBX000_SLOW_ADC_OFF:
526 if (state->revision == 0x8090) {
527 reg = dib8000_read_word(state, 1925);
528 /* reset_sladc = 1 en_slowAdc = 0 */
529 dib8000_write_word(state, 1925,
530 (reg & ~(1<<2)) | (1<<4));
532 reg_908 |= (1 << 1) | (1 << 0);
533 break;
535 case DIBX000_ADC_ON:
536 reg_907 &= 0x0fff;
537 reg_908 &= 0x0003;
538 break;
540 case DIBX000_ADC_OFF: // leave the VBG voltage on
541 reg_907 |= (1 << 14) | (1 << 13) | (1 << 12);
542 reg_908 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
543 break;
545 case DIBX000_VBG_ENABLE:
546 reg_907 &= ~(1 << 15);
547 break;
549 case DIBX000_VBG_DISABLE:
550 reg_907 |= (1 << 15);
551 break;
553 default:
554 break;
557 ret |= dib8000_write_word(state, 907, reg_907);
558 ret |= dib8000_write_word(state, 908, reg_908);
560 return ret;
563 static int dib8000_set_bandwidth(struct dvb_frontend *fe, u32 bw)
565 struct dib8000_state *state = fe->demodulator_priv;
566 u32 timf;
568 if (bw == 0)
569 bw = 6000;
571 if (state->timf == 0) {
572 dprintk("using default timf");
573 timf = state->timf_default;
574 } else {
575 dprintk("using updated timf");
576 timf = state->timf;
579 dib8000_write_word(state, 29, (u16) ((timf >> 16) & 0xffff));
580 dib8000_write_word(state, 30, (u16) ((timf) & 0xffff));
582 return 0;
585 static int dib8000_sad_calib(struct dib8000_state *state)
587 if (state->revision == 0x8090) {
588 dprintk("%s: the sad calibration is not needed for the dib8096P",
589 __func__);
590 return 0;
592 /* internal */
593 dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
594 dib8000_write_word(state, 924, 776); // 0.625*3.3 / 4096
596 /* do the calibration */
597 dib8000_write_word(state, 923, (1 << 0));
598 dib8000_write_word(state, 923, (0 << 0));
600 msleep(1);
601 return 0;
604 int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
606 struct dib8000_state *state = fe->demodulator_priv;
607 if (value > 4095)
608 value = 4095;
609 state->wbd_ref = value;
610 return dib8000_write_word(state, 106, value);
613 EXPORT_SYMBOL(dib8000_set_wbd_ref);
614 static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
616 dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25);
617 if (state->revision != 0x8090) {
618 dib8000_write_word(state, 23,
619 (u16) (((bw->internal * 1000) >> 16) & 0xffff));
620 dib8000_write_word(state, 24,
621 (u16) ((bw->internal * 1000) & 0xffff));
622 } else {
623 dib8000_write_word(state, 23, (u16) (((bw->internal / 2 * 1000) >> 16) & 0xffff));
624 dib8000_write_word(state, 24,
625 (u16) ((bw->internal / 2 * 1000) & 0xffff));
627 dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff));
628 dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff));
629 dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003));
631 if (state->revision != 0x8090)
632 dib8000_write_word(state, 922, bw->sad_cfg);
635 static void dib8000_reset_pll(struct dib8000_state *state)
637 const struct dibx000_bandwidth_config *pll = state->cfg.pll;
638 u16 clk_cfg1, reg;
640 if (state->revision != 0x8090) {
641 dib8000_write_word(state, 901,
642 (pll->pll_prediv << 8) | (pll->pll_ratio << 0));
644 clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
645 (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) |
646 (1 << 3) | (pll->pll_range << 1) |
647 (pll->pll_reset << 0);
649 dib8000_write_word(state, 902, clk_cfg1);
650 clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
651 dib8000_write_word(state, 902, clk_cfg1);
653 dprintk("clk_cfg1: 0x%04x", clk_cfg1);
655 /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
656 if (state->cfg.pll->ADClkSrc == 0)
657 dib8000_write_word(state, 904,
658 (0 << 15) | (0 << 12) | (0 << 10) |
659 (pll->modulo << 8) |
660 (pll->ADClkSrc << 7) | (0 << 1));
661 else if (state->cfg.refclksel != 0)
662 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
663 ((state->cfg.refclksel & 0x3) << 10) |
664 (pll->modulo << 8) |
665 (pll->ADClkSrc << 7) | (0 << 1));
666 else
667 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
668 (3 << 10) | (pll->modulo << 8) |
669 (pll->ADClkSrc << 7) | (0 << 1));
670 } else {
671 dib8000_write_word(state, 1856, (!pll->pll_reset<<13) |
672 (pll->pll_range<<12) | (pll->pll_ratio<<6) |
673 (pll->pll_prediv));
675 reg = dib8000_read_word(state, 1857);
676 dib8000_write_word(state, 1857, reg|(!pll->pll_bypass<<15));
678 reg = dib8000_read_word(state, 1858); /* Force clk out pll /2 */
679 dib8000_write_word(state, 1858, reg | 1);
681 dib8000_write_word(state, 904, (pll->modulo << 8));
684 dib8000_reset_pll_common(state, pll);
687 int dib8000_update_pll(struct dvb_frontend *fe,
688 struct dibx000_bandwidth_config *pll)
690 struct dib8000_state *state = fe->demodulator_priv;
691 u16 reg_1857, reg_1856 = dib8000_read_word(state, 1856);
692 u8 loopdiv, prediv;
693 u32 internal, xtal;
695 /* get back old values */
696 prediv = reg_1856 & 0x3f;
697 loopdiv = (reg_1856 >> 6) & 0x3f;
699 if ((pll != NULL) && (pll->pll_prediv != prediv ||
700 pll->pll_ratio != loopdiv)) {
701 dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, pll->pll_prediv, loopdiv, pll->pll_ratio);
702 reg_1856 &= 0xf000;
703 reg_1857 = dib8000_read_word(state, 1857);
704 /* disable PLL */
705 dib8000_write_word(state, 1857, reg_1857 & ~(1 << 15));
707 dib8000_write_word(state, 1856, reg_1856 |
708 ((pll->pll_ratio & 0x3f) << 6) |
709 (pll->pll_prediv & 0x3f));
711 /* write new system clk into P_sec_len */
712 internal = dib8000_read32(state, 23) / 1000;
713 dprintk("Old Internal = %d", internal);
714 xtal = 2 * (internal / loopdiv) * prediv;
715 internal = 1000 * (xtal/pll->pll_prediv) * pll->pll_ratio;
716 dprintk("Xtal = %d , New Fmem = %d New Fdemod = %d, New Fsampling = %d", xtal, internal/1000, internal/2000, internal/8000);
717 dprintk("New Internal = %d", internal);
719 dib8000_write_word(state, 23,
720 (u16) (((internal / 2) >> 16) & 0xffff));
721 dib8000_write_word(state, 24, (u16) ((internal / 2) & 0xffff));
722 /* enable PLL */
723 dib8000_write_word(state, 1857, reg_1857 | (1 << 15));
725 while (((dib8000_read_word(state, 1856)>>15)&0x1) != 1)
726 dprintk("Waiting for PLL to lock");
728 /* verify */
729 reg_1856 = dib8000_read_word(state, 1856);
730 dprintk("PLL Updated with prediv = %d and loopdiv = %d",
731 reg_1856&0x3f, (reg_1856>>6)&0x3f);
733 return 0;
735 return -EINVAL;
737 EXPORT_SYMBOL(dib8000_update_pll);
740 static int dib8000_reset_gpio(struct dib8000_state *st)
742 /* reset the GPIOs */
743 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
744 dib8000_write_word(st, 1030, st->cfg.gpio_val);
746 /* TODO 782 is P_gpio_od */
748 dib8000_write_word(st, 1032, st->cfg.gpio_pwm_pos);
750 dib8000_write_word(st, 1037, st->cfg.pwm_freq_div);
751 return 0;
754 static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val)
756 st->cfg.gpio_dir = dib8000_read_word(st, 1029);
757 st->cfg.gpio_dir &= ~(1 << num); /* reset the direction bit */
758 st->cfg.gpio_dir |= (dir & 0x1) << num; /* set the new direction */
759 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
761 st->cfg.gpio_val = dib8000_read_word(st, 1030);
762 st->cfg.gpio_val &= ~(1 << num); /* reset the direction bit */
763 st->cfg.gpio_val |= (val & 0x01) << num; /* set the new value */
764 dib8000_write_word(st, 1030, st->cfg.gpio_val);
766 dprintk("gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val);
768 return 0;
771 int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
773 struct dib8000_state *state = fe->demodulator_priv;
774 return dib8000_cfg_gpio(state, num, dir, val);
777 EXPORT_SYMBOL(dib8000_set_gpio);
778 static const u16 dib8000_defaults[] = {
779 /* auto search configuration - lock0 by default waiting
780 * for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */
781 3, 7,
782 0x0004,
783 0x0400,
784 0x0814,
786 12, 11,
787 0x001b,
788 0x7740,
789 0x005b,
790 0x8d80,
791 0x01c9,
792 0xc380,
793 0x0000,
794 0x0080,
795 0x0000,
796 0x0090,
797 0x0001,
798 0xd4c0,
800 /*1, 32,
801 0x6680 // P_corm_thres Lock algorithms configuration */
803 11, 80, /* set ADC level to -16 */
804 (1 << 13) - 825 - 117,
805 (1 << 13) - 837 - 117,
806 (1 << 13) - 811 - 117,
807 (1 << 13) - 766 - 117,
808 (1 << 13) - 737 - 117,
809 (1 << 13) - 693 - 117,
810 (1 << 13) - 648 - 117,
811 (1 << 13) - 619 - 117,
812 (1 << 13) - 575 - 117,
813 (1 << 13) - 531 - 117,
814 (1 << 13) - 501 - 117,
816 4, 108,
822 1, 175,
823 0x0410,
824 1, 179,
825 8192, // P_fft_nb_to_cut
827 6, 181,
828 0x2800, // P_coff_corthres_ ( 2k 4k 8k ) 0x2800
829 0x2800,
830 0x2800,
831 0x2800, // P_coff_cpilthres_ ( 2k 4k 8k ) 0x2800
832 0x2800,
833 0x2800,
835 2, 193,
836 0x0666, // P_pha3_thres
837 0x0000, // P_cti_use_cpe, P_cti_use_prog
839 2, 205,
840 0x200f, // P_cspu_regul, P_cspu_win_cut
841 0x000f, // P_des_shift_work
843 5, 215,
844 0x023d, // P_adp_regul_cnt
845 0x00a4, // P_adp_noise_cnt
846 0x00a4, // P_adp_regul_ext
847 0x7ff0, // P_adp_noise_ext
848 0x3ccc, // P_adp_fil
850 1, 230,
851 0x0000, // P_2d_byp_ti_num
853 1, 263,
854 0x800, //P_equal_thres_wgn
856 1, 268,
857 (2 << 9) | 39, // P_equal_ctrl_synchro, P_equal_speedmode
859 1, 270,
860 0x0001, // P_div_lock0_wait
861 1, 285,
862 0x0020, //p_fec_
863 1, 299,
864 0x0062, /* P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard */
866 1, 338,
867 (1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1
868 (1 << 10) |
869 (0 << 9) | /* P_ctrl_pre_freq_inh=0 */
870 (3 << 5) | /* P_ctrl_pre_freq_step=3 */
871 (1 << 0), /* P_pre_freq_win_len=1 */
876 static u16 dib8000_identify(struct i2c_device *client)
878 u16 value;
880 //because of glitches sometimes
881 value = dib8000_i2c_read16(client, 896);
883 if ((value = dib8000_i2c_read16(client, 896)) != 0x01b3) {
884 dprintk("wrong Vendor ID (read=0x%x)", value);
885 return 0;
888 value = dib8000_i2c_read16(client, 897);
889 if (value != 0x8000 && value != 0x8001 &&
890 value != 0x8002 && value != 0x8090) {
891 dprintk("wrong Device ID (%x)", value);
892 return 0;
895 switch (value) {
896 case 0x8000:
897 dprintk("found DiB8000A");
898 break;
899 case 0x8001:
900 dprintk("found DiB8000B");
901 break;
902 case 0x8002:
903 dprintk("found DiB8000C");
904 break;
905 case 0x8090:
906 dprintk("found DiB8096P");
907 break;
909 return value;
912 static int dib8000_reset(struct dvb_frontend *fe)
914 struct dib8000_state *state = fe->demodulator_priv;
916 if ((state->revision = dib8000_identify(&state->i2c)) == 0)
917 return -EINVAL;
919 /* sram lead in, rdy */
920 if (state->revision != 0x8090)
921 dib8000_write_word(state, 1287, 0x0003);
923 if (state->revision == 0x8000)
924 dprintk("error : dib8000 MA not supported");
926 dibx000_reset_i2c_master(&state->i2c_master);
928 dib8000_set_power_mode(state, DIB8000_POWER_ALL);
930 /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
931 dib8000_set_adc_state(state, DIBX000_VBG_ENABLE);
933 /* restart all parts */
934 dib8000_write_word(state, 770, 0xffff);
935 dib8000_write_word(state, 771, 0xffff);
936 dib8000_write_word(state, 772, 0xfffc);
937 if (state->revision == 0x8090)
938 dib8000_write_word(state, 1280, 0x0045);
939 else
940 dib8000_write_word(state, 1280, 0x004d);
941 dib8000_write_word(state, 1281, 0x000c);
943 dib8000_write_word(state, 770, 0x0000);
944 dib8000_write_word(state, 771, 0x0000);
945 dib8000_write_word(state, 772, 0x0000);
946 dib8000_write_word(state, 898, 0x0004); // sad
947 dib8000_write_word(state, 1280, 0x0000);
948 dib8000_write_word(state, 1281, 0x0000);
950 /* drives */
951 if (state->revision != 0x8090) {
952 if (state->cfg.drives)
953 dib8000_write_word(state, 906, state->cfg.drives);
954 else {
955 dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.");
956 /* min drive SDRAM - not optimal - adjust */
957 dib8000_write_word(state, 906, 0x2d98);
961 dib8000_reset_pll(state);
962 if (state->revision != 0x8090)
963 dib8000_write_word(state, 898, 0x0004);
965 if (dib8000_reset_gpio(state) != 0)
966 dprintk("GPIO reset was not successful.");
968 if ((state->revision != 0x8090) &&
969 (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0))
970 dprintk("OUTPUT_MODE could not be resetted.");
972 state->current_agc = NULL;
974 // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
975 /* P_iqc_ca2 = 0; P_iqc_impnc_on = 0; P_iqc_mode = 0; */
976 if (state->cfg.pll->ifreq == 0)
977 dib8000_write_word(state, 40, 0x0755); /* P_iqc_corr_inh = 0 enable IQcorr block */
978 else
979 dib8000_write_word(state, 40, 0x1f55); /* P_iqc_corr_inh = 1 disable IQcorr block */
982 u16 l = 0, r;
983 const u16 *n;
984 n = dib8000_defaults;
985 l = *n++;
986 while (l) {
987 r = *n++;
988 do {
989 dib8000_write_word(state, r, *n++);
990 r++;
991 } while (--l);
992 l = *n++;
995 if (state->revision != 0x8090)
996 dib8000_write_word(state, 903, (0 << 4) | 2);
997 state->isdbt_cfg_loaded = 0;
999 //div_cfg override for special configs
1000 if (state->cfg.div_cfg != 0)
1001 dib8000_write_word(state, 903, state->cfg.div_cfg);
1003 /* unforce divstr regardless whether i2c enumeration was done or not */
1004 dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1));
1006 dib8000_set_bandwidth(fe, 6000);
1008 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
1009 if (state->revision != 0x8090) {
1010 dib8000_sad_calib(state);
1011 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
1014 dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY);
1016 return 0;
1019 static void dib8000_restart_agc(struct dib8000_state *state)
1021 // P_restart_iqc & P_restart_agc
1022 dib8000_write_word(state, 770, 0x0a00);
1023 dib8000_write_word(state, 770, 0x0000);
1026 static int dib8000_update_lna(struct dib8000_state *state)
1028 u16 dyn_gain;
1030 if (state->cfg.update_lna) {
1031 // read dyn_gain here (because it is demod-dependent and not tuner)
1032 dyn_gain = dib8000_read_word(state, 390);
1034 if (state->cfg.update_lna(state->fe[0], dyn_gain)) {
1035 dib8000_restart_agc(state);
1036 return 1;
1039 return 0;
1042 static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
1044 struct dibx000_agc_config *agc = NULL;
1045 int i;
1046 u16 reg;
1048 if (state->current_band == band && state->current_agc != NULL)
1049 return 0;
1050 state->current_band = band;
1052 for (i = 0; i < state->cfg.agc_config_count; i++)
1053 if (state->cfg.agc[i].band_caps & band) {
1054 agc = &state->cfg.agc[i];
1055 break;
1058 if (agc == NULL) {
1059 dprintk("no valid AGC configuration found for band 0x%02x", band);
1060 return -EINVAL;
1063 state->current_agc = agc;
1065 /* AGC */
1066 dib8000_write_word(state, 76, agc->setup);
1067 dib8000_write_word(state, 77, agc->inv_gain);
1068 dib8000_write_word(state, 78, agc->time_stabiliz);
1069 dib8000_write_word(state, 101, (agc->alpha_level << 12) | agc->thlock);
1071 // Demod AGC loop configuration
1072 dib8000_write_word(state, 102, (agc->alpha_mant << 5) | agc->alpha_exp);
1073 dib8000_write_word(state, 103, (agc->beta_mant << 6) | agc->beta_exp);
1075 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
1076 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
1078 /* AGC continued */
1079 if (state->wbd_ref != 0)
1080 dib8000_write_word(state, 106, state->wbd_ref);
1081 else // use default
1082 dib8000_write_word(state, 106, agc->wbd_ref);
1084 if (state->revision == 0x8090) {
1085 reg = dib8000_read_word(state, 922) & (0x3 << 2);
1086 dib8000_write_word(state, 922, reg | (agc->wbd_sel << 2));
1089 dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
1090 dib8000_write_word(state, 108, agc->agc1_max);
1091 dib8000_write_word(state, 109, agc->agc1_min);
1092 dib8000_write_word(state, 110, agc->agc2_max);
1093 dib8000_write_word(state, 111, agc->agc2_min);
1094 dib8000_write_word(state, 112, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
1095 dib8000_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
1096 dib8000_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
1097 dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
1099 dib8000_write_word(state, 75, agc->agc1_pt3);
1100 if (state->revision != 0x8090)
1101 dib8000_write_word(state, 923,
1102 (dib8000_read_word(state, 923) & 0xffe3) |
1103 (agc->wbd_inv << 4) | (agc->wbd_sel << 2));
1105 return 0;
1108 void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
1110 struct dib8000_state *state = fe->demodulator_priv;
1111 dib8000_set_adc_state(state, DIBX000_ADC_ON);
1112 dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000)));
1114 EXPORT_SYMBOL(dib8000_pwm_agc_reset);
1116 static int dib8000_agc_soft_split(struct dib8000_state *state)
1118 u16 agc, split_offset;
1120 if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
1121 return FE_CALLBACK_TIME_NEVER;
1123 // n_agc_global
1124 agc = dib8000_read_word(state, 390);
1126 if (agc > state->current_agc->split.min_thres)
1127 split_offset = state->current_agc->split.min;
1128 else if (agc < state->current_agc->split.max_thres)
1129 split_offset = state->current_agc->split.max;
1130 else
1131 split_offset = state->current_agc->split.max *
1132 (agc - state->current_agc->split.min_thres) /
1133 (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
1135 dprintk("AGC split_offset: %d", split_offset);
1137 // P_agc_force_split and P_agc_split_offset
1138 dib8000_write_word(state, 107, (dib8000_read_word(state, 107) & 0xff00) | split_offset);
1139 return 5000;
1142 static int dib8000_agc_startup(struct dvb_frontend *fe)
1144 struct dib8000_state *state = fe->demodulator_priv;
1145 enum frontend_tune_state *tune_state = &state->tune_state;
1146 int ret = 0;
1147 u16 reg, upd_demod_gain_period = 0x8000;
1149 switch (*tune_state) {
1150 case CT_AGC_START:
1151 // set power-up level: interf+analog+AGC
1153 if (state->revision != 0x8090)
1154 dib8000_set_adc_state(state, DIBX000_ADC_ON);
1155 else {
1156 dib8000_set_power_mode(state, DIB8000_POWER_ALL);
1158 reg = dib8000_read_word(state, 1947)&0xff00;
1159 dib8000_write_word(state, 1946,
1160 upd_demod_gain_period & 0xFFFF);
1161 /* bit 14 = enDemodGain */
1162 dib8000_write_word(state, 1947, reg | (1<<14) |
1163 ((upd_demod_gain_period >> 16) & 0xFF));
1165 /* enable adc i & q */
1166 reg = dib8000_read_word(state, 1920);
1167 dib8000_write_word(state, 1920, (reg | 0x3) &
1168 (~(1 << 7)));
1171 if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) {
1172 *tune_state = CT_AGC_STOP;
1173 state->status = FE_STATUS_TUNE_FAILED;
1174 break;
1177 ret = 70;
1178 *tune_state = CT_AGC_STEP_0;
1179 break;
1181 case CT_AGC_STEP_0:
1182 //AGC initialization
1183 if (state->cfg.agc_control)
1184 state->cfg.agc_control(fe, 1);
1186 dib8000_restart_agc(state);
1188 // wait AGC rough lock time
1189 ret = 50;
1190 *tune_state = CT_AGC_STEP_1;
1191 break;
1193 case CT_AGC_STEP_1:
1194 // wait AGC accurate lock time
1195 ret = 70;
1197 if (dib8000_update_lna(state))
1198 // wait only AGC rough lock time
1199 ret = 50;
1200 else
1201 *tune_state = CT_AGC_STEP_2;
1202 break;
1204 case CT_AGC_STEP_2:
1205 dib8000_agc_soft_split(state);
1207 if (state->cfg.agc_control)
1208 state->cfg.agc_control(fe, 0);
1210 *tune_state = CT_AGC_STOP;
1211 break;
1212 default:
1213 ret = dib8000_agc_soft_split(state);
1214 break;
1216 return ret;
1220 static void dib8096p_host_bus_drive(struct dib8000_state *state, u8 drive)
1222 u16 reg;
1224 drive &= 0x7;
1226 /* drive host bus 2, 3, 4 */
1227 reg = dib8000_read_word(state, 1798) &
1228 ~(0x7 | (0x7 << 6) | (0x7 << 12));
1229 reg |= (drive<<12) | (drive<<6) | drive;
1230 dib8000_write_word(state, 1798, reg);
1232 /* drive host bus 5,6 */
1233 reg = dib8000_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
1234 reg |= (drive<<8) | (drive<<2);
1235 dib8000_write_word(state, 1799, reg);
1237 /* drive host bus 7, 8, 9 */
1238 reg = dib8000_read_word(state, 1800) &
1239 ~(0x7 | (0x7 << 6) | (0x7 << 12));
1240 reg |= (drive<<12) | (drive<<6) | drive;
1241 dib8000_write_word(state, 1800, reg);
1243 /* drive host bus 10, 11 */
1244 reg = dib8000_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
1245 reg |= (drive<<8) | (drive<<2);
1246 dib8000_write_word(state, 1801, reg);
1248 /* drive host bus 12, 13, 14 */
1249 reg = dib8000_read_word(state, 1802) &
1250 ~(0x7 | (0x7 << 6) | (0x7 << 12));
1251 reg |= (drive<<12) | (drive<<6) | drive;
1252 dib8000_write_word(state, 1802, reg);
1255 static u32 dib8096p_calcSyncFreq(u32 P_Kin, u32 P_Kout,
1256 u32 insertExtSynchro, u32 syncSize)
1258 u32 quantif = 3;
1259 u32 nom = (insertExtSynchro * P_Kin+syncSize);
1260 u32 denom = P_Kout;
1261 u32 syncFreq = ((nom << quantif) / denom);
1263 if ((syncFreq & ((1 << quantif) - 1)) != 0)
1264 syncFreq = (syncFreq >> quantif) + 1;
1265 else
1266 syncFreq = (syncFreq >> quantif);
1268 if (syncFreq != 0)
1269 syncFreq = syncFreq - 1;
1271 return syncFreq;
1274 static void dib8096p_cfg_DibTx(struct dib8000_state *state, u32 P_Kin,
1275 u32 P_Kout, u32 insertExtSynchro, u32 synchroMode,
1276 u32 syncWord, u32 syncSize)
1278 dprintk("Configure DibStream Tx");
1280 dib8000_write_word(state, 1615, 1);
1281 dib8000_write_word(state, 1603, P_Kin);
1282 dib8000_write_word(state, 1605, P_Kout);
1283 dib8000_write_word(state, 1606, insertExtSynchro);
1284 dib8000_write_word(state, 1608, synchroMode);
1285 dib8000_write_word(state, 1609, (syncWord >> 16) & 0xffff);
1286 dib8000_write_word(state, 1610, syncWord & 0xffff);
1287 dib8000_write_word(state, 1612, syncSize);
1288 dib8000_write_word(state, 1615, 0);
1291 static void dib8096p_cfg_DibRx(struct dib8000_state *state, u32 P_Kin,
1292 u32 P_Kout, u32 synchroMode, u32 insertExtSynchro,
1293 u32 syncWord, u32 syncSize, u32 dataOutRate)
1295 u32 syncFreq;
1297 dprintk("Configure DibStream Rx synchroMode = %d", synchroMode);
1299 if ((P_Kin != 0) && (P_Kout != 0)) {
1300 syncFreq = dib8096p_calcSyncFreq(P_Kin, P_Kout,
1301 insertExtSynchro, syncSize);
1302 dib8000_write_word(state, 1542, syncFreq);
1305 dib8000_write_word(state, 1554, 1);
1306 dib8000_write_word(state, 1536, P_Kin);
1307 dib8000_write_word(state, 1537, P_Kout);
1308 dib8000_write_word(state, 1539, synchroMode);
1309 dib8000_write_word(state, 1540, (syncWord >> 16) & 0xffff);
1310 dib8000_write_word(state, 1541, syncWord & 0xffff);
1311 dib8000_write_word(state, 1543, syncSize);
1312 dib8000_write_word(state, 1544, dataOutRate);
1313 dib8000_write_word(state, 1554, 0);
1316 static void dib8096p_enMpegMux(struct dib8000_state *state, int onoff)
1318 u16 reg_1287;
1320 reg_1287 = dib8000_read_word(state, 1287);
1322 switch (onoff) {
1323 case 1:
1324 reg_1287 &= ~(1 << 8);
1325 break;
1326 case 0:
1327 reg_1287 |= (1 << 8);
1328 break;
1331 dib8000_write_word(state, 1287, reg_1287);
1334 static void dib8096p_configMpegMux(struct dib8000_state *state,
1335 u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
1337 u16 reg_1287;
1339 dprintk("Enable Mpeg mux");
1341 dib8096p_enMpegMux(state, 0);
1343 /* If the input mode is MPEG do not divide the serial clock */
1344 if ((enSerialMode == 1) && (state->input_mode_mpeg == 1))
1345 enSerialClkDiv2 = 0;
1347 reg_1287 = ((pulseWidth & 0x1f) << 3) |
1348 ((enSerialMode & 0x1) << 2) | (enSerialClkDiv2 & 0x1);
1349 dib8000_write_word(state, 1287, reg_1287);
1351 dib8096p_enMpegMux(state, 1);
1354 static void dib8096p_setDibTxMux(struct dib8000_state *state, int mode)
1356 u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 7);
1358 switch (mode) {
1359 case MPEG_ON_DIBTX:
1360 dprintk("SET MPEG ON DIBSTREAM TX");
1361 dib8096p_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
1362 reg_1288 |= (1 << 9); break;
1363 case DIV_ON_DIBTX:
1364 dprintk("SET DIV_OUT ON DIBSTREAM TX");
1365 dib8096p_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
1366 reg_1288 |= (1 << 8); break;
1367 case ADC_ON_DIBTX:
1368 dprintk("SET ADC_OUT ON DIBSTREAM TX");
1369 dib8096p_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
1370 reg_1288 |= (1 << 7); break;
1371 default:
1372 break;
1374 dib8000_write_word(state, 1288, reg_1288);
1377 static void dib8096p_setHostBusMux(struct dib8000_state *state, int mode)
1379 u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 4);
1381 switch (mode) {
1382 case DEMOUT_ON_HOSTBUS:
1383 dprintk("SET DEM OUT OLD INTERF ON HOST BUS");
1384 dib8096p_enMpegMux(state, 0);
1385 reg_1288 |= (1 << 6);
1386 break;
1387 case DIBTX_ON_HOSTBUS:
1388 dprintk("SET DIBSTREAM TX ON HOST BUS");
1389 dib8096p_enMpegMux(state, 0);
1390 reg_1288 |= (1 << 5);
1391 break;
1392 case MPEG_ON_HOSTBUS:
1393 dprintk("SET MPEG MUX ON HOST BUS");
1394 reg_1288 |= (1 << 4);
1395 break;
1396 default:
1397 break;
1399 dib8000_write_word(state, 1288, reg_1288);
1402 static int dib8096p_set_diversity_in(struct dvb_frontend *fe, int onoff)
1404 struct dib8000_state *state = fe->demodulator_priv;
1405 u16 reg_1287;
1407 switch (onoff) {
1408 case 0: /* only use the internal way - not the diversity input */
1409 dprintk("%s mode OFF : by default Enable Mpeg INPUT",
1410 __func__);
1411 /* outputRate = 8 */
1412 dib8096p_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0);
1414 /* Do not divide the serial clock of MPEG MUX in
1415 SERIAL MODE in case input mode MPEG is used */
1416 reg_1287 = dib8000_read_word(state, 1287);
1417 /* enSerialClkDiv2 == 1 ? */
1418 if ((reg_1287 & 0x1) == 1) {
1419 /* force enSerialClkDiv2 = 0 */
1420 reg_1287 &= ~0x1;
1421 dib8000_write_word(state, 1287, reg_1287);
1423 state->input_mode_mpeg = 1;
1424 break;
1425 case 1: /* both ways */
1426 case 2: /* only the diversity input */
1427 dprintk("%s ON : Enable diversity INPUT", __func__);
1428 dib8096p_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
1429 state->input_mode_mpeg = 0;
1430 break;
1433 dib8000_set_diversity_in(state->fe[0], onoff);
1434 return 0;
1437 static int dib8096p_set_output_mode(struct dvb_frontend *fe, int mode)
1439 struct dib8000_state *state = fe->demodulator_priv;
1440 u16 outreg, smo_mode, fifo_threshold;
1441 u8 prefer_mpeg_mux_use = 1;
1442 int ret = 0;
1444 dib8096p_host_bus_drive(state, 1);
1446 fifo_threshold = 1792;
1447 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
1448 outreg = dib8000_read_word(state, 1286) &
1449 ~((1 << 10) | (0x7 << 6) | (1 << 1));
1451 switch (mode) {
1452 case OUTMODE_HIGH_Z:
1453 outreg = 0;
1454 break;
1456 case OUTMODE_MPEG2_SERIAL:
1457 if (prefer_mpeg_mux_use) {
1458 dprintk("dib8096P setting output mode TS_SERIAL using Mpeg Mux");
1459 dib8096p_configMpegMux(state, 3, 1, 1);
1460 dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS);
1461 } else {/* Use Smooth block */
1462 dprintk("dib8096P setting output mode TS_SERIAL using Smooth bloc");
1463 dib8096p_setHostBusMux(state,
1464 DEMOUT_ON_HOSTBUS);
1465 outreg |= (2 << 6) | (0 << 1);
1467 break;
1469 case OUTMODE_MPEG2_PAR_GATED_CLK:
1470 if (prefer_mpeg_mux_use) {
1471 dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Mpeg Mux");
1472 dib8096p_configMpegMux(state, 2, 0, 0);
1473 dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS);
1474 } else { /* Use Smooth block */
1475 dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Smooth block");
1476 dib8096p_setHostBusMux(state,
1477 DEMOUT_ON_HOSTBUS);
1478 outreg |= (0 << 6);
1480 break;
1482 case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */
1483 dprintk("dib8096P setting output mode TS_PARALLEL_CONT using Smooth block");
1484 dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
1485 outreg |= (1 << 6);
1486 break;
1488 case OUTMODE_MPEG2_FIFO:
1489 /* Using Smooth block because not supported
1490 by new Mpeg Mux bloc */
1491 dprintk("dib8096P setting output mode TS_FIFO using Smooth block");
1492 dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
1493 outreg |= (5 << 6);
1494 smo_mode |= (3 << 1);
1495 fifo_threshold = 512;
1496 break;
1498 case OUTMODE_DIVERSITY:
1499 dprintk("dib8096P setting output mode MODE_DIVERSITY");
1500 dib8096p_setDibTxMux(state, DIV_ON_DIBTX);
1501 dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
1502 break;
1504 case OUTMODE_ANALOG_ADC:
1505 dprintk("dib8096P setting output mode MODE_ANALOG_ADC");
1506 dib8096p_setDibTxMux(state, ADC_ON_DIBTX);
1507 dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
1508 break;
1511 if (mode != OUTMODE_HIGH_Z)
1512 outreg |= (1<<10);
1514 dprintk("output_mpeg2_in_188_bytes = %d",
1515 state->cfg.output_mpeg2_in_188_bytes);
1516 if (state->cfg.output_mpeg2_in_188_bytes)
1517 smo_mode |= (1 << 5);
1519 ret |= dib8000_write_word(state, 299, smo_mode);
1520 /* synchronous fread */
1521 ret |= dib8000_write_word(state, 299 + 1, fifo_threshold);
1522 ret |= dib8000_write_word(state, 1286, outreg);
1524 return ret;
1527 static int map_addr_to_serpar_number(struct i2c_msg *msg)
1529 if (msg->buf[0] <= 15)
1530 msg->buf[0] -= 1;
1531 else if (msg->buf[0] == 17)
1532 msg->buf[0] = 15;
1533 else if (msg->buf[0] == 16)
1534 msg->buf[0] = 17;
1535 else if (msg->buf[0] == 19)
1536 msg->buf[0] = 16;
1537 else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
1538 msg->buf[0] -= 3;
1539 else if (msg->buf[0] == 28)
1540 msg->buf[0] = 23;
1541 else if (msg->buf[0] == 99)
1542 msg->buf[0] = 99;
1543 else
1544 return -EINVAL;
1545 return 0;
1548 static int dib8096p_tuner_write_serpar(struct i2c_adapter *i2c_adap,
1549 struct i2c_msg msg[], int num)
1551 struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1552 u8 n_overflow = 1;
1553 u16 i = 1000;
1554 u16 serpar_num = msg[0].buf[0];
1556 while (n_overflow == 1 && i) {
1557 n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1;
1558 i--;
1559 if (i == 0)
1560 dprintk("Tuner ITF: write busy (overflow)");
1562 dib8000_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
1563 dib8000_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
1565 return num;
1568 static int dib8096p_tuner_read_serpar(struct i2c_adapter *i2c_adap,
1569 struct i2c_msg msg[], int num)
1571 struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1572 u8 n_overflow = 1, n_empty = 1;
1573 u16 i = 1000;
1574 u16 serpar_num = msg[0].buf[0];
1575 u16 read_word;
1577 while (n_overflow == 1 && i) {
1578 n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1;
1579 i--;
1580 if (i == 0)
1581 dprintk("TunerITF: read busy (overflow)");
1583 dib8000_write_word(state, 1985, (0<<6) | (serpar_num&0x3f));
1585 i = 1000;
1586 while (n_empty == 1 && i) {
1587 n_empty = dib8000_read_word(state, 1984)&0x1;
1588 i--;
1589 if (i == 0)
1590 dprintk("TunerITF: read busy (empty)");
1593 read_word = dib8000_read_word(state, 1987);
1594 msg[1].buf[0] = (read_word >> 8) & 0xff;
1595 msg[1].buf[1] = (read_word) & 0xff;
1597 return num;
1600 static int dib8096p_tuner_rw_serpar(struct i2c_adapter *i2c_adap,
1601 struct i2c_msg msg[], int num)
1603 if (map_addr_to_serpar_number(&msg[0]) == 0) {
1604 if (num == 1) /* write */
1605 return dib8096p_tuner_write_serpar(i2c_adap, msg, 1);
1606 else /* read */
1607 return dib8096p_tuner_read_serpar(i2c_adap, msg, 2);
1609 return num;
1612 static int dib8096p_rw_on_apb(struct i2c_adapter *i2c_adap,
1613 struct i2c_msg msg[], int num, u16 apb_address)
1615 struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1616 u16 word;
1618 if (num == 1) { /* write */
1619 dib8000_write_word(state, apb_address,
1620 ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
1621 } else {
1622 word = dib8000_read_word(state, apb_address);
1623 msg[1].buf[0] = (word >> 8) & 0xff;
1624 msg[1].buf[1] = (word) & 0xff;
1626 return num;
1629 static int dib8096p_tuner_xfer(struct i2c_adapter *i2c_adap,
1630 struct i2c_msg msg[], int num)
1632 struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1633 u16 apb_address = 0, word;
1634 int i = 0;
1636 switch (msg[0].buf[0]) {
1637 case 0x12:
1638 apb_address = 1920;
1639 break;
1640 case 0x14:
1641 apb_address = 1921;
1642 break;
1643 case 0x24:
1644 apb_address = 1922;
1645 break;
1646 case 0x1a:
1647 apb_address = 1923;
1648 break;
1649 case 0x22:
1650 apb_address = 1924;
1651 break;
1652 case 0x33:
1653 apb_address = 1926;
1654 break;
1655 case 0x34:
1656 apb_address = 1927;
1657 break;
1658 case 0x35:
1659 apb_address = 1928;
1660 break;
1661 case 0x36:
1662 apb_address = 1929;
1663 break;
1664 case 0x37:
1665 apb_address = 1930;
1666 break;
1667 case 0x38:
1668 apb_address = 1931;
1669 break;
1670 case 0x39:
1671 apb_address = 1932;
1672 break;
1673 case 0x2a:
1674 apb_address = 1935;
1675 break;
1676 case 0x2b:
1677 apb_address = 1936;
1678 break;
1679 case 0x2c:
1680 apb_address = 1937;
1681 break;
1682 case 0x2d:
1683 apb_address = 1938;
1684 break;
1685 case 0x2e:
1686 apb_address = 1939;
1687 break;
1688 case 0x2f:
1689 apb_address = 1940;
1690 break;
1691 case 0x30:
1692 apb_address = 1941;
1693 break;
1694 case 0x31:
1695 apb_address = 1942;
1696 break;
1697 case 0x32:
1698 apb_address = 1943;
1699 break;
1700 case 0x3e:
1701 apb_address = 1944;
1702 break;
1703 case 0x3f:
1704 apb_address = 1945;
1705 break;
1706 case 0x40:
1707 apb_address = 1948;
1708 break;
1709 case 0x25:
1710 apb_address = 936;
1711 break;
1712 case 0x26:
1713 apb_address = 937;
1714 break;
1715 case 0x27:
1716 apb_address = 938;
1717 break;
1718 case 0x28:
1719 apb_address = 939;
1720 break;
1721 case 0x1d:
1722 /* get sad sel request */
1723 i = ((dib8000_read_word(state, 921) >> 12)&0x3);
1724 word = dib8000_read_word(state, 924+i);
1725 msg[1].buf[0] = (word >> 8) & 0xff;
1726 msg[1].buf[1] = (word) & 0xff;
1727 return num;
1728 case 0x1f:
1729 if (num == 1) { /* write */
1730 word = (u16) ((msg[0].buf[1] << 8) |
1731 msg[0].buf[2]);
1732 /* in the VGAMODE Sel are located on bit 0/1 */
1733 word &= 0x3;
1734 word = (dib8000_read_word(state, 921) &
1735 ~(3<<12)) | (word<<12);
1736 /* Set the proper input */
1737 dib8000_write_word(state, 921, word);
1738 return num;
1742 if (apb_address != 0) /* R/W acces via APB */
1743 return dib8096p_rw_on_apb(i2c_adap, msg, num, apb_address);
1744 else /* R/W access via SERPAR */
1745 return dib8096p_tuner_rw_serpar(i2c_adap, msg, num);
1747 return 0;
1750 static u32 dib8096p_i2c_func(struct i2c_adapter *adapter)
1752 return I2C_FUNC_I2C;
1755 static struct i2c_algorithm dib8096p_tuner_xfer_algo = {
1756 .master_xfer = dib8096p_tuner_xfer,
1757 .functionality = dib8096p_i2c_func,
1760 struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe)
1762 struct dib8000_state *st = fe->demodulator_priv;
1763 return &st->dib8096p_tuner_adap;
1765 EXPORT_SYMBOL(dib8096p_get_i2c_tuner);
1767 int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff)
1769 struct dib8000_state *state = fe->demodulator_priv;
1770 u16 en_cur_state;
1772 dprintk("sleep dib8096p: %d", onoff);
1774 en_cur_state = dib8000_read_word(state, 1922);
1776 /* LNAs and MIX are ON and therefore it is a valid configuration */
1777 if (en_cur_state > 0xff)
1778 state->tuner_enable = en_cur_state ;
1780 if (onoff)
1781 en_cur_state &= 0x00ff;
1782 else {
1783 if (state->tuner_enable != 0)
1784 en_cur_state = state->tuner_enable;
1787 dib8000_write_word(state, 1922, en_cur_state);
1789 return 0;
1791 EXPORT_SYMBOL(dib8096p_tuner_sleep);
1793 static const s32 lut_1000ln_mant[] =
1795 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600
1798 s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
1800 struct dib8000_state *state = fe->demodulator_priv;
1801 u32 ix = 0, tmp_val = 0, exp = 0, mant = 0;
1802 s32 val;
1804 val = dib8000_read32(state, 384);
1805 if (mode) {
1806 tmp_val = val;
1807 while (tmp_val >>= 1)
1808 exp++;
1809 mant = (val * 1000 / (1<<exp));
1810 ix = (u8)((mant-1000)/100); /* index of the LUT */
1811 val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908);
1812 val = (val*256)/1000;
1814 return val;
1816 EXPORT_SYMBOL(dib8000_get_adc_power);
1818 int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ)
1820 struct dib8000_state *state = fe->demodulator_priv;
1821 int val = 0;
1823 switch (IQ) {
1824 case 1:
1825 val = dib8000_read_word(state, 403);
1826 break;
1827 case 0:
1828 val = dib8000_read_word(state, 404);
1829 break;
1831 if (val & 0x200)
1832 val -= 1024;
1834 return val;
1836 EXPORT_SYMBOL(dib8090p_get_dc_power);
1838 static void dib8000_update_timf(struct dib8000_state *state)
1840 u32 timf = state->timf = dib8000_read32(state, 435);
1842 dib8000_write_word(state, 29, (u16) (timf >> 16));
1843 dib8000_write_word(state, 30, (u16) (timf & 0xffff));
1844 dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
1847 u32 dib8000_ctrl_timf(struct dvb_frontend *fe, uint8_t op, uint32_t timf)
1849 struct dib8000_state *state = fe->demodulator_priv;
1851 switch (op) {
1852 case DEMOD_TIMF_SET:
1853 state->timf = timf;
1854 break;
1855 case DEMOD_TIMF_UPDATE:
1856 dib8000_update_timf(state);
1857 break;
1858 case DEMOD_TIMF_GET:
1859 break;
1861 dib8000_set_bandwidth(state->fe[0], 6000);
1863 return state->timf;
1865 EXPORT_SYMBOL(dib8000_ctrl_timf);
1867 static const u16 adc_target_16dB[11] = {
1868 (1 << 13) - 825 - 117,
1869 (1 << 13) - 837 - 117,
1870 (1 << 13) - 811 - 117,
1871 (1 << 13) - 766 - 117,
1872 (1 << 13) - 737 - 117,
1873 (1 << 13) - 693 - 117,
1874 (1 << 13) - 648 - 117,
1875 (1 << 13) - 619 - 117,
1876 (1 << 13) - 575 - 117,
1877 (1 << 13) - 531 - 117,
1878 (1 << 13) - 501 - 117
1880 static const u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
1882 static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
1884 u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
1885 u8 guard, crate, constellation, timeI;
1886 u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled
1887 const s16 *ncoeff = NULL, *ana_fe;
1888 u16 tmcc_pow = 0;
1889 u16 coff_pow = 0x2800;
1890 u16 init_prbs = 0xfff;
1891 u16 ana_gain = 0;
1893 if (state->revision == 0x8090)
1894 dib8000_init_sdram(state);
1896 if (state->ber_monitored_layer != LAYER_ALL)
1897 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
1898 else
1899 dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
1901 i = dib8000_read_word(state, 26) & 1; // P_dds_invspec
1902 dib8000_write_word(state, 26, state->fe[0]->dtv_property_cache.inversion^i);
1904 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
1905 //compute new dds_freq for the seg and adjust prbs
1906 int seg_offset =
1907 state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx -
1908 (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) -
1909 (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2);
1910 int clk = state->cfg.pll->internal;
1911 u32 segtodds = ((u32) (430 << 23) / clk) << 3; // segtodds = SegBW / Fclk * pow(2,26)
1912 int dds_offset = seg_offset * segtodds;
1913 int new_dds, sub_channel;
1914 if ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1915 dds_offset -= (int)(segtodds / 2);
1917 if (state->cfg.pll->ifreq == 0) {
1918 if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0) {
1919 dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
1920 new_dds = dds_offset;
1921 } else
1922 new_dds = dds_offset;
1924 // We shift tuning frequency if the wanted segment is :
1925 // - the segment of center frequency with an odd total number of segments
1926 // - the segment to the left of center frequency with an even total number of segments
1927 // - the segment to the right of center frequency with an even total number of segments
1928 if ((state->fe[0]->dtv_property_cache.delivery_system == SYS_ISDBT)
1929 && (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)
1930 && (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
1931 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
1932 ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1933 || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1934 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx == (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2)))
1935 || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1936 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
1937 ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1938 )) {
1939 new_dds -= ((u32) (850 << 22) / clk) << 4; // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26)
1941 } else {
1942 if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0)
1943 new_dds = state->cfg.pll->ifreq - dds_offset;
1944 else
1945 new_dds = state->cfg.pll->ifreq + dds_offset;
1947 dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff));
1948 dib8000_write_word(state, 28, (u16) (new_dds & 0xffff));
1949 if (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
1950 sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3;
1951 else
1952 sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3;
1953 sub_channel -= 6;
1955 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K
1956 || state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) {
1957 dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); //adp_pass =1
1958 dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); //pha3_force_pha_shift = 1
1959 } else {
1960 dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); //adp_pass =0
1961 dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0
1964 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1965 case TRANSMISSION_MODE_2K:
1966 switch (sub_channel) {
1967 case -6:
1968 init_prbs = 0x0;
1969 break; // 41, 0, 1
1970 case -5:
1971 init_prbs = 0x423;
1972 break; // 02~04
1973 case -4:
1974 init_prbs = 0x9;
1975 break; // 05~07
1976 case -3:
1977 init_prbs = 0x5C7;
1978 break; // 08~10
1979 case -2:
1980 init_prbs = 0x7A6;
1981 break; // 11~13
1982 case -1:
1983 init_prbs = 0x3D8;
1984 break; // 14~16
1985 case 0:
1986 init_prbs = 0x527;
1987 break; // 17~19
1988 case 1:
1989 init_prbs = 0x7FF;
1990 break; // 20~22
1991 case 2:
1992 init_prbs = 0x79B;
1993 break; // 23~25
1994 case 3:
1995 init_prbs = 0x3D6;
1996 break; // 26~28
1997 case 4:
1998 init_prbs = 0x3A2;
1999 break; // 29~31
2000 case 5:
2001 init_prbs = 0x53B;
2002 break; // 32~34
2003 case 6:
2004 init_prbs = 0x2F4;
2005 break; // 35~37
2006 default:
2007 case 7:
2008 init_prbs = 0x213;
2009 break; // 38~40
2011 break;
2013 case TRANSMISSION_MODE_4K:
2014 switch (sub_channel) {
2015 case -6:
2016 init_prbs = 0x0;
2017 break; // 41, 0, 1
2018 case -5:
2019 init_prbs = 0x208;
2020 break; // 02~04
2021 case -4:
2022 init_prbs = 0xC3;
2023 break; // 05~07
2024 case -3:
2025 init_prbs = 0x7B9;
2026 break; // 08~10
2027 case -2:
2028 init_prbs = 0x423;
2029 break; // 11~13
2030 case -1:
2031 init_prbs = 0x5C7;
2032 break; // 14~16
2033 case 0:
2034 init_prbs = 0x3D8;
2035 break; // 17~19
2036 case 1:
2037 init_prbs = 0x7FF;
2038 break; // 20~22
2039 case 2:
2040 init_prbs = 0x3D6;
2041 break; // 23~25
2042 case 3:
2043 init_prbs = 0x53B;
2044 break; // 26~28
2045 case 4:
2046 init_prbs = 0x213;
2047 break; // 29~31
2048 case 5:
2049 init_prbs = 0x29;
2050 break; // 32~34
2051 case 6:
2052 init_prbs = 0xD0;
2053 break; // 35~37
2054 default:
2055 case 7:
2056 init_prbs = 0x48E;
2057 break; // 38~40
2059 break;
2061 default:
2062 case TRANSMISSION_MODE_8K:
2063 switch (sub_channel) {
2064 case -6:
2065 init_prbs = 0x0;
2066 break; // 41, 0, 1
2067 case -5:
2068 init_prbs = 0x740;
2069 break; // 02~04
2070 case -4:
2071 init_prbs = 0x069;
2072 break; // 05~07
2073 case -3:
2074 init_prbs = 0x7DD;
2075 break; // 08~10
2076 case -2:
2077 init_prbs = 0x208;
2078 break; // 11~13
2079 case -1:
2080 init_prbs = 0x7B9;
2081 break; // 14~16
2082 case 0:
2083 init_prbs = 0x5C7;
2084 break; // 17~19
2085 case 1:
2086 init_prbs = 0x7FF;
2087 break; // 20~22
2088 case 2:
2089 init_prbs = 0x53B;
2090 break; // 23~25
2091 case 3:
2092 init_prbs = 0x29;
2093 break; // 26~28
2094 case 4:
2095 init_prbs = 0x48E;
2096 break; // 29~31
2097 case 5:
2098 init_prbs = 0x4C4;
2099 break; // 32~34
2100 case 6:
2101 init_prbs = 0x367;
2102 break; // 33~37
2103 default:
2104 case 7:
2105 init_prbs = 0x684;
2106 break; // 38~40
2108 break;
2110 } else {
2111 dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff));
2112 dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff));
2113 dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003));
2115 /*P_mode == ?? */
2116 dib8000_write_word(state, 10, (seq << 4));
2117 // dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000);
2119 switch (state->fe[0]->dtv_property_cache.guard_interval) {
2120 case GUARD_INTERVAL_1_32:
2121 guard = 0;
2122 break;
2123 case GUARD_INTERVAL_1_16:
2124 guard = 1;
2125 break;
2126 case GUARD_INTERVAL_1_8:
2127 guard = 2;
2128 break;
2129 case GUARD_INTERVAL_1_4:
2130 default:
2131 guard = 3;
2132 break;
2135 dib8000_write_word(state, 1, (init_prbs << 2) | (guard & 0x3)); // ADDR 1
2137 max_constellation = DQPSK;
2138 for (i = 0; i < 3; i++) {
2139 switch (state->fe[0]->dtv_property_cache.layer[i].modulation) {
2140 case DQPSK:
2141 constellation = 0;
2142 break;
2143 case QPSK:
2144 constellation = 1;
2145 break;
2146 case QAM_16:
2147 constellation = 2;
2148 break;
2149 case QAM_64:
2150 default:
2151 constellation = 3;
2152 break;
2155 switch (state->fe[0]->dtv_property_cache.layer[i].fec) {
2156 case FEC_1_2:
2157 crate = 1;
2158 break;
2159 case FEC_2_3:
2160 crate = 2;
2161 break;
2162 case FEC_3_4:
2163 crate = 3;
2164 break;
2165 case FEC_5_6:
2166 crate = 5;
2167 break;
2168 case FEC_7_8:
2169 default:
2170 crate = 7;
2171 break;
2174 if ((state->fe[0]->dtv_property_cache.layer[i].interleaving > 0) &&
2175 ((state->fe[0]->dtv_property_cache.layer[i].interleaving <= 3) ||
2176 (state->fe[0]->dtv_property_cache.layer[i].interleaving == 4 && state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1))
2178 timeI = state->fe[0]->dtv_property_cache.layer[i].interleaving;
2179 else
2180 timeI = 0;
2181 dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe[0]->dtv_property_cache.layer[i].segment_count & 0xf) << 6) |
2182 (crate << 3) | timeI);
2183 if (state->fe[0]->dtv_property_cache.layer[i].segment_count > 0) {
2184 switch (max_constellation) {
2185 case DQPSK:
2186 case QPSK:
2187 if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_16 ||
2188 state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64)
2189 max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation;
2190 break;
2191 case QAM_16:
2192 if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64)
2193 max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation;
2194 break;
2199 mode = fft_to_mode(state);
2201 //dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/
2203 dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) |
2204 ((state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe[0]->dtv_property_cache.
2205 isdbt_sb_mode & 1) << 4));
2207 dprintk("mode = %d ; guard = %d", mode, state->fe[0]->dtv_property_cache.guard_interval);
2209 /* signal optimization parameter */
2211 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception) {
2212 seg_diff_mask = (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0];
2213 for (i = 1; i < 3; i++)
2214 nbseg_diff +=
2215 (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
2216 for (i = 0; i < nbseg_diff; i++)
2217 seg_diff_mask |= 1 << permu_seg[i + 1];
2218 } else {
2219 for (i = 0; i < 3; i++)
2220 nbseg_diff +=
2221 (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
2222 for (i = 0; i < nbseg_diff; i++)
2223 seg_diff_mask |= 1 << permu_seg[i];
2225 dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask);
2227 state->differential_constellation = (seg_diff_mask != 0);
2228 if (state->revision != 0x8090)
2229 dib8000_set_diversity_in(state->fe[0], state->diversity_onoff);
2230 else
2231 dib8096p_set_diversity_in(state->fe[0], state->diversity_onoff);
2233 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
2234 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1)
2235 seg_mask13 = 0x00E0;
2236 else // 1-segment
2237 seg_mask13 = 0x0040;
2238 } else
2239 seg_mask13 = 0x1fff;
2241 // WRITE: Mode & Diff mask
2242 dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask);
2244 if ((seg_diff_mask) || (state->fe[0]->dtv_property_cache.isdbt_sb_mode))
2245 dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
2246 else
2247 dib8000_write_word(state, 268, (2 << 9) | 39); //init value
2249 // ---- SMALL ----
2250 // P_small_seg_diff
2251 dib8000_write_word(state, 352, seg_diff_mask); // ADDR 352
2253 dib8000_write_word(state, 353, seg_mask13); // ADDR 353
2255 /* // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */
2257 // ---- SMALL ----
2258 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
2259 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
2260 case TRANSMISSION_MODE_2K:
2261 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
2262 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
2263 ncoeff = coeff_2k_sb_1seg_dqpsk;
2264 else // QPSK or QAM
2265 ncoeff = coeff_2k_sb_1seg;
2266 } else { // 3-segments
2267 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
2268 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK)
2269 ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
2270 else // QPSK or QAM on external segments
2271 ncoeff = coeff_2k_sb_3seg_0dqpsk;
2272 } else { // QPSK or QAM on central segment
2273 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK)
2274 ncoeff = coeff_2k_sb_3seg_1dqpsk;
2275 else // QPSK or QAM on external segments
2276 ncoeff = coeff_2k_sb_3seg;
2279 break;
2281 case TRANSMISSION_MODE_4K:
2282 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
2283 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
2284 ncoeff = coeff_4k_sb_1seg_dqpsk;
2285 else // QPSK or QAM
2286 ncoeff = coeff_4k_sb_1seg;
2287 } else { // 3-segments
2288 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
2289 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
2290 ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
2291 } else { // QPSK or QAM on external segments
2292 ncoeff = coeff_4k_sb_3seg_0dqpsk;
2294 } else { // QPSK or QAM on central segment
2295 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
2296 ncoeff = coeff_4k_sb_3seg_1dqpsk;
2297 } else // QPSK or QAM on external segments
2298 ncoeff = coeff_4k_sb_3seg;
2301 break;
2303 case TRANSMISSION_MODE_AUTO:
2304 case TRANSMISSION_MODE_8K:
2305 default:
2306 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
2307 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
2308 ncoeff = coeff_8k_sb_1seg_dqpsk;
2309 else // QPSK or QAM
2310 ncoeff = coeff_8k_sb_1seg;
2311 } else { // 3-segments
2312 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
2313 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
2314 ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
2315 } else { // QPSK or QAM on external segments
2316 ncoeff = coeff_8k_sb_3seg_0dqpsk;
2318 } else { // QPSK or QAM on central segment
2319 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
2320 ncoeff = coeff_8k_sb_3seg_1dqpsk;
2321 } else // QPSK or QAM on external segments
2322 ncoeff = coeff_8k_sb_3seg;
2325 break;
2327 for (i = 0; i < 8; i++)
2328 dib8000_write_word(state, 343 + i, ncoeff[i]);
2331 // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5
2332 dib8000_write_word(state, 351,
2333 (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 9) | (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5);
2335 // ---- COFF ----
2336 // Carloff, the most robust
2337 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
2339 // P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64
2340 // 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
2341 dib8000_write_word(state, 187,
2342 (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 2)
2343 | 0x3);
2345 /* // P_small_coef_ext_enable = 1 */
2346 /* dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */
2348 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
2350 // 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)
2351 if (mode == 3)
2352 dib8000_write_word(state, 180, 0x1fcf | ((mode - 1) << 14));
2353 else
2354 dib8000_write_word(state, 180, 0x0fcf | ((mode - 1) << 14));
2355 // P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1,
2356 // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4
2357 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
2358 // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
2359 dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
2360 // P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
2361 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
2363 // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
2364 dib8000_write_word(state, 181, 300);
2365 dib8000_write_word(state, 182, 150);
2366 dib8000_write_word(state, 183, 80);
2367 dib8000_write_word(state, 184, 300);
2368 dib8000_write_word(state, 185, 150);
2369 dib8000_write_word(state, 186, 80);
2370 } else { // Sound Broadcasting mode 3 seg
2371 // P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15
2372 /* if (mode == 3) */
2373 /* dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */
2374 /* else */
2375 /* dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */
2376 dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
2378 // P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1,
2379 // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4
2380 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
2381 // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
2382 dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
2383 //P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
2384 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
2386 // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
2387 dib8000_write_word(state, 181, 350);
2388 dib8000_write_word(state, 182, 300);
2389 dib8000_write_word(state, 183, 250);
2390 dib8000_write_word(state, 184, 350);
2391 dib8000_write_word(state, 185, 300);
2392 dib8000_write_word(state, 186, 250);
2395 } else if (state->isdbt_cfg_loaded == 0) { // if not Sound Broadcasting mode : put default values for 13 segments
2396 dib8000_write_word(state, 180, (16 << 6) | 9);
2397 dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2);
2398 coff_pow = 0x2800;
2399 for (i = 0; i < 6; i++)
2400 dib8000_write_word(state, 181 + i, coff_pow);
2402 // P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1,
2403 // 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
2404 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1);
2406 // P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6
2407 dib8000_write_word(state, 340, (8 << 6) | (6 << 0));
2408 // P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1
2409 dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
2411 // ---- FFT ----
2412 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 && state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
2413 dib8000_write_word(state, 178, 64); // P_fft_powrange=64
2414 else
2415 dib8000_write_word(state, 178, 32); // P_fft_powrange=32
2417 /* make the cpil_coff_lock more robust but slower p_coff_winlen
2418 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
2420 /* if ( ( nbseg_diff>0)&&(nbseg_diff<13))
2421 dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */
2423 dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask); /* P_lmod4_seg_inh */
2424 dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask); /* P_pha3_seg_inh */
2425 dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask); /* P_tac_seg_inh */
2426 if ((!state->fe[0]->dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0))
2427 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */
2428 else
2429 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask); /* P_equal_noise_seg_inh */
2430 dib8000_write_word(state, 287, ~seg_mask13 | 0x1000); /* P_tmcc_seg_inh */
2431 //dib8000_write_word(state, 288, ~seg_mask13 | seg_diff_mask); /* P_tmcc_seg_eq_inh */
2432 if (!autosearching)
2433 dib8000_write_word(state, 288, (~seg_mask13 | seg_diff_mask) & 0x1fff); /* P_tmcc_seg_eq_inh */
2434 else
2435 dib8000_write_word(state, 288, 0x1fff); //disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels.
2436 dprintk("287 = %X (%d)", ~seg_mask13 | 0x1000, ~seg_mask13 | 0x1000);
2438 dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask)); /* P_des_seg_enabled */
2440 /* offset loop parameters */
2441 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
2442 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
2443 /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
2444 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40);
2446 else // Sound Broadcasting mode 3 seg
2447 /* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
2448 dib8000_write_word(state, 32, ((10 - mode) << 12) | (6 << 8) | 0x60);
2449 } else
2450 // TODO in 13 seg, timf_alpha can always be the same or not ?
2451 /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
2452 dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80);
2454 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
2455 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
2456 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (11-P_mode) */
2457 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode));
2459 else // Sound Broadcasting mode 3 seg
2460 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (10-P_mode) */
2461 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (9 - mode));
2462 } else
2463 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = 9 */
2464 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode));
2466 /* P_dvsy_sync_wait - reuse mode */
2467 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
2468 case TRANSMISSION_MODE_8K:
2469 mode = 256;
2470 break;
2471 case TRANSMISSION_MODE_4K:
2472 mode = 128;
2473 break;
2474 default:
2475 case TRANSMISSION_MODE_2K:
2476 mode = 64;
2477 break;
2479 if (state->cfg.diversity_delay == 0)
2480 mode = (mode * (1 << (guard)) * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo
2481 else
2482 mode = (mode * (1 << (guard)) * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for DVSY-fifo
2483 mode <<= 4;
2484 dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | mode);
2486 /* channel estimation fine configuration */
2487 switch (max_constellation) {
2488 case QAM_64:
2489 ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
2490 coeff[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
2491 coeff[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
2492 coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
2493 coeff[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
2494 //if (!state->cfg.hostbus_diversity) //if diversity, we should prehaps use the configuration of the max_constallation -1
2495 break;
2496 case QAM_16:
2497 ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
2498 coeff[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
2499 coeff[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
2500 coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
2501 coeff[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
2502 //if (!((state->cfg.hostbus_diversity) && (max_constellation == QAM_16)))
2503 break;
2504 default:
2505 ana_gain = 0; // 0 : goes along with ADC target at -22dB to keep good mobile performance and lock at sensitivity level
2506 coeff[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
2507 coeff[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
2508 coeff[2] = 0x0333; /* P_adp_regul_ext 0.1 */
2509 coeff[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
2510 break;
2512 for (mode = 0; mode < 4; mode++)
2513 dib8000_write_word(state, 215 + mode, coeff[mode]);
2515 // update ana_gain depending on max constellation
2516 dib8000_write_word(state, 116, ana_gain);
2517 // update ADC target depending on ana_gain
2518 if (ana_gain) { // set -16dB ADC target for ana_gain=-1
2519 for (i = 0; i < 10; i++)
2520 dib8000_write_word(state, 80 + i, adc_target_16dB[i]);
2521 } else { // set -22dB ADC target for ana_gain=0
2522 for (i = 0; i < 10; i++)
2523 dib8000_write_word(state, 80 + i, adc_target_16dB[i] - 355);
2526 // ---- ANA_FE ----
2527 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
2528 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1)
2529 ana_fe = ana_fe_coeff_3seg;
2530 else // 1-segment
2531 ana_fe = ana_fe_coeff_1seg;
2532 } else
2533 ana_fe = ana_fe_coeff_13seg;
2535 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0)
2536 for (mode = 0; mode < 24; mode++)
2537 dib8000_write_word(state, 117 + mode, ana_fe[mode]);
2539 // ---- CHAN_BLK ----
2540 for (i = 0; i < 13; i++) {
2541 if ((((~seg_diff_mask) >> i) & 1) == 1) {
2542 P_cfr_left_edge += (1 << i) * ((i == 0) || ((((seg_mask13 & (~seg_diff_mask)) >> (i - 1)) & 1) == 0));
2543 P_cfr_right_edge += (1 << i) * ((i == 12) || ((((seg_mask13 & (~seg_diff_mask)) >> (i + 1)) & 1) == 0));
2546 dib8000_write_word(state, 222, P_cfr_left_edge); // P_cfr_left_edge
2547 dib8000_write_word(state, 223, P_cfr_right_edge); // P_cfr_right_edge
2548 // "P_cspu_left_edge" not used => do not care
2549 // "P_cspu_right_edge" not used => do not care
2551 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
2552 dib8000_write_word(state, 228, 1); // P_2d_mode_byp=1
2553 dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); // P_cspu_win_cut = 0
2554 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0
2555 && state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) {
2556 //dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0
2557 dib8000_write_word(state, 265, 15); // P_equal_noise_sel = 15
2559 } else if (state->isdbt_cfg_loaded == 0) {
2560 dib8000_write_word(state, 228, 0); // default value
2561 dib8000_write_word(state, 265, 31); // default value
2562 dib8000_write_word(state, 205, 0x200f); // init value
2564 // ---- TMCC ----
2565 for (i = 0; i < 3; i++)
2566 tmcc_pow +=
2567 (((state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe[0]->dtv_property_cache.layer[i].segment_count);
2568 // Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9);
2569 // Threshold is set at 1/4 of max power.
2570 tmcc_pow *= (1 << (9 - 2));
2572 dib8000_write_word(state, 290, tmcc_pow); // P_tmcc_dec_thres_2k
2573 dib8000_write_word(state, 291, tmcc_pow); // P_tmcc_dec_thres_4k
2574 dib8000_write_word(state, 292, tmcc_pow); // P_tmcc_dec_thres_8k
2575 //dib8000_write_word(state, 287, (1 << 13) | 0x1000 );
2576 // ---- PHA3 ----
2578 if (state->isdbt_cfg_loaded == 0)
2579 dib8000_write_word(state, 250, 3285); /*p_2d_hspeed_thr0 */
2581 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)
2582 state->isdbt_cfg_loaded = 0;
2583 else
2584 state->isdbt_cfg_loaded = 1;
2588 static int dib8000_autosearch_start(struct dvb_frontend *fe)
2590 u8 factor;
2591 u32 value;
2592 struct dib8000_state *state = fe->demodulator_priv;
2594 int slist = 0;
2596 state->fe[0]->dtv_property_cache.inversion = 0;
2597 if (!state->fe[0]->dtv_property_cache.isdbt_sb_mode)
2598 state->fe[0]->dtv_property_cache.layer[0].segment_count = 13;
2599 state->fe[0]->dtv_property_cache.layer[0].modulation = QAM_64;
2600 state->fe[0]->dtv_property_cache.layer[0].fec = FEC_2_3;
2601 state->fe[0]->dtv_property_cache.layer[0].interleaving = 0;
2603 //choose the right list, in sb, always do everything
2604 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
2605 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
2606 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
2607 slist = 7;
2608 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));
2609 } else {
2610 if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) {
2611 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
2612 slist = 7;
2613 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 to have autosearch start ok with mode2
2614 } else
2615 slist = 3;
2616 } else {
2617 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
2618 slist = 2;
2619 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
2620 } else
2621 slist = 0;
2624 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO)
2625 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
2626 if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO)
2627 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
2629 dprintk("using list for autosearch : %d", slist);
2630 dib8000_set_channel(state, (unsigned char)slist, 1);
2631 //dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
2633 factor = 1;
2635 //set lock_mask values
2636 dib8000_write_word(state, 6, 0x4);
2637 dib8000_write_word(state, 7, 0x8);
2638 dib8000_write_word(state, 8, 0x1000);
2640 //set lock_mask wait time values
2641 value = 50 * state->cfg.pll->internal * factor;
2642 dib8000_write_word(state, 11, (u16) ((value >> 16) & 0xffff)); // lock0 wait time
2643 dib8000_write_word(state, 12, (u16) (value & 0xffff)); // lock0 wait time
2644 value = 100 * state->cfg.pll->internal * factor;
2645 dib8000_write_word(state, 13, (u16) ((value >> 16) & 0xffff)); // lock1 wait time
2646 dib8000_write_word(state, 14, (u16) (value & 0xffff)); // lock1 wait time
2647 value = 1000 * state->cfg.pll->internal * factor;
2648 dib8000_write_word(state, 15, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
2649 dib8000_write_word(state, 16, (u16) (value & 0xffff)); // lock2 wait time
2651 value = dib8000_read_word(state, 0);
2652 dib8000_write_word(state, 0, (u16) ((1 << 15) | value));
2653 dib8000_read_word(state, 1284); // reset the INT. n_irq_pending
2654 dib8000_write_word(state, 0, (u16) value);
2658 return 0;
2661 static int dib8000_autosearch_irq(struct dvb_frontend *fe)
2663 struct dib8000_state *state = fe->demodulator_priv;
2664 u16 irq_pending = dib8000_read_word(state, 1284);
2666 if (irq_pending & 0x1) { // failed
2667 dprintk("dib8000_autosearch_irq failed");
2668 return 1;
2671 if (irq_pending & 0x2) { // succeeded
2672 dprintk("dib8000_autosearch_irq succeeded");
2673 return 2;
2676 return 0; // still pending
2679 static int dib8000_tune(struct dvb_frontend *fe)
2681 struct dib8000_state *state = fe->demodulator_priv;
2682 int ret = 0;
2683 u16 lock, value, mode = fft_to_mode(state);
2685 // we are already tuned - just resuming from suspend
2686 if (state == NULL)
2687 return -EINVAL;
2689 dib8000_set_bandwidth(fe, state->fe[0]->dtv_property_cache.bandwidth_hz / 1000);
2690 dib8000_set_channel(state, 0, 0);
2692 // restart demod
2693 ret |= dib8000_write_word(state, 770, 0x4000);
2694 ret |= dib8000_write_word(state, 770, 0x0000);
2695 msleep(45);
2697 /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3 */
2698 /* ret |= dib8000_write_word(state, 29, (0 << 9) | (4 << 5) | (0 << 4) | (3 << 0) ); workaround inh_isi stays at 1 */
2700 // never achieved a lock before - wait for timfreq to update
2701 if (state->timf == 0) {
2702 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
2703 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
2704 msleep(300);
2705 else // Sound Broadcasting mode 3 seg
2706 msleep(500);
2707 } else // 13 seg
2708 msleep(200);
2710 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
2711 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
2713 /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40 alpha to check on board */
2714 dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40);
2715 //dib8000_write_word(state, 32, (8 << 12) | (6 << 8) | 0x80);
2717 /* P_ctrl_sfreq_step= (12-P_mode) P_ctrl_sfreq_inh =0 P_ctrl_pha_off_max */
2718 ret |= dib8000_write_word(state, 37, (12 - mode) | ((5 + mode) << 5));
2720 } else { // Sound Broadcasting mode 3 seg
2722 /* P_timf_alpha = (12-P_mode) , P_corm_alpha=6, P_corm_thres=0x60 alpha to check on board */
2723 dib8000_write_word(state, 32, ((12 - mode) << 12) | (6 << 8) | 0x60);
2725 ret |= dib8000_write_word(state, 37, (11 - mode) | ((5 + mode) << 5));
2728 } else { // 13 seg
2729 /* P_timf_alpha = 8 , P_corm_alpha=6, P_corm_thres=0x80 alpha to check on board */
2730 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x80);
2732 ret |= dib8000_write_word(state, 37, (10 - mode) | ((5 + mode) << 5));
2736 // we achieved a coff_cpil_lock - it's time to update the timf
2737 if (state->revision != 0x8090)
2738 lock = dib8000_read_word(state, 568);
2739 else
2740 lock = dib8000_read_word(state, 570);
2741 if ((lock >> 11) & 0x1)
2742 dib8000_update_timf(state);
2744 //now that tune is finished, lock0 should lock on fec_mpeg to output this lock on MP_LOCK. It's changed in autosearch start
2745 dib8000_write_word(state, 6, 0x200);
2747 if (state->revision == 0x8002) {
2748 value = dib8000_read_word(state, 903);
2749 dib8000_write_word(state, 903, value & ~(1 << 3));
2750 msleep(1);
2751 dib8000_write_word(state, 903, value | (1 << 3));
2754 return ret;
2757 static int dib8000_wakeup(struct dvb_frontend *fe)
2759 struct dib8000_state *state = fe->demodulator_priv;
2760 u8 index_frontend;
2761 int ret;
2763 dib8000_set_power_mode(state, DIB8000_POWER_ALL);
2764 dib8000_set_adc_state(state, DIBX000_ADC_ON);
2765 if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
2766 dprintk("could not start Slow ADC");
2768 if (state->revision != 0x8090)
2769 dib8000_sad_calib(state);
2771 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2772 ret = state->fe[index_frontend]->ops.init(state->fe[index_frontend]);
2773 if (ret < 0)
2774 return ret;
2777 return 0;
2780 static int dib8000_sleep(struct dvb_frontend *fe)
2782 struct dib8000_state *state = fe->demodulator_priv;
2783 u8 index_frontend;
2784 int ret;
2786 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2787 ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
2788 if (ret < 0)
2789 return ret;
2792 if (state->revision != 0x8090)
2793 dib8000_set_output_mode(fe, OUTMODE_HIGH_Z);
2794 dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY);
2795 return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF);
2798 enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
2800 struct dib8000_state *state = fe->demodulator_priv;
2801 return state->tune_state;
2803 EXPORT_SYMBOL(dib8000_get_tune_state);
2805 int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
2807 struct dib8000_state *state = fe->demodulator_priv;
2808 state->tune_state = tune_state;
2809 return 0;
2811 EXPORT_SYMBOL(dib8000_set_tune_state);
2813 static int dib8000_get_frontend(struct dvb_frontend *fe)
2815 struct dib8000_state *state = fe->demodulator_priv;
2816 u16 i, val = 0;
2817 fe_status_t stat;
2818 u8 index_frontend, sub_index_frontend;
2820 fe->dtv_property_cache.bandwidth_hz = 6000000;
2822 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2823 state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
2824 if (stat&FE_HAS_SYNC) {
2825 dprintk("TMCC lock on the slave%i", index_frontend);
2826 /* synchronize the cache with the other frontends */
2827 state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend]);
2828 for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL); sub_index_frontend++) {
2829 if (sub_index_frontend != index_frontend) {
2830 state->fe[sub_index_frontend]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode;
2831 state->fe[sub_index_frontend]->dtv_property_cache.inversion = state->fe[index_frontend]->dtv_property_cache.inversion;
2832 state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode = state->fe[index_frontend]->dtv_property_cache.transmission_mode;
2833 state->fe[sub_index_frontend]->dtv_property_cache.guard_interval = state->fe[index_frontend]->dtv_property_cache.guard_interval;
2834 state->fe[sub_index_frontend]->dtv_property_cache.isdbt_partial_reception = state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception;
2835 for (i = 0; i < 3; i++) {
2836 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].segment_count = state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count;
2837 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].interleaving = state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving;
2838 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].fec = state->fe[index_frontend]->dtv_property_cache.layer[i].fec;
2839 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].modulation = state->fe[index_frontend]->dtv_property_cache.layer[i].modulation;
2843 return 0;
2847 fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1;
2849 if (state->revision == 0x8090)
2850 val = dib8000_read_word(state, 572);
2851 else
2852 val = dib8000_read_word(state, 570);
2853 fe->dtv_property_cache.inversion = (val & 0x40) >> 6;
2854 switch ((val & 0x30) >> 4) {
2855 case 1:
2856 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
2857 break;
2858 case 3:
2859 default:
2860 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
2861 break;
2864 switch (val & 0x3) {
2865 case 0:
2866 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
2867 dprintk("dib8000_get_frontend GI = 1/32 ");
2868 break;
2869 case 1:
2870 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
2871 dprintk("dib8000_get_frontend GI = 1/16 ");
2872 break;
2873 case 2:
2874 dprintk("dib8000_get_frontend GI = 1/8 ");
2875 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
2876 break;
2877 case 3:
2878 dprintk("dib8000_get_frontend GI = 1/4 ");
2879 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
2880 break;
2883 val = dib8000_read_word(state, 505);
2884 fe->dtv_property_cache.isdbt_partial_reception = val & 1;
2885 dprintk("dib8000_get_frontend : partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception);
2887 for (i = 0; i < 3; i++) {
2888 val = dib8000_read_word(state, 493 + i);
2889 fe->dtv_property_cache.layer[i].segment_count = val & 0x0F;
2890 dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count);
2892 val = dib8000_read_word(state, 499 + i);
2893 fe->dtv_property_cache.layer[i].interleaving = val & 0x3;
2894 dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ", i, fe->dtv_property_cache.layer[i].interleaving);
2896 val = dib8000_read_word(state, 481 + i);
2897 switch (val & 0x7) {
2898 case 1:
2899 fe->dtv_property_cache.layer[i].fec = FEC_1_2;
2900 dprintk("dib8000_get_frontend : Layer %d Code Rate = 1/2 ", i);
2901 break;
2902 case 2:
2903 fe->dtv_property_cache.layer[i].fec = FEC_2_3;
2904 dprintk("dib8000_get_frontend : Layer %d Code Rate = 2/3 ", i);
2905 break;
2906 case 3:
2907 fe->dtv_property_cache.layer[i].fec = FEC_3_4;
2908 dprintk("dib8000_get_frontend : Layer %d Code Rate = 3/4 ", i);
2909 break;
2910 case 5:
2911 fe->dtv_property_cache.layer[i].fec = FEC_5_6;
2912 dprintk("dib8000_get_frontend : Layer %d Code Rate = 5/6 ", i);
2913 break;
2914 default:
2915 fe->dtv_property_cache.layer[i].fec = FEC_7_8;
2916 dprintk("dib8000_get_frontend : Layer %d Code Rate = 7/8 ", i);
2917 break;
2920 val = dib8000_read_word(state, 487 + i);
2921 switch (val & 0x3) {
2922 case 0:
2923 dprintk("dib8000_get_frontend : Layer %d DQPSK ", i);
2924 fe->dtv_property_cache.layer[i].modulation = DQPSK;
2925 break;
2926 case 1:
2927 fe->dtv_property_cache.layer[i].modulation = QPSK;
2928 dprintk("dib8000_get_frontend : Layer %d QPSK ", i);
2929 break;
2930 case 2:
2931 fe->dtv_property_cache.layer[i].modulation = QAM_16;
2932 dprintk("dib8000_get_frontend : Layer %d QAM16 ", i);
2933 break;
2934 case 3:
2935 default:
2936 dprintk("dib8000_get_frontend : Layer %d QAM64 ", i);
2937 fe->dtv_property_cache.layer[i].modulation = QAM_64;
2938 break;
2942 /* synchronize the cache with the other frontends */
2943 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2944 state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode = fe->dtv_property_cache.isdbt_sb_mode;
2945 state->fe[index_frontend]->dtv_property_cache.inversion = fe->dtv_property_cache.inversion;
2946 state->fe[index_frontend]->dtv_property_cache.transmission_mode = fe->dtv_property_cache.transmission_mode;
2947 state->fe[index_frontend]->dtv_property_cache.guard_interval = fe->dtv_property_cache.guard_interval;
2948 state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception = fe->dtv_property_cache.isdbt_partial_reception;
2949 for (i = 0; i < 3; i++) {
2950 state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count = fe->dtv_property_cache.layer[i].segment_count;
2951 state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving = fe->dtv_property_cache.layer[i].interleaving;
2952 state->fe[index_frontend]->dtv_property_cache.layer[i].fec = fe->dtv_property_cache.layer[i].fec;
2953 state->fe[index_frontend]->dtv_property_cache.layer[i].modulation = fe->dtv_property_cache.layer[i].modulation;
2956 return 0;
2959 static int dib8000_set_frontend(struct dvb_frontend *fe)
2961 struct dib8000_state *state = fe->demodulator_priv;
2962 u8 nbr_pending, exit_condition, index_frontend;
2963 s8 index_frontend_success = -1;
2964 int time, ret;
2965 int time_slave = FE_CALLBACK_TIME_NEVER;
2967 if (state->fe[0]->dtv_property_cache.frequency == 0) {
2968 dprintk("dib8000: must at least specify frequency ");
2969 return 0;
2972 if (state->fe[0]->dtv_property_cache.bandwidth_hz == 0) {
2973 dprintk("dib8000: no bandwidth specified, set to default ");
2974 state->fe[0]->dtv_property_cache.bandwidth_hz = 6000000;
2977 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2978 /* synchronization of the cache */
2979 state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT;
2980 memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));
2982 if (state->revision != 0x8090)
2983 dib8000_set_output_mode(state->fe[index_frontend],
2984 OUTMODE_HIGH_Z);
2985 else
2986 dib8096p_set_output_mode(state->fe[index_frontend],
2987 OUTMODE_HIGH_Z);
2988 if (state->fe[index_frontend]->ops.tuner_ops.set_params)
2989 state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend]);
2991 dib8000_set_tune_state(state->fe[index_frontend], CT_AGC_START);
2994 /* start up the AGC */
2995 do {
2996 time = dib8000_agc_startup(state->fe[0]);
2997 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2998 time_slave = dib8000_agc_startup(state->fe[index_frontend]);
2999 if (time == FE_CALLBACK_TIME_NEVER)
3000 time = time_slave;
3001 else if ((time_slave != FE_CALLBACK_TIME_NEVER) && (time_slave > time))
3002 time = time_slave;
3004 if (time != FE_CALLBACK_TIME_NEVER)
3005 msleep(time / 10);
3006 else
3007 break;
3008 exit_condition = 1;
3009 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3010 if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_AGC_STOP) {
3011 exit_condition = 0;
3012 break;
3015 } while (exit_condition == 0);
3017 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
3018 dib8000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
3020 if ((state->fe[0]->dtv_property_cache.delivery_system != SYS_ISDBT) ||
3021 (state->fe[0]->dtv_property_cache.inversion == INVERSION_AUTO) ||
3022 (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) ||
3023 (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) ||
3024 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) &&
3025 (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0xff) &&
3026 (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0) &&
3027 ((state->fe[0]->dtv_property_cache.layer[0].modulation == QAM_AUTO) ||
3028 (state->fe[0]->dtv_property_cache.layer[0].fec == FEC_AUTO))) ||
3029 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) &&
3030 (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0xff) &&
3031 (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0) &&
3032 ((state->fe[0]->dtv_property_cache.layer[1].modulation == QAM_AUTO) ||
3033 (state->fe[0]->dtv_property_cache.layer[1].fec == FEC_AUTO))) ||
3034 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) &&
3035 (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0xff) &&
3036 (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0) &&
3037 ((state->fe[0]->dtv_property_cache.layer[2].modulation == QAM_AUTO) ||
3038 (state->fe[0]->dtv_property_cache.layer[2].fec == FEC_AUTO))) ||
3039 (((state->fe[0]->dtv_property_cache.layer[0].segment_count == 0) ||
3040 ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) &&
3041 ((state->fe[0]->dtv_property_cache.layer[1].segment_count == 0) ||
3042 ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) &&
3043 ((state->fe[0]->dtv_property_cache.layer[2].segment_count == 0) || ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) {
3044 int i = 100;
3045 u8 found = 0;
3046 u8 tune_failed = 0;
3048 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3049 dib8000_set_bandwidth(state->fe[index_frontend], fe->dtv_property_cache.bandwidth_hz / 1000);
3050 dib8000_autosearch_start(state->fe[index_frontend]);
3053 do {
3054 msleep(20);
3055 nbr_pending = 0;
3056 exit_condition = 0; /* 0: tune pending; 1: tune failed; 2:tune success */
3057 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3058 if (((tune_failed >> index_frontend) & 0x1) == 0) {
3059 found = dib8000_autosearch_irq(state->fe[index_frontend]);
3060 switch (found) {
3061 case 0: /* tune pending */
3062 nbr_pending++;
3063 break;
3064 case 2:
3065 dprintk("autosearch succeed on the frontend%i", index_frontend);
3066 exit_condition = 2;
3067 index_frontend_success = index_frontend;
3068 break;
3069 default:
3070 dprintk("unhandled autosearch result");
3071 case 1:
3072 tune_failed |= (1 << index_frontend);
3073 dprintk("autosearch failed for the frontend%i", index_frontend);
3074 break;
3079 /* if all tune are done and no success, exit: tune failed */
3080 if ((nbr_pending == 0) && (exit_condition == 0))
3081 exit_condition = 1;
3082 } while ((exit_condition == 0) && i--);
3084 if (exit_condition == 1) { /* tune failed */
3085 dprintk("tune failed");
3086 return 0;
3089 dprintk("tune success on frontend%i", index_frontend_success);
3091 dib8000_get_frontend(fe);
3094 for (index_frontend = 0, ret = 0; (ret >= 0) && (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
3095 ret = dib8000_tune(state->fe[index_frontend]);
3097 /* set output mode and diversity input */
3098 if (state->revision != 0x8090) {
3099 dib8000_set_output_mode(state->fe[0], state->cfg.output_mode);
3100 for (index_frontend = 1;
3101 (index_frontend < MAX_NUMBER_OF_FRONTENDS) &&
3102 (state->fe[index_frontend] != NULL);
3103 index_frontend++) {
3104 dib8000_set_output_mode(state->fe[index_frontend],
3105 OUTMODE_DIVERSITY);
3106 dib8000_set_diversity_in(state->fe[index_frontend-1], 1);
3109 /* turn off the diversity of the last chip */
3110 dib8000_set_diversity_in(state->fe[index_frontend-1], 0);
3111 } else {
3112 dib8096p_set_output_mode(state->fe[0], state->cfg.output_mode);
3113 if (state->cfg.enMpegOutput == 0) {
3114 dib8096p_setDibTxMux(state, MPEG_ON_DIBTX);
3115 dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
3117 for (index_frontend = 1;
3118 (index_frontend < MAX_NUMBER_OF_FRONTENDS) &&
3119 (state->fe[index_frontend] != NULL);
3120 index_frontend++) {
3121 dib8096p_set_output_mode(state->fe[index_frontend],
3122 OUTMODE_DIVERSITY);
3123 dib8096p_set_diversity_in(state->fe[index_frontend-1], 1);
3126 /* turn off the diversity of the last chip */
3127 dib8096p_set_diversity_in(state->fe[index_frontend-1], 0);
3130 return ret;
3133 static u16 dib8000_read_lock(struct dvb_frontend *fe)
3135 struct dib8000_state *state = fe->demodulator_priv;
3137 if (state->revision == 0x8090)
3138 return dib8000_read_word(state, 570);
3139 return dib8000_read_word(state, 568);
3142 static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
3144 struct dib8000_state *state = fe->demodulator_priv;
3145 u16 lock_slave = 0, lock;
3146 u8 index_frontend;
3148 if (state->revision == 0x8090)
3149 lock = dib8000_read_word(state, 570);
3150 else
3151 lock = dib8000_read_word(state, 568);
3153 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
3154 lock_slave |= dib8000_read_lock(state->fe[index_frontend]);
3156 *stat = 0;
3158 if (((lock >> 13) & 1) || ((lock_slave >> 13) & 1))
3159 *stat |= FE_HAS_SIGNAL;
3161 if (((lock >> 8) & 1) || ((lock_slave >> 8) & 1)) /* Equal */
3162 *stat |= FE_HAS_CARRIER;
3164 if ((((lock >> 1) & 0xf) == 0xf) || (((lock_slave >> 1) & 0xf) == 0xf)) /* TMCC_SYNC */
3165 *stat |= FE_HAS_SYNC;
3167 if ((((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) && ((lock >> 5) & 7)) /* FEC MPEG */
3168 *stat |= FE_HAS_LOCK;
3170 if (((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) {
3171 lock = dib8000_read_word(state, 554); /* Viterbi Layer A */
3172 if (lock & 0x01)
3173 *stat |= FE_HAS_VITERBI;
3175 lock = dib8000_read_word(state, 555); /* Viterbi Layer B */
3176 if (lock & 0x01)
3177 *stat |= FE_HAS_VITERBI;
3179 lock = dib8000_read_word(state, 556); /* Viterbi Layer C */
3180 if (lock & 0x01)
3181 *stat |= FE_HAS_VITERBI;
3184 return 0;
3187 static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber)
3189 struct dib8000_state *state = fe->demodulator_priv;
3191 /* 13 segments */
3192 if (state->revision == 0x8090)
3193 *ber = (dib8000_read_word(state, 562) << 16) |
3194 dib8000_read_word(state, 563);
3195 else
3196 *ber = (dib8000_read_word(state, 560) << 16) |
3197 dib8000_read_word(state, 561);
3198 return 0;
3201 static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
3203 struct dib8000_state *state = fe->demodulator_priv;
3205 /* packet error on 13 seg */
3206 if (state->revision == 0x8090)
3207 *unc = dib8000_read_word(state, 567);
3208 else
3209 *unc = dib8000_read_word(state, 565);
3210 return 0;
3213 static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
3215 struct dib8000_state *state = fe->demodulator_priv;
3216 u8 index_frontend;
3217 u16 val;
3219 *strength = 0;
3220 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3221 state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
3222 if (val > 65535 - *strength)
3223 *strength = 65535;
3224 else
3225 *strength += val;
3228 val = 65535 - dib8000_read_word(state, 390);
3229 if (val > 65535 - *strength)
3230 *strength = 65535;
3231 else
3232 *strength += val;
3233 return 0;
3236 static u32 dib8000_get_snr(struct dvb_frontend *fe)
3238 struct dib8000_state *state = fe->demodulator_priv;
3239 u32 n, s, exp;
3240 u16 val;
3242 if (state->revision != 0x8090)
3243 val = dib8000_read_word(state, 542);
3244 else
3245 val = dib8000_read_word(state, 544);
3246 n = (val >> 6) & 0xff;
3247 exp = (val & 0x3f);
3248 if ((exp & 0x20) != 0)
3249 exp -= 0x40;
3250 n <<= exp+16;
3252 if (state->revision != 0x8090)
3253 val = dib8000_read_word(state, 543);
3254 else
3255 val = dib8000_read_word(state, 545);
3256 s = (val >> 6) & 0xff;
3257 exp = (val & 0x3f);
3258 if ((exp & 0x20) != 0)
3259 exp -= 0x40;
3260 s <<= exp+16;
3262 if (n > 0) {
3263 u32 t = (s/n) << 16;
3264 return t + ((s << 16) - n*t) / n;
3266 return 0xffffffff;
3269 static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
3271 struct dib8000_state *state = fe->demodulator_priv;
3272 u8 index_frontend;
3273 u32 snr_master;
3275 snr_master = dib8000_get_snr(fe);
3276 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
3277 snr_master += dib8000_get_snr(state->fe[index_frontend]);
3279 if ((snr_master >> 16) != 0) {
3280 snr_master = 10*intlog10(snr_master>>16);
3281 *snr = snr_master / ((1 << 24) / 10);
3283 else
3284 *snr = 0;
3286 return 0;
3289 int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
3291 struct dib8000_state *state = fe->demodulator_priv;
3292 u8 index_frontend = 1;
3294 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
3295 index_frontend++;
3296 if (index_frontend < MAX_NUMBER_OF_FRONTENDS) {
3297 dprintk("set slave fe %p to index %i", fe_slave, index_frontend);
3298 state->fe[index_frontend] = fe_slave;
3299 return 0;
3302 dprintk("too many slave frontend");
3303 return -ENOMEM;
3305 EXPORT_SYMBOL(dib8000_set_slave_frontend);
3307 int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
3309 struct dib8000_state *state = fe->demodulator_priv;
3310 u8 index_frontend = 1;
3312 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
3313 index_frontend++;
3314 if (index_frontend != 1) {
3315 dprintk("remove slave fe %p (index %i)", state->fe[index_frontend-1], index_frontend-1);
3316 state->fe[index_frontend] = NULL;
3317 return 0;
3320 dprintk("no frontend to be removed");
3321 return -ENODEV;
3323 EXPORT_SYMBOL(dib8000_remove_slave_frontend);
3325 struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
3327 struct dib8000_state *state = fe->demodulator_priv;
3329 if (slave_index >= MAX_NUMBER_OF_FRONTENDS)
3330 return NULL;
3331 return state->fe[slave_index];
3333 EXPORT_SYMBOL(dib8000_get_slave_frontend);
3336 int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods,
3337 u8 default_addr, u8 first_addr, u8 is_dib8096p)
3339 int k = 0, ret = 0;
3340 u8 new_addr = 0;
3341 struct i2c_device client = {.adap = host };
3343 client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
3344 if (!client.i2c_write_buffer) {
3345 dprintk("%s: not enough memory", __func__);
3346 return -ENOMEM;
3348 client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
3349 if (!client.i2c_read_buffer) {
3350 dprintk("%s: not enough memory", __func__);
3351 ret = -ENOMEM;
3352 goto error_memory_read;
3354 client.i2c_buffer_lock = kzalloc(sizeof(struct mutex), GFP_KERNEL);
3355 if (!client.i2c_buffer_lock) {
3356 dprintk("%s: not enough memory", __func__);
3357 ret = -ENOMEM;
3358 goto error_memory_lock;
3360 mutex_init(client.i2c_buffer_lock);
3362 for (k = no_of_demods - 1; k >= 0; k--) {
3363 /* designated i2c address */
3364 new_addr = first_addr + (k << 1);
3366 client.addr = new_addr;
3367 if (!is_dib8096p)
3368 dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */
3369 if (dib8000_identify(&client) == 0) {
3370 /* sram lead in, rdy */
3371 if (!is_dib8096p)
3372 dib8000_i2c_write16(&client, 1287, 0x0003);
3373 client.addr = default_addr;
3374 if (dib8000_identify(&client) == 0) {
3375 dprintk("#%d: not identified", k);
3376 ret = -EINVAL;
3377 goto error;
3381 /* start diversity to pull_down div_str - just for i2c-enumeration */
3382 dib8000_i2c_write16(&client, 1286, (1 << 10) | (4 << 6));
3384 /* set new i2c address and force divstart */
3385 dib8000_i2c_write16(&client, 1285, (new_addr << 2) | 0x2);
3386 client.addr = new_addr;
3387 dib8000_identify(&client);
3389 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
3392 for (k = 0; k < no_of_demods; k++) {
3393 new_addr = first_addr | (k << 1);
3394 client.addr = new_addr;
3396 // unforce divstr
3397 dib8000_i2c_write16(&client, 1285, new_addr << 2);
3399 /* deactivate div - it was just for i2c-enumeration */
3400 dib8000_i2c_write16(&client, 1286, 0);
3403 error:
3404 kfree(client.i2c_buffer_lock);
3405 error_memory_lock:
3406 kfree(client.i2c_read_buffer);
3407 error_memory_read:
3408 kfree(client.i2c_write_buffer);
3410 return ret;
3413 EXPORT_SYMBOL(dib8000_i2c_enumeration);
3414 static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
3416 tune->min_delay_ms = 1000;
3417 tune->step_size = 0;
3418 tune->max_drift = 0;
3419 return 0;
3422 static void dib8000_release(struct dvb_frontend *fe)
3424 struct dib8000_state *st = fe->demodulator_priv;
3425 u8 index_frontend;
3427 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++)
3428 dvb_frontend_detach(st->fe[index_frontend]);
3430 dibx000_exit_i2c_master(&st->i2c_master);
3431 i2c_del_adapter(&st->dib8096p_tuner_adap);
3432 kfree(st->fe[0]);
3433 kfree(st);
3436 struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
3438 struct dib8000_state *st = fe->demodulator_priv;
3439 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
3442 EXPORT_SYMBOL(dib8000_get_i2c_master);
3444 int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
3446 struct dib8000_state *st = fe->demodulator_priv;
3447 u16 val = dib8000_read_word(st, 299) & 0xffef;
3448 val |= (onoff & 0x1) << 4;
3450 dprintk("pid filter enabled %d", onoff);
3451 return dib8000_write_word(st, 299, val);
3453 EXPORT_SYMBOL(dib8000_pid_filter_ctrl);
3455 int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
3457 struct dib8000_state *st = fe->demodulator_priv;
3458 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
3459 return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0);
3461 EXPORT_SYMBOL(dib8000_pid_filter);
3463 static const struct dvb_frontend_ops dib8000_ops = {
3464 .delsys = { SYS_ISDBT },
3465 .info = {
3466 .name = "DiBcom 8000 ISDB-T",
3467 .frequency_min = 44250000,
3468 .frequency_max = 867250000,
3469 .frequency_stepsize = 62500,
3470 .caps = FE_CAN_INVERSION_AUTO |
3471 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
3472 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
3473 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
3474 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
3477 .release = dib8000_release,
3479 .init = dib8000_wakeup,
3480 .sleep = dib8000_sleep,
3482 .set_frontend = dib8000_set_frontend,
3483 .get_tune_settings = dib8000_fe_get_tune_settings,
3484 .get_frontend = dib8000_get_frontend,
3486 .read_status = dib8000_read_status,
3487 .read_ber = dib8000_read_ber,
3488 .read_signal_strength = dib8000_read_signal_strength,
3489 .read_snr = dib8000_read_snr,
3490 .read_ucblocks = dib8000_read_unc_blocks,
3493 struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
3495 struct dvb_frontend *fe;
3496 struct dib8000_state *state;
3498 dprintk("dib8000_attach");
3500 state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL);
3501 if (state == NULL)
3502 return NULL;
3503 fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);
3504 if (fe == NULL)
3505 goto error;
3507 memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
3508 state->i2c.adap = i2c_adap;
3509 state->i2c.addr = i2c_addr;
3510 state->i2c.i2c_write_buffer = state->i2c_write_buffer;
3511 state->i2c.i2c_read_buffer = state->i2c_read_buffer;
3512 mutex_init(&state->i2c_buffer_lock);
3513 state->i2c.i2c_buffer_lock = &state->i2c_buffer_lock;
3514 state->gpio_val = cfg->gpio_val;
3515 state->gpio_dir = cfg->gpio_dir;
3517 /* Ensure the output mode remains at the previous default if it's
3518 * not specifically set by the caller.
3520 if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
3521 state->cfg.output_mode = OUTMODE_MPEG2_FIFO;
3523 state->fe[0] = fe;
3524 fe->demodulator_priv = state;
3525 memcpy(&state->fe[0]->ops, &dib8000_ops, sizeof(struct dvb_frontend_ops));
3527 state->timf_default = cfg->pll->timf;
3529 if (dib8000_identify(&state->i2c) == 0)
3530 goto error;
3532 dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr);
3534 /* init 8096p tuner adapter */
3535 strncpy(state->dib8096p_tuner_adap.name, "DiB8096P tuner interface",
3536 sizeof(state->dib8096p_tuner_adap.name));
3537 state->dib8096p_tuner_adap.algo = &dib8096p_tuner_xfer_algo;
3538 state->dib8096p_tuner_adap.algo_data = NULL;
3539 state->dib8096p_tuner_adap.dev.parent = state->i2c.adap->dev.parent;
3540 i2c_set_adapdata(&state->dib8096p_tuner_adap, state);
3541 i2c_add_adapter(&state->dib8096p_tuner_adap);
3543 dib8000_reset(fe);
3545 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5)); /* ber_rs_len = 3 */
3547 return fe;
3549 error:
3550 kfree(state);
3551 return NULL;
3554 EXPORT_SYMBOL(dib8000_attach);
3556 MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@dibcom.fr, " "Patrick Boettcher <pboettcher@dibcom.fr>");
3557 MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator");
3558 MODULE_LICENSE("GPL");