[media] DiBcom: protect the I2C bufer access
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / media / dvb / frontends / dib8000.c
blobfe284d5292f5422f16a846e1077c7df34c576098
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;
86 enum dib8000_power_mode {
87 DIB8000M_POWER_ALL = 0,
88 DIB8000M_POWER_INTERFACE_ONLY,
91 static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
93 u16 ret;
94 struct i2c_msg msg[2] = {
95 {.addr = i2c->addr >> 1, .flags = 0, .len = 2},
96 {.addr = i2c->addr >> 1, .flags = I2C_M_RD, .len = 2},
99 if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) {
100 dprintk("could not acquire lock");
101 return 0;
104 msg[0].buf = i2c->i2c_write_buffer;
105 msg[0].buf[0] = reg >> 8;
106 msg[0].buf[1] = reg & 0xff;
107 msg[1].buf = i2c->i2c_read_buffer;
109 if (i2c_transfer(i2c->adap, msg, 2) != 2)
110 dprintk("i2c read error on %d", reg);
112 ret = (msg[1].buf[0] << 8) | msg[1].buf[1];
113 mutex_unlock(i2c->i2c_buffer_lock);
114 return ret;
117 static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
119 u16 ret;
121 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
122 dprintk("could not acquire lock");
123 return 0;
126 state->i2c_write_buffer[0] = reg >> 8;
127 state->i2c_write_buffer[1] = reg & 0xff;
129 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
130 state->msg[0].addr = state->i2c.addr >> 1;
131 state->msg[0].flags = 0;
132 state->msg[0].buf = state->i2c_write_buffer;
133 state->msg[0].len = 2;
134 state->msg[1].addr = state->i2c.addr >> 1;
135 state->msg[1].flags = I2C_M_RD;
136 state->msg[1].buf = state->i2c_read_buffer;
137 state->msg[1].len = 2;
139 if (i2c_transfer(state->i2c.adap, state->msg, 2) != 2)
140 dprintk("i2c read error on %d", reg);
142 ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
143 mutex_unlock(&state->i2c_buffer_lock);
145 return ret;
148 static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
150 u16 rw[2];
152 rw[0] = dib8000_read_word(state, reg + 0);
153 rw[1] = dib8000_read_word(state, reg + 1);
155 return ((rw[0] << 16) | (rw[1]));
158 static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
160 struct i2c_msg msg = {.addr = i2c->addr >> 1, .flags = 0, .len = 4};
161 int ret = 0;
163 if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) {
164 dprintk("could not acquire lock");
165 return -EINVAL;
168 msg.buf = i2c->i2c_write_buffer;
169 msg.buf[0] = (reg >> 8) & 0xff;
170 msg.buf[1] = reg & 0xff;
171 msg.buf[2] = (val >> 8) & 0xff;
172 msg.buf[3] = val & 0xff;
174 ret = i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
175 mutex_unlock(i2c->i2c_buffer_lock);
177 return ret;
180 static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
182 int ret;
184 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
185 dprintk("could not acquire lock");
186 return -EINVAL;
189 state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
190 state->i2c_write_buffer[1] = reg & 0xff;
191 state->i2c_write_buffer[2] = (val >> 8) & 0xff;
192 state->i2c_write_buffer[3] = val & 0xff;
194 memset(&state->msg[0], 0, sizeof(struct i2c_msg));
195 state->msg[0].addr = state->i2c.addr >> 1;
196 state->msg[0].flags = 0;
197 state->msg[0].buf = state->i2c_write_buffer;
198 state->msg[0].len = 4;
200 ret = (i2c_transfer(state->i2c.adap, state->msg, 1) != 1 ?
201 -EREMOTEIO : 0);
202 mutex_unlock(&state->i2c_buffer_lock);
204 return ret;
207 static const s16 coeff_2k_sb_1seg_dqpsk[8] = {
208 (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
209 (920 << 5) | 0x09
212 static const s16 coeff_2k_sb_1seg[8] = {
213 (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
216 static const s16 coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
217 (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
218 (-931 << 5) | 0x0f
221 static const s16 coeff_2k_sb_3seg_0dqpsk[8] = {
222 (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
223 (982 << 5) | 0x0c
226 static const s16 coeff_2k_sb_3seg_1dqpsk[8] = {
227 (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
228 (-720 << 5) | 0x0d
231 static const s16 coeff_2k_sb_3seg[8] = {
232 (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
233 (-610 << 5) | 0x0a
236 static const s16 coeff_4k_sb_1seg_dqpsk[8] = {
237 (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
238 (-922 << 5) | 0x0d
241 static const s16 coeff_4k_sb_1seg[8] = {
242 (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
243 (-655 << 5) | 0x0a
246 static const s16 coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
247 (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
248 (-958 << 5) | 0x13
251 static const s16 coeff_4k_sb_3seg_0dqpsk[8] = {
252 (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
253 (-568 << 5) | 0x0f
256 static const s16 coeff_4k_sb_3seg_1dqpsk[8] = {
257 (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
258 (-848 << 5) | 0x13
261 static const s16 coeff_4k_sb_3seg[8] = {
262 (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
263 (-869 << 5) | 0x13
266 static const s16 coeff_8k_sb_1seg_dqpsk[8] = {
267 (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
268 (-598 << 5) | 0x10
271 static const s16 coeff_8k_sb_1seg[8] = {
272 (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
273 (585 << 5) | 0x0f
276 static const s16 coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
277 (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
278 (0 << 5) | 0x14
281 static const s16 coeff_8k_sb_3seg_0dqpsk[8] = {
282 (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
283 (-877 << 5) | 0x15
286 static const s16 coeff_8k_sb_3seg_1dqpsk[8] = {
287 (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
288 (-921 << 5) | 0x14
291 static const s16 coeff_8k_sb_3seg[8] = {
292 (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
293 (690 << 5) | 0x14
296 static const s16 ana_fe_coeff_3seg[24] = {
297 81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
300 static const s16 ana_fe_coeff_1seg[24] = {
301 249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
304 static const s16 ana_fe_coeff_13seg[24] = {
305 396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
308 static u16 fft_to_mode(struct dib8000_state *state)
310 u16 mode;
311 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
312 case TRANSMISSION_MODE_2K:
313 mode = 1;
314 break;
315 case TRANSMISSION_MODE_4K:
316 mode = 2;
317 break;
318 default:
319 case TRANSMISSION_MODE_AUTO:
320 case TRANSMISSION_MODE_8K:
321 mode = 3;
322 break;
324 return mode;
327 static void dib8000_set_acquisition_mode(struct dib8000_state *state)
329 u16 nud = dib8000_read_word(state, 298);
330 nud |= (1 << 3) | (1 << 0);
331 dprintk("acquisition mode activated");
332 dib8000_write_word(state, 298, nud);
334 static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode)
336 struct dib8000_state *state = fe->demodulator_priv;
338 u16 outreg, fifo_threshold, smo_mode, sram = 0x0205; /* by default SDRAM deintlv is enabled */
340 outreg = 0;
341 fifo_threshold = 1792;
342 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
344 dprintk("-I- Setting output mode for demod %p to %d",
345 &state->fe[0], mode);
347 switch (mode) {
348 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
349 outreg = (1 << 10); /* 0x0400 */
350 break;
351 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
352 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
353 break;
354 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
355 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
356 break;
357 case OUTMODE_DIVERSITY:
358 if (state->cfg.hostbus_diversity) {
359 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
360 sram &= 0xfdff;
361 } else
362 sram |= 0x0c00;
363 break;
364 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
365 smo_mode |= (3 << 1);
366 fifo_threshold = 512;
367 outreg = (1 << 10) | (5 << 6);
368 break;
369 case OUTMODE_HIGH_Z: // disable
370 outreg = 0;
371 break;
373 case OUTMODE_ANALOG_ADC:
374 outreg = (1 << 10) | (3 << 6);
375 dib8000_set_acquisition_mode(state);
376 break;
378 default:
379 dprintk("Unhandled output_mode passed to be set for demod %p",
380 &state->fe[0]);
381 return -EINVAL;
384 if (state->cfg.output_mpeg2_in_188_bytes)
385 smo_mode |= (1 << 5);
387 dib8000_write_word(state, 299, smo_mode);
388 dib8000_write_word(state, 300, fifo_threshold); /* synchronous fread */
389 dib8000_write_word(state, 1286, outreg);
390 dib8000_write_word(state, 1291, sram);
392 return 0;
395 static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff)
397 struct dib8000_state *state = fe->demodulator_priv;
398 u16 sync_wait = dib8000_read_word(state, 273) & 0xfff0;
400 if (!state->differential_constellation) {
401 dib8000_write_word(state, 272, 1 << 9); //dvsy_off_lmod4 = 1
402 dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2); // sync_enable = 1; comb_mode = 2
403 } else {
404 dib8000_write_word(state, 272, 0); //dvsy_off_lmod4 = 0
405 dib8000_write_word(state, 273, sync_wait); // sync_enable = 0; comb_mode = 0
407 state->diversity_onoff = onoff;
409 switch (onoff) {
410 case 0: /* only use the internal way - not the diversity input */
411 dib8000_write_word(state, 270, 1);
412 dib8000_write_word(state, 271, 0);
413 break;
414 case 1: /* both ways */
415 dib8000_write_word(state, 270, 6);
416 dib8000_write_word(state, 271, 6);
417 break;
418 case 2: /* only the diversity input */
419 dib8000_write_word(state, 270, 0);
420 dib8000_write_word(state, 271, 1);
421 break;
423 return 0;
426 static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_power_mode mode)
428 /* by default everything is going to be powered off */
429 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
430 reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3,
431 reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
433 /* now, depending on the requested mode, we power on */
434 switch (mode) {
435 /* power up everything in the demod */
436 case DIB8000M_POWER_ALL:
437 reg_774 = 0x0000;
438 reg_775 = 0x0000;
439 reg_776 = 0x0000;
440 reg_900 &= 0xfffc;
441 reg_1280 &= 0x00ff;
442 break;
443 case DIB8000M_POWER_INTERFACE_ONLY:
444 reg_1280 &= 0x00ff;
445 break;
448 dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x", reg_774, reg_775, reg_776, reg_900, reg_1280);
449 dib8000_write_word(state, 774, reg_774);
450 dib8000_write_word(state, 775, reg_775);
451 dib8000_write_word(state, 776, reg_776);
452 dib8000_write_word(state, 900, reg_900);
453 dib8000_write_word(state, 1280, reg_1280);
456 static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no)
458 int ret = 0;
459 u16 reg_907 = dib8000_read_word(state, 907), reg_908 = dib8000_read_word(state, 908);
461 switch (no) {
462 case DIBX000_SLOW_ADC_ON:
463 reg_908 |= (1 << 1) | (1 << 0);
464 ret |= dib8000_write_word(state, 908, reg_908);
465 reg_908 &= ~(1 << 1);
466 break;
468 case DIBX000_SLOW_ADC_OFF:
469 reg_908 |= (1 << 1) | (1 << 0);
470 break;
472 case DIBX000_ADC_ON:
473 reg_907 &= 0x0fff;
474 reg_908 &= 0x0003;
475 break;
477 case DIBX000_ADC_OFF: // leave the VBG voltage on
478 reg_907 |= (1 << 14) | (1 << 13) | (1 << 12);
479 reg_908 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
480 break;
482 case DIBX000_VBG_ENABLE:
483 reg_907 &= ~(1 << 15);
484 break;
486 case DIBX000_VBG_DISABLE:
487 reg_907 |= (1 << 15);
488 break;
490 default:
491 break;
494 ret |= dib8000_write_word(state, 907, reg_907);
495 ret |= dib8000_write_word(state, 908, reg_908);
497 return ret;
500 static int dib8000_set_bandwidth(struct dvb_frontend *fe, u32 bw)
502 struct dib8000_state *state = fe->demodulator_priv;
503 u32 timf;
505 if (bw == 0)
506 bw = 6000;
508 if (state->timf == 0) {
509 dprintk("using default timf");
510 timf = state->timf_default;
511 } else {
512 dprintk("using updated timf");
513 timf = state->timf;
516 dib8000_write_word(state, 29, (u16) ((timf >> 16) & 0xffff));
517 dib8000_write_word(state, 30, (u16) ((timf) & 0xffff));
519 return 0;
522 static int dib8000_sad_calib(struct dib8000_state *state)
524 /* internal */
525 dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
526 dib8000_write_word(state, 924, 776); // 0.625*3.3 / 4096
528 /* do the calibration */
529 dib8000_write_word(state, 923, (1 << 0));
530 dib8000_write_word(state, 923, (0 << 0));
532 msleep(1);
533 return 0;
536 int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
538 struct dib8000_state *state = fe->demodulator_priv;
539 if (value > 4095)
540 value = 4095;
541 state->wbd_ref = value;
542 return dib8000_write_word(state, 106, value);
545 EXPORT_SYMBOL(dib8000_set_wbd_ref);
546 static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
548 dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25);
549 dib8000_write_word(state, 23, (u16) (((bw->internal * 1000) >> 16) & 0xffff)); /* P_sec_len */
550 dib8000_write_word(state, 24, (u16) ((bw->internal * 1000) & 0xffff));
551 dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff));
552 dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff));
553 dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003));
555 dib8000_write_word(state, 922, bw->sad_cfg);
558 static void dib8000_reset_pll(struct dib8000_state *state)
560 const struct dibx000_bandwidth_config *pll = state->cfg.pll;
561 u16 clk_cfg1;
563 // clk_cfg0
564 dib8000_write_word(state, 901, (pll->pll_prediv << 8) | (pll->pll_ratio << 0));
566 // clk_cfg1
567 clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
568 (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) |
569 (pll->pll_range << 1) | (pll->pll_reset << 0);
571 dib8000_write_word(state, 902, clk_cfg1);
572 clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
573 dib8000_write_word(state, 902, clk_cfg1);
575 dprintk("clk_cfg1: 0x%04x", clk_cfg1); /* 0x507 1 0 1 000 0 0 11 1 */
577 /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
578 if (state->cfg.pll->ADClkSrc == 0)
579 dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) |
580 (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
581 else if (state->cfg.refclksel != 0)
582 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
583 ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) |
584 (pll->ADClkSrc << 7) | (0 << 1));
585 else
586 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
588 dib8000_reset_pll_common(state, pll);
591 static int dib8000_reset_gpio(struct dib8000_state *st)
593 /* reset the GPIOs */
594 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
595 dib8000_write_word(st, 1030, st->cfg.gpio_val);
597 /* TODO 782 is P_gpio_od */
599 dib8000_write_word(st, 1032, st->cfg.gpio_pwm_pos);
601 dib8000_write_word(st, 1037, st->cfg.pwm_freq_div);
602 return 0;
605 static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val)
607 st->cfg.gpio_dir = dib8000_read_word(st, 1029);
608 st->cfg.gpio_dir &= ~(1 << num); /* reset the direction bit */
609 st->cfg.gpio_dir |= (dir & 0x1) << num; /* set the new direction */
610 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
612 st->cfg.gpio_val = dib8000_read_word(st, 1030);
613 st->cfg.gpio_val &= ~(1 << num); /* reset the direction bit */
614 st->cfg.gpio_val |= (val & 0x01) << num; /* set the new value */
615 dib8000_write_word(st, 1030, st->cfg.gpio_val);
617 dprintk("gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val);
619 return 0;
622 int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
624 struct dib8000_state *state = fe->demodulator_priv;
625 return dib8000_cfg_gpio(state, num, dir, val);
628 EXPORT_SYMBOL(dib8000_set_gpio);
629 static const u16 dib8000_defaults[] = {
630 /* auto search configuration - lock0 by default waiting
631 * for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */
632 3, 7,
633 0x0004,
634 0x0400,
635 0x0814,
637 12, 11,
638 0x001b,
639 0x7740,
640 0x005b,
641 0x8d80,
642 0x01c9,
643 0xc380,
644 0x0000,
645 0x0080,
646 0x0000,
647 0x0090,
648 0x0001,
649 0xd4c0,
651 /*1, 32,
652 0x6680 // P_corm_thres Lock algorithms configuration */
654 11, 80, /* set ADC level to -16 */
655 (1 << 13) - 825 - 117,
656 (1 << 13) - 837 - 117,
657 (1 << 13) - 811 - 117,
658 (1 << 13) - 766 - 117,
659 (1 << 13) - 737 - 117,
660 (1 << 13) - 693 - 117,
661 (1 << 13) - 648 - 117,
662 (1 << 13) - 619 - 117,
663 (1 << 13) - 575 - 117,
664 (1 << 13) - 531 - 117,
665 (1 << 13) - 501 - 117,
667 4, 108,
673 1, 175,
674 0x0410,
675 1, 179,
676 8192, // P_fft_nb_to_cut
678 6, 181,
679 0x2800, // P_coff_corthres_ ( 2k 4k 8k ) 0x2800
680 0x2800,
681 0x2800,
682 0x2800, // P_coff_cpilthres_ ( 2k 4k 8k ) 0x2800
683 0x2800,
684 0x2800,
686 2, 193,
687 0x0666, // P_pha3_thres
688 0x0000, // P_cti_use_cpe, P_cti_use_prog
690 2, 205,
691 0x200f, // P_cspu_regul, P_cspu_win_cut
692 0x000f, // P_des_shift_work
694 5, 215,
695 0x023d, // P_adp_regul_cnt
696 0x00a4, // P_adp_noise_cnt
697 0x00a4, // P_adp_regul_ext
698 0x7ff0, // P_adp_noise_ext
699 0x3ccc, // P_adp_fil
701 1, 230,
702 0x0000, // P_2d_byp_ti_num
704 1, 263,
705 0x800, //P_equal_thres_wgn
707 1, 268,
708 (2 << 9) | 39, // P_equal_ctrl_synchro, P_equal_speedmode
710 1, 270,
711 0x0001, // P_div_lock0_wait
712 1, 285,
713 0x0020, //p_fec_
714 1, 299,
715 0x0062, /* P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard */
717 1, 338,
718 (1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1
719 (1 << 10) |
720 (0 << 9) | /* P_ctrl_pre_freq_inh=0 */
721 (3 << 5) | /* P_ctrl_pre_freq_step=3 */
722 (1 << 0), /* P_pre_freq_win_len=1 */
724 1, 903,
725 (0 << 4) | 2, // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW)
730 static u16 dib8000_identify(struct i2c_device *client)
732 u16 value;
734 //because of glitches sometimes
735 value = dib8000_i2c_read16(client, 896);
737 if ((value = dib8000_i2c_read16(client, 896)) != 0x01b3) {
738 dprintk("wrong Vendor ID (read=0x%x)", value);
739 return 0;
742 value = dib8000_i2c_read16(client, 897);
743 if (value != 0x8000 && value != 0x8001 && value != 0x8002) {
744 dprintk("wrong Device ID (%x)", value);
745 return 0;
748 switch (value) {
749 case 0x8000:
750 dprintk("found DiB8000A");
751 break;
752 case 0x8001:
753 dprintk("found DiB8000B");
754 break;
755 case 0x8002:
756 dprintk("found DiB8000C");
757 break;
759 return value;
762 static int dib8000_reset(struct dvb_frontend *fe)
764 struct dib8000_state *state = fe->demodulator_priv;
766 dib8000_write_word(state, 1287, 0x0003); /* sram lead in, rdy */
768 if ((state->revision = dib8000_identify(&state->i2c)) == 0)
769 return -EINVAL;
771 if (state->revision == 0x8000)
772 dprintk("error : dib8000 MA not supported");
774 dibx000_reset_i2c_master(&state->i2c_master);
776 dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
778 /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
779 dib8000_set_adc_state(state, DIBX000_VBG_ENABLE);
781 /* restart all parts */
782 dib8000_write_word(state, 770, 0xffff);
783 dib8000_write_word(state, 771, 0xffff);
784 dib8000_write_word(state, 772, 0xfffc);
785 dib8000_write_word(state, 898, 0x000c); // sad
786 dib8000_write_word(state, 1280, 0x004d);
787 dib8000_write_word(state, 1281, 0x000c);
789 dib8000_write_word(state, 770, 0x0000);
790 dib8000_write_word(state, 771, 0x0000);
791 dib8000_write_word(state, 772, 0x0000);
792 dib8000_write_word(state, 898, 0x0004); // sad
793 dib8000_write_word(state, 1280, 0x0000);
794 dib8000_write_word(state, 1281, 0x0000);
796 /* drives */
797 if (state->cfg.drives)
798 dib8000_write_word(state, 906, state->cfg.drives);
799 else {
800 dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.");
801 dib8000_write_word(state, 906, 0x2d98); // min drive SDRAM - not optimal - adjust
804 dib8000_reset_pll(state);
806 if (dib8000_reset_gpio(state) != 0)
807 dprintk("GPIO reset was not successful.");
809 if (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0)
810 dprintk("OUTPUT_MODE could not be resetted.");
812 state->current_agc = NULL;
814 // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
815 /* P_iqc_ca2 = 0; P_iqc_impnc_on = 0; P_iqc_mode = 0; */
816 if (state->cfg.pll->ifreq == 0)
817 dib8000_write_word(state, 40, 0x0755); /* P_iqc_corr_inh = 0 enable IQcorr block */
818 else
819 dib8000_write_word(state, 40, 0x1f55); /* P_iqc_corr_inh = 1 disable IQcorr block */
822 u16 l = 0, r;
823 const u16 *n;
824 n = dib8000_defaults;
825 l = *n++;
826 while (l) {
827 r = *n++;
828 do {
829 dib8000_write_word(state, r, *n++);
830 r++;
831 } while (--l);
832 l = *n++;
835 state->isdbt_cfg_loaded = 0;
837 //div_cfg override for special configs
838 if (state->cfg.div_cfg != 0)
839 dib8000_write_word(state, 903, state->cfg.div_cfg);
841 /* unforce divstr regardless whether i2c enumeration was done or not */
842 dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1));
844 dib8000_set_bandwidth(fe, 6000);
846 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
847 dib8000_sad_calib(state);
848 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
850 dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY);
852 return 0;
855 static void dib8000_restart_agc(struct dib8000_state *state)
857 // P_restart_iqc & P_restart_agc
858 dib8000_write_word(state, 770, 0x0a00);
859 dib8000_write_word(state, 770, 0x0000);
862 static int dib8000_update_lna(struct dib8000_state *state)
864 u16 dyn_gain;
866 if (state->cfg.update_lna) {
867 // read dyn_gain here (because it is demod-dependent and not tuner)
868 dyn_gain = dib8000_read_word(state, 390);
870 if (state->cfg.update_lna(state->fe[0], dyn_gain)) {
871 dib8000_restart_agc(state);
872 return 1;
875 return 0;
878 static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
880 struct dibx000_agc_config *agc = NULL;
881 int i;
882 if (state->current_band == band && state->current_agc != NULL)
883 return 0;
884 state->current_band = band;
886 for (i = 0; i < state->cfg.agc_config_count; i++)
887 if (state->cfg.agc[i].band_caps & band) {
888 agc = &state->cfg.agc[i];
889 break;
892 if (agc == NULL) {
893 dprintk("no valid AGC configuration found for band 0x%02x", band);
894 return -EINVAL;
897 state->current_agc = agc;
899 /* AGC */
900 dib8000_write_word(state, 76, agc->setup);
901 dib8000_write_word(state, 77, agc->inv_gain);
902 dib8000_write_word(state, 78, agc->time_stabiliz);
903 dib8000_write_word(state, 101, (agc->alpha_level << 12) | agc->thlock);
905 // Demod AGC loop configuration
906 dib8000_write_word(state, 102, (agc->alpha_mant << 5) | agc->alpha_exp);
907 dib8000_write_word(state, 103, (agc->beta_mant << 6) | agc->beta_exp);
909 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
910 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
912 /* AGC continued */
913 if (state->wbd_ref != 0)
914 dib8000_write_word(state, 106, state->wbd_ref);
915 else // use default
916 dib8000_write_word(state, 106, agc->wbd_ref);
917 dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
918 dib8000_write_word(state, 108, agc->agc1_max);
919 dib8000_write_word(state, 109, agc->agc1_min);
920 dib8000_write_word(state, 110, agc->agc2_max);
921 dib8000_write_word(state, 111, agc->agc2_min);
922 dib8000_write_word(state, 112, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
923 dib8000_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
924 dib8000_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
925 dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
927 dib8000_write_word(state, 75, agc->agc1_pt3);
928 dib8000_write_word(state, 923, (dib8000_read_word(state, 923) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2)); /*LB : 929 -> 923 */
930 return 0;
933 void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
935 struct dib8000_state *state = fe->demodulator_priv;
936 dib8000_set_adc_state(state, DIBX000_ADC_ON);
937 dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000)));
939 EXPORT_SYMBOL(dib8000_pwm_agc_reset);
941 static int dib8000_agc_soft_split(struct dib8000_state *state)
943 u16 agc, split_offset;
945 if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
946 return FE_CALLBACK_TIME_NEVER;
948 // n_agc_global
949 agc = dib8000_read_word(state, 390);
951 if (agc > state->current_agc->split.min_thres)
952 split_offset = state->current_agc->split.min;
953 else if (agc < state->current_agc->split.max_thres)
954 split_offset = state->current_agc->split.max;
955 else
956 split_offset = state->current_agc->split.max *
957 (agc - state->current_agc->split.min_thres) /
958 (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
960 dprintk("AGC split_offset: %d", split_offset);
962 // P_agc_force_split and P_agc_split_offset
963 dib8000_write_word(state, 107, (dib8000_read_word(state, 107) & 0xff00) | split_offset);
964 return 5000;
967 static int dib8000_agc_startup(struct dvb_frontend *fe)
969 struct dib8000_state *state = fe->demodulator_priv;
970 enum frontend_tune_state *tune_state = &state->tune_state;
972 int ret = 0;
974 switch (*tune_state) {
975 case CT_AGC_START:
976 // set power-up level: interf+analog+AGC
978 dib8000_set_adc_state(state, DIBX000_ADC_ON);
980 if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) {
981 *tune_state = CT_AGC_STOP;
982 state->status = FE_STATUS_TUNE_FAILED;
983 break;
986 ret = 70;
987 *tune_state = CT_AGC_STEP_0;
988 break;
990 case CT_AGC_STEP_0:
991 //AGC initialization
992 if (state->cfg.agc_control)
993 state->cfg.agc_control(fe, 1);
995 dib8000_restart_agc(state);
997 // wait AGC rough lock time
998 ret = 50;
999 *tune_state = CT_AGC_STEP_1;
1000 break;
1002 case CT_AGC_STEP_1:
1003 // wait AGC accurate lock time
1004 ret = 70;
1006 if (dib8000_update_lna(state))
1007 // wait only AGC rough lock time
1008 ret = 50;
1009 else
1010 *tune_state = CT_AGC_STEP_2;
1011 break;
1013 case CT_AGC_STEP_2:
1014 dib8000_agc_soft_split(state);
1016 if (state->cfg.agc_control)
1017 state->cfg.agc_control(fe, 0);
1019 *tune_state = CT_AGC_STOP;
1020 break;
1021 default:
1022 ret = dib8000_agc_soft_split(state);
1023 break;
1025 return ret;
1029 static const s32 lut_1000ln_mant[] =
1031 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600
1034 s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
1036 struct dib8000_state *state = fe->demodulator_priv;
1037 u32 ix = 0, tmp_val = 0, exp = 0, mant = 0;
1038 s32 val;
1040 val = dib8000_read32(state, 384);
1041 if (mode) {
1042 tmp_val = val;
1043 while (tmp_val >>= 1)
1044 exp++;
1045 mant = (val * 1000 / (1<<exp));
1046 ix = (u8)((mant-1000)/100); /* index of the LUT */
1047 val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908);
1048 val = (val*256)/1000;
1050 return val;
1052 EXPORT_SYMBOL(dib8000_get_adc_power);
1054 static void dib8000_update_timf(struct dib8000_state *state)
1056 u32 timf = state->timf = dib8000_read32(state, 435);
1058 dib8000_write_word(state, 29, (u16) (timf >> 16));
1059 dib8000_write_word(state, 30, (u16) (timf & 0xffff));
1060 dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
1063 static const u16 adc_target_16dB[11] = {
1064 (1 << 13) - 825 - 117,
1065 (1 << 13) - 837 - 117,
1066 (1 << 13) - 811 - 117,
1067 (1 << 13) - 766 - 117,
1068 (1 << 13) - 737 - 117,
1069 (1 << 13) - 693 - 117,
1070 (1 << 13) - 648 - 117,
1071 (1 << 13) - 619 - 117,
1072 (1 << 13) - 575 - 117,
1073 (1 << 13) - 531 - 117,
1074 (1 << 13) - 501 - 117
1076 static const u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
1078 static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
1080 u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
1081 u8 guard, crate, constellation, timeI;
1082 u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled
1083 const s16 *ncoeff = NULL, *ana_fe;
1084 u16 tmcc_pow = 0;
1085 u16 coff_pow = 0x2800;
1086 u16 init_prbs = 0xfff;
1087 u16 ana_gain = 0;
1089 if (state->ber_monitored_layer != LAYER_ALL)
1090 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
1091 else
1092 dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
1094 i = dib8000_read_word(state, 26) & 1; // P_dds_invspec
1095 dib8000_write_word(state, 26, state->fe[0]->dtv_property_cache.inversion^i);
1097 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
1098 //compute new dds_freq for the seg and adjust prbs
1099 int seg_offset =
1100 state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx -
1101 (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) -
1102 (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2);
1103 int clk = state->cfg.pll->internal;
1104 u32 segtodds = ((u32) (430 << 23) / clk) << 3; // segtodds = SegBW / Fclk * pow(2,26)
1105 int dds_offset = seg_offset * segtodds;
1106 int new_dds, sub_channel;
1107 if ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1108 dds_offset -= (int)(segtodds / 2);
1110 if (state->cfg.pll->ifreq == 0) {
1111 if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0) {
1112 dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
1113 new_dds = dds_offset;
1114 } else
1115 new_dds = dds_offset;
1117 // We shift tuning frequency if the wanted segment is :
1118 // - the segment of center frequency with an odd total number of segments
1119 // - the segment to the left of center frequency with an even total number of segments
1120 // - the segment to the right of center frequency with an even total number of segments
1121 if ((state->fe[0]->dtv_property_cache.delivery_system == SYS_ISDBT)
1122 && (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)
1123 && (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
1124 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
1125 ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1126 || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1127 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx == (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2)))
1128 || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1129 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
1130 ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1131 )) {
1132 new_dds -= ((u32) (850 << 22) / clk) << 4; // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26)
1134 } else {
1135 if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0)
1136 new_dds = state->cfg.pll->ifreq - dds_offset;
1137 else
1138 new_dds = state->cfg.pll->ifreq + dds_offset;
1140 dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff));
1141 dib8000_write_word(state, 28, (u16) (new_dds & 0xffff));
1142 if (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
1143 sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3;
1144 else
1145 sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3;
1146 sub_channel -= 6;
1148 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K
1149 || state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) {
1150 dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); //adp_pass =1
1151 dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); //pha3_force_pha_shift = 1
1152 } else {
1153 dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); //adp_pass =0
1154 dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0
1157 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1158 case TRANSMISSION_MODE_2K:
1159 switch (sub_channel) {
1160 case -6:
1161 init_prbs = 0x0;
1162 break; // 41, 0, 1
1163 case -5:
1164 init_prbs = 0x423;
1165 break; // 02~04
1166 case -4:
1167 init_prbs = 0x9;
1168 break; // 05~07
1169 case -3:
1170 init_prbs = 0x5C7;
1171 break; // 08~10
1172 case -2:
1173 init_prbs = 0x7A6;
1174 break; // 11~13
1175 case -1:
1176 init_prbs = 0x3D8;
1177 break; // 14~16
1178 case 0:
1179 init_prbs = 0x527;
1180 break; // 17~19
1181 case 1:
1182 init_prbs = 0x7FF;
1183 break; // 20~22
1184 case 2:
1185 init_prbs = 0x79B;
1186 break; // 23~25
1187 case 3:
1188 init_prbs = 0x3D6;
1189 break; // 26~28
1190 case 4:
1191 init_prbs = 0x3A2;
1192 break; // 29~31
1193 case 5:
1194 init_prbs = 0x53B;
1195 break; // 32~34
1196 case 6:
1197 init_prbs = 0x2F4;
1198 break; // 35~37
1199 default:
1200 case 7:
1201 init_prbs = 0x213;
1202 break; // 38~40
1204 break;
1206 case TRANSMISSION_MODE_4K:
1207 switch (sub_channel) {
1208 case -6:
1209 init_prbs = 0x0;
1210 break; // 41, 0, 1
1211 case -5:
1212 init_prbs = 0x208;
1213 break; // 02~04
1214 case -4:
1215 init_prbs = 0xC3;
1216 break; // 05~07
1217 case -3:
1218 init_prbs = 0x7B9;
1219 break; // 08~10
1220 case -2:
1221 init_prbs = 0x423;
1222 break; // 11~13
1223 case -1:
1224 init_prbs = 0x5C7;
1225 break; // 14~16
1226 case 0:
1227 init_prbs = 0x3D8;
1228 break; // 17~19
1229 case 1:
1230 init_prbs = 0x7FF;
1231 break; // 20~22
1232 case 2:
1233 init_prbs = 0x3D6;
1234 break; // 23~25
1235 case 3:
1236 init_prbs = 0x53B;
1237 break; // 26~28
1238 case 4:
1239 init_prbs = 0x213;
1240 break; // 29~31
1241 case 5:
1242 init_prbs = 0x29;
1243 break; // 32~34
1244 case 6:
1245 init_prbs = 0xD0;
1246 break; // 35~37
1247 default:
1248 case 7:
1249 init_prbs = 0x48E;
1250 break; // 38~40
1252 break;
1254 default:
1255 case TRANSMISSION_MODE_8K:
1256 switch (sub_channel) {
1257 case -6:
1258 init_prbs = 0x0;
1259 break; // 41, 0, 1
1260 case -5:
1261 init_prbs = 0x740;
1262 break; // 02~04
1263 case -4:
1264 init_prbs = 0x069;
1265 break; // 05~07
1266 case -3:
1267 init_prbs = 0x7DD;
1268 break; // 08~10
1269 case -2:
1270 init_prbs = 0x208;
1271 break; // 11~13
1272 case -1:
1273 init_prbs = 0x7B9;
1274 break; // 14~16
1275 case 0:
1276 init_prbs = 0x5C7;
1277 break; // 17~19
1278 case 1:
1279 init_prbs = 0x7FF;
1280 break; // 20~22
1281 case 2:
1282 init_prbs = 0x53B;
1283 break; // 23~25
1284 case 3:
1285 init_prbs = 0x29;
1286 break; // 26~28
1287 case 4:
1288 init_prbs = 0x48E;
1289 break; // 29~31
1290 case 5:
1291 init_prbs = 0x4C4;
1292 break; // 32~34
1293 case 6:
1294 init_prbs = 0x367;
1295 break; // 33~37
1296 default:
1297 case 7:
1298 init_prbs = 0x684;
1299 break; // 38~40
1301 break;
1303 } else {
1304 dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff));
1305 dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff));
1306 dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003));
1308 /*P_mode == ?? */
1309 dib8000_write_word(state, 10, (seq << 4));
1310 // dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000);
1312 switch (state->fe[0]->dtv_property_cache.guard_interval) {
1313 case GUARD_INTERVAL_1_32:
1314 guard = 0;
1315 break;
1316 case GUARD_INTERVAL_1_16:
1317 guard = 1;
1318 break;
1319 case GUARD_INTERVAL_1_8:
1320 guard = 2;
1321 break;
1322 case GUARD_INTERVAL_1_4:
1323 default:
1324 guard = 3;
1325 break;
1328 dib8000_write_word(state, 1, (init_prbs << 2) | (guard & 0x3)); // ADDR 1
1330 max_constellation = DQPSK;
1331 for (i = 0; i < 3; i++) {
1332 switch (state->fe[0]->dtv_property_cache.layer[i].modulation) {
1333 case DQPSK:
1334 constellation = 0;
1335 break;
1336 case QPSK:
1337 constellation = 1;
1338 break;
1339 case QAM_16:
1340 constellation = 2;
1341 break;
1342 case QAM_64:
1343 default:
1344 constellation = 3;
1345 break;
1348 switch (state->fe[0]->dtv_property_cache.layer[i].fec) {
1349 case FEC_1_2:
1350 crate = 1;
1351 break;
1352 case FEC_2_3:
1353 crate = 2;
1354 break;
1355 case FEC_3_4:
1356 crate = 3;
1357 break;
1358 case FEC_5_6:
1359 crate = 5;
1360 break;
1361 case FEC_7_8:
1362 default:
1363 crate = 7;
1364 break;
1367 if ((state->fe[0]->dtv_property_cache.layer[i].interleaving > 0) &&
1368 ((state->fe[0]->dtv_property_cache.layer[i].interleaving <= 3) ||
1369 (state->fe[0]->dtv_property_cache.layer[i].interleaving == 4 && state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1))
1371 timeI = state->fe[0]->dtv_property_cache.layer[i].interleaving;
1372 else
1373 timeI = 0;
1374 dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe[0]->dtv_property_cache.layer[i].segment_count & 0xf) << 6) |
1375 (crate << 3) | timeI);
1376 if (state->fe[0]->dtv_property_cache.layer[i].segment_count > 0) {
1377 switch (max_constellation) {
1378 case DQPSK:
1379 case QPSK:
1380 if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_16 ||
1381 state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64)
1382 max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation;
1383 break;
1384 case QAM_16:
1385 if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64)
1386 max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation;
1387 break;
1392 mode = fft_to_mode(state);
1394 //dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/
1396 dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) |
1397 ((state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe[0]->dtv_property_cache.
1398 isdbt_sb_mode & 1) << 4));
1400 dprintk("mode = %d ; guard = %d", mode, state->fe[0]->dtv_property_cache.guard_interval);
1402 /* signal optimization parameter */
1404 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception) {
1405 seg_diff_mask = (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0];
1406 for (i = 1; i < 3; i++)
1407 nbseg_diff +=
1408 (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
1409 for (i = 0; i < nbseg_diff; i++)
1410 seg_diff_mask |= 1 << permu_seg[i + 1];
1411 } else {
1412 for (i = 0; i < 3; i++)
1413 nbseg_diff +=
1414 (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
1415 for (i = 0; i < nbseg_diff; i++)
1416 seg_diff_mask |= 1 << permu_seg[i];
1418 dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask);
1420 state->differential_constellation = (seg_diff_mask != 0);
1421 dib8000_set_diversity_in(state->fe[0], state->diversity_onoff);
1423 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1424 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1)
1425 seg_mask13 = 0x00E0;
1426 else // 1-segment
1427 seg_mask13 = 0x0040;
1428 } else
1429 seg_mask13 = 0x1fff;
1431 // WRITE: Mode & Diff mask
1432 dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask);
1434 if ((seg_diff_mask) || (state->fe[0]->dtv_property_cache.isdbt_sb_mode))
1435 dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
1436 else
1437 dib8000_write_word(state, 268, (2 << 9) | 39); //init value
1439 // ---- SMALL ----
1440 // P_small_seg_diff
1441 dib8000_write_word(state, 352, seg_diff_mask); // ADDR 352
1443 dib8000_write_word(state, 353, seg_mask13); // ADDR 353
1445 /* // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */
1447 // ---- SMALL ----
1448 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1449 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1450 case TRANSMISSION_MODE_2K:
1451 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1452 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
1453 ncoeff = coeff_2k_sb_1seg_dqpsk;
1454 else // QPSK or QAM
1455 ncoeff = coeff_2k_sb_1seg;
1456 } else { // 3-segments
1457 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
1458 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK)
1459 ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
1460 else // QPSK or QAM on external segments
1461 ncoeff = coeff_2k_sb_3seg_0dqpsk;
1462 } else { // QPSK or QAM on central segment
1463 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK)
1464 ncoeff = coeff_2k_sb_3seg_1dqpsk;
1465 else // QPSK or QAM on external segments
1466 ncoeff = coeff_2k_sb_3seg;
1469 break;
1471 case TRANSMISSION_MODE_4K:
1472 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1473 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
1474 ncoeff = coeff_4k_sb_1seg_dqpsk;
1475 else // QPSK or QAM
1476 ncoeff = coeff_4k_sb_1seg;
1477 } else { // 3-segments
1478 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
1479 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1480 ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
1481 } else { // QPSK or QAM on external segments
1482 ncoeff = coeff_4k_sb_3seg_0dqpsk;
1484 } else { // QPSK or QAM on central segment
1485 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1486 ncoeff = coeff_4k_sb_3seg_1dqpsk;
1487 } else // QPSK or QAM on external segments
1488 ncoeff = coeff_4k_sb_3seg;
1491 break;
1493 case TRANSMISSION_MODE_AUTO:
1494 case TRANSMISSION_MODE_8K:
1495 default:
1496 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1497 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
1498 ncoeff = coeff_8k_sb_1seg_dqpsk;
1499 else // QPSK or QAM
1500 ncoeff = coeff_8k_sb_1seg;
1501 } else { // 3-segments
1502 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
1503 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1504 ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
1505 } else { // QPSK or QAM on external segments
1506 ncoeff = coeff_8k_sb_3seg_0dqpsk;
1508 } else { // QPSK or QAM on central segment
1509 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1510 ncoeff = coeff_8k_sb_3seg_1dqpsk;
1511 } else // QPSK or QAM on external segments
1512 ncoeff = coeff_8k_sb_3seg;
1515 break;
1517 for (i = 0; i < 8; i++)
1518 dib8000_write_word(state, 343 + i, ncoeff[i]);
1521 // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5
1522 dib8000_write_word(state, 351,
1523 (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 9) | (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5);
1525 // ---- COFF ----
1526 // Carloff, the most robust
1527 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1529 // P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64
1530 // 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
1531 dib8000_write_word(state, 187,
1532 (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 2)
1533 | 0x3);
1535 /* // P_small_coef_ext_enable = 1 */
1536 /* dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */
1538 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1540 // 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)
1541 if (mode == 3)
1542 dib8000_write_word(state, 180, 0x1fcf | ((mode - 1) << 14));
1543 else
1544 dib8000_write_word(state, 180, 0x0fcf | ((mode - 1) << 14));
1545 // P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1,
1546 // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4
1547 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
1548 // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
1549 dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
1550 // P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
1551 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1553 // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
1554 dib8000_write_word(state, 181, 300);
1555 dib8000_write_word(state, 182, 150);
1556 dib8000_write_word(state, 183, 80);
1557 dib8000_write_word(state, 184, 300);
1558 dib8000_write_word(state, 185, 150);
1559 dib8000_write_word(state, 186, 80);
1560 } else { // Sound Broadcasting mode 3 seg
1561 // P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15
1562 /* if (mode == 3) */
1563 /* dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */
1564 /* else */
1565 /* dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */
1566 dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
1568 // P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1,
1569 // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4
1570 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
1571 // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
1572 dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
1573 //P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
1574 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1576 // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
1577 dib8000_write_word(state, 181, 350);
1578 dib8000_write_word(state, 182, 300);
1579 dib8000_write_word(state, 183, 250);
1580 dib8000_write_word(state, 184, 350);
1581 dib8000_write_word(state, 185, 300);
1582 dib8000_write_word(state, 186, 250);
1585 } else if (state->isdbt_cfg_loaded == 0) { // if not Sound Broadcasting mode : put default values for 13 segments
1586 dib8000_write_word(state, 180, (16 << 6) | 9);
1587 dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2);
1588 coff_pow = 0x2800;
1589 for (i = 0; i < 6; i++)
1590 dib8000_write_word(state, 181 + i, coff_pow);
1592 // P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1,
1593 // 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
1594 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1);
1596 // P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6
1597 dib8000_write_word(state, 340, (8 << 6) | (6 << 0));
1598 // P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1
1599 dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1601 // ---- FFT ----
1602 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 && state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1603 dib8000_write_word(state, 178, 64); // P_fft_powrange=64
1604 else
1605 dib8000_write_word(state, 178, 32); // P_fft_powrange=32
1607 /* make the cpil_coff_lock more robust but slower p_coff_winlen
1608 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
1610 /* if ( ( nbseg_diff>0)&&(nbseg_diff<13))
1611 dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */
1613 dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask); /* P_lmod4_seg_inh */
1614 dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask); /* P_pha3_seg_inh */
1615 dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask); /* P_tac_seg_inh */
1616 if ((!state->fe[0]->dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0))
1617 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */
1618 else
1619 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask); /* P_equal_noise_seg_inh */
1620 dib8000_write_word(state, 287, ~seg_mask13 | 0x1000); /* P_tmcc_seg_inh */
1621 //dib8000_write_word(state, 288, ~seg_mask13 | seg_diff_mask); /* P_tmcc_seg_eq_inh */
1622 if (!autosearching)
1623 dib8000_write_word(state, 288, (~seg_mask13 | seg_diff_mask) & 0x1fff); /* P_tmcc_seg_eq_inh */
1624 else
1625 dib8000_write_word(state, 288, 0x1fff); //disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels.
1626 dprintk("287 = %X (%d)", ~seg_mask13 | 0x1000, ~seg_mask13 | 0x1000);
1628 dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask)); /* P_des_seg_enabled */
1630 /* offset loop parameters */
1631 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1632 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1633 /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1634 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40);
1636 else // Sound Broadcasting mode 3 seg
1637 /* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1638 dib8000_write_word(state, 32, ((10 - mode) << 12) | (6 << 8) | 0x60);
1639 } else
1640 // TODO in 13 seg, timf_alpha can always be the same or not ?
1641 /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
1642 dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80);
1644 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1645 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1646 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (11-P_mode) */
1647 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode));
1649 else // Sound Broadcasting mode 3 seg
1650 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (10-P_mode) */
1651 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (9 - mode));
1652 } else
1653 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = 9 */
1654 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode));
1656 /* P_dvsy_sync_wait - reuse mode */
1657 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1658 case TRANSMISSION_MODE_8K:
1659 mode = 256;
1660 break;
1661 case TRANSMISSION_MODE_4K:
1662 mode = 128;
1663 break;
1664 default:
1665 case TRANSMISSION_MODE_2K:
1666 mode = 64;
1667 break;
1669 if (state->cfg.diversity_delay == 0)
1670 mode = (mode * (1 << (guard)) * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo
1671 else
1672 mode = (mode * (1 << (guard)) * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for DVSY-fifo
1673 mode <<= 4;
1674 dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | mode);
1676 /* channel estimation fine configuration */
1677 switch (max_constellation) {
1678 case QAM_64:
1679 ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
1680 coeff[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
1681 coeff[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
1682 coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1683 coeff[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
1684 //if (!state->cfg.hostbus_diversity) //if diversity, we should prehaps use the configuration of the max_constallation -1
1685 break;
1686 case QAM_16:
1687 ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
1688 coeff[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
1689 coeff[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
1690 coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1691 coeff[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
1692 //if (!((state->cfg.hostbus_diversity) && (max_constellation == QAM_16)))
1693 break;
1694 default:
1695 ana_gain = 0; // 0 : goes along with ADC target at -22dB to keep good mobile performance and lock at sensitivity level
1696 coeff[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
1697 coeff[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
1698 coeff[2] = 0x0333; /* P_adp_regul_ext 0.1 */
1699 coeff[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
1700 break;
1702 for (mode = 0; mode < 4; mode++)
1703 dib8000_write_word(state, 215 + mode, coeff[mode]);
1705 // update ana_gain depending on max constellation
1706 dib8000_write_word(state, 116, ana_gain);
1707 // update ADC target depending on ana_gain
1708 if (ana_gain) { // set -16dB ADC target for ana_gain=-1
1709 for (i = 0; i < 10; i++)
1710 dib8000_write_word(state, 80 + i, adc_target_16dB[i]);
1711 } else { // set -22dB ADC target for ana_gain=0
1712 for (i = 0; i < 10; i++)
1713 dib8000_write_word(state, 80 + i, adc_target_16dB[i] - 355);
1716 // ---- ANA_FE ----
1717 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
1718 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1)
1719 ana_fe = ana_fe_coeff_3seg;
1720 else // 1-segment
1721 ana_fe = ana_fe_coeff_1seg;
1722 } else
1723 ana_fe = ana_fe_coeff_13seg;
1725 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0)
1726 for (mode = 0; mode < 24; mode++)
1727 dib8000_write_word(state, 117 + mode, ana_fe[mode]);
1729 // ---- CHAN_BLK ----
1730 for (i = 0; i < 13; i++) {
1731 if ((((~seg_diff_mask) >> i) & 1) == 1) {
1732 P_cfr_left_edge += (1 << i) * ((i == 0) || ((((seg_mask13 & (~seg_diff_mask)) >> (i - 1)) & 1) == 0));
1733 P_cfr_right_edge += (1 << i) * ((i == 12) || ((((seg_mask13 & (~seg_diff_mask)) >> (i + 1)) & 1) == 0));
1736 dib8000_write_word(state, 222, P_cfr_left_edge); // P_cfr_left_edge
1737 dib8000_write_word(state, 223, P_cfr_right_edge); // P_cfr_right_edge
1738 // "P_cspu_left_edge" not used => do not care
1739 // "P_cspu_right_edge" not used => do not care
1741 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1742 dib8000_write_word(state, 228, 1); // P_2d_mode_byp=1
1743 dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); // P_cspu_win_cut = 0
1744 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0
1745 && state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) {
1746 //dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0
1747 dib8000_write_word(state, 265, 15); // P_equal_noise_sel = 15
1749 } else if (state->isdbt_cfg_loaded == 0) {
1750 dib8000_write_word(state, 228, 0); // default value
1751 dib8000_write_word(state, 265, 31); // default value
1752 dib8000_write_word(state, 205, 0x200f); // init value
1754 // ---- TMCC ----
1755 for (i = 0; i < 3; i++)
1756 tmcc_pow +=
1757 (((state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe[0]->dtv_property_cache.layer[i].segment_count);
1758 // Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9);
1759 // Threshold is set at 1/4 of max power.
1760 tmcc_pow *= (1 << (9 - 2));
1762 dib8000_write_word(state, 290, tmcc_pow); // P_tmcc_dec_thres_2k
1763 dib8000_write_word(state, 291, tmcc_pow); // P_tmcc_dec_thres_4k
1764 dib8000_write_word(state, 292, tmcc_pow); // P_tmcc_dec_thres_8k
1765 //dib8000_write_word(state, 287, (1 << 13) | 0x1000 );
1766 // ---- PHA3 ----
1768 if (state->isdbt_cfg_loaded == 0)
1769 dib8000_write_word(state, 250, 3285); /*p_2d_hspeed_thr0 */
1771 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)
1772 state->isdbt_cfg_loaded = 0;
1773 else
1774 state->isdbt_cfg_loaded = 1;
1778 static int dib8000_autosearch_start(struct dvb_frontend *fe)
1780 u8 factor;
1781 u32 value;
1782 struct dib8000_state *state = fe->demodulator_priv;
1784 int slist = 0;
1786 state->fe[0]->dtv_property_cache.inversion = 0;
1787 if (!state->fe[0]->dtv_property_cache.isdbt_sb_mode)
1788 state->fe[0]->dtv_property_cache.layer[0].segment_count = 13;
1789 state->fe[0]->dtv_property_cache.layer[0].modulation = QAM_64;
1790 state->fe[0]->dtv_property_cache.layer[0].fec = FEC_2_3;
1791 state->fe[0]->dtv_property_cache.layer[0].interleaving = 0;
1793 //choose the right list, in sb, always do everything
1794 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
1795 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1796 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1797 slist = 7;
1798 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));
1799 } else {
1800 if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) {
1801 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1802 slist = 7;
1803 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 to have autosearch start ok with mode2
1804 } else
1805 slist = 3;
1806 } else {
1807 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1808 slist = 2;
1809 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
1810 } else
1811 slist = 0;
1814 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO)
1815 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1816 if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO)
1817 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1819 dprintk("using list for autosearch : %d", slist);
1820 dib8000_set_channel(state, (unsigned char)slist, 1);
1821 //dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
1823 factor = 1;
1825 //set lock_mask values
1826 dib8000_write_word(state, 6, 0x4);
1827 dib8000_write_word(state, 7, 0x8);
1828 dib8000_write_word(state, 8, 0x1000);
1830 //set lock_mask wait time values
1831 value = 50 * state->cfg.pll->internal * factor;
1832 dib8000_write_word(state, 11, (u16) ((value >> 16) & 0xffff)); // lock0 wait time
1833 dib8000_write_word(state, 12, (u16) (value & 0xffff)); // lock0 wait time
1834 value = 100 * state->cfg.pll->internal * factor;
1835 dib8000_write_word(state, 13, (u16) ((value >> 16) & 0xffff)); // lock1 wait time
1836 dib8000_write_word(state, 14, (u16) (value & 0xffff)); // lock1 wait time
1837 value = 1000 * state->cfg.pll->internal * factor;
1838 dib8000_write_word(state, 15, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
1839 dib8000_write_word(state, 16, (u16) (value & 0xffff)); // lock2 wait time
1841 value = dib8000_read_word(state, 0);
1842 dib8000_write_word(state, 0, (u16) ((1 << 15) | value));
1843 dib8000_read_word(state, 1284); // reset the INT. n_irq_pending
1844 dib8000_write_word(state, 0, (u16) value);
1848 return 0;
1851 static int dib8000_autosearch_irq(struct dvb_frontend *fe)
1853 struct dib8000_state *state = fe->demodulator_priv;
1854 u16 irq_pending = dib8000_read_word(state, 1284);
1856 if (irq_pending & 0x1) { // failed
1857 dprintk("dib8000_autosearch_irq failed");
1858 return 1;
1861 if (irq_pending & 0x2) { // succeeded
1862 dprintk("dib8000_autosearch_irq succeeded");
1863 return 2;
1866 return 0; // still pending
1869 static int dib8000_tune(struct dvb_frontend *fe)
1871 struct dib8000_state *state = fe->demodulator_priv;
1872 int ret = 0;
1873 u16 value, mode = fft_to_mode(state);
1875 // we are already tuned - just resuming from suspend
1876 if (state == NULL)
1877 return -EINVAL;
1879 dib8000_set_bandwidth(fe, state->fe[0]->dtv_property_cache.bandwidth_hz / 1000);
1880 dib8000_set_channel(state, 0, 0);
1882 // restart demod
1883 ret |= dib8000_write_word(state, 770, 0x4000);
1884 ret |= dib8000_write_word(state, 770, 0x0000);
1885 msleep(45);
1887 /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3 */
1888 /* ret |= dib8000_write_word(state, 29, (0 << 9) | (4 << 5) | (0 << 4) | (3 << 0) ); workaround inh_isi stays at 1 */
1890 // never achieved a lock before - wait for timfreq to update
1891 if (state->timf == 0) {
1892 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1893 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1894 msleep(300);
1895 else // Sound Broadcasting mode 3 seg
1896 msleep(500);
1897 } else // 13 seg
1898 msleep(200);
1900 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1901 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1903 /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40 alpha to check on board */
1904 dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40);
1905 //dib8000_write_word(state, 32, (8 << 12) | (6 << 8) | 0x80);
1907 /* P_ctrl_sfreq_step= (12-P_mode) P_ctrl_sfreq_inh =0 P_ctrl_pha_off_max */
1908 ret |= dib8000_write_word(state, 37, (12 - mode) | ((5 + mode) << 5));
1910 } else { // Sound Broadcasting mode 3 seg
1912 /* P_timf_alpha = (12-P_mode) , P_corm_alpha=6, P_corm_thres=0x60 alpha to check on board */
1913 dib8000_write_word(state, 32, ((12 - mode) << 12) | (6 << 8) | 0x60);
1915 ret |= dib8000_write_word(state, 37, (11 - mode) | ((5 + mode) << 5));
1918 } else { // 13 seg
1919 /* P_timf_alpha = 8 , P_corm_alpha=6, P_corm_thres=0x80 alpha to check on board */
1920 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x80);
1922 ret |= dib8000_write_word(state, 37, (10 - mode) | ((5 + mode) << 5));
1926 // we achieved a coff_cpil_lock - it's time to update the timf
1927 if ((dib8000_read_word(state, 568) >> 11) & 0x1)
1928 dib8000_update_timf(state);
1930 //now that tune is finished, lock0 should lock on fec_mpeg to output this lock on MP_LOCK. It's changed in autosearch start
1931 dib8000_write_word(state, 6, 0x200);
1933 if (state->revision == 0x8002) {
1934 value = dib8000_read_word(state, 903);
1935 dib8000_write_word(state, 903, value & ~(1 << 3));
1936 msleep(1);
1937 dib8000_write_word(state, 903, value | (1 << 3));
1940 return ret;
1943 static int dib8000_wakeup(struct dvb_frontend *fe)
1945 struct dib8000_state *state = fe->demodulator_priv;
1946 u8 index_frontend;
1947 int ret;
1949 dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
1950 dib8000_set_adc_state(state, DIBX000_ADC_ON);
1951 if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
1952 dprintk("could not start Slow ADC");
1954 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1955 ret = state->fe[index_frontend]->ops.init(state->fe[index_frontend]);
1956 if (ret < 0)
1957 return ret;
1960 return 0;
1963 static int dib8000_sleep(struct dvb_frontend *fe)
1965 struct dib8000_state *state = fe->demodulator_priv;
1966 u8 index_frontend;
1967 int ret;
1969 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1970 ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
1971 if (ret < 0)
1972 return ret;
1975 dib8000_set_output_mode(fe, OUTMODE_HIGH_Z);
1976 dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY);
1977 return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF);
1980 enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
1982 struct dib8000_state *state = fe->demodulator_priv;
1983 return state->tune_state;
1985 EXPORT_SYMBOL(dib8000_get_tune_state);
1987 int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
1989 struct dib8000_state *state = fe->demodulator_priv;
1990 state->tune_state = tune_state;
1991 return 0;
1993 EXPORT_SYMBOL(dib8000_set_tune_state);
1995 static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1997 struct dib8000_state *state = fe->demodulator_priv;
1998 u16 i, val = 0;
1999 fe_status_t stat;
2000 u8 index_frontend, sub_index_frontend;
2002 fe->dtv_property_cache.bandwidth_hz = 6000000;
2004 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2005 state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
2006 if (stat&FE_HAS_SYNC) {
2007 dprintk("TMCC lock on the slave%i", index_frontend);
2008 /* synchronize the cache with the other frontends */
2009 state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend], fep);
2010 for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL); sub_index_frontend++) {
2011 if (sub_index_frontend != index_frontend) {
2012 state->fe[sub_index_frontend]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode;
2013 state->fe[sub_index_frontend]->dtv_property_cache.inversion = state->fe[index_frontend]->dtv_property_cache.inversion;
2014 state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode = state->fe[index_frontend]->dtv_property_cache.transmission_mode;
2015 state->fe[sub_index_frontend]->dtv_property_cache.guard_interval = state->fe[index_frontend]->dtv_property_cache.guard_interval;
2016 state->fe[sub_index_frontend]->dtv_property_cache.isdbt_partial_reception = state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception;
2017 for (i = 0; i < 3; i++) {
2018 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].segment_count = state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count;
2019 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].interleaving = state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving;
2020 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].fec = state->fe[index_frontend]->dtv_property_cache.layer[i].fec;
2021 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].modulation = state->fe[index_frontend]->dtv_property_cache.layer[i].modulation;
2025 return 0;
2029 fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1;
2031 val = dib8000_read_word(state, 570);
2032 fe->dtv_property_cache.inversion = (val & 0x40) >> 6;
2033 switch ((val & 0x30) >> 4) {
2034 case 1:
2035 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
2036 break;
2037 case 3:
2038 default:
2039 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
2040 break;
2043 switch (val & 0x3) {
2044 case 0:
2045 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
2046 dprintk("dib8000_get_frontend GI = 1/32 ");
2047 break;
2048 case 1:
2049 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
2050 dprintk("dib8000_get_frontend GI = 1/16 ");
2051 break;
2052 case 2:
2053 dprintk("dib8000_get_frontend GI = 1/8 ");
2054 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
2055 break;
2056 case 3:
2057 dprintk("dib8000_get_frontend GI = 1/4 ");
2058 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
2059 break;
2062 val = dib8000_read_word(state, 505);
2063 fe->dtv_property_cache.isdbt_partial_reception = val & 1;
2064 dprintk("dib8000_get_frontend : partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception);
2066 for (i = 0; i < 3; i++) {
2067 val = dib8000_read_word(state, 493 + i);
2068 fe->dtv_property_cache.layer[i].segment_count = val & 0x0F;
2069 dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count);
2071 val = dib8000_read_word(state, 499 + i);
2072 fe->dtv_property_cache.layer[i].interleaving = val & 0x3;
2073 dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ", i, fe->dtv_property_cache.layer[i].interleaving);
2075 val = dib8000_read_word(state, 481 + i);
2076 switch (val & 0x7) {
2077 case 1:
2078 fe->dtv_property_cache.layer[i].fec = FEC_1_2;
2079 dprintk("dib8000_get_frontend : Layer %d Code Rate = 1/2 ", i);
2080 break;
2081 case 2:
2082 fe->dtv_property_cache.layer[i].fec = FEC_2_3;
2083 dprintk("dib8000_get_frontend : Layer %d Code Rate = 2/3 ", i);
2084 break;
2085 case 3:
2086 fe->dtv_property_cache.layer[i].fec = FEC_3_4;
2087 dprintk("dib8000_get_frontend : Layer %d Code Rate = 3/4 ", i);
2088 break;
2089 case 5:
2090 fe->dtv_property_cache.layer[i].fec = FEC_5_6;
2091 dprintk("dib8000_get_frontend : Layer %d Code Rate = 5/6 ", i);
2092 break;
2093 default:
2094 fe->dtv_property_cache.layer[i].fec = FEC_7_8;
2095 dprintk("dib8000_get_frontend : Layer %d Code Rate = 7/8 ", i);
2096 break;
2099 val = dib8000_read_word(state, 487 + i);
2100 switch (val & 0x3) {
2101 case 0:
2102 dprintk("dib8000_get_frontend : Layer %d DQPSK ", i);
2103 fe->dtv_property_cache.layer[i].modulation = DQPSK;
2104 break;
2105 case 1:
2106 fe->dtv_property_cache.layer[i].modulation = QPSK;
2107 dprintk("dib8000_get_frontend : Layer %d QPSK ", i);
2108 break;
2109 case 2:
2110 fe->dtv_property_cache.layer[i].modulation = QAM_16;
2111 dprintk("dib8000_get_frontend : Layer %d QAM16 ", i);
2112 break;
2113 case 3:
2114 default:
2115 dprintk("dib8000_get_frontend : Layer %d QAM64 ", i);
2116 fe->dtv_property_cache.layer[i].modulation = QAM_64;
2117 break;
2121 /* synchronize the cache with the other frontends */
2122 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2123 state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode = fe->dtv_property_cache.isdbt_sb_mode;
2124 state->fe[index_frontend]->dtv_property_cache.inversion = fe->dtv_property_cache.inversion;
2125 state->fe[index_frontend]->dtv_property_cache.transmission_mode = fe->dtv_property_cache.transmission_mode;
2126 state->fe[index_frontend]->dtv_property_cache.guard_interval = fe->dtv_property_cache.guard_interval;
2127 state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception = fe->dtv_property_cache.isdbt_partial_reception;
2128 for (i = 0; i < 3; i++) {
2129 state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count = fe->dtv_property_cache.layer[i].segment_count;
2130 state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving = fe->dtv_property_cache.layer[i].interleaving;
2131 state->fe[index_frontend]->dtv_property_cache.layer[i].fec = fe->dtv_property_cache.layer[i].fec;
2132 state->fe[index_frontend]->dtv_property_cache.layer[i].modulation = fe->dtv_property_cache.layer[i].modulation;
2135 return 0;
2138 static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
2140 struct dib8000_state *state = fe->demodulator_priv;
2141 u8 nbr_pending, exit_condition, index_frontend;
2142 s8 index_frontend_success = -1;
2143 int time, ret;
2144 int time_slave = FE_CALLBACK_TIME_NEVER;
2146 if (state->fe[0]->dtv_property_cache.frequency == 0) {
2147 dprintk("dib8000: must at least specify frequency ");
2148 return 0;
2151 if (state->fe[0]->dtv_property_cache.bandwidth_hz == 0) {
2152 dprintk("dib8000: no bandwidth specified, set to default ");
2153 state->fe[0]->dtv_property_cache.bandwidth_hz = 6000000;
2156 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2157 /* synchronization of the cache */
2158 state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT;
2159 memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));
2161 dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_HIGH_Z);
2162 if (state->fe[index_frontend]->ops.tuner_ops.set_params)
2163 state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend], fep);
2165 dib8000_set_tune_state(state->fe[index_frontend], CT_AGC_START);
2168 /* start up the AGC */
2169 do {
2170 time = dib8000_agc_startup(state->fe[0]);
2171 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2172 time_slave = dib8000_agc_startup(state->fe[index_frontend]);
2173 if (time == FE_CALLBACK_TIME_NEVER)
2174 time = time_slave;
2175 else if ((time_slave != FE_CALLBACK_TIME_NEVER) && (time_slave > time))
2176 time = time_slave;
2178 if (time != FE_CALLBACK_TIME_NEVER)
2179 msleep(time / 10);
2180 else
2181 break;
2182 exit_condition = 1;
2183 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2184 if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_AGC_STOP) {
2185 exit_condition = 0;
2186 break;
2189 } while (exit_condition == 0);
2191 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2192 dib8000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
2194 if ((state->fe[0]->dtv_property_cache.delivery_system != SYS_ISDBT) ||
2195 (state->fe[0]->dtv_property_cache.inversion == INVERSION_AUTO) ||
2196 (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) ||
2197 (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) ||
2198 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) &&
2199 (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0xff) &&
2200 (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0) &&
2201 ((state->fe[0]->dtv_property_cache.layer[0].modulation == QAM_AUTO) ||
2202 (state->fe[0]->dtv_property_cache.layer[0].fec == FEC_AUTO))) ||
2203 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) &&
2204 (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0xff) &&
2205 (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0) &&
2206 ((state->fe[0]->dtv_property_cache.layer[1].modulation == QAM_AUTO) ||
2207 (state->fe[0]->dtv_property_cache.layer[1].fec == FEC_AUTO))) ||
2208 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) &&
2209 (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0xff) &&
2210 (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0) &&
2211 ((state->fe[0]->dtv_property_cache.layer[2].modulation == QAM_AUTO) ||
2212 (state->fe[0]->dtv_property_cache.layer[2].fec == FEC_AUTO))) ||
2213 (((state->fe[0]->dtv_property_cache.layer[0].segment_count == 0) ||
2214 ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) &&
2215 ((state->fe[0]->dtv_property_cache.layer[1].segment_count == 0) ||
2216 ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) &&
2217 ((state->fe[0]->dtv_property_cache.layer[2].segment_count == 0) || ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) {
2218 int i = 80000;
2219 u8 found = 0;
2220 u8 tune_failed = 0;
2222 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2223 dib8000_set_bandwidth(state->fe[index_frontend], fe->dtv_property_cache.bandwidth_hz / 1000);
2224 dib8000_autosearch_start(state->fe[index_frontend]);
2227 do {
2228 msleep(20);
2229 nbr_pending = 0;
2230 exit_condition = 0; /* 0: tune pending; 1: tune failed; 2:tune success */
2231 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2232 if (((tune_failed >> index_frontend) & 0x1) == 0) {
2233 found = dib8000_autosearch_irq(state->fe[index_frontend]);
2234 switch (found) {
2235 case 0: /* tune pending */
2236 nbr_pending++;
2237 break;
2238 case 2:
2239 dprintk("autosearch succeed on the frontend%i", index_frontend);
2240 exit_condition = 2;
2241 index_frontend_success = index_frontend;
2242 break;
2243 default:
2244 dprintk("unhandled autosearch result");
2245 case 1:
2246 dprintk("autosearch failed for the frontend%i", index_frontend);
2247 break;
2252 /* if all tune are done and no success, exit: tune failed */
2253 if ((nbr_pending == 0) && (exit_condition == 0))
2254 exit_condition = 1;
2255 } while ((exit_condition == 0) && i--);
2257 if (exit_condition == 1) { /* tune failed */
2258 dprintk("tune failed");
2259 return 0;
2262 dprintk("tune success on frontend%i", index_frontend_success);
2264 dib8000_get_frontend(fe, fep);
2267 for (index_frontend = 0, ret = 0; (ret >= 0) && (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2268 ret = dib8000_tune(state->fe[index_frontend]);
2270 /* set output mode and diversity input */
2271 dib8000_set_output_mode(state->fe[0], state->cfg.output_mode);
2272 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2273 dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_DIVERSITY);
2274 dib8000_set_diversity_in(state->fe[index_frontend-1], 1);
2277 /* turn off the diversity of the last chip */
2278 dib8000_set_diversity_in(state->fe[index_frontend-1], 0);
2280 return ret;
2283 static u16 dib8000_read_lock(struct dvb_frontend *fe)
2285 struct dib8000_state *state = fe->demodulator_priv;
2287 return dib8000_read_word(state, 568);
2290 static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
2292 struct dib8000_state *state = fe->demodulator_priv;
2293 u16 lock_slave = 0, lock = dib8000_read_word(state, 568);
2294 u8 index_frontend;
2296 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2297 lock_slave |= dib8000_read_lock(state->fe[index_frontend]);
2299 *stat = 0;
2301 if (((lock >> 13) & 1) || ((lock_slave >> 13) & 1))
2302 *stat |= FE_HAS_SIGNAL;
2304 if (((lock >> 8) & 1) || ((lock_slave >> 8) & 1)) /* Equal */
2305 *stat |= FE_HAS_CARRIER;
2307 if ((((lock >> 1) & 0xf) == 0xf) || (((lock_slave >> 1) & 0xf) == 0xf)) /* TMCC_SYNC */
2308 *stat |= FE_HAS_SYNC;
2310 if ((((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) && ((lock >> 5) & 7)) /* FEC MPEG */
2311 *stat |= FE_HAS_LOCK;
2313 if (((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) {
2314 lock = dib8000_read_word(state, 554); /* Viterbi Layer A */
2315 if (lock & 0x01)
2316 *stat |= FE_HAS_VITERBI;
2318 lock = dib8000_read_word(state, 555); /* Viterbi Layer B */
2319 if (lock & 0x01)
2320 *stat |= FE_HAS_VITERBI;
2322 lock = dib8000_read_word(state, 556); /* Viterbi Layer C */
2323 if (lock & 0x01)
2324 *stat |= FE_HAS_VITERBI;
2327 return 0;
2330 static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber)
2332 struct dib8000_state *state = fe->demodulator_priv;
2333 *ber = (dib8000_read_word(state, 560) << 16) | dib8000_read_word(state, 561); // 13 segments
2334 return 0;
2337 static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
2339 struct dib8000_state *state = fe->demodulator_priv;
2340 *unc = dib8000_read_word(state, 565); // packet error on 13 seg
2341 return 0;
2344 static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2346 struct dib8000_state *state = fe->demodulator_priv;
2347 u8 index_frontend;
2348 u16 val;
2350 *strength = 0;
2351 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2352 state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
2353 if (val > 65535 - *strength)
2354 *strength = 65535;
2355 else
2356 *strength += val;
2359 val = 65535 - dib8000_read_word(state, 390);
2360 if (val > 65535 - *strength)
2361 *strength = 65535;
2362 else
2363 *strength += val;
2364 return 0;
2367 static u32 dib8000_get_snr(struct dvb_frontend *fe)
2369 struct dib8000_state *state = fe->demodulator_priv;
2370 u32 n, s, exp;
2371 u16 val;
2373 val = dib8000_read_word(state, 542);
2374 n = (val >> 6) & 0xff;
2375 exp = (val & 0x3f);
2376 if ((exp & 0x20) != 0)
2377 exp -= 0x40;
2378 n <<= exp+16;
2380 val = dib8000_read_word(state, 543);
2381 s = (val >> 6) & 0xff;
2382 exp = (val & 0x3f);
2383 if ((exp & 0x20) != 0)
2384 exp -= 0x40;
2385 s <<= exp+16;
2387 if (n > 0) {
2388 u32 t = (s/n) << 16;
2389 return t + ((s << 16) - n*t) / n;
2391 return 0xffffffff;
2394 static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
2396 struct dib8000_state *state = fe->demodulator_priv;
2397 u8 index_frontend;
2398 u32 snr_master;
2400 snr_master = dib8000_get_snr(fe);
2401 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2402 snr_master += dib8000_get_snr(state->fe[index_frontend]);
2404 if (snr_master != 0) {
2405 snr_master = 10*intlog10(snr_master>>16);
2406 *snr = snr_master / ((1 << 24) / 10);
2408 else
2409 *snr = 0;
2411 return 0;
2414 int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
2416 struct dib8000_state *state = fe->demodulator_priv;
2417 u8 index_frontend = 1;
2419 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
2420 index_frontend++;
2421 if (index_frontend < MAX_NUMBER_OF_FRONTENDS) {
2422 dprintk("set slave fe %p to index %i", fe_slave, index_frontend);
2423 state->fe[index_frontend] = fe_slave;
2424 return 0;
2427 dprintk("too many slave frontend");
2428 return -ENOMEM;
2430 EXPORT_SYMBOL(dib8000_set_slave_frontend);
2432 int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
2434 struct dib8000_state *state = fe->demodulator_priv;
2435 u8 index_frontend = 1;
2437 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
2438 index_frontend++;
2439 if (index_frontend != 1) {
2440 dprintk("remove slave fe %p (index %i)", state->fe[index_frontend-1], index_frontend-1);
2441 state->fe[index_frontend] = NULL;
2442 return 0;
2445 dprintk("no frontend to be removed");
2446 return -ENODEV;
2448 EXPORT_SYMBOL(dib8000_remove_slave_frontend);
2450 struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
2452 struct dib8000_state *state = fe->demodulator_priv;
2454 if (slave_index >= MAX_NUMBER_OF_FRONTENDS)
2455 return NULL;
2456 return state->fe[slave_index];
2458 EXPORT_SYMBOL(dib8000_get_slave_frontend);
2461 int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
2463 int k = 0, ret = 0;
2464 u8 new_addr = 0;
2465 struct i2c_device client = {.adap = host };
2467 client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
2468 if (!client.i2c_write_buffer) {
2469 dprintk("%s: not enough memory", __func__);
2470 return -ENOMEM;
2472 client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
2473 if (!client.i2c_read_buffer) {
2474 dprintk("%s: not enough memory", __func__);
2475 ret = -ENOMEM;
2476 goto error_memory_read;
2478 client.i2c_buffer_lock = kzalloc(sizeof(struct mutex), GFP_KERNEL);
2479 if (!client.i2c_buffer_lock) {
2480 dprintk("%s: not enough memory", __func__);
2481 ret = -ENOMEM;
2482 goto error_memory_lock;
2484 mutex_init(client.i2c_buffer_lock);
2486 for (k = no_of_demods - 1; k >= 0; k--) {
2487 /* designated i2c address */
2488 new_addr = first_addr + (k << 1);
2490 client.addr = new_addr;
2491 dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */
2492 if (dib8000_identify(&client) == 0) {
2493 dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */
2494 client.addr = default_addr;
2495 if (dib8000_identify(&client) == 0) {
2496 dprintk("#%d: not identified", k);
2497 ret = -EINVAL;
2498 goto error;
2502 /* start diversity to pull_down div_str - just for i2c-enumeration */
2503 dib8000_i2c_write16(&client, 1286, (1 << 10) | (4 << 6));
2505 /* set new i2c address and force divstart */
2506 dib8000_i2c_write16(&client, 1285, (new_addr << 2) | 0x2);
2507 client.addr = new_addr;
2508 dib8000_identify(&client);
2510 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
2513 for (k = 0; k < no_of_demods; k++) {
2514 new_addr = first_addr | (k << 1);
2515 client.addr = new_addr;
2517 // unforce divstr
2518 dib8000_i2c_write16(&client, 1285, new_addr << 2);
2520 /* deactivate div - it was just for i2c-enumeration */
2521 dib8000_i2c_write16(&client, 1286, 0);
2524 error:
2525 kfree(client.i2c_buffer_lock);
2526 error_memory_lock:
2527 kfree(client.i2c_read_buffer);
2528 error_memory_read:
2529 kfree(client.i2c_write_buffer);
2531 return ret;
2534 EXPORT_SYMBOL(dib8000_i2c_enumeration);
2535 static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
2537 tune->min_delay_ms = 1000;
2538 tune->step_size = 0;
2539 tune->max_drift = 0;
2540 return 0;
2543 static void dib8000_release(struct dvb_frontend *fe)
2545 struct dib8000_state *st = fe->demodulator_priv;
2546 u8 index_frontend;
2548 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++)
2549 dvb_frontend_detach(st->fe[index_frontend]);
2551 dibx000_exit_i2c_master(&st->i2c_master);
2552 kfree(st->fe[0]);
2553 kfree(st);
2556 struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
2558 struct dib8000_state *st = fe->demodulator_priv;
2559 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
2562 EXPORT_SYMBOL(dib8000_get_i2c_master);
2564 int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
2566 struct dib8000_state *st = fe->demodulator_priv;
2567 u16 val = dib8000_read_word(st, 299) & 0xffef;
2568 val |= (onoff & 0x1) << 4;
2570 dprintk("pid filter enabled %d", onoff);
2571 return dib8000_write_word(st, 299, val);
2573 EXPORT_SYMBOL(dib8000_pid_filter_ctrl);
2575 int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
2577 struct dib8000_state *st = fe->demodulator_priv;
2578 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
2579 return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0);
2581 EXPORT_SYMBOL(dib8000_pid_filter);
2583 static const struct dvb_frontend_ops dib8000_ops = {
2584 .info = {
2585 .name = "DiBcom 8000 ISDB-T",
2586 .type = FE_OFDM,
2587 .frequency_min = 44250000,
2588 .frequency_max = 867250000,
2589 .frequency_stepsize = 62500,
2590 .caps = FE_CAN_INVERSION_AUTO |
2591 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2592 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2593 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2594 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2597 .release = dib8000_release,
2599 .init = dib8000_wakeup,
2600 .sleep = dib8000_sleep,
2602 .set_frontend = dib8000_set_frontend,
2603 .get_tune_settings = dib8000_fe_get_tune_settings,
2604 .get_frontend = dib8000_get_frontend,
2606 .read_status = dib8000_read_status,
2607 .read_ber = dib8000_read_ber,
2608 .read_signal_strength = dib8000_read_signal_strength,
2609 .read_snr = dib8000_read_snr,
2610 .read_ucblocks = dib8000_read_unc_blocks,
2613 struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
2615 struct dvb_frontend *fe;
2616 struct dib8000_state *state;
2618 dprintk("dib8000_attach");
2620 state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL);
2621 if (state == NULL)
2622 return NULL;
2623 fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);
2624 if (fe == NULL)
2625 goto error;
2627 memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
2628 state->i2c.adap = i2c_adap;
2629 state->i2c.addr = i2c_addr;
2630 state->i2c.i2c_write_buffer = state->i2c_write_buffer;
2631 state->i2c.i2c_read_buffer = state->i2c_read_buffer;
2632 mutex_init(&state->i2c_buffer_lock);
2633 state->i2c.i2c_buffer_lock = &state->i2c_buffer_lock;
2634 state->gpio_val = cfg->gpio_val;
2635 state->gpio_dir = cfg->gpio_dir;
2637 /* Ensure the output mode remains at the previous default if it's
2638 * not specifically set by the caller.
2640 if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2641 state->cfg.output_mode = OUTMODE_MPEG2_FIFO;
2643 state->fe[0] = fe;
2644 fe->demodulator_priv = state;
2645 memcpy(&state->fe[0]->ops, &dib8000_ops, sizeof(struct dvb_frontend_ops));
2647 state->timf_default = cfg->pll->timf;
2649 if (dib8000_identify(&state->i2c) == 0)
2650 goto error;
2652 dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr);
2654 dib8000_reset(fe);
2656 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5)); /* ber_rs_len = 3 */
2658 return fe;
2660 error:
2661 kfree(state);
2662 return NULL;
2665 EXPORT_SYMBOL(dib8000_attach);
2667 MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@dibcom.fr, " "Patrick Boettcher <pboettcher@dibcom.fr>");
2668 MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator");
2669 MODULE_LICENSE("GPL");