[media] DiB7090: add support for the dib7090 based
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / media / dvb / frontends / dib7000p.c
blob18495bd166e66ca6a3be631e258cc3a51f09f0d1
1 /*
2 * Linux-DVB Driver for DiBcom's second generation DiB7000P (PC).
4 * Copyright (C) 2005-7 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>
14 #include "dvb_math.h"
15 #include "dvb_frontend.h"
17 #include "dib7000p.h"
19 static int debug;
20 module_param(debug, int, 0644);
21 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
23 static int buggy_sfn_workaround;
24 module_param(buggy_sfn_workaround, int, 0644);
25 MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
27 #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0)
29 struct i2c_device {
30 struct i2c_adapter *i2c_adap;
31 u8 i2c_addr;
34 struct dib7000p_state {
35 struct dvb_frontend demod;
36 struct dib7000p_config cfg;
38 u8 i2c_addr;
39 struct i2c_adapter *i2c_adap;
41 struct dibx000_i2c_master i2c_master;
43 u16 wbd_ref;
45 u8 current_band;
46 u32 current_bandwidth;
47 struct dibx000_agc_config *current_agc;
48 u32 timf;
50 u8 div_force_off:1;
51 u8 div_state:1;
52 u16 div_sync_wait;
54 u8 agc_state;
56 u16 gpio_dir;
57 u16 gpio_val;
59 u8 sfn_workaround_active:1;
61 #define SOC7090 0x7090
62 u16 version;
64 u16 tuner_enable;
65 struct i2c_adapter dib7090_tuner_adap;
68 enum dib7000p_power_mode {
69 DIB7000P_POWER_ALL = 0,
70 DIB7000P_POWER_ANALOG_ADC,
71 DIB7000P_POWER_INTERFACE_ONLY,
74 static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode);
75 static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff);
77 static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
79 u8 wb[2] = { reg >> 8, reg & 0xff };
80 u8 rb[2];
81 struct i2c_msg msg[2] = {
82 {.addr = state->i2c_addr >> 1,.flags = 0,.buf = wb,.len = 2},
83 {.addr = state->i2c_addr >> 1,.flags = I2C_M_RD,.buf = rb,.len = 2},
86 if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
87 dprintk("i2c read error on %d", reg);
89 return (rb[0] << 8) | rb[1];
92 static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
94 u8 b[4] = {
95 (reg >> 8) & 0xff, reg & 0xff,
96 (val >> 8) & 0xff, val & 0xff,
98 struct i2c_msg msg = {
99 .addr = state->i2c_addr >> 1,.flags = 0,.buf = b,.len = 4
101 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
104 static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf)
106 u16 l = 0, r, *n;
107 n = buf;
108 l = *n++;
109 while (l) {
110 r = *n++;
112 do {
113 dib7000p_write_word(state, r, *n++);
114 r++;
115 } while (--l);
116 l = *n++;
120 static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
122 int ret = 0;
123 u16 outreg, fifo_threshold, smo_mode;
125 outreg = 0;
126 fifo_threshold = 1792;
127 smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
129 dprintk("setting output mode for demod %p to %d", &state->demod, mode);
131 switch (mode) {
132 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
133 outreg = (1 << 10); /* 0x0400 */
134 break;
135 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
136 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
137 break;
138 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
139 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */
140 break;
141 case OUTMODE_DIVERSITY:
142 if (state->cfg.hostbus_diversity)
143 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
144 else
145 outreg = (1 << 11);
146 break;
147 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
148 smo_mode |= (3 << 1);
149 fifo_threshold = 512;
150 outreg = (1 << 10) | (5 << 6);
151 break;
152 case OUTMODE_ANALOG_ADC:
153 outreg = (1 << 10) | (3 << 6);
154 break;
155 case OUTMODE_HIGH_Z: // disable
156 outreg = 0;
157 break;
158 default:
159 dprintk("Unhandled output_mode passed to be set for demod %p", &state->demod);
160 break;
163 if (state->cfg.output_mpeg2_in_188_bytes)
164 smo_mode |= (1 << 5);
166 ret |= dib7000p_write_word(state, 235, smo_mode);
167 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
168 if (state->version != SOC7090)
169 ret |= dib7000p_write_word(state, 1286, outreg); /* P_Div_active */
171 return ret;
174 static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
176 struct dib7000p_state *state = demod->demodulator_priv;
178 if (state->div_force_off) {
179 dprintk("diversity combination deactivated - forced by COFDM parameters");
180 onoff = 0;
181 dib7000p_write_word(state, 207, 0);
182 } else
183 dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
185 state->div_state = (u8) onoff;
187 if (onoff) {
188 dib7000p_write_word(state, 204, 6);
189 dib7000p_write_word(state, 205, 16);
190 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
191 } else {
192 dib7000p_write_word(state, 204, 1);
193 dib7000p_write_word(state, 205, 0);
196 return 0;
199 static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode)
201 /* by default everything is powered off */
202 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0x0007, reg_899 = 0x0003, reg_1280 = (0xfe00) | (dib7000p_read_word(state, 1280) & 0x01ff);
204 /* now, depending on the requested mode, we power on */
205 switch (mode) {
206 /* power up everything in the demod */
207 case DIB7000P_POWER_ALL:
208 reg_774 = 0x0000;
209 reg_775 = 0x0000;
210 reg_776 = 0x0;
211 reg_899 = 0x0;
212 if (state->version == SOC7090)
213 reg_1280 &= 0x001f;
214 else
215 reg_1280 &= 0x01ff;
216 break;
218 case DIB7000P_POWER_ANALOG_ADC:
219 /* dem, cfg, iqc, sad, agc */
220 reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
221 /* nud */
222 reg_776 &= ~((1 << 0));
223 /* Dout */
224 if (state->version != SOC7090)
225 reg_1280 &= ~((1 << 11));
226 reg_1280 &= ~(1 << 6);
227 /* fall through wanted to enable the interfaces */
229 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
230 case DIB7000P_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C */
231 if (state->version == SOC7090)
232 reg_1280 &= ~((1 << 7) | (1 << 5));
233 else
234 reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
235 break;
237 /* TODO following stuff is just converted from the dib7000-driver - check when is used what */
240 dib7000p_write_word(state, 774, reg_774);
241 dib7000p_write_word(state, 775, reg_775);
242 dib7000p_write_word(state, 776, reg_776);
243 dib7000p_write_word(state, 899, reg_899);
244 dib7000p_write_word(state, 1280, reg_1280);
246 return 0;
249 static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no)
251 u16 reg_908 = dib7000p_read_word(state, 908), reg_909 = dib7000p_read_word(state, 909);
252 u16 reg;
254 switch (no) {
255 case DIBX000_SLOW_ADC_ON:
256 if (state->version == SOC7090) {
257 reg = dib7000p_read_word(state, 1925);
259 dib7000p_write_word(state, 1925, reg | (1 << 4) | (1 << 2)); /* en_slowAdc = 1 & reset_sladc = 1 */
261 reg = dib7000p_read_word(state, 1925); /* read acces to make it works... strange ... */
262 msleep(200);
263 dib7000p_write_word(state, 1925, reg & ~(1 << 4)); /* en_slowAdc = 1 & reset_sladc = 0 */
265 reg = dib7000p_read_word(state, 72) & ~((0x3 << 14) | (0x3 << 12));
266 dib7000p_write_word(state, 72, reg | (1 << 14) | (3 << 12) | 524); /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ; (Vin2 = Vcm) */
267 } else {
268 reg_909 |= (1 << 1) | (1 << 0);
269 dib7000p_write_word(state, 909, reg_909);
270 reg_909 &= ~(1 << 1);
272 break;
274 case DIBX000_SLOW_ADC_OFF:
275 if (state->version == SOC7090) {
276 reg = dib7000p_read_word(state, 1925);
277 dib7000p_write_word(state, 1925, (reg & ~(1 << 2)) | (1 << 4)); /* reset_sladc = 1 en_slowAdc = 0 */
278 } else
279 reg_909 |= (1 << 1) | (1 << 0);
280 break;
282 case DIBX000_ADC_ON:
283 reg_908 &= 0x0fff;
284 reg_909 &= 0x0003;
285 break;
287 case DIBX000_ADC_OFF: // leave the VBG voltage on
288 reg_908 |= (1 << 14) | (1 << 13) | (1 << 12);
289 reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
290 break;
292 case DIBX000_VBG_ENABLE:
293 reg_908 &= ~(1 << 15);
294 break;
296 case DIBX000_VBG_DISABLE:
297 reg_908 |= (1 << 15);
298 break;
300 default:
301 break;
304 // dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
306 reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4;
307 reg_908 |= (state->cfg.enable_current_mirror & 1) << 7;
309 dib7000p_write_word(state, 908, reg_908);
310 dib7000p_write_word(state, 909, reg_909);
313 static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
315 u32 timf;
317 // store the current bandwidth for later use
318 state->current_bandwidth = bw;
320 if (state->timf == 0) {
321 dprintk("using default timf");
322 timf = state->cfg.bw->timf;
323 } else {
324 dprintk("using updated timf");
325 timf = state->timf;
328 timf = timf * (bw / 50) / 160;
330 dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
331 dib7000p_write_word(state, 24, (u16) ((timf) & 0xffff));
333 return 0;
336 static int dib7000p_sad_calib(struct dib7000p_state *state)
338 /* internal */
339 // dib7000p_write_word(state, 72, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth
340 dib7000p_write_word(state, 73, (0 << 1) | (0 << 0));
342 if (state->version == SOC7090)
343 dib7000p_write_word(state, 74, 2048); // P_sad_calib_value = (0.9/1.8)*4096
344 else
345 dib7000p_write_word(state, 74, 776); // P_sad_calib_value = 0.625*3.3 / 4096
347 /* do the calibration */
348 dib7000p_write_word(state, 73, (1 << 0));
349 dib7000p_write_word(state, 73, (0 << 0));
351 msleep(1);
353 return 0;
356 int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
358 struct dib7000p_state *state = demod->demodulator_priv;
359 if (value > 4095)
360 value = 4095;
361 state->wbd_ref = value;
362 return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value);
364 EXPORT_SYMBOL(dib7000p_set_wbd_ref);
366 static void dib7000p_reset_pll(struct dib7000p_state *state)
368 struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
369 u16 clk_cfg0;
371 if (state->version == SOC7090) {
372 dib7000p_write_word(state, 1856, (!bw->pll_reset << 13) | (bw->pll_range << 12) | (bw->pll_ratio << 6) | (bw->pll_prediv));
374 while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1) {
377 dib7000p_write_word(state, 1857, dib7000p_read_word(state, 1857) | (!bw->pll_bypass << 15));
378 } else {
379 /* force PLL bypass */
380 clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) |
381 (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0);
383 dib7000p_write_word(state, 900, clk_cfg0);
385 /* P_pll_cfg */
386 dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset);
387 clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff);
388 dib7000p_write_word(state, 900, clk_cfg0);
391 dib7000p_write_word(state, 18, (u16) (((bw->internal * 1000) >> 16) & 0xffff));
392 dib7000p_write_word(state, 19, (u16) ((bw->internal * 1000) & 0xffff));
393 dib7000p_write_word(state, 21, (u16) ((bw->ifreq >> 16) & 0xffff));
394 dib7000p_write_word(state, 22, (u16) ((bw->ifreq) & 0xffff));
396 dib7000p_write_word(state, 72, bw->sad_cfg);
399 static u32 dib7000p_get_internal_freq(struct dib7000p_state *state)
401 u32 internal = (u32) dib7000p_read_word(state, 18) << 16;
402 internal |= (u32) dib7000p_read_word(state, 19);
403 internal /= 1000;
405 return internal;
408 int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
410 struct dib7000p_state *state = fe->demodulator_priv;
411 u16 reg_1857, reg_1856 = dib7000p_read_word(state, 1856);
412 u8 loopdiv, prediv;
413 u32 internal, xtal;
415 /* get back old values */
416 prediv = reg_1856 & 0x3f;
417 loopdiv = (reg_1856 >> 6) & 0x3f;
419 if ((bw != NULL) && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) {
420 dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio);
421 reg_1856 &= 0xf000;
422 reg_1857 = dib7000p_read_word(state, 1857);
423 dib7000p_write_word(state, 1857, reg_1857 & ~(1 << 15)); // desable pll
425 dib7000p_write_word(state, 1856, reg_1856 | ((bw->pll_ratio & 0x3f) << 6) | (bw->pll_prediv & 0x3f));
427 /* write new system clk into P_sec_len */
428 internal = dib7000p_get_internal_freq(state);
429 xtal = (internal / loopdiv) * prediv;
430 internal = 1000 * (xtal / bw->pll_prediv) * bw->pll_ratio; /* new internal */
431 dib7000p_write_word(state, 18, (u16) ((internal >> 16) & 0xffff));
432 dib7000p_write_word(state, 19, (u16) (internal & 0xffff));
434 dib7000p_write_word(state, 1857, reg_1857 | (1 << 15)); // enable pll
436 while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1) {
437 dprintk("Waiting for PLL to lock");
440 return 0;
442 return -EIO;
444 EXPORT_SYMBOL(dib7000p_update_pll);
446 static int dib7000p_reset_gpio(struct dib7000p_state *st)
448 /* reset the GPIOs */
449 dprintk("gpio dir: %x: val: %x, pwm_pos: %x", st->gpio_dir, st->gpio_val, st->cfg.gpio_pwm_pos);
451 dib7000p_write_word(st, 1029, st->gpio_dir);
452 dib7000p_write_word(st, 1030, st->gpio_val);
454 /* TODO 1031 is P_gpio_od */
456 dib7000p_write_word(st, 1032, st->cfg.gpio_pwm_pos);
458 dib7000p_write_word(st, 1037, st->cfg.pwm_freq_div);
459 return 0;
462 static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val)
464 st->gpio_dir = dib7000p_read_word(st, 1029);
465 st->gpio_dir &= ~(1 << num); /* reset the direction bit */
466 st->gpio_dir |= (dir & 0x1) << num; /* set the new direction */
467 dib7000p_write_word(st, 1029, st->gpio_dir);
469 st->gpio_val = dib7000p_read_word(st, 1030);
470 st->gpio_val &= ~(1 << num); /* reset the direction bit */
471 st->gpio_val |= (val & 0x01) << num; /* set the new value */
472 dib7000p_write_word(st, 1030, st->gpio_val);
474 return 0;
477 int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val)
479 struct dib7000p_state *state = demod->demodulator_priv;
480 return dib7000p_cfg_gpio(state, num, dir, val);
482 EXPORT_SYMBOL(dib7000p_set_gpio);
484 static u16 dib7000p_defaults[] = {
485 // auto search configuration
486 3, 2,
487 0x0004,
488 0x1000,
489 0x0814, /* Equal Lock */
491 12, 6,
492 0x001b,
493 0x7740,
494 0x005b,
495 0x8d80,
496 0x01c9,
497 0xc380,
498 0x0000,
499 0x0080,
500 0x0000,
501 0x0090,
502 0x0001,
503 0xd4c0,
505 1, 26,
506 0x6680, // P_timf_alpha=6, P_corm_alpha=6, P_corm_thres=128 default: 6,4,26
508 /* set ADC level to -16 */
509 11, 79,
510 (1 << 13) - 825 - 117,
511 (1 << 13) - 837 - 117,
512 (1 << 13) - 811 - 117,
513 (1 << 13) - 766 - 117,
514 (1 << 13) - 737 - 117,
515 (1 << 13) - 693 - 117,
516 (1 << 13) - 648 - 117,
517 (1 << 13) - 619 - 117,
518 (1 << 13) - 575 - 117,
519 (1 << 13) - 531 - 117,
520 (1 << 13) - 501 - 117,
522 1, 142,
523 0x0410, // P_palf_filter_on=1, P_palf_filter_freeze=0, P_palf_alpha_regul=16
525 /* disable power smoothing */
526 8, 145,
536 1, 154,
537 1 << 13, // P_fft_freq_dir=1, P_fft_nb_to_cut=0
539 1, 168,
540 0x0ccd, // P_pha3_thres, default 0x3000
542 // 1, 169,
543 // 0x0010, // P_cti_use_cpe=0, P_cti_use_prog=0, P_cti_win_len=16, default: 0x0010
545 1, 183,
546 0x200f, // P_cspu_regul=512, P_cspu_win_cut=15, default: 0x2005
548 1, 212,
549 0x169, // P_vit_ksi_dwn = 5 P_vit_ksi_up = 5 0x1e1, // P_vit_ksi_dwn = 4 P_vit_ksi_up = 7
551 5, 187,
552 0x023d, // P_adp_regul_cnt=573, default: 410
553 0x00a4, // P_adp_noise_cnt=
554 0x00a4, // P_adp_regul_ext
555 0x7ff0, // P_adp_noise_ext
556 0x3ccc, // P_adp_fil
558 1, 198,
559 0x800, // P_equal_thres_wgn
561 1, 222,
562 0x0010, // P_fec_ber_rs_len=2
564 1, 235,
565 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
567 2, 901,
568 0x0006, // P_clk_cfg1
569 (3 << 10) | (1 << 6), // P_divclksel=3 P_divbitsel=1
571 1, 905,
572 0x2c8e, // Tuner IO bank: max drive (14mA) + divout pads max drive
577 static int dib7000p_demod_reset(struct dib7000p_state *state)
579 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
581 if (state->version == SOC7090)
582 dibx000_reset_i2c_master(&state->i2c_master);
584 dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE);
586 /* restart all parts */
587 dib7000p_write_word(state, 770, 0xffff);
588 dib7000p_write_word(state, 771, 0xffff);
589 dib7000p_write_word(state, 772, 0x001f);
590 dib7000p_write_word(state, 898, 0x0003);
591 dib7000p_write_word(state, 1280, 0x001f - ((1 << 4) | (1 << 3)));
593 dib7000p_write_word(state, 770, 0);
594 dib7000p_write_word(state, 771, 0);
595 dib7000p_write_word(state, 772, 0);
596 dib7000p_write_word(state, 898, 0);
597 dib7000p_write_word(state, 1280, 0);
599 /* default */
600 dib7000p_reset_pll(state);
602 if (dib7000p_reset_gpio(state) != 0)
603 dprintk("GPIO reset was not successful.");
605 if (state->version == SOC7090) {
606 dib7000p_write_word(state, 899, 0);
608 /* impulse noise */
609 dib7000p_write_word(state, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */
610 dib7000p_write_word(state, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */
611 dib7000p_write_word(state, 44, 300); /* 300 fag P_iqc_dect_min = +280 */
612 //dib7000p_write_word(state, 273, (1<<6) | 10); /* P_vit_inoise_sel = 1, P_vit_inoise_gain = 10*/
613 dib7000p_write_word(state, 273, (1<<6) | 30); //26/* P_vit_inoise_sel = 1, P_vit_inoise_gain = 26*/// FAG
615 if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
616 dprintk("OUTPUT_MODE could not be reset.");
618 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
619 dib7000p_sad_calib(state);
620 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
622 /* unforce divstr regardless whether i2c enumeration was done or not */
623 dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1));
625 dib7000p_set_bandwidth(state, 8000);
627 if(state->version == SOC7090) {
628 dib7000p_write_word(state, 36, 0x5755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */
629 } else { // P_iqc_alpha_pha, P_iqc_alpha_amp_dcc_alpha, ...
630 if (state->cfg.tuner_is_baseband)
631 dib7000p_write_word(state, 36, 0x0755);
632 else
633 dib7000p_write_word(state, 36, 0x1f55);
636 dib7000p_write_tab(state, dib7000p_defaults);
638 dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
640 return 0;
643 static void dib7000p_pll_clk_cfg(struct dib7000p_state *state)
645 u16 tmp = 0;
646 tmp = dib7000p_read_word(state, 903);
647 dib7000p_write_word(state, 903, (tmp | 0x1)); //pwr-up pll
648 tmp = dib7000p_read_word(state, 900);
649 dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6)); //use High freq clock
652 static void dib7000p_restart_agc(struct dib7000p_state *state)
654 // P_restart_iqc & P_restart_agc
655 dib7000p_write_word(state, 770, (1 << 11) | (1 << 9));
656 dib7000p_write_word(state, 770, 0x0000);
659 static int dib7000p_update_lna(struct dib7000p_state *state)
661 u16 dyn_gain;
663 // when there is no LNA to program return immediatly
664 if (state->cfg.update_lna) {
665 // read dyn_gain here (because it is demod-dependent and not fe)
666 dyn_gain = dib7000p_read_word(state, 394);
667 if (state->cfg.update_lna(&state->demod, dyn_gain)) { // LNA has changed
668 dib7000p_restart_agc(state);
669 return 1;
673 return 0;
676 static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
678 struct dibx000_agc_config *agc = NULL;
679 int i;
680 if (state->current_band == band && state->current_agc != NULL)
681 return 0;
682 state->current_band = band;
684 for (i = 0; i < state->cfg.agc_config_count; i++)
685 if (state->cfg.agc[i].band_caps & band) {
686 agc = &state->cfg.agc[i];
687 break;
690 if (agc == NULL) {
691 dprintk("no valid AGC configuration found for band 0x%02x", band);
692 return -EINVAL;
695 state->current_agc = agc;
697 /* AGC */
698 dib7000p_write_word(state, 75, agc->setup);
699 dib7000p_write_word(state, 76, agc->inv_gain);
700 dib7000p_write_word(state, 77, agc->time_stabiliz);
701 dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);
703 // Demod AGC loop configuration
704 dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);
705 dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp);
707 /* AGC continued */
708 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
709 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
711 if (state->wbd_ref != 0)
712 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref);
713 else
714 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref);
716 dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
718 dib7000p_write_word(state, 107, agc->agc1_max);
719 dib7000p_write_word(state, 108, agc->agc1_min);
720 dib7000p_write_word(state, 109, agc->agc2_max);
721 dib7000p_write_word(state, 110, agc->agc2_min);
722 dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
723 dib7000p_write_word(state, 112, agc->agc1_pt3);
724 dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
725 dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
726 dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
727 return 0;
730 static void dib7000p_set_dds(struct dib7000p_state *state, s32 offset_khz)
732 u32 internal = dib7000p_get_internal_freq(state);
733 s32 unit_khz_dds_val = 67108864 / (internal); /* 2**26 / Fsampling is the unit 1KHz offset */
734 u32 abs_offset_khz = ABS(offset_khz);
735 u32 dds = state->cfg.bw->ifreq & 0x1ffffff;
736 u8 invert = !!(state->cfg.bw->ifreq & (1 << 25));
738 dprintk("setting a frequency offset of %dkHz internal freq = %d invert = %d", offset_khz, internal, invert);
740 if (offset_khz < 0)
741 unit_khz_dds_val *= -1;
743 /* IF tuner */
744 if (invert)
745 dds -= (abs_offset_khz * unit_khz_dds_val); /* /100 because of /100 on the unit_khz_dds_val line calc for better accuracy */
746 else
747 dds += (abs_offset_khz * unit_khz_dds_val);
749 if (abs_offset_khz <= (internal / 2)) { /* Max dds offset is the half of the demod freq */
750 dib7000p_write_word(state, 21, (u16) (((dds >> 16) & 0x1ff) | (0 << 10) | (invert << 9)));
751 dib7000p_write_word(state, 22, (u16) (dds & 0xffff));
755 static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
757 struct dib7000p_state *state = demod->demodulator_priv;
758 int ret = -1;
759 u8 *agc_state = &state->agc_state;
760 u8 agc_split;
761 u16 reg;
762 u32 upd_demod_gain_period = 0x1000;
764 switch (state->agc_state) {
765 case 0:
766 // set power-up level: interf+analog+AGC
767 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
768 if (state->version == SOC7090) {
769 reg = dib7000p_read_word(state, 0x79b) & 0xff00;
770 dib7000p_write_word(state, 0x79a, upd_demod_gain_period & 0xFFFF); /* lsb */
771 dib7000p_write_word(state, 0x79b, reg | (1 << 14) | ((upd_demod_gain_period >> 16) & 0xFF)); // bit 14 = enDemodGain
773 /* enable adc i & q */
774 reg = dib7000p_read_word(state, 0x780);
775 dib7000p_write_word(state, 0x780, (reg | (0x3)) & (~(1 << 7)));
776 } else {
777 dib7000p_set_adc_state(state, DIBX000_ADC_ON);
778 dib7000p_pll_clk_cfg(state);
781 if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency / 1000)) != 0)
782 return -1;
784 dib7000p_set_dds(state, 0);
785 ret = 7;
786 (*agc_state)++;
787 break;
789 case 1:
790 // AGC initialization
791 if (state->cfg.agc_control)
792 state->cfg.agc_control(&state->demod, 1);
794 dib7000p_write_word(state, 78, 32768);
795 if (!state->current_agc->perform_agc_softsplit) {
796 /* we are using the wbd - so slow AGC startup */
797 /* force 0 split on WBD and restart AGC */
798 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));
799 (*agc_state)++;
800 ret = 5;
801 } else {
802 /* default AGC startup */
803 (*agc_state) = 4;
804 /* wait AGC rough lock time */
805 ret = 7;
808 dib7000p_restart_agc(state);
809 break;
811 case 2: /* fast split search path after 5sec */
812 dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4)); /* freeze AGC loop */
813 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */
814 (*agc_state)++;
815 ret = 14;
816 break;
818 case 3: /* split search ended */
819 agc_split = (u8) dib7000p_read_word(state, 396); /* store the split value for the next time */
820 dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */
822 dib7000p_write_word(state, 75, state->current_agc->setup); /* std AGC loop */
823 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
825 dib7000p_restart_agc(state);
827 dprintk("SPLIT %p: %hd", demod, agc_split);
829 (*agc_state)++;
830 ret = 5;
831 break;
833 case 4: /* LNA startup */
834 // wait AGC accurate lock time
835 ret = 7;
837 if (dib7000p_update_lna(state))
838 // wait only AGC rough lock time
839 ret = 5;
840 else // nothing was done, go to the next state
841 (*agc_state)++;
842 break;
844 case 5:
845 if (state->cfg.agc_control)
846 state->cfg.agc_control(&state->demod, 0);
847 (*agc_state)++;
848 break;
849 default:
850 break;
852 return ret;
855 static void dib7000p_update_timf(struct dib7000p_state *state)
857 u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428);
858 state->timf = timf * 160 / (state->current_bandwidth / 50);
859 dib7000p_write_word(state, 23, (u16) (timf >> 16));
860 dib7000p_write_word(state, 24, (u16) (timf & 0xffff));
861 dprintk("updated timf_frequency: %d (default: %d)", state->timf, state->cfg.bw->timf);
865 u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
867 struct dib7000p_state *state = fe->demodulator_priv;
868 switch (op) {
869 case DEMOD_TIMF_SET:
870 state->timf = timf;
871 break;
872 case DEMOD_TIMF_UPDATE:
873 dib7000p_update_timf(state);
874 break;
875 case DEMOD_TIMF_GET:
876 break;
878 dib7000p_set_bandwidth(state, state->current_bandwidth);
879 return state->timf;
881 EXPORT_SYMBOL(dib7000p_ctrl_timf);
883 static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq)
885 u16 value, est[4];
887 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
889 /* nfft, guard, qam, alpha */
890 value = 0;
891 switch (ch->u.ofdm.transmission_mode) {
892 case TRANSMISSION_MODE_2K:
893 value |= (0 << 7);
894 break;
895 case TRANSMISSION_MODE_4K:
896 value |= (2 << 7);
897 break;
898 default:
899 case TRANSMISSION_MODE_8K:
900 value |= (1 << 7);
901 break;
903 switch (ch->u.ofdm.guard_interval) {
904 case GUARD_INTERVAL_1_32:
905 value |= (0 << 5);
906 break;
907 case GUARD_INTERVAL_1_16:
908 value |= (1 << 5);
909 break;
910 case GUARD_INTERVAL_1_4:
911 value |= (3 << 5);
912 break;
913 default:
914 case GUARD_INTERVAL_1_8:
915 value |= (2 << 5);
916 break;
918 switch (ch->u.ofdm.constellation) {
919 case QPSK:
920 value |= (0 << 3);
921 break;
922 case QAM_16:
923 value |= (1 << 3);
924 break;
925 default:
926 case QAM_64:
927 value |= (2 << 3);
928 break;
930 switch (HIERARCHY_1) {
931 case HIERARCHY_2:
932 value |= 2;
933 break;
934 case HIERARCHY_4:
935 value |= 4;
936 break;
937 default:
938 case HIERARCHY_1:
939 value |= 1;
940 break;
942 dib7000p_write_word(state, 0, value);
943 dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */
945 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
946 value = 0;
947 if (1 != 0)
948 value |= (1 << 6);
949 if (ch->u.ofdm.hierarchy_information == 1)
950 value |= (1 << 4);
951 if (1 == 1)
952 value |= 1;
953 switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
954 case FEC_2_3:
955 value |= (2 << 1);
956 break;
957 case FEC_3_4:
958 value |= (3 << 1);
959 break;
960 case FEC_5_6:
961 value |= (5 << 1);
962 break;
963 case FEC_7_8:
964 value |= (7 << 1);
965 break;
966 default:
967 case FEC_1_2:
968 value |= (1 << 1);
969 break;
971 dib7000p_write_word(state, 208, value);
973 /* offset loop parameters */
974 dib7000p_write_word(state, 26, 0x6680); // timf(6xxx)
975 dib7000p_write_word(state, 32, 0x0003); // pha_off_max(xxx3)
976 dib7000p_write_word(state, 29, 0x1273); // isi
977 dib7000p_write_word(state, 33, 0x0005); // sfreq(xxx5)
979 /* P_dvsy_sync_wait */
980 switch (ch->u.ofdm.transmission_mode) {
981 case TRANSMISSION_MODE_8K:
982 value = 256;
983 break;
984 case TRANSMISSION_MODE_4K:
985 value = 128;
986 break;
987 case TRANSMISSION_MODE_2K:
988 default:
989 value = 64;
990 break;
992 switch (ch->u.ofdm.guard_interval) {
993 case GUARD_INTERVAL_1_16:
994 value *= 2;
995 break;
996 case GUARD_INTERVAL_1_8:
997 value *= 4;
998 break;
999 case GUARD_INTERVAL_1_4:
1000 value *= 8;
1001 break;
1002 default:
1003 case GUARD_INTERVAL_1_32:
1004 value *= 1;
1005 break;
1007 if (state->cfg.diversity_delay == 0)
1008 state->div_sync_wait = (value * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo
1009 else
1010 state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for one DVSY-fifo
1012 /* deactive the possibility of diversity reception if extended interleaver */
1013 state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K;
1014 dib7000p_set_diversity_in(&state->demod, state->div_state);
1016 /* channel estimation fine configuration */
1017 switch (ch->u.ofdm.constellation) {
1018 case QAM_64:
1019 est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
1020 est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
1021 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1022 est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
1023 break;
1024 case QAM_16:
1025 est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
1026 est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
1027 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1028 est[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
1029 break;
1030 default:
1031 est[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
1032 est[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
1033 est[2] = 0x0333; /* P_adp_regul_ext 0.1 */
1034 est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
1035 break;
1037 for (value = 0; value < 4; value++)
1038 dib7000p_write_word(state, 187 + value, est[value]);
1041 static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
1043 struct dib7000p_state *state = demod->demodulator_priv;
1044 struct dvb_frontend_parameters schan;
1045 u32 value, factor;
1046 u32 internal = dib7000p_get_internal_freq(state);
1048 schan = *ch;
1049 schan.u.ofdm.constellation = QAM_64;
1050 schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
1051 schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
1052 schan.u.ofdm.code_rate_HP = FEC_2_3;
1053 schan.u.ofdm.code_rate_LP = FEC_3_4;
1054 schan.u.ofdm.hierarchy_information = 0;
1056 dib7000p_set_channel(state, &schan, 7);
1058 factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth);
1059 if (factor >= 5000)
1060 factor = 1;
1061 else
1062 factor = 6;
1064 // always use the setting for 8MHz here lock_time for 7,6 MHz are longer
1065 value = 30 * internal * factor;
1066 dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff)); // lock0 wait time
1067 dib7000p_write_word(state, 7, (u16) (value & 0xffff)); // lock0 wait time
1068 value = 100 * internal * factor;
1069 dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff)); // lock1 wait time
1070 dib7000p_write_word(state, 9, (u16) (value & 0xffff)); // lock1 wait time
1071 value = 500 * internal * factor;
1072 dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
1073 dib7000p_write_word(state, 11, (u16) (value & 0xffff)); // lock2 wait time
1075 value = dib7000p_read_word(state, 0);
1076 dib7000p_write_word(state, 0, (u16) ((1 << 9) | value));
1077 dib7000p_read_word(state, 1284);
1078 dib7000p_write_word(state, 0, (u16) value);
1080 return 0;
1083 static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod)
1085 struct dib7000p_state *state = demod->demodulator_priv;
1086 u16 irq_pending = dib7000p_read_word(state, 1284);
1088 if (irq_pending & 0x1) // failed
1089 return 1;
1091 if (irq_pending & 0x2) // succeeded
1092 return 2;
1094 return 0; // still pending
1097 static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw)
1099 static s16 notch[] = { 16143, 14402, 12238, 9713, 6902, 3888, 759, -2392 };
1100 static u8 sine[] = { 0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
1101 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
1102 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
1103 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
1104 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
1105 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
1106 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
1107 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
1108 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
1109 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
1110 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
1111 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
1112 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
1113 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
1114 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
1115 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1116 255, 255, 255, 255, 255, 255
1119 u32 xtal = state->cfg.bw->xtal_hz / 1000;
1120 int f_rel = DIV_ROUND_CLOSEST(rf_khz, xtal) * xtal - rf_khz;
1121 int k;
1122 int coef_re[8], coef_im[8];
1123 int bw_khz = bw;
1124 u32 pha;
1126 dprintk("relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal);
1128 if (f_rel < -bw_khz / 2 || f_rel > bw_khz / 2)
1129 return;
1131 bw_khz /= 100;
1133 dib7000p_write_word(state, 142, 0x0610);
1135 for (k = 0; k < 8; k++) {
1136 pha = ((f_rel * (k + 1) * 112 * 80 / bw_khz) / 1000) & 0x3ff;
1138 if (pha == 0) {
1139 coef_re[k] = 256;
1140 coef_im[k] = 0;
1141 } else if (pha < 256) {
1142 coef_re[k] = sine[256 - (pha & 0xff)];
1143 coef_im[k] = sine[pha & 0xff];
1144 } else if (pha == 256) {
1145 coef_re[k] = 0;
1146 coef_im[k] = 256;
1147 } else if (pha < 512) {
1148 coef_re[k] = -sine[pha & 0xff];
1149 coef_im[k] = sine[256 - (pha & 0xff)];
1150 } else if (pha == 512) {
1151 coef_re[k] = -256;
1152 coef_im[k] = 0;
1153 } else if (pha < 768) {
1154 coef_re[k] = -sine[256 - (pha & 0xff)];
1155 coef_im[k] = -sine[pha & 0xff];
1156 } else if (pha == 768) {
1157 coef_re[k] = 0;
1158 coef_im[k] = -256;
1159 } else {
1160 coef_re[k] = sine[pha & 0xff];
1161 coef_im[k] = -sine[256 - (pha & 0xff)];
1164 coef_re[k] *= notch[k];
1165 coef_re[k] += (1 << 14);
1166 if (coef_re[k] >= (1 << 24))
1167 coef_re[k] = (1 << 24) - 1;
1168 coef_re[k] /= (1 << 15);
1170 coef_im[k] *= notch[k];
1171 coef_im[k] += (1 << 14);
1172 if (coef_im[k] >= (1 << 24))
1173 coef_im[k] = (1 << 24) - 1;
1174 coef_im[k] /= (1 << 15);
1176 dprintk("PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]);
1178 dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
1179 dib7000p_write_word(state, 144, coef_im[k] & 0x3ff);
1180 dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
1182 dib7000p_write_word(state, 143, 0);
1185 static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
1187 struct dib7000p_state *state = demod->demodulator_priv;
1188 u16 tmp = 0;
1190 if (ch != NULL)
1191 dib7000p_set_channel(state, ch, 0);
1192 else
1193 return -EINVAL;
1195 // restart demod
1196 dib7000p_write_word(state, 770, 0x4000);
1197 dib7000p_write_word(state, 770, 0x0000);
1198 msleep(45);
1200 /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */
1201 tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
1202 if (state->sfn_workaround_active) {
1203 dprintk("SFN workaround is active");
1204 tmp |= (1 << 9);
1205 dib7000p_write_word(state, 166, 0x4000); // P_pha3_force_pha_shift
1206 } else {
1207 dib7000p_write_word(state, 166, 0x0000); // P_pha3_force_pha_shift
1209 dib7000p_write_word(state, 29, tmp);
1211 // never achieved a lock with that bandwidth so far - wait for osc-freq to update
1212 if (state->timf == 0)
1213 msleep(200);
1215 /* offset loop parameters */
1217 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
1218 tmp = (6 << 8) | 0x80;
1219 switch (ch->u.ofdm.transmission_mode) {
1220 case TRANSMISSION_MODE_2K:
1221 tmp |= (2 << 12);
1222 break;
1223 case TRANSMISSION_MODE_4K:
1224 tmp |= (3 << 12);
1225 break;
1226 default:
1227 case TRANSMISSION_MODE_8K:
1228 tmp |= (4 << 12);
1229 break;
1231 dib7000p_write_word(state, 26, tmp); /* timf_a(6xxx) */
1233 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1234 tmp = (0 << 4);
1235 switch (ch->u.ofdm.transmission_mode) {
1236 case TRANSMISSION_MODE_2K:
1237 tmp |= 0x6;
1238 break;
1239 case TRANSMISSION_MODE_4K:
1240 tmp |= 0x7;
1241 break;
1242 default:
1243 case TRANSMISSION_MODE_8K:
1244 tmp |= 0x8;
1245 break;
1247 dib7000p_write_word(state, 32, tmp);
1249 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1250 tmp = (0 << 4);
1251 switch (ch->u.ofdm.transmission_mode) {
1252 case TRANSMISSION_MODE_2K:
1253 tmp |= 0x6;
1254 break;
1255 case TRANSMISSION_MODE_4K:
1256 tmp |= 0x7;
1257 break;
1258 default:
1259 case TRANSMISSION_MODE_8K:
1260 tmp |= 0x8;
1261 break;
1263 dib7000p_write_word(state, 33, tmp);
1265 tmp = dib7000p_read_word(state, 509);
1266 if (!((tmp >> 6) & 0x1)) {
1267 /* restart the fec */
1268 tmp = dib7000p_read_word(state, 771);
1269 dib7000p_write_word(state, 771, tmp | (1 << 1));
1270 dib7000p_write_word(state, 771, tmp);
1271 msleep(40);
1272 tmp = dib7000p_read_word(state, 509);
1274 // we achieved a lock - it's time to update the osc freq
1275 if ((tmp >> 6) & 0x1) {
1276 dib7000p_update_timf(state);
1277 /* P_timf_alpha += 2 */
1278 tmp = dib7000p_read_word(state, 26);
1279 dib7000p_write_word(state, 26, (tmp & ~(0xf << 12)) | ((((tmp >> 12) & 0xf) + 5) << 12));
1282 if (state->cfg.spur_protect)
1283 dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1285 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1286 return 0;
1289 static int dib7000p_wakeup(struct dvb_frontend *demod)
1291 struct dib7000p_state *state = demod->demodulator_priv;
1292 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
1293 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
1294 if (state->version == SOC7090)
1295 dib7000p_sad_calib(state);
1296 return 0;
1299 static int dib7000p_sleep(struct dvb_frontend *demod)
1301 struct dib7000p_state *state = demod->demodulator_priv;
1302 if (state->version == SOC7090)
1303 return dib7090_set_output_mode(demod, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1304 return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1307 static int dib7000p_identify(struct dib7000p_state *st)
1309 u16 value;
1310 dprintk("checking demod on I2C address: %d (%x)", st->i2c_addr, st->i2c_addr);
1312 if ((value = dib7000p_read_word(st, 768)) != 0x01b3) {
1313 dprintk("wrong Vendor ID (read=0x%x)", value);
1314 return -EREMOTEIO;
1317 if ((value = dib7000p_read_word(st, 769)) != 0x4000) {
1318 dprintk("wrong Device ID (%x)", value);
1319 return -EREMOTEIO;
1322 return 0;
1325 static int dib7000p_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1327 struct dib7000p_state *state = fe->demodulator_priv;
1328 u16 tps = dib7000p_read_word(state, 463);
1330 fep->inversion = INVERSION_AUTO;
1332 fep->u.ofdm.bandwidth = BANDWIDTH_TO_INDEX(state->current_bandwidth);
1334 switch ((tps >> 8) & 0x3) {
1335 case 0:
1336 fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
1337 break;
1338 case 1:
1339 fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
1340 break;
1341 /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */
1344 switch (tps & 0x3) {
1345 case 0:
1346 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
1347 break;
1348 case 1:
1349 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
1350 break;
1351 case 2:
1352 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
1353 break;
1354 case 3:
1355 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
1356 break;
1359 switch ((tps >> 14) & 0x3) {
1360 case 0:
1361 fep->u.ofdm.constellation = QPSK;
1362 break;
1363 case 1:
1364 fep->u.ofdm.constellation = QAM_16;
1365 break;
1366 case 2:
1367 default:
1368 fep->u.ofdm.constellation = QAM_64;
1369 break;
1372 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1373 /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1375 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
1376 switch ((tps >> 5) & 0x7) {
1377 case 1:
1378 fep->u.ofdm.code_rate_HP = FEC_1_2;
1379 break;
1380 case 2:
1381 fep->u.ofdm.code_rate_HP = FEC_2_3;
1382 break;
1383 case 3:
1384 fep->u.ofdm.code_rate_HP = FEC_3_4;
1385 break;
1386 case 5:
1387 fep->u.ofdm.code_rate_HP = FEC_5_6;
1388 break;
1389 case 7:
1390 default:
1391 fep->u.ofdm.code_rate_HP = FEC_7_8;
1392 break;
1396 switch ((tps >> 2) & 0x7) {
1397 case 1:
1398 fep->u.ofdm.code_rate_LP = FEC_1_2;
1399 break;
1400 case 2:
1401 fep->u.ofdm.code_rate_LP = FEC_2_3;
1402 break;
1403 case 3:
1404 fep->u.ofdm.code_rate_LP = FEC_3_4;
1405 break;
1406 case 5:
1407 fep->u.ofdm.code_rate_LP = FEC_5_6;
1408 break;
1409 case 7:
1410 default:
1411 fep->u.ofdm.code_rate_LP = FEC_7_8;
1412 break;
1415 /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */
1417 return 0;
1420 static int dib7000p_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1422 struct dib7000p_state *state = fe->demodulator_priv;
1423 int time, ret;
1425 if (state->version == SOC7090) {
1426 dib7090_set_diversity_in(fe, 0);
1427 dib7090_set_output_mode(fe, OUTMODE_HIGH_Z);
1429 else
1430 dib7000p_set_output_mode(state, OUTMODE_HIGH_Z);
1432 /* maybe the parameter has been changed */
1433 state->sfn_workaround_active = buggy_sfn_workaround;
1435 if (fe->ops.tuner_ops.set_params)
1436 fe->ops.tuner_ops.set_params(fe, fep);
1438 /* start up the AGC */
1439 state->agc_state = 0;
1440 do {
1441 time = dib7000p_agc_startup(fe, fep);
1442 if (time != -1)
1443 msleep(time);
1444 } while (time != -1);
1446 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
1447 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || fep->u.ofdm.constellation == QAM_AUTO || fep->u.ofdm.code_rate_HP == FEC_AUTO) {
1448 int i = 800, found;
1450 dib7000p_autosearch_start(fe, fep);
1451 do {
1452 msleep(1);
1453 found = dib7000p_autosearch_is_irq(fe);
1454 } while (found == 0 && i--);
1456 dprintk("autosearch returns: %d", found);
1457 if (found == 0 || found == 1)
1458 return 0; // no channel found
1460 dib7000p_get_frontend(fe, fep);
1463 ret = dib7000p_tune(fe, fep);
1465 /* make this a config parameter */
1466 if (state->version == SOC7090)
1467 dib7090_set_output_mode(fe, state->cfg.output_mode);
1468 else
1469 dib7000p_set_output_mode(state, state->cfg.output_mode);
1471 return ret;
1474 static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t * stat)
1476 struct dib7000p_state *state = fe->demodulator_priv;
1477 u16 lock = dib7000p_read_word(state, 509);
1479 *stat = 0;
1481 if (lock & 0x8000)
1482 *stat |= FE_HAS_SIGNAL;
1483 if (lock & 0x3000)
1484 *stat |= FE_HAS_CARRIER;
1485 if (lock & 0x0100)
1486 *stat |= FE_HAS_VITERBI;
1487 if (lock & 0x0010)
1488 *stat |= FE_HAS_SYNC;
1489 if ((lock & 0x0038) == 0x38)
1490 *stat |= FE_HAS_LOCK;
1492 return 0;
1495 static int dib7000p_read_ber(struct dvb_frontend *fe, u32 * ber)
1497 struct dib7000p_state *state = fe->demodulator_priv;
1498 *ber = (dib7000p_read_word(state, 500) << 16) | dib7000p_read_word(state, 501);
1499 return 0;
1502 static int dib7000p_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
1504 struct dib7000p_state *state = fe->demodulator_priv;
1505 *unc = dib7000p_read_word(state, 506);
1506 return 0;
1509 static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
1511 struct dib7000p_state *state = fe->demodulator_priv;
1512 u16 val = dib7000p_read_word(state, 394);
1513 *strength = 65535 - val;
1514 return 0;
1517 static int dib7000p_read_snr(struct dvb_frontend *fe, u16 * snr)
1519 struct dib7000p_state *state = fe->demodulator_priv;
1520 u16 val;
1521 s32 signal_mant, signal_exp, noise_mant, noise_exp;
1522 u32 result = 0;
1524 val = dib7000p_read_word(state, 479);
1525 noise_mant = (val >> 4) & 0xff;
1526 noise_exp = ((val & 0xf) << 2);
1527 val = dib7000p_read_word(state, 480);
1528 noise_exp += ((val >> 14) & 0x3);
1529 if ((noise_exp & 0x20) != 0)
1530 noise_exp -= 0x40;
1532 signal_mant = (val >> 6) & 0xFF;
1533 signal_exp = (val & 0x3F);
1534 if ((signal_exp & 0x20) != 0)
1535 signal_exp -= 0x40;
1537 if (signal_mant != 0)
1538 result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
1539 else
1540 result = intlog10(2) * 10 * signal_exp - 100;
1542 if (noise_mant != 0)
1543 result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
1544 else
1545 result -= intlog10(2) * 10 * noise_exp - 100;
1547 *snr = result / ((1 << 24) / 10);
1548 return 0;
1551 static int dib7000p_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
1553 tune->min_delay_ms = 1000;
1554 return 0;
1557 static void dib7000p_release(struct dvb_frontend *demod)
1559 struct dib7000p_state *st = demod->demodulator_priv;
1560 dibx000_exit_i2c_master(&st->i2c_master);
1561 i2c_del_adapter(&st->dib7090_tuner_adap);
1562 kfree(st);
1565 int dib7000pc_detection(struct i2c_adapter *i2c_adap)
1567 u8 tx[2], rx[2];
1568 struct i2c_msg msg[2] = {
1569 {.addr = 18 >> 1,.flags = 0,.buf = tx,.len = 2},
1570 {.addr = 18 >> 1,.flags = I2C_M_RD,.buf = rx,.len = 2},
1573 tx[0] = 0x03;
1574 tx[1] = 0x00;
1576 if (i2c_transfer(i2c_adap, msg, 2) == 2)
1577 if (rx[0] == 0x01 && rx[1] == 0xb3) {
1578 dprintk("-D- DiB7000PC detected");
1579 return 1;
1582 msg[0].addr = msg[1].addr = 0x40;
1584 if (i2c_transfer(i2c_adap, msg, 2) == 2)
1585 if (rx[0] == 0x01 && rx[1] == 0xb3) {
1586 dprintk("-D- DiB7000PC detected");
1587 return 1;
1590 dprintk("-D- DiB7000PC not detected");
1591 return 0;
1593 EXPORT_SYMBOL(dib7000pc_detection);
1595 struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
1597 struct dib7000p_state *st = demod->demodulator_priv;
1598 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1600 EXPORT_SYMBOL(dib7000p_get_i2c_master);
1602 int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1604 struct dib7000p_state *state = fe->demodulator_priv;
1605 u16 val = dib7000p_read_word(state, 235) & 0xffef;
1606 val |= (onoff & 0x1) << 4;
1607 dprintk("PID filter enabled %d", onoff);
1608 return dib7000p_write_word(state, 235, val);
1610 EXPORT_SYMBOL(dib7000p_pid_filter_ctrl);
1612 int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1614 struct dib7000p_state *state = fe->demodulator_priv;
1615 dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
1616 return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0);
1618 EXPORT_SYMBOL(dib7000p_pid_filter);
1620 int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
1622 struct dib7000p_state *dpst;
1623 int k = 0;
1624 u8 new_addr = 0;
1626 dpst = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
1627 if (!dpst)
1628 return -ENOMEM;
1630 dpst->i2c_adap = i2c;
1632 for (k = no_of_demods - 1; k >= 0; k--) {
1633 dpst->cfg = cfg[k];
1635 /* designated i2c address */
1636 if (cfg[k].default_i2c_addr != 0)
1637 new_addr = cfg[k].default_i2c_addr + (k << 1);
1638 else
1639 new_addr = (0x40 + k) << 1;
1640 dpst->i2c_addr = new_addr;
1641 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */
1642 if (dib7000p_identify(dpst) != 0) {
1643 dpst->i2c_addr = default_addr;
1644 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */
1645 if (dib7000p_identify(dpst) != 0) {
1646 dprintk("DiB7000P #%d: not identified\n", k);
1647 kfree(dpst);
1648 return -EIO;
1652 /* start diversity to pull_down div_str - just for i2c-enumeration */
1653 dib7000p_set_output_mode(dpst, OUTMODE_DIVERSITY);
1655 /* set new i2c address and force divstart */
1656 dib7000p_write_word(dpst, 1285, (new_addr << 2) | 0x2);
1658 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
1661 for (k = 0; k < no_of_demods; k++) {
1662 dpst->cfg = cfg[k];
1663 if (cfg[k].default_i2c_addr != 0)
1664 dpst->i2c_addr = (cfg[k].default_i2c_addr + k) << 1;
1665 else
1666 dpst->i2c_addr = (0x40 + k) << 1;
1668 // unforce divstr
1669 dib7000p_write_word(dpst, 1285, dpst->i2c_addr << 2);
1671 /* deactivate div - it was just for i2c-enumeration */
1672 dib7000p_set_output_mode(dpst, OUTMODE_HIGH_Z);
1675 kfree(dpst);
1676 return 0;
1678 EXPORT_SYMBOL(dib7000p_i2c_enumeration);
1680 static const s32 lut_1000ln_mant[] = {
1681 6908, 6956, 7003, 7047, 7090, 7131, 7170, 7208, 7244, 7279, 7313, 7346, 7377, 7408, 7438, 7467, 7495, 7523, 7549, 7575, 7600
1684 static s32 dib7000p_get_adc_power(struct dvb_frontend *fe)
1686 struct dib7000p_state *state = fe->demodulator_priv;
1687 u32 tmp_val = 0, exp = 0, mant = 0;
1688 s32 pow_i;
1689 u16 buf[2];
1690 u8 ix = 0;
1692 buf[0] = dib7000p_read_word(state, 0x184);
1693 buf[1] = dib7000p_read_word(state, 0x185);
1694 pow_i = (buf[0] << 16) | buf[1];
1695 dprintk("raw pow_i = %d", pow_i);
1697 tmp_val = pow_i;
1698 while (tmp_val >>= 1)
1699 exp++;
1701 mant = (pow_i * 1000 / (1 << exp));
1702 dprintk(" mant = %d exp = %d", mant / 1000, exp);
1704 ix = (u8) ((mant - 1000) / 100); /* index of the LUT */
1705 dprintk(" ix = %d", ix);
1707 pow_i = (lut_1000ln_mant[ix] + 693 * (exp - 20) - 6908);
1708 pow_i = (pow_i << 8) / 1000;
1709 dprintk(" pow_i = %d", pow_i);
1711 return pow_i;
1714 static int map_addr_to_serpar_number(struct i2c_msg *msg)
1716 if ((msg->buf[0] <= 15))
1717 msg->buf[0] -= 1;
1718 else if (msg->buf[0] == 17)
1719 msg->buf[0] = 15;
1720 else if (msg->buf[0] == 16)
1721 msg->buf[0] = 17;
1722 else if (msg->buf[0] == 19)
1723 msg->buf[0] = 16;
1724 else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
1725 msg->buf[0] -= 3;
1726 else if (msg->buf[0] == 28)
1727 msg->buf[0] = 23;
1728 else {
1729 return -EINVAL;
1731 return 0;
1734 static int w7090p_tuner_write_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1736 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1737 u8 n_overflow = 1;
1738 u16 i = 1000;
1739 u16 serpar_num = msg[0].buf[0];
1741 while (n_overflow == 1 && i) {
1742 n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
1743 i--;
1744 if (i == 0)
1745 dprintk("Tuner ITF: write busy (overflow)");
1747 dib7000p_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
1748 dib7000p_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
1750 return num;
1753 static int w7090p_tuner_read_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1755 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1756 u8 n_overflow = 1, n_empty = 1;
1757 u16 i = 1000;
1758 u16 serpar_num = msg[0].buf[0];
1759 u16 read_word;
1761 while (n_overflow == 1 && i) {
1762 n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
1763 i--;
1764 if (i == 0)
1765 dprintk("TunerITF: read busy (overflow)");
1767 dib7000p_write_word(state, 1985, (0 << 6) | (serpar_num & 0x3f));
1769 i = 1000;
1770 while (n_empty == 1 && i) {
1771 n_empty = dib7000p_read_word(state, 1984) & 0x1;
1772 i--;
1773 if (i == 0)
1774 dprintk("TunerITF: read busy (empty)");
1776 read_word = dib7000p_read_word(state, 1987);
1777 msg[1].buf[0] = (read_word >> 8) & 0xff;
1778 msg[1].buf[1] = (read_word) & 0xff;
1780 return num;
1783 static int w7090p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1785 if (map_addr_to_serpar_number(&msg[0]) == 0) { /* else = Tuner regs to ignore : DIG_CFG, CTRL_RF_LT, PLL_CFG, PWM1_REG, ADCCLK, DIG_CFG_3; SLEEP_EN... */
1786 if (num == 1) { /* write */
1787 return w7090p_tuner_write_serpar(i2c_adap, msg, 1);
1788 } else { /* read */
1789 return w7090p_tuner_read_serpar(i2c_adap, msg, 2);
1792 return num;
1795 int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num, u16 apb_address)
1797 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1798 u16 word;
1800 if (num == 1) { /* write */
1801 dib7000p_write_word(state, apb_address, ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
1802 } else {
1803 word = dib7000p_read_word(state, apb_address);
1804 msg[1].buf[0] = (word >> 8) & 0xff;
1805 msg[1].buf[1] = (word) & 0xff;
1808 return num;
1811 static int dib7090_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1813 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1815 u16 apb_address = 0, word;
1816 int i = 0;
1817 switch (msg[0].buf[0]) {
1818 case 0x12:
1819 apb_address = 1920;
1820 break;
1821 case 0x14:
1822 apb_address = 1921;
1823 break;
1824 case 0x24:
1825 apb_address = 1922;
1826 break;
1827 case 0x1a:
1828 apb_address = 1923;
1829 break;
1830 case 0x22:
1831 apb_address = 1924;
1832 break;
1833 case 0x33:
1834 apb_address = 1926;
1835 break;
1836 case 0x34:
1837 apb_address = 1927;
1838 break;
1839 case 0x35:
1840 apb_address = 1928;
1841 break;
1842 case 0x36:
1843 apb_address = 1929;
1844 break;
1845 case 0x37:
1846 apb_address = 1930;
1847 break;
1848 case 0x38:
1849 apb_address = 1931;
1850 break;
1851 case 0x39:
1852 apb_address = 1932;
1853 break;
1854 case 0x2a:
1855 apb_address = 1935;
1856 break;
1857 case 0x2b:
1858 apb_address = 1936;
1859 break;
1860 case 0x2c:
1861 apb_address = 1937;
1862 break;
1863 case 0x2d:
1864 apb_address = 1938;
1865 break;
1866 case 0x2e:
1867 apb_address = 1939;
1868 break;
1869 case 0x2f:
1870 apb_address = 1940;
1871 break;
1872 case 0x30:
1873 apb_address = 1941;
1874 break;
1875 case 0x31:
1876 apb_address = 1942;
1877 break;
1878 case 0x32:
1879 apb_address = 1943;
1880 break;
1881 case 0x3e:
1882 apb_address = 1944;
1883 break;
1884 case 0x3f:
1885 apb_address = 1945;
1886 break;
1887 case 0x40:
1888 apb_address = 1948;
1889 break;
1890 case 0x25:
1891 apb_address = 914;
1892 break;
1893 case 0x26:
1894 apb_address = 915;
1895 break;
1896 case 0x27:
1897 apb_address = 916;
1898 break;
1899 case 0x28:
1900 apb_address = 917;
1901 break;
1902 case 0x1d:
1903 i = ((dib7000p_read_word(state, 72) >> 12) & 0x3);
1904 word = dib7000p_read_word(state, 384 + i);
1905 msg[1].buf[0] = (word >> 8) & 0xff;
1906 msg[1].buf[1] = (word) & 0xff;
1907 return num;
1908 case 0x1f:
1909 if (num == 1) { /* write */
1910 word = (u16) ((msg[0].buf[1] << 8) | msg[0].buf[2]);
1911 word &= 0x3;
1912 word = (dib7000p_read_word(state, 72) & ~(3 << 12)) | (word << 12); //Mask bit 12,13
1913 dib7000p_write_word(state, 72, word); /* Set the proper input */
1914 return num;
1918 if (apb_address != 0) /* R/W acces via APB */
1919 return dib7090p_rw_on_apb(i2c_adap, msg, num, apb_address);
1920 else /* R/W access via SERPAR */
1921 return w7090p_tuner_rw_serpar(i2c_adap, msg, num);
1923 return 0;
1926 static u32 dib7000p_i2c_func(struct i2c_adapter *adapter)
1928 return I2C_FUNC_I2C;
1931 static struct i2c_algorithm dib7090_tuner_xfer_algo = {
1932 .master_xfer = dib7090_tuner_xfer,
1933 .functionality = dib7000p_i2c_func,
1936 struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
1938 struct dib7000p_state *st = fe->demodulator_priv;
1939 return &st->dib7090_tuner_adap;
1941 EXPORT_SYMBOL(dib7090_get_i2c_tuner);
1943 static int dib7090_host_bus_drive(struct dib7000p_state *state, u8 drive)
1945 u16 reg;
1947 /* drive host bus 2, 3, 4 */
1948 reg = dib7000p_read_word(state, 1798) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1949 reg |= (drive << 12) | (drive << 6) | drive;
1950 dib7000p_write_word(state, 1798, reg);
1952 /* drive host bus 5,6 */
1953 reg = dib7000p_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
1954 reg |= (drive << 8) | (drive << 2);
1955 dib7000p_write_word(state, 1799, reg);
1957 /* drive host bus 7, 8, 9 */
1958 reg = dib7000p_read_word(state, 1800) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1959 reg |= (drive << 12) | (drive << 6) | drive;
1960 dib7000p_write_word(state, 1800, reg);
1962 /* drive host bus 10, 11 */
1963 reg = dib7000p_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
1964 reg |= (drive << 8) | (drive << 2);
1965 dib7000p_write_word(state, 1801, reg);
1967 /* drive host bus 12, 13, 14 */
1968 reg = dib7000p_read_word(state, 1802) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1969 reg |= (drive << 12) | (drive << 6) | drive;
1970 dib7000p_write_word(state, 1802, reg);
1972 return 0;
1975 static u32 dib7090_calcSyncFreq(u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 syncSize)
1977 u32 quantif = 3;
1978 u32 nom = (insertExtSynchro * P_Kin + syncSize);
1979 u32 denom = P_Kout;
1980 u32 syncFreq = ((nom << quantif) / denom);
1982 if ((syncFreq & ((1 << quantif) - 1)) != 0)
1983 syncFreq = (syncFreq >> quantif) + 1;
1984 else
1985 syncFreq = (syncFreq >> quantif);
1987 if (syncFreq != 0)
1988 syncFreq = syncFreq - 1;
1990 return syncFreq;
1993 static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize)
1995 u8 index_buf;
1996 u16 rx_copy_buf[22];
1998 dprintk("Configure DibStream Tx");
1999 for (index_buf = 0; index_buf<22; index_buf++)
2000 rx_copy_buf[index_buf] = dib7000p_read_word(state, 1536+index_buf);
2002 dib7000p_write_word(state, 1615, 1);
2003 dib7000p_write_word(state, 1603, P_Kin);
2004 dib7000p_write_word(state, 1605, P_Kout);
2005 dib7000p_write_word(state, 1606, insertExtSynchro);
2006 dib7000p_write_word(state, 1608, synchroMode);
2007 dib7000p_write_word(state, 1609, (syncWord >> 16) & 0xffff);
2008 dib7000p_write_word(state, 1610, syncWord & 0xffff);
2009 dib7000p_write_word(state, 1612, syncSize);
2010 dib7000p_write_word(state, 1615, 0);
2012 for (index_buf = 0; index_buf<22; index_buf++)
2013 dib7000p_write_word(state, 1536+index_buf, rx_copy_buf[index_buf]);
2015 return 0;
2018 static int dib7090_cfg_DibRx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 synchroMode, u32 insertExtSynchro, u32 syncWord, u32 syncSize,
2019 u32 dataOutRate)
2021 u32 syncFreq;
2023 dprintk("Configure DibStream Rx");
2024 if ((P_Kin != 0) && (P_Kout != 0))
2026 syncFreq = dib7090_calcSyncFreq(P_Kin, P_Kout, insertExtSynchro, syncSize);
2027 dib7000p_write_word(state, 1542, syncFreq);
2029 dib7000p_write_word(state, 1554, 1);
2030 dib7000p_write_word(state, 1536, P_Kin);
2031 dib7000p_write_word(state, 1537, P_Kout);
2032 dib7000p_write_word(state, 1539, synchroMode);
2033 dib7000p_write_word(state, 1540, (syncWord >> 16) & 0xffff);
2034 dib7000p_write_word(state, 1541, syncWord & 0xffff);
2035 dib7000p_write_word(state, 1543, syncSize);
2036 dib7000p_write_word(state, 1544, dataOutRate);
2037 dib7000p_write_word(state, 1554, 0);
2039 return 0;
2042 static int dib7090_enDivOnHostBus(struct dib7000p_state *state)
2044 u16 reg;
2046 dprintk("Enable Diversity on host bus");
2047 reg = (1 << 8) | (1 << 5); // P_enDivOutOnDibTx = 1 ; P_enDibTxOnHostBus = 1
2048 dib7000p_write_word(state, 1288, reg);
2050 return dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
2053 static int dib7090_enAdcOnHostBus(struct dib7000p_state *state)
2055 u16 reg;
2057 dprintk("Enable ADC on host bus");
2058 reg = (1 << 7) | (1 << 5); //P_enAdcOnDibTx = 1 ; P_enDibTxOnHostBus = 1
2059 dib7000p_write_word(state, 1288, reg);
2061 return dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
2064 static int dib7090_enMpegOnHostBus(struct dib7000p_state *state)
2066 u16 reg;
2068 dprintk("Enable Mpeg on host bus");
2069 reg = (1 << 9) | (1 << 5); //P_enMpegOnDibTx = 1 ; P_enDibTxOnHostBus = 1
2070 dib7000p_write_word(state, 1288, reg);
2072 return dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
2075 static int dib7090_enMpegInput(struct dib7000p_state *state)
2077 dprintk("Enable Mpeg input");
2078 return dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */
2081 static int dib7090_enMpegMux(struct dib7000p_state *state, u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
2083 u16 reg = (1 << 7) | ((pulseWidth & 0x1f) << 2) | ((enSerialMode & 0x1) << 1) | (enSerialClkDiv2 & 0x1);
2085 dprintk("Enable Mpeg mux");
2086 dib7000p_write_word(state, 1287, reg);
2088 reg &= ~(1 << 7); // P_restart_mpegMux = 0
2089 dib7000p_write_word(state, 1287, reg);
2091 reg = (1 << 4); //P_enMpegMuxOnHostBus = 1
2092 dib7000p_write_word(state, 1288, reg);
2094 return 0;
2097 static int dib7090_disableMpegMux(struct dib7000p_state *state)
2099 u16 reg;
2101 dprintk("Disable Mpeg mux");
2102 dib7000p_write_word(state, 1288, 0); //P_enMpegMuxOnHostBus = 0
2104 reg = dib7000p_read_word(state, 1287);
2105 reg &= ~(1 << 7); // P_restart_mpegMux = 0
2106 dib7000p_write_word(state, 1287, reg);
2108 return 0;
2111 static int dib7090_set_input_mode(struct dvb_frontend *fe, int mode)
2113 struct dib7000p_state *state = fe->demodulator_priv;
2115 switch(mode) {
2116 case INPUT_MODE_DIVERSITY:
2117 dprintk("Enable diversity INPUT");
2118 dib7090_cfg_DibRx(state, 5,5,0,0,0,0,0);
2119 break;
2120 case INPUT_MODE_MPEG:
2121 dprintk("Enable Mpeg INPUT");
2122 dib7090_cfg_DibRx(state, 8,5,0,0,0,8,0); /*outputRate = 8 */
2123 break;
2124 case INPUT_MODE_OFF:
2125 default:
2126 dprintk("Disable INPUT");
2127 dib7090_cfg_DibRx(state, 0,0,0,0,0,0,0);
2128 break;
2130 return 0;
2133 static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff)
2135 switch (onoff) {
2136 case 0: /* only use the internal way - not the diversity input */
2137 dib7090_set_input_mode(fe, INPUT_MODE_MPEG);
2138 break;
2139 case 1: /* both ways */
2140 case 2: /* only the diversity input */
2141 dib7090_set_input_mode(fe, INPUT_MODE_DIVERSITY);
2142 break;
2145 return 0;
2148 static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode)
2150 struct dib7000p_state *state = fe->demodulator_priv;
2152 u16 outreg, smo_mode, fifo_threshold;
2153 u8 prefer_mpeg_mux_use = 1;
2154 int ret = 0;
2156 dib7090_host_bus_drive(state, 1);
2158 fifo_threshold = 1792;
2159 smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
2160 outreg = dib7000p_read_word(state, 1286) & ~((1 << 10) | (0x7 << 6) | (1 << 1));
2162 switch (mode) {
2163 case OUTMODE_HIGH_Z:
2164 outreg = 0;
2165 break;
2167 case OUTMODE_MPEG2_SERIAL:
2168 if (prefer_mpeg_mux_use) {
2169 dprintk("Sip 7090P setting output mode TS_SERIAL using Mpeg Mux");
2170 dib7090_enMpegOnHostBus(state);
2171 dib7090_enMpegInput(state);
2172 if (state->cfg.enMpegOutput == 1)
2173 dib7090_enMpegMux(state, 3, 1, 1);
2175 } else { /* Use Smooth block */
2176 dprintk("Sip 7090P setting output mode TS_SERIAL using Smooth bloc");
2177 dib7090_disableMpegMux(state);
2178 dib7000p_write_word(state, 1288, (1 << 6)); //P_enDemOutInterfOnHostBus = 1
2179 outreg |= (2 << 6) | (0 << 1);
2181 break;
2183 case OUTMODE_MPEG2_PAR_GATED_CLK:
2184 if (prefer_mpeg_mux_use) {
2185 dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Mpeg Mux");
2186 dib7090_enMpegOnHostBus(state);
2187 dib7090_enMpegInput(state);
2188 if (state->cfg.enMpegOutput == 1)
2189 dib7090_enMpegMux(state, 2, 0, 0);
2190 } else { /* Use Smooth block */
2191 dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Smooth block");
2192 dib7090_disableMpegMux(state);
2193 dib7000p_write_word(state, 1288, (1 << 6)); //P_enDemOutInterfOnHostBus = 1
2194 outreg |= (0 << 6);
2196 break;
2198 case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */
2199 dprintk("Sip 7090P setting output mode TS_PARALLEL_CONT using Smooth block");
2200 dib7090_disableMpegMux(state);
2201 dib7000p_write_word(state, 1288, (1 << 6)); //P_enDemOutInterfOnHostBus = 1
2202 outreg |= (1 << 6);
2203 break;
2205 case OUTMODE_MPEG2_FIFO: /* Using Smooth block because not supported by new Mpeg Mux bloc */
2206 dprintk("Sip 7090P setting output mode TS_FIFO using Smooth block");
2207 dib7090_disableMpegMux(state);
2208 dib7000p_write_word(state, 1288, (1 << 6)); //P_enDemOutInterfOnHostBus = 1
2209 outreg |= (5 << 6);
2210 smo_mode |= (3 << 1);
2211 fifo_threshold = 512;
2212 break;
2214 case OUTMODE_DIVERSITY:
2215 dprintk("Sip 7090P setting output mode MODE_DIVERSITY");
2216 dib7090_disableMpegMux(state);
2217 dib7090_enDivOnHostBus(state);
2218 break;
2220 case OUTMODE_ANALOG_ADC:
2221 dprintk("Sip 7090P setting output mode MODE_ANALOG_ADC");
2222 dib7090_enAdcOnHostBus(state);
2223 break;
2226 if (state->cfg.output_mpeg2_in_188_bytes)
2227 smo_mode |= (1 << 5);
2229 ret |= dib7000p_write_word(state, 235, smo_mode);
2230 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
2231 ret |= dib7000p_write_word(state, 1286, outreg | (1 << 10)); /* allways set Dout active = 1 !!! */
2233 return ret;
2236 int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
2238 struct dib7000p_state *state = fe->demodulator_priv;
2239 u16 en_cur_state;
2241 dprintk("sleep dib7090: %d", onoff);
2243 en_cur_state = dib7000p_read_word(state, 1922);
2245 if (en_cur_state > 0xff) { //LNAs and MIX are ON and therefore it is a valid configuration
2246 state->tuner_enable = en_cur_state;
2249 if (onoff)
2250 en_cur_state &= 0x00ff; //Mask to be applied
2251 else {
2252 if (state->tuner_enable != 0)
2253 en_cur_state = state->tuner_enable;
2256 dib7000p_write_word(state, 1922, en_cur_state);
2258 return 0;
2260 EXPORT_SYMBOL(dib7090_tuner_sleep);
2262 int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart)
2264 dprintk("AGC restart callback: %d", restart);
2265 return 0;
2267 EXPORT_SYMBOL(dib7090_agc_restart);
2269 int dib7090_get_adc_power(struct dvb_frontend *fe)
2271 return dib7000p_get_adc_power(fe);
2273 EXPORT_SYMBOL(dib7090_get_adc_power);
2275 int dib7090_slave_reset(struct dvb_frontend *fe)
2277 struct dib7000p_state *state = fe->demodulator_priv;
2278 u16 reg;
2280 reg = dib7000p_read_word(state, 1794);
2281 dib7000p_write_word(state, 1794, reg | (4 << 12));
2283 dib7000p_write_word(state, 1032, 0xffff);
2284 return 0;
2286 EXPORT_SYMBOL(dib7090_slave_reset);
2288 static struct dvb_frontend_ops dib7000p_ops;
2289 struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
2291 struct dvb_frontend *demod;
2292 struct dib7000p_state *st;
2293 st = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
2294 if (st == NULL)
2295 return NULL;
2297 memcpy(&st->cfg, cfg, sizeof(struct dib7000p_config));
2298 st->i2c_adap = i2c_adap;
2299 st->i2c_addr = i2c_addr;
2300 st->gpio_val = cfg->gpio_val;
2301 st->gpio_dir = cfg->gpio_dir;
2303 /* Ensure the output mode remains at the previous default if it's
2304 * not specifically set by the caller.
2306 if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2307 st->cfg.output_mode = OUTMODE_MPEG2_FIFO;
2309 demod = &st->demod;
2310 demod->demodulator_priv = st;
2311 memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));
2313 dib7000p_write_word(st, 1287, 0x0003); /* sram lead in, rdy */
2315 if (dib7000p_identify(st) != 0)
2316 goto error;
2318 st->version = dib7000p_read_word(st, 897);
2320 /* FIXME: make sure the dev.parent field is initialized, or else
2321 request_firmware() will hit an OOPS (this should be moved somewhere
2322 more common) */
2324 dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr);
2326 /* init 7090 tuner adapter */
2327 strncpy(st->dib7090_tuner_adap.name, "DiB7090 tuner interface", sizeof(st->dib7090_tuner_adap.name));
2328 st->dib7090_tuner_adap.algo = &dib7090_tuner_xfer_algo;
2329 st->dib7090_tuner_adap.algo_data = NULL;
2330 st->dib7090_tuner_adap.dev.parent = st->i2c_adap->dev.parent;
2331 i2c_set_adapdata(&st->dib7090_tuner_adap, st);
2332 i2c_add_adapter(&st->dib7090_tuner_adap);
2334 dib7000p_demod_reset(st);
2336 if (st->version == SOC7090) {
2337 dib7090_set_output_mode(demod, st->cfg.output_mode);
2338 dib7090_set_diversity_in(demod, 0);
2341 return demod;
2343 error:
2344 kfree(st);
2345 return NULL;
2347 EXPORT_SYMBOL(dib7000p_attach);
2349 static struct dvb_frontend_ops dib7000p_ops = {
2350 .info = {
2351 .name = "DiBcom 7000PC",
2352 .type = FE_OFDM,
2353 .frequency_min = 44250000,
2354 .frequency_max = 867250000,
2355 .frequency_stepsize = 62500,
2356 .caps = FE_CAN_INVERSION_AUTO |
2357 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2358 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2359 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2360 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2363 .release = dib7000p_release,
2365 .init = dib7000p_wakeup,
2366 .sleep = dib7000p_sleep,
2368 .set_frontend = dib7000p_set_frontend,
2369 .get_tune_settings = dib7000p_fe_get_tune_settings,
2370 .get_frontend = dib7000p_get_frontend,
2372 .read_status = dib7000p_read_status,
2373 .read_ber = dib7000p_read_ber,
2374 .read_signal_strength = dib7000p_read_signal_strength,
2375 .read_snr = dib7000p_read_snr,
2376 .read_ucblocks = dib7000p_read_unc_blocks,
2379 MODULE_AUTHOR("Olivier Grenie <ogrenie@dibcom.fr>");
2380 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
2381 MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
2382 MODULE_LICENSE("GPL");