DiBxxxx: get rid of DMA buffer on stack
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / media / dvb / frontends / dib7000p.c
blob0c9f40c2a251fbaad72fe3520e6f6ec48d76cb13
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;
67 /* for the I2C transfer */
68 struct i2c_msg msg[2];
69 u8 i2c_write_buffer[4];
70 u8 i2c_read_buffer[2];
73 enum dib7000p_power_mode {
74 DIB7000P_POWER_ALL = 0,
75 DIB7000P_POWER_ANALOG_ADC,
76 DIB7000P_POWER_INTERFACE_ONLY,
79 static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode);
80 static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff);
82 static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
84 state->i2c_write_buffer[0] = reg >> 8;
85 state->i2c_write_buffer[1] = reg & 0xff;
87 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
88 state->msg[0].addr = state->i2c_addr >> 1;
89 state->msg[0].flags = 0;
90 state->msg[0].buf = state->i2c_write_buffer;
91 state->msg[0].len = 2;
92 state->msg[1].addr = state->i2c_addr >> 1;
93 state->msg[1].flags = I2C_M_RD;
94 state->msg[1].buf = state->i2c_read_buffer;
95 state->msg[1].len = 2;
97 if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
98 dprintk("i2c read error on %d", reg);
100 return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
103 static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
105 state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
106 state->i2c_write_buffer[1] = reg & 0xff;
107 state->i2c_write_buffer[2] = (val >> 8) & 0xff;
108 state->i2c_write_buffer[3] = val & 0xff;
110 memset(&state->msg[0], 0, sizeof(struct i2c_msg));
111 state->msg[0].addr = state->i2c_addr >> 1;
112 state->msg[0].flags = 0;
113 state->msg[0].buf = state->i2c_write_buffer;
114 state->msg[0].len = 4;
116 return i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
119 static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf)
121 u16 l = 0, r, *n;
122 n = buf;
123 l = *n++;
124 while (l) {
125 r = *n++;
127 do {
128 dib7000p_write_word(state, r, *n++);
129 r++;
130 } while (--l);
131 l = *n++;
135 static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
137 int ret = 0;
138 u16 outreg, fifo_threshold, smo_mode;
140 outreg = 0;
141 fifo_threshold = 1792;
142 smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
144 dprintk("setting output mode for demod %p to %d", &state->demod, mode);
146 switch (mode) {
147 case OUTMODE_MPEG2_PAR_GATED_CLK:
148 outreg = (1 << 10); /* 0x0400 */
149 break;
150 case OUTMODE_MPEG2_PAR_CONT_CLK:
151 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
152 break;
153 case OUTMODE_MPEG2_SERIAL:
154 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */
155 break;
156 case OUTMODE_DIVERSITY:
157 if (state->cfg.hostbus_diversity)
158 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
159 else
160 outreg = (1 << 11);
161 break;
162 case OUTMODE_MPEG2_FIFO:
163 smo_mode |= (3 << 1);
164 fifo_threshold = 512;
165 outreg = (1 << 10) | (5 << 6);
166 break;
167 case OUTMODE_ANALOG_ADC:
168 outreg = (1 << 10) | (3 << 6);
169 break;
170 case OUTMODE_HIGH_Z:
171 outreg = 0;
172 break;
173 default:
174 dprintk("Unhandled output_mode passed to be set for demod %p", &state->demod);
175 break;
178 if (state->cfg.output_mpeg2_in_188_bytes)
179 smo_mode |= (1 << 5);
181 ret |= dib7000p_write_word(state, 235, smo_mode);
182 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
183 if (state->version != SOC7090)
184 ret |= dib7000p_write_word(state, 1286, outreg); /* P_Div_active */
186 return ret;
189 static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
191 struct dib7000p_state *state = demod->demodulator_priv;
193 if (state->div_force_off) {
194 dprintk("diversity combination deactivated - forced by COFDM parameters");
195 onoff = 0;
196 dib7000p_write_word(state, 207, 0);
197 } else
198 dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
200 state->div_state = (u8) onoff;
202 if (onoff) {
203 dib7000p_write_word(state, 204, 6);
204 dib7000p_write_word(state, 205, 16);
205 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
206 } else {
207 dib7000p_write_word(state, 204, 1);
208 dib7000p_write_word(state, 205, 0);
211 return 0;
214 static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode)
216 /* by default everything is powered off */
217 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0x0007, reg_899 = 0x0003, reg_1280 = (0xfe00) | (dib7000p_read_word(state, 1280) & 0x01ff);
219 /* now, depending on the requested mode, we power on */
220 switch (mode) {
221 /* power up everything in the demod */
222 case DIB7000P_POWER_ALL:
223 reg_774 = 0x0000;
224 reg_775 = 0x0000;
225 reg_776 = 0x0;
226 reg_899 = 0x0;
227 if (state->version == SOC7090)
228 reg_1280 &= 0x001f;
229 else
230 reg_1280 &= 0x01ff;
231 break;
233 case DIB7000P_POWER_ANALOG_ADC:
234 /* dem, cfg, iqc, sad, agc */
235 reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
236 /* nud */
237 reg_776 &= ~((1 << 0));
238 /* Dout */
239 if (state->version != SOC7090)
240 reg_1280 &= ~((1 << 11));
241 reg_1280 &= ~(1 << 6);
242 /* fall through wanted to enable the interfaces */
244 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
245 case DIB7000P_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C */
246 if (state->version == SOC7090)
247 reg_1280 &= ~((1 << 7) | (1 << 5));
248 else
249 reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
250 break;
252 /* TODO following stuff is just converted from the dib7000-driver - check when is used what */
255 dib7000p_write_word(state, 774, reg_774);
256 dib7000p_write_word(state, 775, reg_775);
257 dib7000p_write_word(state, 776, reg_776);
258 dib7000p_write_word(state, 899, reg_899);
259 dib7000p_write_word(state, 1280, reg_1280);
261 return 0;
264 static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no)
266 u16 reg_908 = dib7000p_read_word(state, 908), reg_909 = dib7000p_read_word(state, 909);
267 u16 reg;
269 switch (no) {
270 case DIBX000_SLOW_ADC_ON:
271 if (state->version == SOC7090) {
272 reg = dib7000p_read_word(state, 1925);
274 dib7000p_write_word(state, 1925, reg | (1 << 4) | (1 << 2)); /* en_slowAdc = 1 & reset_sladc = 1 */
276 reg = dib7000p_read_word(state, 1925); /* read acces to make it works... strange ... */
277 msleep(200);
278 dib7000p_write_word(state, 1925, reg & ~(1 << 4)); /* en_slowAdc = 1 & reset_sladc = 0 */
280 reg = dib7000p_read_word(state, 72) & ~((0x3 << 14) | (0x3 << 12));
281 dib7000p_write_word(state, 72, reg | (1 << 14) | (3 << 12) | 524); /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ; (Vin2 = Vcm) */
282 } else {
283 reg_909 |= (1 << 1) | (1 << 0);
284 dib7000p_write_word(state, 909, reg_909);
285 reg_909 &= ~(1 << 1);
287 break;
289 case DIBX000_SLOW_ADC_OFF:
290 if (state->version == SOC7090) {
291 reg = dib7000p_read_word(state, 1925);
292 dib7000p_write_word(state, 1925, (reg & ~(1 << 2)) | (1 << 4)); /* reset_sladc = 1 en_slowAdc = 0 */
293 } else
294 reg_909 |= (1 << 1) | (1 << 0);
295 break;
297 case DIBX000_ADC_ON:
298 reg_908 &= 0x0fff;
299 reg_909 &= 0x0003;
300 break;
302 case DIBX000_ADC_OFF:
303 reg_908 |= (1 << 14) | (1 << 13) | (1 << 12);
304 reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
305 break;
307 case DIBX000_VBG_ENABLE:
308 reg_908 &= ~(1 << 15);
309 break;
311 case DIBX000_VBG_DISABLE:
312 reg_908 |= (1 << 15);
313 break;
315 default:
316 break;
319 // dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
321 reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4;
322 reg_908 |= (state->cfg.enable_current_mirror & 1) << 7;
324 dib7000p_write_word(state, 908, reg_908);
325 dib7000p_write_word(state, 909, reg_909);
328 static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
330 u32 timf;
332 // store the current bandwidth for later use
333 state->current_bandwidth = bw;
335 if (state->timf == 0) {
336 dprintk("using default timf");
337 timf = state->cfg.bw->timf;
338 } else {
339 dprintk("using updated timf");
340 timf = state->timf;
343 timf = timf * (bw / 50) / 160;
345 dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
346 dib7000p_write_word(state, 24, (u16) ((timf) & 0xffff));
348 return 0;
351 static int dib7000p_sad_calib(struct dib7000p_state *state)
353 /* internal */
354 dib7000p_write_word(state, 73, (0 << 1) | (0 << 0));
356 if (state->version == SOC7090)
357 dib7000p_write_word(state, 74, 2048);
358 else
359 dib7000p_write_word(state, 74, 776);
361 /* do the calibration */
362 dib7000p_write_word(state, 73, (1 << 0));
363 dib7000p_write_word(state, 73, (0 << 0));
365 msleep(1);
367 return 0;
370 int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
372 struct dib7000p_state *state = demod->demodulator_priv;
373 if (value > 4095)
374 value = 4095;
375 state->wbd_ref = value;
376 return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value);
378 EXPORT_SYMBOL(dib7000p_set_wbd_ref);
380 static void dib7000p_reset_pll(struct dib7000p_state *state)
382 struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
383 u16 clk_cfg0;
385 if (state->version == SOC7090) {
386 dib7000p_write_word(state, 1856, (!bw->pll_reset << 13) | (bw->pll_range << 12) | (bw->pll_ratio << 6) | (bw->pll_prediv));
388 while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
391 dib7000p_write_word(state, 1857, dib7000p_read_word(state, 1857) | (!bw->pll_bypass << 15));
392 } else {
393 /* force PLL bypass */
394 clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) |
395 (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0);
397 dib7000p_write_word(state, 900, clk_cfg0);
399 /* P_pll_cfg */
400 dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset);
401 clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff);
402 dib7000p_write_word(state, 900, clk_cfg0);
405 dib7000p_write_word(state, 18, (u16) (((bw->internal * 1000) >> 16) & 0xffff));
406 dib7000p_write_word(state, 19, (u16) ((bw->internal * 1000) & 0xffff));
407 dib7000p_write_word(state, 21, (u16) ((bw->ifreq >> 16) & 0xffff));
408 dib7000p_write_word(state, 22, (u16) ((bw->ifreq) & 0xffff));
410 dib7000p_write_word(state, 72, bw->sad_cfg);
413 static u32 dib7000p_get_internal_freq(struct dib7000p_state *state)
415 u32 internal = (u32) dib7000p_read_word(state, 18) << 16;
416 internal |= (u32) dib7000p_read_word(state, 19);
417 internal /= 1000;
419 return internal;
422 int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
424 struct dib7000p_state *state = fe->demodulator_priv;
425 u16 reg_1857, reg_1856 = dib7000p_read_word(state, 1856);
426 u8 loopdiv, prediv;
427 u32 internal, xtal;
429 /* get back old values */
430 prediv = reg_1856 & 0x3f;
431 loopdiv = (reg_1856 >> 6) & 0x3f;
433 if ((bw != NULL) && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) {
434 dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio);
435 reg_1856 &= 0xf000;
436 reg_1857 = dib7000p_read_word(state, 1857);
437 dib7000p_write_word(state, 1857, reg_1857 & ~(1 << 15));
439 dib7000p_write_word(state, 1856, reg_1856 | ((bw->pll_ratio & 0x3f) << 6) | (bw->pll_prediv & 0x3f));
441 /* write new system clk into P_sec_len */
442 internal = dib7000p_get_internal_freq(state);
443 xtal = (internal / loopdiv) * prediv;
444 internal = 1000 * (xtal / bw->pll_prediv) * bw->pll_ratio; /* new internal */
445 dib7000p_write_word(state, 18, (u16) ((internal >> 16) & 0xffff));
446 dib7000p_write_word(state, 19, (u16) (internal & 0xffff));
448 dib7000p_write_word(state, 1857, reg_1857 | (1 << 15));
450 while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
451 dprintk("Waiting for PLL to lock");
453 return 0;
455 return -EIO;
457 EXPORT_SYMBOL(dib7000p_update_pll);
459 static int dib7000p_reset_gpio(struct dib7000p_state *st)
461 /* reset the GPIOs */
462 dprintk("gpio dir: %x: val: %x, pwm_pos: %x", st->gpio_dir, st->gpio_val, st->cfg.gpio_pwm_pos);
464 dib7000p_write_word(st, 1029, st->gpio_dir);
465 dib7000p_write_word(st, 1030, st->gpio_val);
467 /* TODO 1031 is P_gpio_od */
469 dib7000p_write_word(st, 1032, st->cfg.gpio_pwm_pos);
471 dib7000p_write_word(st, 1037, st->cfg.pwm_freq_div);
472 return 0;
475 static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val)
477 st->gpio_dir = dib7000p_read_word(st, 1029);
478 st->gpio_dir &= ~(1 << num); /* reset the direction bit */
479 st->gpio_dir |= (dir & 0x1) << num; /* set the new direction */
480 dib7000p_write_word(st, 1029, st->gpio_dir);
482 st->gpio_val = dib7000p_read_word(st, 1030);
483 st->gpio_val &= ~(1 << num); /* reset the direction bit */
484 st->gpio_val |= (val & 0x01) << num; /* set the new value */
485 dib7000p_write_word(st, 1030, st->gpio_val);
487 return 0;
490 int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val)
492 struct dib7000p_state *state = demod->demodulator_priv;
493 return dib7000p_cfg_gpio(state, num, dir, val);
495 EXPORT_SYMBOL(dib7000p_set_gpio);
497 static u16 dib7000p_defaults[] = {
498 // auto search configuration
499 3, 2,
500 0x0004,
501 0x1000,
502 0x0814, /* Equal Lock */
504 12, 6,
505 0x001b,
506 0x7740,
507 0x005b,
508 0x8d80,
509 0x01c9,
510 0xc380,
511 0x0000,
512 0x0080,
513 0x0000,
514 0x0090,
515 0x0001,
516 0xd4c0,
518 1, 26,
519 0x6680,
521 /* set ADC level to -16 */
522 11, 79,
523 (1 << 13) - 825 - 117,
524 (1 << 13) - 837 - 117,
525 (1 << 13) - 811 - 117,
526 (1 << 13) - 766 - 117,
527 (1 << 13) - 737 - 117,
528 (1 << 13) - 693 - 117,
529 (1 << 13) - 648 - 117,
530 (1 << 13) - 619 - 117,
531 (1 << 13) - 575 - 117,
532 (1 << 13) - 531 - 117,
533 (1 << 13) - 501 - 117,
535 1, 142,
536 0x0410,
538 /* disable power smoothing */
539 8, 145,
549 1, 154,
550 1 << 13,
552 1, 168,
553 0x0ccd,
555 1, 183,
556 0x200f,
558 1, 212,
559 0x169,
561 5, 187,
562 0x023d,
563 0x00a4,
564 0x00a4,
565 0x7ff0,
566 0x3ccc,
568 1, 198,
569 0x800,
571 1, 222,
572 0x0010,
574 1, 235,
575 0x0062,
577 2, 901,
578 0x0006,
579 (3 << 10) | (1 << 6),
581 1, 905,
582 0x2c8e,
587 static int dib7000p_demod_reset(struct dib7000p_state *state)
589 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
591 if (state->version == SOC7090)
592 dibx000_reset_i2c_master(&state->i2c_master);
594 dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE);
596 /* restart all parts */
597 dib7000p_write_word(state, 770, 0xffff);
598 dib7000p_write_word(state, 771, 0xffff);
599 dib7000p_write_word(state, 772, 0x001f);
600 dib7000p_write_word(state, 898, 0x0003);
601 dib7000p_write_word(state, 1280, 0x001f - ((1 << 4) | (1 << 3)));
603 dib7000p_write_word(state, 770, 0);
604 dib7000p_write_word(state, 771, 0);
605 dib7000p_write_word(state, 772, 0);
606 dib7000p_write_word(state, 898, 0);
607 dib7000p_write_word(state, 1280, 0);
609 /* default */
610 dib7000p_reset_pll(state);
612 if (dib7000p_reset_gpio(state) != 0)
613 dprintk("GPIO reset was not successful.");
615 if (state->version == SOC7090) {
616 dib7000p_write_word(state, 899, 0);
618 /* impulse noise */
619 dib7000p_write_word(state, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */
620 dib7000p_write_word(state, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */
621 dib7000p_write_word(state, 44, 300); /* 300 fag P_iqc_dect_min = +280 */
622 dib7000p_write_word(state, 273, (1<<6) | 30);
624 if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
625 dprintk("OUTPUT_MODE could not be reset.");
627 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
628 dib7000p_sad_calib(state);
629 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
631 /* unforce divstr regardless whether i2c enumeration was done or not */
632 dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1));
634 dib7000p_set_bandwidth(state, 8000);
636 if (state->version == SOC7090) {
637 dib7000p_write_word(state, 36, 0x5755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */
638 } else {
639 if (state->cfg.tuner_is_baseband)
640 dib7000p_write_word(state, 36, 0x0755);
641 else
642 dib7000p_write_word(state, 36, 0x1f55);
645 dib7000p_write_tab(state, dib7000p_defaults);
647 dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
649 return 0;
652 static void dib7000p_pll_clk_cfg(struct dib7000p_state *state)
654 u16 tmp = 0;
655 tmp = dib7000p_read_word(state, 903);
656 dib7000p_write_word(state, 903, (tmp | 0x1));
657 tmp = dib7000p_read_word(state, 900);
658 dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6));
661 static void dib7000p_restart_agc(struct dib7000p_state *state)
663 // P_restart_iqc & P_restart_agc
664 dib7000p_write_word(state, 770, (1 << 11) | (1 << 9));
665 dib7000p_write_word(state, 770, 0x0000);
668 static int dib7000p_update_lna(struct dib7000p_state *state)
670 u16 dyn_gain;
672 if (state->cfg.update_lna) {
673 dyn_gain = dib7000p_read_word(state, 394);
674 if (state->cfg.update_lna(&state->demod, dyn_gain)) {
675 dib7000p_restart_agc(state);
676 return 1;
680 return 0;
683 static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
685 struct dibx000_agc_config *agc = NULL;
686 int i;
687 if (state->current_band == band && state->current_agc != NULL)
688 return 0;
689 state->current_band = band;
691 for (i = 0; i < state->cfg.agc_config_count; i++)
692 if (state->cfg.agc[i].band_caps & band) {
693 agc = &state->cfg.agc[i];
694 break;
697 if (agc == NULL) {
698 dprintk("no valid AGC configuration found for band 0x%02x", band);
699 return -EINVAL;
702 state->current_agc = agc;
704 /* AGC */
705 dib7000p_write_word(state, 75, agc->setup);
706 dib7000p_write_word(state, 76, agc->inv_gain);
707 dib7000p_write_word(state, 77, agc->time_stabiliz);
708 dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);
710 // Demod AGC loop configuration
711 dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);
712 dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp);
714 /* AGC continued */
715 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
716 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
718 if (state->wbd_ref != 0)
719 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref);
720 else
721 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref);
723 dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
725 dib7000p_write_word(state, 107, agc->agc1_max);
726 dib7000p_write_word(state, 108, agc->agc1_min);
727 dib7000p_write_word(state, 109, agc->agc2_max);
728 dib7000p_write_word(state, 110, agc->agc2_min);
729 dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
730 dib7000p_write_word(state, 112, agc->agc1_pt3);
731 dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
732 dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
733 dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
734 return 0;
737 static void dib7000p_set_dds(struct dib7000p_state *state, s32 offset_khz)
739 u32 internal = dib7000p_get_internal_freq(state);
740 s32 unit_khz_dds_val = 67108864 / (internal); /* 2**26 / Fsampling is the unit 1KHz offset */
741 u32 abs_offset_khz = ABS(offset_khz);
742 u32 dds = state->cfg.bw->ifreq & 0x1ffffff;
743 u8 invert = !!(state->cfg.bw->ifreq & (1 << 25));
745 dprintk("setting a frequency offset of %dkHz internal freq = %d invert = %d", offset_khz, internal, invert);
747 if (offset_khz < 0)
748 unit_khz_dds_val *= -1;
750 /* IF tuner */
751 if (invert)
752 dds -= (abs_offset_khz * unit_khz_dds_val); /* /100 because of /100 on the unit_khz_dds_val line calc for better accuracy */
753 else
754 dds += (abs_offset_khz * unit_khz_dds_val);
756 if (abs_offset_khz <= (internal / 2)) { /* Max dds offset is the half of the demod freq */
757 dib7000p_write_word(state, 21, (u16) (((dds >> 16) & 0x1ff) | (0 << 10) | (invert << 9)));
758 dib7000p_write_word(state, 22, (u16) (dds & 0xffff));
762 static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
764 struct dib7000p_state *state = demod->demodulator_priv;
765 int ret = -1;
766 u8 *agc_state = &state->agc_state;
767 u8 agc_split;
768 u16 reg;
769 u32 upd_demod_gain_period = 0x1000;
771 switch (state->agc_state) {
772 case 0:
773 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
774 if (state->version == SOC7090) {
775 reg = dib7000p_read_word(state, 0x79b) & 0xff00;
776 dib7000p_write_word(state, 0x79a, upd_demod_gain_period & 0xFFFF); /* lsb */
777 dib7000p_write_word(state, 0x79b, reg | (1 << 14) | ((upd_demod_gain_period >> 16) & 0xFF));
779 /* enable adc i & q */
780 reg = dib7000p_read_word(state, 0x780);
781 dib7000p_write_word(state, 0x780, (reg | (0x3)) & (~(1 << 7)));
782 } else {
783 dib7000p_set_adc_state(state, DIBX000_ADC_ON);
784 dib7000p_pll_clk_cfg(state);
787 if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency / 1000)) != 0)
788 return -1;
790 dib7000p_set_dds(state, 0);
791 ret = 7;
792 (*agc_state)++;
793 break;
795 case 1:
796 if (state->cfg.agc_control)
797 state->cfg.agc_control(&state->demod, 1);
799 dib7000p_write_word(state, 78, 32768);
800 if (!state->current_agc->perform_agc_softsplit) {
801 /* we are using the wbd - so slow AGC startup */
802 /* force 0 split on WBD and restart AGC */
803 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));
804 (*agc_state)++;
805 ret = 5;
806 } else {
807 /* default AGC startup */
808 (*agc_state) = 4;
809 /* wait AGC rough lock time */
810 ret = 7;
813 dib7000p_restart_agc(state);
814 break;
816 case 2: /* fast split search path after 5sec */
817 dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4)); /* freeze AGC loop */
818 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */
819 (*agc_state)++;
820 ret = 14;
821 break;
823 case 3: /* split search ended */
824 agc_split = (u8) dib7000p_read_word(state, 396); /* store the split value for the next time */
825 dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */
827 dib7000p_write_word(state, 75, state->current_agc->setup); /* std AGC loop */
828 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
830 dib7000p_restart_agc(state);
832 dprintk("SPLIT %p: %hd", demod, agc_split);
834 (*agc_state)++;
835 ret = 5;
836 break;
838 case 4: /* LNA startup */
839 ret = 7;
841 if (dib7000p_update_lna(state))
842 ret = 5;
843 else
844 (*agc_state)++;
845 break;
847 case 5:
848 if (state->cfg.agc_control)
849 state->cfg.agc_control(&state->demod, 0);
850 (*agc_state)++;
851 break;
852 default:
853 break;
855 return ret;
858 static void dib7000p_update_timf(struct dib7000p_state *state)
860 u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428);
861 state->timf = timf * 160 / (state->current_bandwidth / 50);
862 dib7000p_write_word(state, 23, (u16) (timf >> 16));
863 dib7000p_write_word(state, 24, (u16) (timf & 0xffff));
864 dprintk("updated timf_frequency: %d (default: %d)", state->timf, state->cfg.bw->timf);
868 u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
870 struct dib7000p_state *state = fe->demodulator_priv;
871 switch (op) {
872 case DEMOD_TIMF_SET:
873 state->timf = timf;
874 break;
875 case DEMOD_TIMF_UPDATE:
876 dib7000p_update_timf(state);
877 break;
878 case DEMOD_TIMF_GET:
879 break;
881 dib7000p_set_bandwidth(state, state->current_bandwidth);
882 return state->timf;
884 EXPORT_SYMBOL(dib7000p_ctrl_timf);
886 static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq)
888 u16 value, est[4];
890 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
892 /* nfft, guard, qam, alpha */
893 value = 0;
894 switch (ch->u.ofdm.transmission_mode) {
895 case TRANSMISSION_MODE_2K:
896 value |= (0 << 7);
897 break;
898 case TRANSMISSION_MODE_4K:
899 value |= (2 << 7);
900 break;
901 default:
902 case TRANSMISSION_MODE_8K:
903 value |= (1 << 7);
904 break;
906 switch (ch->u.ofdm.guard_interval) {
907 case GUARD_INTERVAL_1_32:
908 value |= (0 << 5);
909 break;
910 case GUARD_INTERVAL_1_16:
911 value |= (1 << 5);
912 break;
913 case GUARD_INTERVAL_1_4:
914 value |= (3 << 5);
915 break;
916 default:
917 case GUARD_INTERVAL_1_8:
918 value |= (2 << 5);
919 break;
921 switch (ch->u.ofdm.constellation) {
922 case QPSK:
923 value |= (0 << 3);
924 break;
925 case QAM_16:
926 value |= (1 << 3);
927 break;
928 default:
929 case QAM_64:
930 value |= (2 << 3);
931 break;
933 switch (HIERARCHY_1) {
934 case HIERARCHY_2:
935 value |= 2;
936 break;
937 case HIERARCHY_4:
938 value |= 4;
939 break;
940 default:
941 case HIERARCHY_1:
942 value |= 1;
943 break;
945 dib7000p_write_word(state, 0, value);
946 dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */
948 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
949 value = 0;
950 if (1 != 0)
951 value |= (1 << 6);
952 if (ch->u.ofdm.hierarchy_information == 1)
953 value |= (1 << 4);
954 if (1 == 1)
955 value |= 1;
956 switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
957 case FEC_2_3:
958 value |= (2 << 1);
959 break;
960 case FEC_3_4:
961 value |= (3 << 1);
962 break;
963 case FEC_5_6:
964 value |= (5 << 1);
965 break;
966 case FEC_7_8:
967 value |= (7 << 1);
968 break;
969 default:
970 case FEC_1_2:
971 value |= (1 << 1);
972 break;
974 dib7000p_write_word(state, 208, value);
976 /* offset loop parameters */
977 dib7000p_write_word(state, 26, 0x6680);
978 dib7000p_write_word(state, 32, 0x0003);
979 dib7000p_write_word(state, 29, 0x1273);
980 dib7000p_write_word(state, 33, 0x0005);
982 /* P_dvsy_sync_wait */
983 switch (ch->u.ofdm.transmission_mode) {
984 case TRANSMISSION_MODE_8K:
985 value = 256;
986 break;
987 case TRANSMISSION_MODE_4K:
988 value = 128;
989 break;
990 case TRANSMISSION_MODE_2K:
991 default:
992 value = 64;
993 break;
995 switch (ch->u.ofdm.guard_interval) {
996 case GUARD_INTERVAL_1_16:
997 value *= 2;
998 break;
999 case GUARD_INTERVAL_1_8:
1000 value *= 4;
1001 break;
1002 case GUARD_INTERVAL_1_4:
1003 value *= 8;
1004 break;
1005 default:
1006 case GUARD_INTERVAL_1_32:
1007 value *= 1;
1008 break;
1010 if (state->cfg.diversity_delay == 0)
1011 state->div_sync_wait = (value * 3) / 2 + 48;
1012 else
1013 state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay;
1015 /* deactive the possibility of diversity reception if extended interleaver */
1016 state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K;
1017 dib7000p_set_diversity_in(&state->demod, state->div_state);
1019 /* channel estimation fine configuration */
1020 switch (ch->u.ofdm.constellation) {
1021 case QAM_64:
1022 est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
1023 est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
1024 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1025 est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
1026 break;
1027 case QAM_16:
1028 est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
1029 est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
1030 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1031 est[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
1032 break;
1033 default:
1034 est[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
1035 est[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
1036 est[2] = 0x0333; /* P_adp_regul_ext 0.1 */
1037 est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
1038 break;
1040 for (value = 0; value < 4; value++)
1041 dib7000p_write_word(state, 187 + value, est[value]);
1044 static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
1046 struct dib7000p_state *state = demod->demodulator_priv;
1047 struct dvb_frontend_parameters schan;
1048 u32 value, factor;
1049 u32 internal = dib7000p_get_internal_freq(state);
1051 schan = *ch;
1052 schan.u.ofdm.constellation = QAM_64;
1053 schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
1054 schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
1055 schan.u.ofdm.code_rate_HP = FEC_2_3;
1056 schan.u.ofdm.code_rate_LP = FEC_3_4;
1057 schan.u.ofdm.hierarchy_information = 0;
1059 dib7000p_set_channel(state, &schan, 7);
1061 factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth);
1062 if (factor >= 5000)
1063 factor = 1;
1064 else
1065 factor = 6;
1067 value = 30 * internal * factor;
1068 dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff));
1069 dib7000p_write_word(state, 7, (u16) (value & 0xffff));
1070 value = 100 * internal * factor;
1071 dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff));
1072 dib7000p_write_word(state, 9, (u16) (value & 0xffff));
1073 value = 500 * internal * factor;
1074 dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff));
1075 dib7000p_write_word(state, 11, (u16) (value & 0xffff));
1077 value = dib7000p_read_word(state, 0);
1078 dib7000p_write_word(state, 0, (u16) ((1 << 9) | value));
1079 dib7000p_read_word(state, 1284);
1080 dib7000p_write_word(state, 0, (u16) value);
1082 return 0;
1085 static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod)
1087 struct dib7000p_state *state = demod->demodulator_priv;
1088 u16 irq_pending = dib7000p_read_word(state, 1284);
1090 if (irq_pending & 0x1)
1091 return 1;
1093 if (irq_pending & 0x2)
1094 return 2;
1096 return 0;
1099 static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw)
1101 static s16 notch[] = { 16143, 14402, 12238, 9713, 6902, 3888, 759, -2392 };
1102 static u8 sine[] = { 0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
1103 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
1104 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
1105 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
1106 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
1107 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
1108 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
1109 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
1110 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
1111 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
1112 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
1113 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
1114 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
1115 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
1116 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
1117 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1118 255, 255, 255, 255, 255, 255
1121 u32 xtal = state->cfg.bw->xtal_hz / 1000;
1122 int f_rel = DIV_ROUND_CLOSEST(rf_khz, xtal) * xtal - rf_khz;
1123 int k;
1124 int coef_re[8], coef_im[8];
1125 int bw_khz = bw;
1126 u32 pha;
1128 dprintk("relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal);
1130 if (f_rel < -bw_khz / 2 || f_rel > bw_khz / 2)
1131 return;
1133 bw_khz /= 100;
1135 dib7000p_write_word(state, 142, 0x0610);
1137 for (k = 0; k < 8; k++) {
1138 pha = ((f_rel * (k + 1) * 112 * 80 / bw_khz) / 1000) & 0x3ff;
1140 if (pha == 0) {
1141 coef_re[k] = 256;
1142 coef_im[k] = 0;
1143 } else if (pha < 256) {
1144 coef_re[k] = sine[256 - (pha & 0xff)];
1145 coef_im[k] = sine[pha & 0xff];
1146 } else if (pha == 256) {
1147 coef_re[k] = 0;
1148 coef_im[k] = 256;
1149 } else if (pha < 512) {
1150 coef_re[k] = -sine[pha & 0xff];
1151 coef_im[k] = sine[256 - (pha & 0xff)];
1152 } else if (pha == 512) {
1153 coef_re[k] = -256;
1154 coef_im[k] = 0;
1155 } else if (pha < 768) {
1156 coef_re[k] = -sine[256 - (pha & 0xff)];
1157 coef_im[k] = -sine[pha & 0xff];
1158 } else if (pha == 768) {
1159 coef_re[k] = 0;
1160 coef_im[k] = -256;
1161 } else {
1162 coef_re[k] = sine[pha & 0xff];
1163 coef_im[k] = -sine[256 - (pha & 0xff)];
1166 coef_re[k] *= notch[k];
1167 coef_re[k] += (1 << 14);
1168 if (coef_re[k] >= (1 << 24))
1169 coef_re[k] = (1 << 24) - 1;
1170 coef_re[k] /= (1 << 15);
1172 coef_im[k] *= notch[k];
1173 coef_im[k] += (1 << 14);
1174 if (coef_im[k] >= (1 << 24))
1175 coef_im[k] = (1 << 24) - 1;
1176 coef_im[k] /= (1 << 15);
1178 dprintk("PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]);
1180 dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
1181 dib7000p_write_word(state, 144, coef_im[k] & 0x3ff);
1182 dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
1184 dib7000p_write_word(state, 143, 0);
1187 static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
1189 struct dib7000p_state *state = demod->demodulator_priv;
1190 u16 tmp = 0;
1192 if (ch != NULL)
1193 dib7000p_set_channel(state, ch, 0);
1194 else
1195 return -EINVAL;
1197 // restart demod
1198 dib7000p_write_word(state, 770, 0x4000);
1199 dib7000p_write_word(state, 770, 0x0000);
1200 msleep(45);
1202 /* 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 */
1203 tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
1204 if (state->sfn_workaround_active) {
1205 dprintk("SFN workaround is active");
1206 tmp |= (1 << 9);
1207 dib7000p_write_word(state, 166, 0x4000);
1208 } else {
1209 dib7000p_write_word(state, 166, 0x0000);
1211 dib7000p_write_word(state, 29, tmp);
1213 // never achieved a lock with that bandwidth so far - wait for osc-freq to update
1214 if (state->timf == 0)
1215 msleep(200);
1217 /* offset loop parameters */
1219 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
1220 tmp = (6 << 8) | 0x80;
1221 switch (ch->u.ofdm.transmission_mode) {
1222 case TRANSMISSION_MODE_2K:
1223 tmp |= (2 << 12);
1224 break;
1225 case TRANSMISSION_MODE_4K:
1226 tmp |= (3 << 12);
1227 break;
1228 default:
1229 case TRANSMISSION_MODE_8K:
1230 tmp |= (4 << 12);
1231 break;
1233 dib7000p_write_word(state, 26, tmp); /* timf_a(6xxx) */
1235 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1236 tmp = (0 << 4);
1237 switch (ch->u.ofdm.transmission_mode) {
1238 case TRANSMISSION_MODE_2K:
1239 tmp |= 0x6;
1240 break;
1241 case TRANSMISSION_MODE_4K:
1242 tmp |= 0x7;
1243 break;
1244 default:
1245 case TRANSMISSION_MODE_8K:
1246 tmp |= 0x8;
1247 break;
1249 dib7000p_write_word(state, 32, tmp);
1251 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1252 tmp = (0 << 4);
1253 switch (ch->u.ofdm.transmission_mode) {
1254 case TRANSMISSION_MODE_2K:
1255 tmp |= 0x6;
1256 break;
1257 case TRANSMISSION_MODE_4K:
1258 tmp |= 0x7;
1259 break;
1260 default:
1261 case TRANSMISSION_MODE_8K:
1262 tmp |= 0x8;
1263 break;
1265 dib7000p_write_word(state, 33, tmp);
1267 tmp = dib7000p_read_word(state, 509);
1268 if (!((tmp >> 6) & 0x1)) {
1269 /* restart the fec */
1270 tmp = dib7000p_read_word(state, 771);
1271 dib7000p_write_word(state, 771, tmp | (1 << 1));
1272 dib7000p_write_word(state, 771, tmp);
1273 msleep(40);
1274 tmp = dib7000p_read_word(state, 509);
1276 // we achieved a lock - it's time to update the osc freq
1277 if ((tmp >> 6) & 0x1) {
1278 dib7000p_update_timf(state);
1279 /* P_timf_alpha += 2 */
1280 tmp = dib7000p_read_word(state, 26);
1281 dib7000p_write_word(state, 26, (tmp & ~(0xf << 12)) | ((((tmp >> 12) & 0xf) + 5) << 12));
1284 if (state->cfg.spur_protect)
1285 dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1287 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1288 return 0;
1291 static int dib7000p_wakeup(struct dvb_frontend *demod)
1293 struct dib7000p_state *state = demod->demodulator_priv;
1294 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
1295 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
1296 if (state->version == SOC7090)
1297 dib7000p_sad_calib(state);
1298 return 0;
1301 static int dib7000p_sleep(struct dvb_frontend *demod)
1303 struct dib7000p_state *state = demod->demodulator_priv;
1304 if (state->version == SOC7090)
1305 return dib7090_set_output_mode(demod, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1306 return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1309 static int dib7000p_identify(struct dib7000p_state *st)
1311 u16 value;
1312 dprintk("checking demod on I2C address: %d (%x)", st->i2c_addr, st->i2c_addr);
1314 if ((value = dib7000p_read_word(st, 768)) != 0x01b3) {
1315 dprintk("wrong Vendor ID (read=0x%x)", value);
1316 return -EREMOTEIO;
1319 if ((value = dib7000p_read_word(st, 769)) != 0x4000) {
1320 dprintk("wrong Device ID (%x)", value);
1321 return -EREMOTEIO;
1324 return 0;
1327 static int dib7000p_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1329 struct dib7000p_state *state = fe->demodulator_priv;
1330 u16 tps = dib7000p_read_word(state, 463);
1332 fep->inversion = INVERSION_AUTO;
1334 fep->u.ofdm.bandwidth = BANDWIDTH_TO_INDEX(state->current_bandwidth);
1336 switch ((tps >> 8) & 0x3) {
1337 case 0:
1338 fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
1339 break;
1340 case 1:
1341 fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
1342 break;
1343 /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */
1346 switch (tps & 0x3) {
1347 case 0:
1348 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
1349 break;
1350 case 1:
1351 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
1352 break;
1353 case 2:
1354 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
1355 break;
1356 case 3:
1357 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
1358 break;
1361 switch ((tps >> 14) & 0x3) {
1362 case 0:
1363 fep->u.ofdm.constellation = QPSK;
1364 break;
1365 case 1:
1366 fep->u.ofdm.constellation = QAM_16;
1367 break;
1368 case 2:
1369 default:
1370 fep->u.ofdm.constellation = QAM_64;
1371 break;
1374 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1375 /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1377 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
1378 switch ((tps >> 5) & 0x7) {
1379 case 1:
1380 fep->u.ofdm.code_rate_HP = FEC_1_2;
1381 break;
1382 case 2:
1383 fep->u.ofdm.code_rate_HP = FEC_2_3;
1384 break;
1385 case 3:
1386 fep->u.ofdm.code_rate_HP = FEC_3_4;
1387 break;
1388 case 5:
1389 fep->u.ofdm.code_rate_HP = FEC_5_6;
1390 break;
1391 case 7:
1392 default:
1393 fep->u.ofdm.code_rate_HP = FEC_7_8;
1394 break;
1398 switch ((tps >> 2) & 0x7) {
1399 case 1:
1400 fep->u.ofdm.code_rate_LP = FEC_1_2;
1401 break;
1402 case 2:
1403 fep->u.ofdm.code_rate_LP = FEC_2_3;
1404 break;
1405 case 3:
1406 fep->u.ofdm.code_rate_LP = FEC_3_4;
1407 break;
1408 case 5:
1409 fep->u.ofdm.code_rate_LP = FEC_5_6;
1410 break;
1411 case 7:
1412 default:
1413 fep->u.ofdm.code_rate_LP = FEC_7_8;
1414 break;
1417 /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */
1419 return 0;
1422 static int dib7000p_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1424 struct dib7000p_state *state = fe->demodulator_priv;
1425 int time, ret;
1427 if (state->version == SOC7090) {
1428 dib7090_set_diversity_in(fe, 0);
1429 dib7090_set_output_mode(fe, OUTMODE_HIGH_Z);
1430 } else
1431 dib7000p_set_output_mode(state, OUTMODE_HIGH_Z);
1433 /* maybe the parameter has been changed */
1434 state->sfn_workaround_active = buggy_sfn_workaround;
1436 if (fe->ops.tuner_ops.set_params)
1437 fe->ops.tuner_ops.set_params(fe, fep);
1439 /* start up the AGC */
1440 state->agc_state = 0;
1441 do {
1442 time = dib7000p_agc_startup(fe, fep);
1443 if (time != -1)
1444 msleep(time);
1445 } while (time != -1);
1447 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
1448 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || fep->u.ofdm.constellation == QAM_AUTO || fep->u.ofdm.code_rate_HP == FEC_AUTO) {
1449 int i = 800, found;
1451 dib7000p_autosearch_start(fe, fep);
1452 do {
1453 msleep(1);
1454 found = dib7000p_autosearch_is_irq(fe);
1455 } while (found == 0 && i--);
1457 dprintk("autosearch returns: %d", found);
1458 if (found == 0 || found == 1)
1459 return 0;
1461 dib7000p_get_frontend(fe, fep);
1464 ret = dib7000p_tune(fe, fep);
1466 /* make this a config parameter */
1467 if (state->version == SOC7090)
1468 dib7090_set_output_mode(fe, state->cfg.output_mode);
1469 else
1470 dib7000p_set_output_mode(state, state->cfg.output_mode);
1472 return ret;
1475 static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t * stat)
1477 struct dib7000p_state *state = fe->demodulator_priv;
1478 u16 lock = dib7000p_read_word(state, 509);
1480 *stat = 0;
1482 if (lock & 0x8000)
1483 *stat |= FE_HAS_SIGNAL;
1484 if (lock & 0x3000)
1485 *stat |= FE_HAS_CARRIER;
1486 if (lock & 0x0100)
1487 *stat |= FE_HAS_VITERBI;
1488 if (lock & 0x0010)
1489 *stat |= FE_HAS_SYNC;
1490 if ((lock & 0x0038) == 0x38)
1491 *stat |= FE_HAS_LOCK;
1493 return 0;
1496 static int dib7000p_read_ber(struct dvb_frontend *fe, u32 * ber)
1498 struct dib7000p_state *state = fe->demodulator_priv;
1499 *ber = (dib7000p_read_word(state, 500) << 16) | dib7000p_read_word(state, 501);
1500 return 0;
1503 static int dib7000p_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
1505 struct dib7000p_state *state = fe->demodulator_priv;
1506 *unc = dib7000p_read_word(state, 506);
1507 return 0;
1510 static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
1512 struct dib7000p_state *state = fe->demodulator_priv;
1513 u16 val = dib7000p_read_word(state, 394);
1514 *strength = 65535 - val;
1515 return 0;
1518 static int dib7000p_read_snr(struct dvb_frontend *fe, u16 * snr)
1520 struct dib7000p_state *state = fe->demodulator_priv;
1521 u16 val;
1522 s32 signal_mant, signal_exp, noise_mant, noise_exp;
1523 u32 result = 0;
1525 val = dib7000p_read_word(state, 479);
1526 noise_mant = (val >> 4) & 0xff;
1527 noise_exp = ((val & 0xf) << 2);
1528 val = dib7000p_read_word(state, 480);
1529 noise_exp += ((val >> 14) & 0x3);
1530 if ((noise_exp & 0x20) != 0)
1531 noise_exp -= 0x40;
1533 signal_mant = (val >> 6) & 0xFF;
1534 signal_exp = (val & 0x3F);
1535 if ((signal_exp & 0x20) != 0)
1536 signal_exp -= 0x40;
1538 if (signal_mant != 0)
1539 result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
1540 else
1541 result = intlog10(2) * 10 * signal_exp - 100;
1543 if (noise_mant != 0)
1544 result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
1545 else
1546 result -= intlog10(2) * 10 * noise_exp - 100;
1548 *snr = result / ((1 << 24) / 10);
1549 return 0;
1552 static int dib7000p_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
1554 tune->min_delay_ms = 1000;
1555 return 0;
1558 static void dib7000p_release(struct dvb_frontend *demod)
1560 struct dib7000p_state *st = demod->demodulator_priv;
1561 dibx000_exit_i2c_master(&st->i2c_master);
1562 i2c_del_adapter(&st->dib7090_tuner_adap);
1563 kfree(st);
1566 int dib7000pc_detection(struct i2c_adapter *i2c_adap)
1568 u8 *tx, *rx;
1569 struct i2c_msg msg[2] = {
1570 {.addr = 18 >> 1, .flags = 0, .len = 2},
1571 {.addr = 18 >> 1, .flags = I2C_M_RD, .len = 2},
1573 int ret = 0;
1575 tx = kzalloc(2*sizeof(u8), GFP_KERNEL);
1576 if (!tx)
1577 return -ENOMEM;
1578 rx = kzalloc(2*sizeof(u8), GFP_KERNEL);
1579 if (!rx) {
1580 goto rx_memory_error;
1581 ret = -ENOMEM;
1584 msg[0].buf = tx;
1585 msg[1].buf = rx;
1587 tx[0] = 0x03;
1588 tx[1] = 0x00;
1590 if (i2c_transfer(i2c_adap, msg, 2) == 2)
1591 if (rx[0] == 0x01 && rx[1] == 0xb3) {
1592 dprintk("-D- DiB7000PC detected");
1593 return 1;
1596 msg[0].addr = msg[1].addr = 0x40;
1598 if (i2c_transfer(i2c_adap, msg, 2) == 2)
1599 if (rx[0] == 0x01 && rx[1] == 0xb3) {
1600 dprintk("-D- DiB7000PC detected");
1601 return 1;
1604 dprintk("-D- DiB7000PC not detected");
1606 kfree(rx);
1607 rx_memory_error:
1608 kfree(tx);
1609 return ret;
1611 EXPORT_SYMBOL(dib7000pc_detection);
1613 struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
1615 struct dib7000p_state *st = demod->demodulator_priv;
1616 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1618 EXPORT_SYMBOL(dib7000p_get_i2c_master);
1620 int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1622 struct dib7000p_state *state = fe->demodulator_priv;
1623 u16 val = dib7000p_read_word(state, 235) & 0xffef;
1624 val |= (onoff & 0x1) << 4;
1625 dprintk("PID filter enabled %d", onoff);
1626 return dib7000p_write_word(state, 235, val);
1628 EXPORT_SYMBOL(dib7000p_pid_filter_ctrl);
1630 int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1632 struct dib7000p_state *state = fe->demodulator_priv;
1633 dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
1634 return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0);
1636 EXPORT_SYMBOL(dib7000p_pid_filter);
1638 int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
1640 struct dib7000p_state *dpst;
1641 int k = 0;
1642 u8 new_addr = 0;
1644 dpst = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
1645 if (!dpst)
1646 return -ENOMEM;
1648 dpst->i2c_adap = i2c;
1650 for (k = no_of_demods - 1; k >= 0; k--) {
1651 dpst->cfg = cfg[k];
1653 /* designated i2c address */
1654 if (cfg[k].default_i2c_addr != 0)
1655 new_addr = cfg[k].default_i2c_addr + (k << 1);
1656 else
1657 new_addr = (0x40 + k) << 1;
1658 dpst->i2c_addr = new_addr;
1659 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */
1660 if (dib7000p_identify(dpst) != 0) {
1661 dpst->i2c_addr = default_addr;
1662 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */
1663 if (dib7000p_identify(dpst) != 0) {
1664 dprintk("DiB7000P #%d: not identified\n", k);
1665 kfree(dpst);
1666 return -EIO;
1670 /* start diversity to pull_down div_str - just for i2c-enumeration */
1671 dib7000p_set_output_mode(dpst, OUTMODE_DIVERSITY);
1673 /* set new i2c address and force divstart */
1674 dib7000p_write_word(dpst, 1285, (new_addr << 2) | 0x2);
1676 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
1679 for (k = 0; k < no_of_demods; k++) {
1680 dpst->cfg = cfg[k];
1681 if (cfg[k].default_i2c_addr != 0)
1682 dpst->i2c_addr = (cfg[k].default_i2c_addr + k) << 1;
1683 else
1684 dpst->i2c_addr = (0x40 + k) << 1;
1686 // unforce divstr
1687 dib7000p_write_word(dpst, 1285, dpst->i2c_addr << 2);
1689 /* deactivate div - it was just for i2c-enumeration */
1690 dib7000p_set_output_mode(dpst, OUTMODE_HIGH_Z);
1693 kfree(dpst);
1694 return 0;
1696 EXPORT_SYMBOL(dib7000p_i2c_enumeration);
1698 static const s32 lut_1000ln_mant[] = {
1699 6908, 6956, 7003, 7047, 7090, 7131, 7170, 7208, 7244, 7279, 7313, 7346, 7377, 7408, 7438, 7467, 7495, 7523, 7549, 7575, 7600
1702 static s32 dib7000p_get_adc_power(struct dvb_frontend *fe)
1704 struct dib7000p_state *state = fe->demodulator_priv;
1705 u32 tmp_val = 0, exp = 0, mant = 0;
1706 s32 pow_i;
1707 u16 buf[2];
1708 u8 ix = 0;
1710 buf[0] = dib7000p_read_word(state, 0x184);
1711 buf[1] = dib7000p_read_word(state, 0x185);
1712 pow_i = (buf[0] << 16) | buf[1];
1713 dprintk("raw pow_i = %d", pow_i);
1715 tmp_val = pow_i;
1716 while (tmp_val >>= 1)
1717 exp++;
1719 mant = (pow_i * 1000 / (1 << exp));
1720 dprintk(" mant = %d exp = %d", mant / 1000, exp);
1722 ix = (u8) ((mant - 1000) / 100); /* index of the LUT */
1723 dprintk(" ix = %d", ix);
1725 pow_i = (lut_1000ln_mant[ix] + 693 * (exp - 20) - 6908);
1726 pow_i = (pow_i << 8) / 1000;
1727 dprintk(" pow_i = %d", pow_i);
1729 return pow_i;
1732 static int map_addr_to_serpar_number(struct i2c_msg *msg)
1734 if ((msg->buf[0] <= 15))
1735 msg->buf[0] -= 1;
1736 else if (msg->buf[0] == 17)
1737 msg->buf[0] = 15;
1738 else if (msg->buf[0] == 16)
1739 msg->buf[0] = 17;
1740 else if (msg->buf[0] == 19)
1741 msg->buf[0] = 16;
1742 else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
1743 msg->buf[0] -= 3;
1744 else if (msg->buf[0] == 28)
1745 msg->buf[0] = 23;
1746 else
1747 return -EINVAL;
1748 return 0;
1751 static int w7090p_tuner_write_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1753 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1754 u8 n_overflow = 1;
1755 u16 i = 1000;
1756 u16 serpar_num = msg[0].buf[0];
1758 while (n_overflow == 1 && i) {
1759 n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
1760 i--;
1761 if (i == 0)
1762 dprintk("Tuner ITF: write busy (overflow)");
1764 dib7000p_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
1765 dib7000p_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
1767 return num;
1770 static int w7090p_tuner_read_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1772 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1773 u8 n_overflow = 1, n_empty = 1;
1774 u16 i = 1000;
1775 u16 serpar_num = msg[0].buf[0];
1776 u16 read_word;
1778 while (n_overflow == 1 && i) {
1779 n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
1780 i--;
1781 if (i == 0)
1782 dprintk("TunerITF: read busy (overflow)");
1784 dib7000p_write_word(state, 1985, (0 << 6) | (serpar_num & 0x3f));
1786 i = 1000;
1787 while (n_empty == 1 && i) {
1788 n_empty = dib7000p_read_word(state, 1984) & 0x1;
1789 i--;
1790 if (i == 0)
1791 dprintk("TunerITF: read busy (empty)");
1793 read_word = dib7000p_read_word(state, 1987);
1794 msg[1].buf[0] = (read_word >> 8) & 0xff;
1795 msg[1].buf[1] = (read_word) & 0xff;
1797 return num;
1800 static int w7090p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1802 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... */
1803 if (num == 1) { /* write */
1804 return w7090p_tuner_write_serpar(i2c_adap, msg, 1);
1805 } else { /* read */
1806 return w7090p_tuner_read_serpar(i2c_adap, msg, 2);
1809 return num;
1812 int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num, u16 apb_address)
1814 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1815 u16 word;
1817 if (num == 1) { /* write */
1818 dib7000p_write_word(state, apb_address, ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
1819 } else {
1820 word = dib7000p_read_word(state, apb_address);
1821 msg[1].buf[0] = (word >> 8) & 0xff;
1822 msg[1].buf[1] = (word) & 0xff;
1825 return num;
1828 static int dib7090_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1830 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1832 u16 apb_address = 0, word;
1833 int i = 0;
1834 switch (msg[0].buf[0]) {
1835 case 0x12:
1836 apb_address = 1920;
1837 break;
1838 case 0x14:
1839 apb_address = 1921;
1840 break;
1841 case 0x24:
1842 apb_address = 1922;
1843 break;
1844 case 0x1a:
1845 apb_address = 1923;
1846 break;
1847 case 0x22:
1848 apb_address = 1924;
1849 break;
1850 case 0x33:
1851 apb_address = 1926;
1852 break;
1853 case 0x34:
1854 apb_address = 1927;
1855 break;
1856 case 0x35:
1857 apb_address = 1928;
1858 break;
1859 case 0x36:
1860 apb_address = 1929;
1861 break;
1862 case 0x37:
1863 apb_address = 1930;
1864 break;
1865 case 0x38:
1866 apb_address = 1931;
1867 break;
1868 case 0x39:
1869 apb_address = 1932;
1870 break;
1871 case 0x2a:
1872 apb_address = 1935;
1873 break;
1874 case 0x2b:
1875 apb_address = 1936;
1876 break;
1877 case 0x2c:
1878 apb_address = 1937;
1879 break;
1880 case 0x2d:
1881 apb_address = 1938;
1882 break;
1883 case 0x2e:
1884 apb_address = 1939;
1885 break;
1886 case 0x2f:
1887 apb_address = 1940;
1888 break;
1889 case 0x30:
1890 apb_address = 1941;
1891 break;
1892 case 0x31:
1893 apb_address = 1942;
1894 break;
1895 case 0x32:
1896 apb_address = 1943;
1897 break;
1898 case 0x3e:
1899 apb_address = 1944;
1900 break;
1901 case 0x3f:
1902 apb_address = 1945;
1903 break;
1904 case 0x40:
1905 apb_address = 1948;
1906 break;
1907 case 0x25:
1908 apb_address = 914;
1909 break;
1910 case 0x26:
1911 apb_address = 915;
1912 break;
1913 case 0x27:
1914 apb_address = 916;
1915 break;
1916 case 0x28:
1917 apb_address = 917;
1918 break;
1919 case 0x1d:
1920 i = ((dib7000p_read_word(state, 72) >> 12) & 0x3);
1921 word = dib7000p_read_word(state, 384 + i);
1922 msg[1].buf[0] = (word >> 8) & 0xff;
1923 msg[1].buf[1] = (word) & 0xff;
1924 return num;
1925 case 0x1f:
1926 if (num == 1) { /* write */
1927 word = (u16) ((msg[0].buf[1] << 8) | msg[0].buf[2]);
1928 word &= 0x3;
1929 word = (dib7000p_read_word(state, 72) & ~(3 << 12)) | (word << 12);
1930 dib7000p_write_word(state, 72, word); /* Set the proper input */
1931 return num;
1935 if (apb_address != 0) /* R/W acces via APB */
1936 return dib7090p_rw_on_apb(i2c_adap, msg, num, apb_address);
1937 else /* R/W access via SERPAR */
1938 return w7090p_tuner_rw_serpar(i2c_adap, msg, num);
1940 return 0;
1943 static u32 dib7000p_i2c_func(struct i2c_adapter *adapter)
1945 return I2C_FUNC_I2C;
1948 static struct i2c_algorithm dib7090_tuner_xfer_algo = {
1949 .master_xfer = dib7090_tuner_xfer,
1950 .functionality = dib7000p_i2c_func,
1953 struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
1955 struct dib7000p_state *st = fe->demodulator_priv;
1956 return &st->dib7090_tuner_adap;
1958 EXPORT_SYMBOL(dib7090_get_i2c_tuner);
1960 static int dib7090_host_bus_drive(struct dib7000p_state *state, u8 drive)
1962 u16 reg;
1964 /* drive host bus 2, 3, 4 */
1965 reg = dib7000p_read_word(state, 1798) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1966 reg |= (drive << 12) | (drive << 6) | drive;
1967 dib7000p_write_word(state, 1798, reg);
1969 /* drive host bus 5,6 */
1970 reg = dib7000p_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
1971 reg |= (drive << 8) | (drive << 2);
1972 dib7000p_write_word(state, 1799, reg);
1974 /* drive host bus 7, 8, 9 */
1975 reg = dib7000p_read_word(state, 1800) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1976 reg |= (drive << 12) | (drive << 6) | drive;
1977 dib7000p_write_word(state, 1800, reg);
1979 /* drive host bus 10, 11 */
1980 reg = dib7000p_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
1981 reg |= (drive << 8) | (drive << 2);
1982 dib7000p_write_word(state, 1801, reg);
1984 /* drive host bus 12, 13, 14 */
1985 reg = dib7000p_read_word(state, 1802) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1986 reg |= (drive << 12) | (drive << 6) | drive;
1987 dib7000p_write_word(state, 1802, reg);
1989 return 0;
1992 static u32 dib7090_calcSyncFreq(u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 syncSize)
1994 u32 quantif = 3;
1995 u32 nom = (insertExtSynchro * P_Kin + syncSize);
1996 u32 denom = P_Kout;
1997 u32 syncFreq = ((nom << quantif) / denom);
1999 if ((syncFreq & ((1 << quantif) - 1)) != 0)
2000 syncFreq = (syncFreq >> quantif) + 1;
2001 else
2002 syncFreq = (syncFreq >> quantif);
2004 if (syncFreq != 0)
2005 syncFreq = syncFreq - 1;
2007 return syncFreq;
2010 static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize)
2012 u8 index_buf;
2013 u16 rx_copy_buf[22];
2015 dprintk("Configure DibStream Tx");
2016 for (index_buf = 0; index_buf < 22; index_buf++)
2017 rx_copy_buf[index_buf] = dib7000p_read_word(state, 1536+index_buf);
2019 dib7000p_write_word(state, 1615, 1);
2020 dib7000p_write_word(state, 1603, P_Kin);
2021 dib7000p_write_word(state, 1605, P_Kout);
2022 dib7000p_write_word(state, 1606, insertExtSynchro);
2023 dib7000p_write_word(state, 1608, synchroMode);
2024 dib7000p_write_word(state, 1609, (syncWord >> 16) & 0xffff);
2025 dib7000p_write_word(state, 1610, syncWord & 0xffff);
2026 dib7000p_write_word(state, 1612, syncSize);
2027 dib7000p_write_word(state, 1615, 0);
2029 for (index_buf = 0; index_buf < 22; index_buf++)
2030 dib7000p_write_word(state, 1536+index_buf, rx_copy_buf[index_buf]);
2032 return 0;
2035 static int dib7090_cfg_DibRx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 synchroMode, u32 insertExtSynchro, u32 syncWord, u32 syncSize,
2036 u32 dataOutRate)
2038 u32 syncFreq;
2040 dprintk("Configure DibStream Rx");
2041 if ((P_Kin != 0) && (P_Kout != 0)) {
2042 syncFreq = dib7090_calcSyncFreq(P_Kin, P_Kout, insertExtSynchro, syncSize);
2043 dib7000p_write_word(state, 1542, syncFreq);
2045 dib7000p_write_word(state, 1554, 1);
2046 dib7000p_write_word(state, 1536, P_Kin);
2047 dib7000p_write_word(state, 1537, P_Kout);
2048 dib7000p_write_word(state, 1539, synchroMode);
2049 dib7000p_write_word(state, 1540, (syncWord >> 16) & 0xffff);
2050 dib7000p_write_word(state, 1541, syncWord & 0xffff);
2051 dib7000p_write_word(state, 1543, syncSize);
2052 dib7000p_write_word(state, 1544, dataOutRate);
2053 dib7000p_write_word(state, 1554, 0);
2055 return 0;
2058 static int dib7090_enDivOnHostBus(struct dib7000p_state *state)
2060 u16 reg;
2062 dprintk("Enable Diversity on host bus");
2063 reg = (1 << 8) | (1 << 5);
2064 dib7000p_write_word(state, 1288, reg);
2066 return dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
2069 static int dib7090_enAdcOnHostBus(struct dib7000p_state *state)
2071 u16 reg;
2073 dprintk("Enable ADC on host bus");
2074 reg = (1 << 7) | (1 << 5);
2075 dib7000p_write_word(state, 1288, reg);
2077 return dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
2080 static int dib7090_enMpegOnHostBus(struct dib7000p_state *state)
2082 u16 reg;
2084 dprintk("Enable Mpeg on host bus");
2085 reg = (1 << 9) | (1 << 5);
2086 dib7000p_write_word(state, 1288, reg);
2088 return dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
2091 static int dib7090_enMpegInput(struct dib7000p_state *state)
2093 dprintk("Enable Mpeg input");
2094 return dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */
2097 static int dib7090_enMpegMux(struct dib7000p_state *state, u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
2099 u16 reg = (1 << 7) | ((pulseWidth & 0x1f) << 2) | ((enSerialMode & 0x1) << 1) | (enSerialClkDiv2 & 0x1);
2101 dprintk("Enable Mpeg mux");
2102 dib7000p_write_word(state, 1287, reg);
2104 reg &= ~(1 << 7);
2105 dib7000p_write_word(state, 1287, reg);
2107 reg = (1 << 4);
2108 dib7000p_write_word(state, 1288, reg);
2110 return 0;
2113 static int dib7090_disableMpegMux(struct dib7000p_state *state)
2115 u16 reg;
2117 dprintk("Disable Mpeg mux");
2118 dib7000p_write_word(state, 1288, 0);
2120 reg = dib7000p_read_word(state, 1287);
2121 reg &= ~(1 << 7);
2122 dib7000p_write_word(state, 1287, reg);
2124 return 0;
2127 static int dib7090_set_input_mode(struct dvb_frontend *fe, int mode)
2129 struct dib7000p_state *state = fe->demodulator_priv;
2131 switch (mode) {
2132 case INPUT_MODE_DIVERSITY:
2133 dprintk("Enable diversity INPUT");
2134 dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
2135 break;
2136 case INPUT_MODE_MPEG:
2137 dprintk("Enable Mpeg INPUT");
2138 dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */
2139 break;
2140 case INPUT_MODE_OFF:
2141 default:
2142 dprintk("Disable INPUT");
2143 dib7090_cfg_DibRx(state, 0, 0, 0, 0, 0, 0, 0);
2144 break;
2146 return 0;
2149 static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff)
2151 switch (onoff) {
2152 case 0: /* only use the internal way - not the diversity input */
2153 dib7090_set_input_mode(fe, INPUT_MODE_MPEG);
2154 break;
2155 case 1: /* both ways */
2156 case 2: /* only the diversity input */
2157 dib7090_set_input_mode(fe, INPUT_MODE_DIVERSITY);
2158 break;
2161 return 0;
2164 static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode)
2166 struct dib7000p_state *state = fe->demodulator_priv;
2168 u16 outreg, smo_mode, fifo_threshold;
2169 u8 prefer_mpeg_mux_use = 1;
2170 int ret = 0;
2172 dib7090_host_bus_drive(state, 1);
2174 fifo_threshold = 1792;
2175 smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
2176 outreg = dib7000p_read_word(state, 1286) & ~((1 << 10) | (0x7 << 6) | (1 << 1));
2178 switch (mode) {
2179 case OUTMODE_HIGH_Z:
2180 outreg = 0;
2181 break;
2183 case OUTMODE_MPEG2_SERIAL:
2184 if (prefer_mpeg_mux_use) {
2185 dprintk("Sip 7090P setting output mode TS_SERIAL using Mpeg Mux");
2186 dib7090_enMpegOnHostBus(state);
2187 dib7090_enMpegInput(state);
2188 if (state->cfg.enMpegOutput == 1)
2189 dib7090_enMpegMux(state, 3, 1, 1);
2191 } else { /* Use Smooth block */
2192 dprintk("Sip 7090P setting output mode TS_SERIAL using Smooth bloc");
2193 dib7090_disableMpegMux(state);
2194 dib7000p_write_word(state, 1288, (1 << 6));
2195 outreg |= (2 << 6) | (0 << 1);
2197 break;
2199 case OUTMODE_MPEG2_PAR_GATED_CLK:
2200 if (prefer_mpeg_mux_use) {
2201 dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Mpeg Mux");
2202 dib7090_enMpegOnHostBus(state);
2203 dib7090_enMpegInput(state);
2204 if (state->cfg.enMpegOutput == 1)
2205 dib7090_enMpegMux(state, 2, 0, 0);
2206 } else { /* Use Smooth block */
2207 dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Smooth block");
2208 dib7090_disableMpegMux(state);
2209 dib7000p_write_word(state, 1288, (1 << 6));
2210 outreg |= (0 << 6);
2212 break;
2214 case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */
2215 dprintk("Sip 7090P setting output mode TS_PARALLEL_CONT using Smooth block");
2216 dib7090_disableMpegMux(state);
2217 dib7000p_write_word(state, 1288, (1 << 6));
2218 outreg |= (1 << 6);
2219 break;
2221 case OUTMODE_MPEG2_FIFO: /* Using Smooth block because not supported by new Mpeg Mux bloc */
2222 dprintk("Sip 7090P setting output mode TS_FIFO using Smooth block");
2223 dib7090_disableMpegMux(state);
2224 dib7000p_write_word(state, 1288, (1 << 6));
2225 outreg |= (5 << 6);
2226 smo_mode |= (3 << 1);
2227 fifo_threshold = 512;
2228 break;
2230 case OUTMODE_DIVERSITY:
2231 dprintk("Sip 7090P setting output mode MODE_DIVERSITY");
2232 dib7090_disableMpegMux(state);
2233 dib7090_enDivOnHostBus(state);
2234 break;
2236 case OUTMODE_ANALOG_ADC:
2237 dprintk("Sip 7090P setting output mode MODE_ANALOG_ADC");
2238 dib7090_enAdcOnHostBus(state);
2239 break;
2242 if (state->cfg.output_mpeg2_in_188_bytes)
2243 smo_mode |= (1 << 5);
2245 ret |= dib7000p_write_word(state, 235, smo_mode);
2246 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
2247 ret |= dib7000p_write_word(state, 1286, outreg | (1 << 10)); /* allways set Dout active = 1 !!! */
2249 return ret;
2252 int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
2254 struct dib7000p_state *state = fe->demodulator_priv;
2255 u16 en_cur_state;
2257 dprintk("sleep dib7090: %d", onoff);
2259 en_cur_state = dib7000p_read_word(state, 1922);
2261 if (en_cur_state > 0xff)
2262 state->tuner_enable = en_cur_state;
2264 if (onoff)
2265 en_cur_state &= 0x00ff;
2266 else {
2267 if (state->tuner_enable != 0)
2268 en_cur_state = state->tuner_enable;
2271 dib7000p_write_word(state, 1922, en_cur_state);
2273 return 0;
2275 EXPORT_SYMBOL(dib7090_tuner_sleep);
2277 int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart)
2279 dprintk("AGC restart callback: %d", restart);
2280 return 0;
2282 EXPORT_SYMBOL(dib7090_agc_restart);
2284 int dib7090_get_adc_power(struct dvb_frontend *fe)
2286 return dib7000p_get_adc_power(fe);
2288 EXPORT_SYMBOL(dib7090_get_adc_power);
2290 int dib7090_slave_reset(struct dvb_frontend *fe)
2292 struct dib7000p_state *state = fe->demodulator_priv;
2293 u16 reg;
2295 reg = dib7000p_read_word(state, 1794);
2296 dib7000p_write_word(state, 1794, reg | (4 << 12));
2298 dib7000p_write_word(state, 1032, 0xffff);
2299 return 0;
2301 EXPORT_SYMBOL(dib7090_slave_reset);
2303 static struct dvb_frontend_ops dib7000p_ops;
2304 struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
2306 struct dvb_frontend *demod;
2307 struct dib7000p_state *st;
2308 st = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
2309 if (st == NULL)
2310 return NULL;
2312 memcpy(&st->cfg, cfg, sizeof(struct dib7000p_config));
2313 st->i2c_adap = i2c_adap;
2314 st->i2c_addr = i2c_addr;
2315 st->gpio_val = cfg->gpio_val;
2316 st->gpio_dir = cfg->gpio_dir;
2318 /* Ensure the output mode remains at the previous default if it's
2319 * not specifically set by the caller.
2321 if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2322 st->cfg.output_mode = OUTMODE_MPEG2_FIFO;
2324 demod = &st->demod;
2325 demod->demodulator_priv = st;
2326 memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));
2328 dib7000p_write_word(st, 1287, 0x0003); /* sram lead in, rdy */
2330 if (dib7000p_identify(st) != 0)
2331 goto error;
2333 st->version = dib7000p_read_word(st, 897);
2335 /* FIXME: make sure the dev.parent field is initialized, or else
2336 request_firmware() will hit an OOPS (this should be moved somewhere
2337 more common) */
2339 dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr);
2341 /* init 7090 tuner adapter */
2342 strncpy(st->dib7090_tuner_adap.name, "DiB7090 tuner interface", sizeof(st->dib7090_tuner_adap.name));
2343 st->dib7090_tuner_adap.algo = &dib7090_tuner_xfer_algo;
2344 st->dib7090_tuner_adap.algo_data = NULL;
2345 st->dib7090_tuner_adap.dev.parent = st->i2c_adap->dev.parent;
2346 i2c_set_adapdata(&st->dib7090_tuner_adap, st);
2347 i2c_add_adapter(&st->dib7090_tuner_adap);
2349 dib7000p_demod_reset(st);
2351 if (st->version == SOC7090) {
2352 dib7090_set_output_mode(demod, st->cfg.output_mode);
2353 dib7090_set_diversity_in(demod, 0);
2356 return demod;
2358 error:
2359 kfree(st);
2360 return NULL;
2362 EXPORT_SYMBOL(dib7000p_attach);
2364 static struct dvb_frontend_ops dib7000p_ops = {
2365 .info = {
2366 .name = "DiBcom 7000PC",
2367 .type = FE_OFDM,
2368 .frequency_min = 44250000,
2369 .frequency_max = 867250000,
2370 .frequency_stepsize = 62500,
2371 .caps = FE_CAN_INVERSION_AUTO |
2372 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2373 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2374 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2375 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2378 .release = dib7000p_release,
2380 .init = dib7000p_wakeup,
2381 .sleep = dib7000p_sleep,
2383 .set_frontend = dib7000p_set_frontend,
2384 .get_tune_settings = dib7000p_fe_get_tune_settings,
2385 .get_frontend = dib7000p_get_frontend,
2387 .read_status = dib7000p_read_status,
2388 .read_ber = dib7000p_read_ber,
2389 .read_signal_strength = dib7000p_read_signal_strength,
2390 .read_snr = dib7000p_read_snr,
2391 .read_ucblocks = dib7000p_read_unc_blocks,
2394 MODULE_AUTHOR("Olivier Grenie <ogrenie@dibcom.fr>");
2395 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
2396 MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
2397 MODULE_LICENSE("GPL");