USB: convert drivers/media/* to use module_usb_driver()
[zen-stable.git] / drivers / media / dvb / frontends / dib7000p.c
blobce8534ff142efe448de4cf2b7f325edc74fadaab
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>
13 #include <linux/mutex.h>
15 #include "dvb_math.h"
16 #include "dvb_frontend.h"
18 #include "dib7000p.h"
20 static int debug;
21 module_param(debug, int, 0644);
22 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
24 static int buggy_sfn_workaround;
25 module_param(buggy_sfn_workaround, int, 0644);
26 MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
28 #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0)
30 struct i2c_device {
31 struct i2c_adapter *i2c_adap;
32 u8 i2c_addr;
35 struct dib7000p_state {
36 struct dvb_frontend demod;
37 struct dib7000p_config cfg;
39 u8 i2c_addr;
40 struct i2c_adapter *i2c_adap;
42 struct dibx000_i2c_master i2c_master;
44 u16 wbd_ref;
46 u8 current_band;
47 u32 current_bandwidth;
48 struct dibx000_agc_config *current_agc;
49 u32 timf;
51 u8 div_force_off:1;
52 u8 div_state:1;
53 u16 div_sync_wait;
55 u8 agc_state;
57 u16 gpio_dir;
58 u16 gpio_val;
60 u8 sfn_workaround_active:1;
62 #define SOC7090 0x7090
63 u16 version;
65 u16 tuner_enable;
66 struct i2c_adapter dib7090_tuner_adap;
68 /* for the I2C transfer */
69 struct i2c_msg msg[2];
70 u8 i2c_write_buffer[4];
71 u8 i2c_read_buffer[2];
72 struct mutex i2c_buffer_lock;
75 enum dib7000p_power_mode {
76 DIB7000P_POWER_ALL = 0,
77 DIB7000P_POWER_ANALOG_ADC,
78 DIB7000P_POWER_INTERFACE_ONLY,
81 static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode);
82 static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff);
84 static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
86 u16 ret;
88 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
89 dprintk("could not acquire lock");
90 return 0;
93 state->i2c_write_buffer[0] = reg >> 8;
94 state->i2c_write_buffer[1] = reg & 0xff;
96 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
97 state->msg[0].addr = state->i2c_addr >> 1;
98 state->msg[0].flags = 0;
99 state->msg[0].buf = state->i2c_write_buffer;
100 state->msg[0].len = 2;
101 state->msg[1].addr = state->i2c_addr >> 1;
102 state->msg[1].flags = I2C_M_RD;
103 state->msg[1].buf = state->i2c_read_buffer;
104 state->msg[1].len = 2;
106 if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
107 dprintk("i2c read error on %d", reg);
109 ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
110 mutex_unlock(&state->i2c_buffer_lock);
111 return ret;
114 static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
116 int ret;
118 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
119 dprintk("could not acquire lock");
120 return -EINVAL;
123 state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
124 state->i2c_write_buffer[1] = reg & 0xff;
125 state->i2c_write_buffer[2] = (val >> 8) & 0xff;
126 state->i2c_write_buffer[3] = val & 0xff;
128 memset(&state->msg[0], 0, sizeof(struct i2c_msg));
129 state->msg[0].addr = state->i2c_addr >> 1;
130 state->msg[0].flags = 0;
131 state->msg[0].buf = state->i2c_write_buffer;
132 state->msg[0].len = 4;
134 ret = (i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ?
135 -EREMOTEIO : 0);
136 mutex_unlock(&state->i2c_buffer_lock);
137 return ret;
140 static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf)
142 u16 l = 0, r, *n;
143 n = buf;
144 l = *n++;
145 while (l) {
146 r = *n++;
148 do {
149 dib7000p_write_word(state, r, *n++);
150 r++;
151 } while (--l);
152 l = *n++;
156 static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
158 int ret = 0;
159 u16 outreg, fifo_threshold, smo_mode;
161 outreg = 0;
162 fifo_threshold = 1792;
163 smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
165 dprintk("setting output mode for demod %p to %d", &state->demod, mode);
167 switch (mode) {
168 case OUTMODE_MPEG2_PAR_GATED_CLK:
169 outreg = (1 << 10); /* 0x0400 */
170 break;
171 case OUTMODE_MPEG2_PAR_CONT_CLK:
172 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
173 break;
174 case OUTMODE_MPEG2_SERIAL:
175 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */
176 break;
177 case OUTMODE_DIVERSITY:
178 if (state->cfg.hostbus_diversity)
179 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
180 else
181 outreg = (1 << 11);
182 break;
183 case OUTMODE_MPEG2_FIFO:
184 smo_mode |= (3 << 1);
185 fifo_threshold = 512;
186 outreg = (1 << 10) | (5 << 6);
187 break;
188 case OUTMODE_ANALOG_ADC:
189 outreg = (1 << 10) | (3 << 6);
190 break;
191 case OUTMODE_HIGH_Z:
192 outreg = 0;
193 break;
194 default:
195 dprintk("Unhandled output_mode passed to be set for demod %p", &state->demod);
196 break;
199 if (state->cfg.output_mpeg2_in_188_bytes)
200 smo_mode |= (1 << 5);
202 ret |= dib7000p_write_word(state, 235, smo_mode);
203 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
204 if (state->version != SOC7090)
205 ret |= dib7000p_write_word(state, 1286, outreg); /* P_Div_active */
207 return ret;
210 static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
212 struct dib7000p_state *state = demod->demodulator_priv;
214 if (state->div_force_off) {
215 dprintk("diversity combination deactivated - forced by COFDM parameters");
216 onoff = 0;
217 dib7000p_write_word(state, 207, 0);
218 } else
219 dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
221 state->div_state = (u8) onoff;
223 if (onoff) {
224 dib7000p_write_word(state, 204, 6);
225 dib7000p_write_word(state, 205, 16);
226 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
227 } else {
228 dib7000p_write_word(state, 204, 1);
229 dib7000p_write_word(state, 205, 0);
232 return 0;
235 static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode)
237 /* by default everything is powered off */
238 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0x0007, reg_899 = 0x0003, reg_1280 = (0xfe00) | (dib7000p_read_word(state, 1280) & 0x01ff);
240 /* now, depending on the requested mode, we power on */
241 switch (mode) {
242 /* power up everything in the demod */
243 case DIB7000P_POWER_ALL:
244 reg_774 = 0x0000;
245 reg_775 = 0x0000;
246 reg_776 = 0x0;
247 reg_899 = 0x0;
248 if (state->version == SOC7090)
249 reg_1280 &= 0x001f;
250 else
251 reg_1280 &= 0x01ff;
252 break;
254 case DIB7000P_POWER_ANALOG_ADC:
255 /* dem, cfg, iqc, sad, agc */
256 reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
257 /* nud */
258 reg_776 &= ~((1 << 0));
259 /* Dout */
260 if (state->version != SOC7090)
261 reg_1280 &= ~((1 << 11));
262 reg_1280 &= ~(1 << 6);
263 /* fall through wanted to enable the interfaces */
265 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
266 case DIB7000P_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C */
267 if (state->version == SOC7090)
268 reg_1280 &= ~((1 << 7) | (1 << 5));
269 else
270 reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
271 break;
273 /* TODO following stuff is just converted from the dib7000-driver - check when is used what */
276 dib7000p_write_word(state, 774, reg_774);
277 dib7000p_write_word(state, 775, reg_775);
278 dib7000p_write_word(state, 776, reg_776);
279 dib7000p_write_word(state, 899, reg_899);
280 dib7000p_write_word(state, 1280, reg_1280);
282 return 0;
285 static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no)
287 u16 reg_908 = dib7000p_read_word(state, 908), reg_909 = dib7000p_read_word(state, 909);
288 u16 reg;
290 switch (no) {
291 case DIBX000_SLOW_ADC_ON:
292 if (state->version == SOC7090) {
293 reg = dib7000p_read_word(state, 1925);
295 dib7000p_write_word(state, 1925, reg | (1 << 4) | (1 << 2)); /* en_slowAdc = 1 & reset_sladc = 1 */
297 reg = dib7000p_read_word(state, 1925); /* read acces to make it works... strange ... */
298 msleep(200);
299 dib7000p_write_word(state, 1925, reg & ~(1 << 4)); /* en_slowAdc = 1 & reset_sladc = 0 */
301 reg = dib7000p_read_word(state, 72) & ~((0x3 << 14) | (0x3 << 12));
302 dib7000p_write_word(state, 72, reg | (1 << 14) | (3 << 12) | 524); /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ; (Vin2 = Vcm) */
303 } else {
304 reg_909 |= (1 << 1) | (1 << 0);
305 dib7000p_write_word(state, 909, reg_909);
306 reg_909 &= ~(1 << 1);
308 break;
310 case DIBX000_SLOW_ADC_OFF:
311 if (state->version == SOC7090) {
312 reg = dib7000p_read_word(state, 1925);
313 dib7000p_write_word(state, 1925, (reg & ~(1 << 2)) | (1 << 4)); /* reset_sladc = 1 en_slowAdc = 0 */
314 } else
315 reg_909 |= (1 << 1) | (1 << 0);
316 break;
318 case DIBX000_ADC_ON:
319 reg_908 &= 0x0fff;
320 reg_909 &= 0x0003;
321 break;
323 case DIBX000_ADC_OFF:
324 reg_908 |= (1 << 14) | (1 << 13) | (1 << 12);
325 reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
326 break;
328 case DIBX000_VBG_ENABLE:
329 reg_908 &= ~(1 << 15);
330 break;
332 case DIBX000_VBG_DISABLE:
333 reg_908 |= (1 << 15);
334 break;
336 default:
337 break;
340 // dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
342 reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4;
343 reg_908 |= (state->cfg.enable_current_mirror & 1) << 7;
345 dib7000p_write_word(state, 908, reg_908);
346 dib7000p_write_word(state, 909, reg_909);
349 static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
351 u32 timf;
353 // store the current bandwidth for later use
354 state->current_bandwidth = bw;
356 if (state->timf == 0) {
357 dprintk("using default timf");
358 timf = state->cfg.bw->timf;
359 } else {
360 dprintk("using updated timf");
361 timf = state->timf;
364 timf = timf * (bw / 50) / 160;
366 dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
367 dib7000p_write_word(state, 24, (u16) ((timf) & 0xffff));
369 return 0;
372 static int dib7000p_sad_calib(struct dib7000p_state *state)
374 /* internal */
375 dib7000p_write_word(state, 73, (0 << 1) | (0 << 0));
377 if (state->version == SOC7090)
378 dib7000p_write_word(state, 74, 2048);
379 else
380 dib7000p_write_word(state, 74, 776);
382 /* do the calibration */
383 dib7000p_write_word(state, 73, (1 << 0));
384 dib7000p_write_word(state, 73, (0 << 0));
386 msleep(1);
388 return 0;
391 int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
393 struct dib7000p_state *state = demod->demodulator_priv;
394 if (value > 4095)
395 value = 4095;
396 state->wbd_ref = value;
397 return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value);
399 EXPORT_SYMBOL(dib7000p_set_wbd_ref);
401 static void dib7000p_reset_pll(struct dib7000p_state *state)
403 struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
404 u16 clk_cfg0;
406 if (state->version == SOC7090) {
407 dib7000p_write_word(state, 1856, (!bw->pll_reset << 13) | (bw->pll_range << 12) | (bw->pll_ratio << 6) | (bw->pll_prediv));
409 while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
412 dib7000p_write_word(state, 1857, dib7000p_read_word(state, 1857) | (!bw->pll_bypass << 15));
413 } else {
414 /* force PLL bypass */
415 clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) |
416 (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0);
418 dib7000p_write_word(state, 900, clk_cfg0);
420 /* P_pll_cfg */
421 dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset);
422 clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff);
423 dib7000p_write_word(state, 900, clk_cfg0);
426 dib7000p_write_word(state, 18, (u16) (((bw->internal * 1000) >> 16) & 0xffff));
427 dib7000p_write_word(state, 19, (u16) ((bw->internal * 1000) & 0xffff));
428 dib7000p_write_word(state, 21, (u16) ((bw->ifreq >> 16) & 0xffff));
429 dib7000p_write_word(state, 22, (u16) ((bw->ifreq) & 0xffff));
431 dib7000p_write_word(state, 72, bw->sad_cfg);
434 static u32 dib7000p_get_internal_freq(struct dib7000p_state *state)
436 u32 internal = (u32) dib7000p_read_word(state, 18) << 16;
437 internal |= (u32) dib7000p_read_word(state, 19);
438 internal /= 1000;
440 return internal;
443 int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
445 struct dib7000p_state *state = fe->demodulator_priv;
446 u16 reg_1857, reg_1856 = dib7000p_read_word(state, 1856);
447 u8 loopdiv, prediv;
448 u32 internal, xtal;
450 /* get back old values */
451 prediv = reg_1856 & 0x3f;
452 loopdiv = (reg_1856 >> 6) & 0x3f;
454 if ((bw != NULL) && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) {
455 dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio);
456 reg_1856 &= 0xf000;
457 reg_1857 = dib7000p_read_word(state, 1857);
458 dib7000p_write_word(state, 1857, reg_1857 & ~(1 << 15));
460 dib7000p_write_word(state, 1856, reg_1856 | ((bw->pll_ratio & 0x3f) << 6) | (bw->pll_prediv & 0x3f));
462 /* write new system clk into P_sec_len */
463 internal = dib7000p_get_internal_freq(state);
464 xtal = (internal / loopdiv) * prediv;
465 internal = 1000 * (xtal / bw->pll_prediv) * bw->pll_ratio; /* new internal */
466 dib7000p_write_word(state, 18, (u16) ((internal >> 16) & 0xffff));
467 dib7000p_write_word(state, 19, (u16) (internal & 0xffff));
469 dib7000p_write_word(state, 1857, reg_1857 | (1 << 15));
471 while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
472 dprintk("Waiting for PLL to lock");
474 return 0;
476 return -EIO;
478 EXPORT_SYMBOL(dib7000p_update_pll);
480 static int dib7000p_reset_gpio(struct dib7000p_state *st)
482 /* reset the GPIOs */
483 dprintk("gpio dir: %x: val: %x, pwm_pos: %x", st->gpio_dir, st->gpio_val, st->cfg.gpio_pwm_pos);
485 dib7000p_write_word(st, 1029, st->gpio_dir);
486 dib7000p_write_word(st, 1030, st->gpio_val);
488 /* TODO 1031 is P_gpio_od */
490 dib7000p_write_word(st, 1032, st->cfg.gpio_pwm_pos);
492 dib7000p_write_word(st, 1037, st->cfg.pwm_freq_div);
493 return 0;
496 static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val)
498 st->gpio_dir = dib7000p_read_word(st, 1029);
499 st->gpio_dir &= ~(1 << num); /* reset the direction bit */
500 st->gpio_dir |= (dir & 0x1) << num; /* set the new direction */
501 dib7000p_write_word(st, 1029, st->gpio_dir);
503 st->gpio_val = dib7000p_read_word(st, 1030);
504 st->gpio_val &= ~(1 << num); /* reset the direction bit */
505 st->gpio_val |= (val & 0x01) << num; /* set the new value */
506 dib7000p_write_word(st, 1030, st->gpio_val);
508 return 0;
511 int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val)
513 struct dib7000p_state *state = demod->demodulator_priv;
514 return dib7000p_cfg_gpio(state, num, dir, val);
516 EXPORT_SYMBOL(dib7000p_set_gpio);
518 static u16 dib7000p_defaults[] = {
519 // auto search configuration
520 3, 2,
521 0x0004,
522 0x1000,
523 0x0814, /* Equal Lock */
525 12, 6,
526 0x001b,
527 0x7740,
528 0x005b,
529 0x8d80,
530 0x01c9,
531 0xc380,
532 0x0000,
533 0x0080,
534 0x0000,
535 0x0090,
536 0x0001,
537 0xd4c0,
539 1, 26,
540 0x6680,
542 /* set ADC level to -16 */
543 11, 79,
544 (1 << 13) - 825 - 117,
545 (1 << 13) - 837 - 117,
546 (1 << 13) - 811 - 117,
547 (1 << 13) - 766 - 117,
548 (1 << 13) - 737 - 117,
549 (1 << 13) - 693 - 117,
550 (1 << 13) - 648 - 117,
551 (1 << 13) - 619 - 117,
552 (1 << 13) - 575 - 117,
553 (1 << 13) - 531 - 117,
554 (1 << 13) - 501 - 117,
556 1, 142,
557 0x0410,
559 /* disable power smoothing */
560 8, 145,
570 1, 154,
571 1 << 13,
573 1, 168,
574 0x0ccd,
576 1, 183,
577 0x200f,
579 1, 212,
580 0x169,
582 5, 187,
583 0x023d,
584 0x00a4,
585 0x00a4,
586 0x7ff0,
587 0x3ccc,
589 1, 198,
590 0x800,
592 1, 222,
593 0x0010,
595 1, 235,
596 0x0062,
598 2, 901,
599 0x0006,
600 (3 << 10) | (1 << 6),
602 1, 905,
603 0x2c8e,
608 static int dib7000p_demod_reset(struct dib7000p_state *state)
610 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
612 if (state->version == SOC7090)
613 dibx000_reset_i2c_master(&state->i2c_master);
615 dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE);
617 /* restart all parts */
618 dib7000p_write_word(state, 770, 0xffff);
619 dib7000p_write_word(state, 771, 0xffff);
620 dib7000p_write_word(state, 772, 0x001f);
621 dib7000p_write_word(state, 898, 0x0003);
622 dib7000p_write_word(state, 1280, 0x001f - ((1 << 4) | (1 << 3)));
624 dib7000p_write_word(state, 770, 0);
625 dib7000p_write_word(state, 771, 0);
626 dib7000p_write_word(state, 772, 0);
627 dib7000p_write_word(state, 898, 0);
628 dib7000p_write_word(state, 1280, 0);
630 /* default */
631 dib7000p_reset_pll(state);
633 if (dib7000p_reset_gpio(state) != 0)
634 dprintk("GPIO reset was not successful.");
636 if (state->version == SOC7090) {
637 dib7000p_write_word(state, 899, 0);
639 /* impulse noise */
640 dib7000p_write_word(state, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */
641 dib7000p_write_word(state, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */
642 dib7000p_write_word(state, 44, 300); /* 300 fag P_iqc_dect_min = +280 */
643 dib7000p_write_word(state, 273, (1<<6) | 30);
645 if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
646 dprintk("OUTPUT_MODE could not be reset.");
648 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
649 dib7000p_sad_calib(state);
650 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
652 /* unforce divstr regardless whether i2c enumeration was done or not */
653 dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1));
655 dib7000p_set_bandwidth(state, 8000);
657 if (state->version == SOC7090) {
658 dib7000p_write_word(state, 36, 0x5755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */
659 } else {
660 if (state->cfg.tuner_is_baseband)
661 dib7000p_write_word(state, 36, 0x0755);
662 else
663 dib7000p_write_word(state, 36, 0x1f55);
666 dib7000p_write_tab(state, dib7000p_defaults);
668 dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
670 return 0;
673 static void dib7000p_pll_clk_cfg(struct dib7000p_state *state)
675 u16 tmp = 0;
676 tmp = dib7000p_read_word(state, 903);
677 dib7000p_write_word(state, 903, (tmp | 0x1));
678 tmp = dib7000p_read_word(state, 900);
679 dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6));
682 static void dib7000p_restart_agc(struct dib7000p_state *state)
684 // P_restart_iqc & P_restart_agc
685 dib7000p_write_word(state, 770, (1 << 11) | (1 << 9));
686 dib7000p_write_word(state, 770, 0x0000);
689 static int dib7000p_update_lna(struct dib7000p_state *state)
691 u16 dyn_gain;
693 if (state->cfg.update_lna) {
694 dyn_gain = dib7000p_read_word(state, 394);
695 if (state->cfg.update_lna(&state->demod, dyn_gain)) {
696 dib7000p_restart_agc(state);
697 return 1;
701 return 0;
704 static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
706 struct dibx000_agc_config *agc = NULL;
707 int i;
708 if (state->current_band == band && state->current_agc != NULL)
709 return 0;
710 state->current_band = band;
712 for (i = 0; i < state->cfg.agc_config_count; i++)
713 if (state->cfg.agc[i].band_caps & band) {
714 agc = &state->cfg.agc[i];
715 break;
718 if (agc == NULL) {
719 dprintk("no valid AGC configuration found for band 0x%02x", band);
720 return -EINVAL;
723 state->current_agc = agc;
725 /* AGC */
726 dib7000p_write_word(state, 75, agc->setup);
727 dib7000p_write_word(state, 76, agc->inv_gain);
728 dib7000p_write_word(state, 77, agc->time_stabiliz);
729 dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);
731 // Demod AGC loop configuration
732 dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);
733 dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp);
735 /* AGC continued */
736 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
737 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
739 if (state->wbd_ref != 0)
740 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref);
741 else
742 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref);
744 dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
746 dib7000p_write_word(state, 107, agc->agc1_max);
747 dib7000p_write_word(state, 108, agc->agc1_min);
748 dib7000p_write_word(state, 109, agc->agc2_max);
749 dib7000p_write_word(state, 110, agc->agc2_min);
750 dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
751 dib7000p_write_word(state, 112, agc->agc1_pt3);
752 dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
753 dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
754 dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
755 return 0;
758 static void dib7000p_set_dds(struct dib7000p_state *state, s32 offset_khz)
760 u32 internal = dib7000p_get_internal_freq(state);
761 s32 unit_khz_dds_val = 67108864 / (internal); /* 2**26 / Fsampling is the unit 1KHz offset */
762 u32 abs_offset_khz = ABS(offset_khz);
763 u32 dds = state->cfg.bw->ifreq & 0x1ffffff;
764 u8 invert = !!(state->cfg.bw->ifreq & (1 << 25));
766 dprintk("setting a frequency offset of %dkHz internal freq = %d invert = %d", offset_khz, internal, invert);
768 if (offset_khz < 0)
769 unit_khz_dds_val *= -1;
771 /* IF tuner */
772 if (invert)
773 dds -= (abs_offset_khz * unit_khz_dds_val); /* /100 because of /100 on the unit_khz_dds_val line calc for better accuracy */
774 else
775 dds += (abs_offset_khz * unit_khz_dds_val);
777 if (abs_offset_khz <= (internal / 2)) { /* Max dds offset is the half of the demod freq */
778 dib7000p_write_word(state, 21, (u16) (((dds >> 16) & 0x1ff) | (0 << 10) | (invert << 9)));
779 dib7000p_write_word(state, 22, (u16) (dds & 0xffff));
783 static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
785 struct dib7000p_state *state = demod->demodulator_priv;
786 int ret = -1;
787 u8 *agc_state = &state->agc_state;
788 u8 agc_split;
789 u16 reg;
790 u32 upd_demod_gain_period = 0x1000;
792 switch (state->agc_state) {
793 case 0:
794 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
795 if (state->version == SOC7090) {
796 reg = dib7000p_read_word(state, 0x79b) & 0xff00;
797 dib7000p_write_word(state, 0x79a, upd_demod_gain_period & 0xFFFF); /* lsb */
798 dib7000p_write_word(state, 0x79b, reg | (1 << 14) | ((upd_demod_gain_period >> 16) & 0xFF));
800 /* enable adc i & q */
801 reg = dib7000p_read_word(state, 0x780);
802 dib7000p_write_word(state, 0x780, (reg | (0x3)) & (~(1 << 7)));
803 } else {
804 dib7000p_set_adc_state(state, DIBX000_ADC_ON);
805 dib7000p_pll_clk_cfg(state);
808 if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency / 1000)) != 0)
809 return -1;
811 dib7000p_set_dds(state, 0);
812 ret = 7;
813 (*agc_state)++;
814 break;
816 case 1:
817 if (state->cfg.agc_control)
818 state->cfg.agc_control(&state->demod, 1);
820 dib7000p_write_word(state, 78, 32768);
821 if (!state->current_agc->perform_agc_softsplit) {
822 /* we are using the wbd - so slow AGC startup */
823 /* force 0 split on WBD and restart AGC */
824 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));
825 (*agc_state)++;
826 ret = 5;
827 } else {
828 /* default AGC startup */
829 (*agc_state) = 4;
830 /* wait AGC rough lock time */
831 ret = 7;
834 dib7000p_restart_agc(state);
835 break;
837 case 2: /* fast split search path after 5sec */
838 dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4)); /* freeze AGC loop */
839 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */
840 (*agc_state)++;
841 ret = 14;
842 break;
844 case 3: /* split search ended */
845 agc_split = (u8) dib7000p_read_word(state, 396); /* store the split value for the next time */
846 dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */
848 dib7000p_write_word(state, 75, state->current_agc->setup); /* std AGC loop */
849 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
851 dib7000p_restart_agc(state);
853 dprintk("SPLIT %p: %hd", demod, agc_split);
855 (*agc_state)++;
856 ret = 5;
857 break;
859 case 4: /* LNA startup */
860 ret = 7;
862 if (dib7000p_update_lna(state))
863 ret = 5;
864 else
865 (*agc_state)++;
866 break;
868 case 5:
869 if (state->cfg.agc_control)
870 state->cfg.agc_control(&state->demod, 0);
871 (*agc_state)++;
872 break;
873 default:
874 break;
876 return ret;
879 static void dib7000p_update_timf(struct dib7000p_state *state)
881 u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428);
882 state->timf = timf * 160 / (state->current_bandwidth / 50);
883 dib7000p_write_word(state, 23, (u16) (timf >> 16));
884 dib7000p_write_word(state, 24, (u16) (timf & 0xffff));
885 dprintk("updated timf_frequency: %d (default: %d)", state->timf, state->cfg.bw->timf);
889 u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
891 struct dib7000p_state *state = fe->demodulator_priv;
892 switch (op) {
893 case DEMOD_TIMF_SET:
894 state->timf = timf;
895 break;
896 case DEMOD_TIMF_UPDATE:
897 dib7000p_update_timf(state);
898 break;
899 case DEMOD_TIMF_GET:
900 break;
902 dib7000p_set_bandwidth(state, state->current_bandwidth);
903 return state->timf;
905 EXPORT_SYMBOL(dib7000p_ctrl_timf);
907 static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq)
909 u16 value, est[4];
911 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
913 /* nfft, guard, qam, alpha */
914 value = 0;
915 switch (ch->u.ofdm.transmission_mode) {
916 case TRANSMISSION_MODE_2K:
917 value |= (0 << 7);
918 break;
919 case TRANSMISSION_MODE_4K:
920 value |= (2 << 7);
921 break;
922 default:
923 case TRANSMISSION_MODE_8K:
924 value |= (1 << 7);
925 break;
927 switch (ch->u.ofdm.guard_interval) {
928 case GUARD_INTERVAL_1_32:
929 value |= (0 << 5);
930 break;
931 case GUARD_INTERVAL_1_16:
932 value |= (1 << 5);
933 break;
934 case GUARD_INTERVAL_1_4:
935 value |= (3 << 5);
936 break;
937 default:
938 case GUARD_INTERVAL_1_8:
939 value |= (2 << 5);
940 break;
942 switch (ch->u.ofdm.constellation) {
943 case QPSK:
944 value |= (0 << 3);
945 break;
946 case QAM_16:
947 value |= (1 << 3);
948 break;
949 default:
950 case QAM_64:
951 value |= (2 << 3);
952 break;
954 switch (HIERARCHY_1) {
955 case HIERARCHY_2:
956 value |= 2;
957 break;
958 case HIERARCHY_4:
959 value |= 4;
960 break;
961 default:
962 case HIERARCHY_1:
963 value |= 1;
964 break;
966 dib7000p_write_word(state, 0, value);
967 dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */
969 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
970 value = 0;
971 if (1 != 0)
972 value |= (1 << 6);
973 if (ch->u.ofdm.hierarchy_information == 1)
974 value |= (1 << 4);
975 if (1 == 1)
976 value |= 1;
977 switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
978 case FEC_2_3:
979 value |= (2 << 1);
980 break;
981 case FEC_3_4:
982 value |= (3 << 1);
983 break;
984 case FEC_5_6:
985 value |= (5 << 1);
986 break;
987 case FEC_7_8:
988 value |= (7 << 1);
989 break;
990 default:
991 case FEC_1_2:
992 value |= (1 << 1);
993 break;
995 dib7000p_write_word(state, 208, value);
997 /* offset loop parameters */
998 dib7000p_write_word(state, 26, 0x6680);
999 dib7000p_write_word(state, 32, 0x0003);
1000 dib7000p_write_word(state, 29, 0x1273);
1001 dib7000p_write_word(state, 33, 0x0005);
1003 /* P_dvsy_sync_wait */
1004 switch (ch->u.ofdm.transmission_mode) {
1005 case TRANSMISSION_MODE_8K:
1006 value = 256;
1007 break;
1008 case TRANSMISSION_MODE_4K:
1009 value = 128;
1010 break;
1011 case TRANSMISSION_MODE_2K:
1012 default:
1013 value = 64;
1014 break;
1016 switch (ch->u.ofdm.guard_interval) {
1017 case GUARD_INTERVAL_1_16:
1018 value *= 2;
1019 break;
1020 case GUARD_INTERVAL_1_8:
1021 value *= 4;
1022 break;
1023 case GUARD_INTERVAL_1_4:
1024 value *= 8;
1025 break;
1026 default:
1027 case GUARD_INTERVAL_1_32:
1028 value *= 1;
1029 break;
1031 if (state->cfg.diversity_delay == 0)
1032 state->div_sync_wait = (value * 3) / 2 + 48;
1033 else
1034 state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay;
1036 /* deactive the possibility of diversity reception if extended interleaver */
1037 state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K;
1038 dib7000p_set_diversity_in(&state->demod, state->div_state);
1040 /* channel estimation fine configuration */
1041 switch (ch->u.ofdm.constellation) {
1042 case QAM_64:
1043 est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
1044 est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
1045 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1046 est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
1047 break;
1048 case QAM_16:
1049 est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
1050 est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
1051 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1052 est[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
1053 break;
1054 default:
1055 est[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
1056 est[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
1057 est[2] = 0x0333; /* P_adp_regul_ext 0.1 */
1058 est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
1059 break;
1061 for (value = 0; value < 4; value++)
1062 dib7000p_write_word(state, 187 + value, est[value]);
1065 static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
1067 struct dib7000p_state *state = demod->demodulator_priv;
1068 struct dvb_frontend_parameters schan;
1069 u32 value, factor;
1070 u32 internal = dib7000p_get_internal_freq(state);
1072 schan = *ch;
1073 schan.u.ofdm.constellation = QAM_64;
1074 schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
1075 schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
1076 schan.u.ofdm.code_rate_HP = FEC_2_3;
1077 schan.u.ofdm.code_rate_LP = FEC_3_4;
1078 schan.u.ofdm.hierarchy_information = 0;
1080 dib7000p_set_channel(state, &schan, 7);
1082 factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth);
1083 if (factor >= 5000)
1084 factor = 1;
1085 else
1086 factor = 6;
1088 value = 30 * internal * factor;
1089 dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff));
1090 dib7000p_write_word(state, 7, (u16) (value & 0xffff));
1091 value = 100 * internal * factor;
1092 dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff));
1093 dib7000p_write_word(state, 9, (u16) (value & 0xffff));
1094 value = 500 * internal * factor;
1095 dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff));
1096 dib7000p_write_word(state, 11, (u16) (value & 0xffff));
1098 value = dib7000p_read_word(state, 0);
1099 dib7000p_write_word(state, 0, (u16) ((1 << 9) | value));
1100 dib7000p_read_word(state, 1284);
1101 dib7000p_write_word(state, 0, (u16) value);
1103 return 0;
1106 static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod)
1108 struct dib7000p_state *state = demod->demodulator_priv;
1109 u16 irq_pending = dib7000p_read_word(state, 1284);
1111 if (irq_pending & 0x1)
1112 return 1;
1114 if (irq_pending & 0x2)
1115 return 2;
1117 return 0;
1120 static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw)
1122 static s16 notch[] = { 16143, 14402, 12238, 9713, 6902, 3888, 759, -2392 };
1123 static u8 sine[] = { 0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
1124 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
1125 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
1126 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
1127 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
1128 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
1129 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
1130 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
1131 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
1132 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
1133 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
1134 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
1135 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
1136 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
1137 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
1138 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1139 255, 255, 255, 255, 255, 255
1142 u32 xtal = state->cfg.bw->xtal_hz / 1000;
1143 int f_rel = DIV_ROUND_CLOSEST(rf_khz, xtal) * xtal - rf_khz;
1144 int k;
1145 int coef_re[8], coef_im[8];
1146 int bw_khz = bw;
1147 u32 pha;
1149 dprintk("relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal);
1151 if (f_rel < -bw_khz / 2 || f_rel > bw_khz / 2)
1152 return;
1154 bw_khz /= 100;
1156 dib7000p_write_word(state, 142, 0x0610);
1158 for (k = 0; k < 8; k++) {
1159 pha = ((f_rel * (k + 1) * 112 * 80 / bw_khz) / 1000) & 0x3ff;
1161 if (pha == 0) {
1162 coef_re[k] = 256;
1163 coef_im[k] = 0;
1164 } else if (pha < 256) {
1165 coef_re[k] = sine[256 - (pha & 0xff)];
1166 coef_im[k] = sine[pha & 0xff];
1167 } else if (pha == 256) {
1168 coef_re[k] = 0;
1169 coef_im[k] = 256;
1170 } else if (pha < 512) {
1171 coef_re[k] = -sine[pha & 0xff];
1172 coef_im[k] = sine[256 - (pha & 0xff)];
1173 } else if (pha == 512) {
1174 coef_re[k] = -256;
1175 coef_im[k] = 0;
1176 } else if (pha < 768) {
1177 coef_re[k] = -sine[256 - (pha & 0xff)];
1178 coef_im[k] = -sine[pha & 0xff];
1179 } else if (pha == 768) {
1180 coef_re[k] = 0;
1181 coef_im[k] = -256;
1182 } else {
1183 coef_re[k] = sine[pha & 0xff];
1184 coef_im[k] = -sine[256 - (pha & 0xff)];
1187 coef_re[k] *= notch[k];
1188 coef_re[k] += (1 << 14);
1189 if (coef_re[k] >= (1 << 24))
1190 coef_re[k] = (1 << 24) - 1;
1191 coef_re[k] /= (1 << 15);
1193 coef_im[k] *= notch[k];
1194 coef_im[k] += (1 << 14);
1195 if (coef_im[k] >= (1 << 24))
1196 coef_im[k] = (1 << 24) - 1;
1197 coef_im[k] /= (1 << 15);
1199 dprintk("PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]);
1201 dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
1202 dib7000p_write_word(state, 144, coef_im[k] & 0x3ff);
1203 dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
1205 dib7000p_write_word(state, 143, 0);
1208 static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
1210 struct dib7000p_state *state = demod->demodulator_priv;
1211 u16 tmp = 0;
1213 if (ch != NULL)
1214 dib7000p_set_channel(state, ch, 0);
1215 else
1216 return -EINVAL;
1218 // restart demod
1219 dib7000p_write_word(state, 770, 0x4000);
1220 dib7000p_write_word(state, 770, 0x0000);
1221 msleep(45);
1223 /* 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 */
1224 tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
1225 if (state->sfn_workaround_active) {
1226 dprintk("SFN workaround is active");
1227 tmp |= (1 << 9);
1228 dib7000p_write_word(state, 166, 0x4000);
1229 } else {
1230 dib7000p_write_word(state, 166, 0x0000);
1232 dib7000p_write_word(state, 29, tmp);
1234 // never achieved a lock with that bandwidth so far - wait for osc-freq to update
1235 if (state->timf == 0)
1236 msleep(200);
1238 /* offset loop parameters */
1240 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
1241 tmp = (6 << 8) | 0x80;
1242 switch (ch->u.ofdm.transmission_mode) {
1243 case TRANSMISSION_MODE_2K:
1244 tmp |= (2 << 12);
1245 break;
1246 case TRANSMISSION_MODE_4K:
1247 tmp |= (3 << 12);
1248 break;
1249 default:
1250 case TRANSMISSION_MODE_8K:
1251 tmp |= (4 << 12);
1252 break;
1254 dib7000p_write_word(state, 26, tmp); /* timf_a(6xxx) */
1256 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1257 tmp = (0 << 4);
1258 switch (ch->u.ofdm.transmission_mode) {
1259 case TRANSMISSION_MODE_2K:
1260 tmp |= 0x6;
1261 break;
1262 case TRANSMISSION_MODE_4K:
1263 tmp |= 0x7;
1264 break;
1265 default:
1266 case TRANSMISSION_MODE_8K:
1267 tmp |= 0x8;
1268 break;
1270 dib7000p_write_word(state, 32, tmp);
1272 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1273 tmp = (0 << 4);
1274 switch (ch->u.ofdm.transmission_mode) {
1275 case TRANSMISSION_MODE_2K:
1276 tmp |= 0x6;
1277 break;
1278 case TRANSMISSION_MODE_4K:
1279 tmp |= 0x7;
1280 break;
1281 default:
1282 case TRANSMISSION_MODE_8K:
1283 tmp |= 0x8;
1284 break;
1286 dib7000p_write_word(state, 33, tmp);
1288 tmp = dib7000p_read_word(state, 509);
1289 if (!((tmp >> 6) & 0x1)) {
1290 /* restart the fec */
1291 tmp = dib7000p_read_word(state, 771);
1292 dib7000p_write_word(state, 771, tmp | (1 << 1));
1293 dib7000p_write_word(state, 771, tmp);
1294 msleep(40);
1295 tmp = dib7000p_read_word(state, 509);
1297 // we achieved a lock - it's time to update the osc freq
1298 if ((tmp >> 6) & 0x1) {
1299 dib7000p_update_timf(state);
1300 /* P_timf_alpha += 2 */
1301 tmp = dib7000p_read_word(state, 26);
1302 dib7000p_write_word(state, 26, (tmp & ~(0xf << 12)) | ((((tmp >> 12) & 0xf) + 5) << 12));
1305 if (state->cfg.spur_protect)
1306 dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1308 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1309 return 0;
1312 static int dib7000p_wakeup(struct dvb_frontend *demod)
1314 struct dib7000p_state *state = demod->demodulator_priv;
1315 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
1316 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
1317 if (state->version == SOC7090)
1318 dib7000p_sad_calib(state);
1319 return 0;
1322 static int dib7000p_sleep(struct dvb_frontend *demod)
1324 struct dib7000p_state *state = demod->demodulator_priv;
1325 if (state->version == SOC7090)
1326 return dib7090_set_output_mode(demod, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1327 return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1330 static int dib7000p_identify(struct dib7000p_state *st)
1332 u16 value;
1333 dprintk("checking demod on I2C address: %d (%x)", st->i2c_addr, st->i2c_addr);
1335 if ((value = dib7000p_read_word(st, 768)) != 0x01b3) {
1336 dprintk("wrong Vendor ID (read=0x%x)", value);
1337 return -EREMOTEIO;
1340 if ((value = dib7000p_read_word(st, 769)) != 0x4000) {
1341 dprintk("wrong Device ID (%x)", value);
1342 return -EREMOTEIO;
1345 return 0;
1348 static int dib7000p_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1350 struct dib7000p_state *state = fe->demodulator_priv;
1351 u16 tps = dib7000p_read_word(state, 463);
1353 fep->inversion = INVERSION_AUTO;
1355 fep->u.ofdm.bandwidth = BANDWIDTH_TO_INDEX(state->current_bandwidth);
1357 switch ((tps >> 8) & 0x3) {
1358 case 0:
1359 fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
1360 break;
1361 case 1:
1362 fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
1363 break;
1364 /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */
1367 switch (tps & 0x3) {
1368 case 0:
1369 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
1370 break;
1371 case 1:
1372 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
1373 break;
1374 case 2:
1375 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
1376 break;
1377 case 3:
1378 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
1379 break;
1382 switch ((tps >> 14) & 0x3) {
1383 case 0:
1384 fep->u.ofdm.constellation = QPSK;
1385 break;
1386 case 1:
1387 fep->u.ofdm.constellation = QAM_16;
1388 break;
1389 case 2:
1390 default:
1391 fep->u.ofdm.constellation = QAM_64;
1392 break;
1395 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1396 /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1398 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
1399 switch ((tps >> 5) & 0x7) {
1400 case 1:
1401 fep->u.ofdm.code_rate_HP = FEC_1_2;
1402 break;
1403 case 2:
1404 fep->u.ofdm.code_rate_HP = FEC_2_3;
1405 break;
1406 case 3:
1407 fep->u.ofdm.code_rate_HP = FEC_3_4;
1408 break;
1409 case 5:
1410 fep->u.ofdm.code_rate_HP = FEC_5_6;
1411 break;
1412 case 7:
1413 default:
1414 fep->u.ofdm.code_rate_HP = FEC_7_8;
1415 break;
1419 switch ((tps >> 2) & 0x7) {
1420 case 1:
1421 fep->u.ofdm.code_rate_LP = FEC_1_2;
1422 break;
1423 case 2:
1424 fep->u.ofdm.code_rate_LP = FEC_2_3;
1425 break;
1426 case 3:
1427 fep->u.ofdm.code_rate_LP = FEC_3_4;
1428 break;
1429 case 5:
1430 fep->u.ofdm.code_rate_LP = FEC_5_6;
1431 break;
1432 case 7:
1433 default:
1434 fep->u.ofdm.code_rate_LP = FEC_7_8;
1435 break;
1438 /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */
1440 return 0;
1443 static int dib7000p_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1445 struct dib7000p_state *state = fe->demodulator_priv;
1446 int time, ret;
1448 if (state->version == SOC7090) {
1449 dib7090_set_diversity_in(fe, 0);
1450 dib7090_set_output_mode(fe, OUTMODE_HIGH_Z);
1451 } else
1452 dib7000p_set_output_mode(state, OUTMODE_HIGH_Z);
1454 /* maybe the parameter has been changed */
1455 state->sfn_workaround_active = buggy_sfn_workaround;
1457 if (fe->ops.tuner_ops.set_params)
1458 fe->ops.tuner_ops.set_params(fe, fep);
1460 /* start up the AGC */
1461 state->agc_state = 0;
1462 do {
1463 time = dib7000p_agc_startup(fe, fep);
1464 if (time != -1)
1465 msleep(time);
1466 } while (time != -1);
1468 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
1469 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || fep->u.ofdm.constellation == QAM_AUTO || fep->u.ofdm.code_rate_HP == FEC_AUTO) {
1470 int i = 800, found;
1472 dib7000p_autosearch_start(fe, fep);
1473 do {
1474 msleep(1);
1475 found = dib7000p_autosearch_is_irq(fe);
1476 } while (found == 0 && i--);
1478 dprintk("autosearch returns: %d", found);
1479 if (found == 0 || found == 1)
1480 return 0;
1482 dib7000p_get_frontend(fe, fep);
1485 ret = dib7000p_tune(fe, fep);
1487 /* make this a config parameter */
1488 if (state->version == SOC7090)
1489 dib7090_set_output_mode(fe, state->cfg.output_mode);
1490 else
1491 dib7000p_set_output_mode(state, state->cfg.output_mode);
1493 return ret;
1496 static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t * stat)
1498 struct dib7000p_state *state = fe->demodulator_priv;
1499 u16 lock = dib7000p_read_word(state, 509);
1501 *stat = 0;
1503 if (lock & 0x8000)
1504 *stat |= FE_HAS_SIGNAL;
1505 if (lock & 0x3000)
1506 *stat |= FE_HAS_CARRIER;
1507 if (lock & 0x0100)
1508 *stat |= FE_HAS_VITERBI;
1509 if (lock & 0x0010)
1510 *stat |= FE_HAS_SYNC;
1511 if ((lock & 0x0038) == 0x38)
1512 *stat |= FE_HAS_LOCK;
1514 return 0;
1517 static int dib7000p_read_ber(struct dvb_frontend *fe, u32 * ber)
1519 struct dib7000p_state *state = fe->demodulator_priv;
1520 *ber = (dib7000p_read_word(state, 500) << 16) | dib7000p_read_word(state, 501);
1521 return 0;
1524 static int dib7000p_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
1526 struct dib7000p_state *state = fe->demodulator_priv;
1527 *unc = dib7000p_read_word(state, 506);
1528 return 0;
1531 static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
1533 struct dib7000p_state *state = fe->demodulator_priv;
1534 u16 val = dib7000p_read_word(state, 394);
1535 *strength = 65535 - val;
1536 return 0;
1539 static int dib7000p_read_snr(struct dvb_frontend *fe, u16 * snr)
1541 struct dib7000p_state *state = fe->demodulator_priv;
1542 u16 val;
1543 s32 signal_mant, signal_exp, noise_mant, noise_exp;
1544 u32 result = 0;
1546 val = dib7000p_read_word(state, 479);
1547 noise_mant = (val >> 4) & 0xff;
1548 noise_exp = ((val & 0xf) << 2);
1549 val = dib7000p_read_word(state, 480);
1550 noise_exp += ((val >> 14) & 0x3);
1551 if ((noise_exp & 0x20) != 0)
1552 noise_exp -= 0x40;
1554 signal_mant = (val >> 6) & 0xFF;
1555 signal_exp = (val & 0x3F);
1556 if ((signal_exp & 0x20) != 0)
1557 signal_exp -= 0x40;
1559 if (signal_mant != 0)
1560 result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
1561 else
1562 result = intlog10(2) * 10 * signal_exp - 100;
1564 if (noise_mant != 0)
1565 result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
1566 else
1567 result -= intlog10(2) * 10 * noise_exp - 100;
1569 *snr = result / ((1 << 24) / 10);
1570 return 0;
1573 static int dib7000p_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
1575 tune->min_delay_ms = 1000;
1576 return 0;
1579 static void dib7000p_release(struct dvb_frontend *demod)
1581 struct dib7000p_state *st = demod->demodulator_priv;
1582 dibx000_exit_i2c_master(&st->i2c_master);
1583 i2c_del_adapter(&st->dib7090_tuner_adap);
1584 kfree(st);
1587 int dib7000pc_detection(struct i2c_adapter *i2c_adap)
1589 u8 *tx, *rx;
1590 struct i2c_msg msg[2] = {
1591 {.addr = 18 >> 1, .flags = 0, .len = 2},
1592 {.addr = 18 >> 1, .flags = I2C_M_RD, .len = 2},
1594 int ret = 0;
1596 tx = kzalloc(2*sizeof(u8), GFP_KERNEL);
1597 if (!tx)
1598 return -ENOMEM;
1599 rx = kzalloc(2*sizeof(u8), GFP_KERNEL);
1600 if (!rx) {
1601 ret = -ENOMEM;
1602 goto rx_memory_error;
1605 msg[0].buf = tx;
1606 msg[1].buf = rx;
1608 tx[0] = 0x03;
1609 tx[1] = 0x00;
1611 if (i2c_transfer(i2c_adap, msg, 2) == 2)
1612 if (rx[0] == 0x01 && rx[1] == 0xb3) {
1613 dprintk("-D- DiB7000PC detected");
1614 return 1;
1617 msg[0].addr = msg[1].addr = 0x40;
1619 if (i2c_transfer(i2c_adap, msg, 2) == 2)
1620 if (rx[0] == 0x01 && rx[1] == 0xb3) {
1621 dprintk("-D- DiB7000PC detected");
1622 return 1;
1625 dprintk("-D- DiB7000PC not detected");
1627 kfree(rx);
1628 rx_memory_error:
1629 kfree(tx);
1630 return ret;
1632 EXPORT_SYMBOL(dib7000pc_detection);
1634 struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
1636 struct dib7000p_state *st = demod->demodulator_priv;
1637 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1639 EXPORT_SYMBOL(dib7000p_get_i2c_master);
1641 int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1643 struct dib7000p_state *state = fe->demodulator_priv;
1644 u16 val = dib7000p_read_word(state, 235) & 0xffef;
1645 val |= (onoff & 0x1) << 4;
1646 dprintk("PID filter enabled %d", onoff);
1647 return dib7000p_write_word(state, 235, val);
1649 EXPORT_SYMBOL(dib7000p_pid_filter_ctrl);
1651 int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1653 struct dib7000p_state *state = fe->demodulator_priv;
1654 dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
1655 return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0);
1657 EXPORT_SYMBOL(dib7000p_pid_filter);
1659 int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
1661 struct dib7000p_state *dpst;
1662 int k = 0;
1663 u8 new_addr = 0;
1665 dpst = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
1666 if (!dpst)
1667 return -ENOMEM;
1669 dpst->i2c_adap = i2c;
1670 mutex_init(&dpst->i2c_buffer_lock);
1672 for (k = no_of_demods - 1; k >= 0; k--) {
1673 dpst->cfg = cfg[k];
1675 /* designated i2c address */
1676 if (cfg[k].default_i2c_addr != 0)
1677 new_addr = cfg[k].default_i2c_addr + (k << 1);
1678 else
1679 new_addr = (0x40 + k) << 1;
1680 dpst->i2c_addr = new_addr;
1681 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */
1682 if (dib7000p_identify(dpst) != 0) {
1683 dpst->i2c_addr = default_addr;
1684 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */
1685 if (dib7000p_identify(dpst) != 0) {
1686 dprintk("DiB7000P #%d: not identified\n", k);
1687 kfree(dpst);
1688 return -EIO;
1692 /* start diversity to pull_down div_str - just for i2c-enumeration */
1693 dib7000p_set_output_mode(dpst, OUTMODE_DIVERSITY);
1695 /* set new i2c address and force divstart */
1696 dib7000p_write_word(dpst, 1285, (new_addr << 2) | 0x2);
1698 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
1701 for (k = 0; k < no_of_demods; k++) {
1702 dpst->cfg = cfg[k];
1703 if (cfg[k].default_i2c_addr != 0)
1704 dpst->i2c_addr = (cfg[k].default_i2c_addr + k) << 1;
1705 else
1706 dpst->i2c_addr = (0x40 + k) << 1;
1708 // unforce divstr
1709 dib7000p_write_word(dpst, 1285, dpst->i2c_addr << 2);
1711 /* deactivate div - it was just for i2c-enumeration */
1712 dib7000p_set_output_mode(dpst, OUTMODE_HIGH_Z);
1715 kfree(dpst);
1716 return 0;
1718 EXPORT_SYMBOL(dib7000p_i2c_enumeration);
1720 static const s32 lut_1000ln_mant[] = {
1721 6908, 6956, 7003, 7047, 7090, 7131, 7170, 7208, 7244, 7279, 7313, 7346, 7377, 7408, 7438, 7467, 7495, 7523, 7549, 7575, 7600
1724 static s32 dib7000p_get_adc_power(struct dvb_frontend *fe)
1726 struct dib7000p_state *state = fe->demodulator_priv;
1727 u32 tmp_val = 0, exp = 0, mant = 0;
1728 s32 pow_i;
1729 u16 buf[2];
1730 u8 ix = 0;
1732 buf[0] = dib7000p_read_word(state, 0x184);
1733 buf[1] = dib7000p_read_word(state, 0x185);
1734 pow_i = (buf[0] << 16) | buf[1];
1735 dprintk("raw pow_i = %d", pow_i);
1737 tmp_val = pow_i;
1738 while (tmp_val >>= 1)
1739 exp++;
1741 mant = (pow_i * 1000 / (1 << exp));
1742 dprintk(" mant = %d exp = %d", mant / 1000, exp);
1744 ix = (u8) ((mant - 1000) / 100); /* index of the LUT */
1745 dprintk(" ix = %d", ix);
1747 pow_i = (lut_1000ln_mant[ix] + 693 * (exp - 20) - 6908);
1748 pow_i = (pow_i << 8) / 1000;
1749 dprintk(" pow_i = %d", pow_i);
1751 return pow_i;
1754 static int map_addr_to_serpar_number(struct i2c_msg *msg)
1756 if ((msg->buf[0] <= 15))
1757 msg->buf[0] -= 1;
1758 else if (msg->buf[0] == 17)
1759 msg->buf[0] = 15;
1760 else if (msg->buf[0] == 16)
1761 msg->buf[0] = 17;
1762 else if (msg->buf[0] == 19)
1763 msg->buf[0] = 16;
1764 else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
1765 msg->buf[0] -= 3;
1766 else if (msg->buf[0] == 28)
1767 msg->buf[0] = 23;
1768 else
1769 return -EINVAL;
1770 return 0;
1773 static int w7090p_tuner_write_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1775 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1776 u8 n_overflow = 1;
1777 u16 i = 1000;
1778 u16 serpar_num = msg[0].buf[0];
1780 while (n_overflow == 1 && i) {
1781 n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
1782 i--;
1783 if (i == 0)
1784 dprintk("Tuner ITF: write busy (overflow)");
1786 dib7000p_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
1787 dib7000p_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
1789 return num;
1792 static int w7090p_tuner_read_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1794 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1795 u8 n_overflow = 1, n_empty = 1;
1796 u16 i = 1000;
1797 u16 serpar_num = msg[0].buf[0];
1798 u16 read_word;
1800 while (n_overflow == 1 && i) {
1801 n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
1802 i--;
1803 if (i == 0)
1804 dprintk("TunerITF: read busy (overflow)");
1806 dib7000p_write_word(state, 1985, (0 << 6) | (serpar_num & 0x3f));
1808 i = 1000;
1809 while (n_empty == 1 && i) {
1810 n_empty = dib7000p_read_word(state, 1984) & 0x1;
1811 i--;
1812 if (i == 0)
1813 dprintk("TunerITF: read busy (empty)");
1815 read_word = dib7000p_read_word(state, 1987);
1816 msg[1].buf[0] = (read_word >> 8) & 0xff;
1817 msg[1].buf[1] = (read_word) & 0xff;
1819 return num;
1822 static int w7090p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1824 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... */
1825 if (num == 1) { /* write */
1826 return w7090p_tuner_write_serpar(i2c_adap, msg, 1);
1827 } else { /* read */
1828 return w7090p_tuner_read_serpar(i2c_adap, msg, 2);
1831 return num;
1834 int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num, u16 apb_address)
1836 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1837 u16 word;
1839 if (num == 1) { /* write */
1840 dib7000p_write_word(state, apb_address, ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
1841 } else {
1842 word = dib7000p_read_word(state, apb_address);
1843 msg[1].buf[0] = (word >> 8) & 0xff;
1844 msg[1].buf[1] = (word) & 0xff;
1847 return num;
1850 static int dib7090_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1852 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1854 u16 apb_address = 0, word;
1855 int i = 0;
1856 switch (msg[0].buf[0]) {
1857 case 0x12:
1858 apb_address = 1920;
1859 break;
1860 case 0x14:
1861 apb_address = 1921;
1862 break;
1863 case 0x24:
1864 apb_address = 1922;
1865 break;
1866 case 0x1a:
1867 apb_address = 1923;
1868 break;
1869 case 0x22:
1870 apb_address = 1924;
1871 break;
1872 case 0x33:
1873 apb_address = 1926;
1874 break;
1875 case 0x34:
1876 apb_address = 1927;
1877 break;
1878 case 0x35:
1879 apb_address = 1928;
1880 break;
1881 case 0x36:
1882 apb_address = 1929;
1883 break;
1884 case 0x37:
1885 apb_address = 1930;
1886 break;
1887 case 0x38:
1888 apb_address = 1931;
1889 break;
1890 case 0x39:
1891 apb_address = 1932;
1892 break;
1893 case 0x2a:
1894 apb_address = 1935;
1895 break;
1896 case 0x2b:
1897 apb_address = 1936;
1898 break;
1899 case 0x2c:
1900 apb_address = 1937;
1901 break;
1902 case 0x2d:
1903 apb_address = 1938;
1904 break;
1905 case 0x2e:
1906 apb_address = 1939;
1907 break;
1908 case 0x2f:
1909 apb_address = 1940;
1910 break;
1911 case 0x30:
1912 apb_address = 1941;
1913 break;
1914 case 0x31:
1915 apb_address = 1942;
1916 break;
1917 case 0x32:
1918 apb_address = 1943;
1919 break;
1920 case 0x3e:
1921 apb_address = 1944;
1922 break;
1923 case 0x3f:
1924 apb_address = 1945;
1925 break;
1926 case 0x40:
1927 apb_address = 1948;
1928 break;
1929 case 0x25:
1930 apb_address = 914;
1931 break;
1932 case 0x26:
1933 apb_address = 915;
1934 break;
1935 case 0x27:
1936 apb_address = 916;
1937 break;
1938 case 0x28:
1939 apb_address = 917;
1940 break;
1941 case 0x1d:
1942 i = ((dib7000p_read_word(state, 72) >> 12) & 0x3);
1943 word = dib7000p_read_word(state, 384 + i);
1944 msg[1].buf[0] = (word >> 8) & 0xff;
1945 msg[1].buf[1] = (word) & 0xff;
1946 return num;
1947 case 0x1f:
1948 if (num == 1) { /* write */
1949 word = (u16) ((msg[0].buf[1] << 8) | msg[0].buf[2]);
1950 word &= 0x3;
1951 word = (dib7000p_read_word(state, 72) & ~(3 << 12)) | (word << 12);
1952 dib7000p_write_word(state, 72, word); /* Set the proper input */
1953 return num;
1957 if (apb_address != 0) /* R/W acces via APB */
1958 return dib7090p_rw_on_apb(i2c_adap, msg, num, apb_address);
1959 else /* R/W access via SERPAR */
1960 return w7090p_tuner_rw_serpar(i2c_adap, msg, num);
1962 return 0;
1965 static u32 dib7000p_i2c_func(struct i2c_adapter *adapter)
1967 return I2C_FUNC_I2C;
1970 static struct i2c_algorithm dib7090_tuner_xfer_algo = {
1971 .master_xfer = dib7090_tuner_xfer,
1972 .functionality = dib7000p_i2c_func,
1975 struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
1977 struct dib7000p_state *st = fe->demodulator_priv;
1978 return &st->dib7090_tuner_adap;
1980 EXPORT_SYMBOL(dib7090_get_i2c_tuner);
1982 static int dib7090_host_bus_drive(struct dib7000p_state *state, u8 drive)
1984 u16 reg;
1986 /* drive host bus 2, 3, 4 */
1987 reg = dib7000p_read_word(state, 1798) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1988 reg |= (drive << 12) | (drive << 6) | drive;
1989 dib7000p_write_word(state, 1798, reg);
1991 /* drive host bus 5,6 */
1992 reg = dib7000p_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
1993 reg |= (drive << 8) | (drive << 2);
1994 dib7000p_write_word(state, 1799, reg);
1996 /* drive host bus 7, 8, 9 */
1997 reg = dib7000p_read_word(state, 1800) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1998 reg |= (drive << 12) | (drive << 6) | drive;
1999 dib7000p_write_word(state, 1800, reg);
2001 /* drive host bus 10, 11 */
2002 reg = dib7000p_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
2003 reg |= (drive << 8) | (drive << 2);
2004 dib7000p_write_word(state, 1801, reg);
2006 /* drive host bus 12, 13, 14 */
2007 reg = dib7000p_read_word(state, 1802) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
2008 reg |= (drive << 12) | (drive << 6) | drive;
2009 dib7000p_write_word(state, 1802, reg);
2011 return 0;
2014 static u32 dib7090_calcSyncFreq(u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 syncSize)
2016 u32 quantif = 3;
2017 u32 nom = (insertExtSynchro * P_Kin + syncSize);
2018 u32 denom = P_Kout;
2019 u32 syncFreq = ((nom << quantif) / denom);
2021 if ((syncFreq & ((1 << quantif) - 1)) != 0)
2022 syncFreq = (syncFreq >> quantif) + 1;
2023 else
2024 syncFreq = (syncFreq >> quantif);
2026 if (syncFreq != 0)
2027 syncFreq = syncFreq - 1;
2029 return syncFreq;
2032 static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize)
2034 u8 index_buf;
2035 u16 rx_copy_buf[22];
2037 dprintk("Configure DibStream Tx");
2038 for (index_buf = 0; index_buf < 22; index_buf++)
2039 rx_copy_buf[index_buf] = dib7000p_read_word(state, 1536+index_buf);
2041 dib7000p_write_word(state, 1615, 1);
2042 dib7000p_write_word(state, 1603, P_Kin);
2043 dib7000p_write_word(state, 1605, P_Kout);
2044 dib7000p_write_word(state, 1606, insertExtSynchro);
2045 dib7000p_write_word(state, 1608, synchroMode);
2046 dib7000p_write_word(state, 1609, (syncWord >> 16) & 0xffff);
2047 dib7000p_write_word(state, 1610, syncWord & 0xffff);
2048 dib7000p_write_word(state, 1612, syncSize);
2049 dib7000p_write_word(state, 1615, 0);
2051 for (index_buf = 0; index_buf < 22; index_buf++)
2052 dib7000p_write_word(state, 1536+index_buf, rx_copy_buf[index_buf]);
2054 return 0;
2057 static int dib7090_cfg_DibRx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 synchroMode, u32 insertExtSynchro, u32 syncWord, u32 syncSize,
2058 u32 dataOutRate)
2060 u32 syncFreq;
2062 dprintk("Configure DibStream Rx");
2063 if ((P_Kin != 0) && (P_Kout != 0)) {
2064 syncFreq = dib7090_calcSyncFreq(P_Kin, P_Kout, insertExtSynchro, syncSize);
2065 dib7000p_write_word(state, 1542, syncFreq);
2067 dib7000p_write_word(state, 1554, 1);
2068 dib7000p_write_word(state, 1536, P_Kin);
2069 dib7000p_write_word(state, 1537, P_Kout);
2070 dib7000p_write_word(state, 1539, synchroMode);
2071 dib7000p_write_word(state, 1540, (syncWord >> 16) & 0xffff);
2072 dib7000p_write_word(state, 1541, syncWord & 0xffff);
2073 dib7000p_write_word(state, 1543, syncSize);
2074 dib7000p_write_word(state, 1544, dataOutRate);
2075 dib7000p_write_word(state, 1554, 0);
2077 return 0;
2080 static int dib7090_enDivOnHostBus(struct dib7000p_state *state)
2082 u16 reg;
2084 dprintk("Enable Diversity on host bus");
2085 reg = (1 << 8) | (1 << 5);
2086 dib7000p_write_word(state, 1288, reg);
2088 return dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
2091 static int dib7090_enAdcOnHostBus(struct dib7000p_state *state)
2093 u16 reg;
2095 dprintk("Enable ADC on host bus");
2096 reg = (1 << 7) | (1 << 5);
2097 dib7000p_write_word(state, 1288, reg);
2099 return dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
2102 static int dib7090_enMpegOnHostBus(struct dib7000p_state *state)
2104 u16 reg;
2106 dprintk("Enable Mpeg on host bus");
2107 reg = (1 << 9) | (1 << 5);
2108 dib7000p_write_word(state, 1288, reg);
2110 return dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
2113 static int dib7090_enMpegInput(struct dib7000p_state *state)
2115 dprintk("Enable Mpeg input");
2116 return dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */
2119 static int dib7090_enMpegMux(struct dib7000p_state *state, u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
2121 u16 reg = (1 << 7) | ((pulseWidth & 0x1f) << 2) | ((enSerialMode & 0x1) << 1) | (enSerialClkDiv2 & 0x1);
2123 dprintk("Enable Mpeg mux");
2124 dib7000p_write_word(state, 1287, reg);
2126 reg &= ~(1 << 7);
2127 dib7000p_write_word(state, 1287, reg);
2129 reg = (1 << 4);
2130 dib7000p_write_word(state, 1288, reg);
2132 return 0;
2135 static int dib7090_disableMpegMux(struct dib7000p_state *state)
2137 u16 reg;
2139 dprintk("Disable Mpeg mux");
2140 dib7000p_write_word(state, 1288, 0);
2142 reg = dib7000p_read_word(state, 1287);
2143 reg &= ~(1 << 7);
2144 dib7000p_write_word(state, 1287, reg);
2146 return 0;
2149 static int dib7090_set_input_mode(struct dvb_frontend *fe, int mode)
2151 struct dib7000p_state *state = fe->demodulator_priv;
2153 switch (mode) {
2154 case INPUT_MODE_DIVERSITY:
2155 dprintk("Enable diversity INPUT");
2156 dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
2157 break;
2158 case INPUT_MODE_MPEG:
2159 dprintk("Enable Mpeg INPUT");
2160 dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */
2161 break;
2162 case INPUT_MODE_OFF:
2163 default:
2164 dprintk("Disable INPUT");
2165 dib7090_cfg_DibRx(state, 0, 0, 0, 0, 0, 0, 0);
2166 break;
2168 return 0;
2171 static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff)
2173 switch (onoff) {
2174 case 0: /* only use the internal way - not the diversity input */
2175 dib7090_set_input_mode(fe, INPUT_MODE_MPEG);
2176 break;
2177 case 1: /* both ways */
2178 case 2: /* only the diversity input */
2179 dib7090_set_input_mode(fe, INPUT_MODE_DIVERSITY);
2180 break;
2183 return 0;
2186 static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode)
2188 struct dib7000p_state *state = fe->demodulator_priv;
2190 u16 outreg, smo_mode, fifo_threshold;
2191 u8 prefer_mpeg_mux_use = 1;
2192 int ret = 0;
2194 dib7090_host_bus_drive(state, 1);
2196 fifo_threshold = 1792;
2197 smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
2198 outreg = dib7000p_read_word(state, 1286) & ~((1 << 10) | (0x7 << 6) | (1 << 1));
2200 switch (mode) {
2201 case OUTMODE_HIGH_Z:
2202 outreg = 0;
2203 break;
2205 case OUTMODE_MPEG2_SERIAL:
2206 if (prefer_mpeg_mux_use) {
2207 dprintk("Sip 7090P setting output mode TS_SERIAL using Mpeg Mux");
2208 dib7090_enMpegOnHostBus(state);
2209 dib7090_enMpegInput(state);
2210 if (state->cfg.enMpegOutput == 1)
2211 dib7090_enMpegMux(state, 3, 1, 1);
2213 } else { /* Use Smooth block */
2214 dprintk("Sip 7090P setting output mode TS_SERIAL using Smooth bloc");
2215 dib7090_disableMpegMux(state);
2216 dib7000p_write_word(state, 1288, (1 << 6));
2217 outreg |= (2 << 6) | (0 << 1);
2219 break;
2221 case OUTMODE_MPEG2_PAR_GATED_CLK:
2222 if (prefer_mpeg_mux_use) {
2223 dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Mpeg Mux");
2224 dib7090_enMpegOnHostBus(state);
2225 dib7090_enMpegInput(state);
2226 if (state->cfg.enMpegOutput == 1)
2227 dib7090_enMpegMux(state, 2, 0, 0);
2228 } else { /* Use Smooth block */
2229 dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Smooth block");
2230 dib7090_disableMpegMux(state);
2231 dib7000p_write_word(state, 1288, (1 << 6));
2232 outreg |= (0 << 6);
2234 break;
2236 case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */
2237 dprintk("Sip 7090P setting output mode TS_PARALLEL_CONT using Smooth block");
2238 dib7090_disableMpegMux(state);
2239 dib7000p_write_word(state, 1288, (1 << 6));
2240 outreg |= (1 << 6);
2241 break;
2243 case OUTMODE_MPEG2_FIFO: /* Using Smooth block because not supported by new Mpeg Mux bloc */
2244 dprintk("Sip 7090P setting output mode TS_FIFO using Smooth block");
2245 dib7090_disableMpegMux(state);
2246 dib7000p_write_word(state, 1288, (1 << 6));
2247 outreg |= (5 << 6);
2248 smo_mode |= (3 << 1);
2249 fifo_threshold = 512;
2250 break;
2252 case OUTMODE_DIVERSITY:
2253 dprintk("Sip 7090P setting output mode MODE_DIVERSITY");
2254 dib7090_disableMpegMux(state);
2255 dib7090_enDivOnHostBus(state);
2256 break;
2258 case OUTMODE_ANALOG_ADC:
2259 dprintk("Sip 7090P setting output mode MODE_ANALOG_ADC");
2260 dib7090_enAdcOnHostBus(state);
2261 break;
2264 if (state->cfg.output_mpeg2_in_188_bytes)
2265 smo_mode |= (1 << 5);
2267 ret |= dib7000p_write_word(state, 235, smo_mode);
2268 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
2269 ret |= dib7000p_write_word(state, 1286, outreg | (1 << 10)); /* allways set Dout active = 1 !!! */
2271 return ret;
2274 int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
2276 struct dib7000p_state *state = fe->demodulator_priv;
2277 u16 en_cur_state;
2279 dprintk("sleep dib7090: %d", onoff);
2281 en_cur_state = dib7000p_read_word(state, 1922);
2283 if (en_cur_state > 0xff)
2284 state->tuner_enable = en_cur_state;
2286 if (onoff)
2287 en_cur_state &= 0x00ff;
2288 else {
2289 if (state->tuner_enable != 0)
2290 en_cur_state = state->tuner_enable;
2293 dib7000p_write_word(state, 1922, en_cur_state);
2295 return 0;
2297 EXPORT_SYMBOL(dib7090_tuner_sleep);
2299 int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart)
2301 dprintk("AGC restart callback: %d", restart);
2302 return 0;
2304 EXPORT_SYMBOL(dib7090_agc_restart);
2306 int dib7090_get_adc_power(struct dvb_frontend *fe)
2308 return dib7000p_get_adc_power(fe);
2310 EXPORT_SYMBOL(dib7090_get_adc_power);
2312 int dib7090_slave_reset(struct dvb_frontend *fe)
2314 struct dib7000p_state *state = fe->demodulator_priv;
2315 u16 reg;
2317 reg = dib7000p_read_word(state, 1794);
2318 dib7000p_write_word(state, 1794, reg | (4 << 12));
2320 dib7000p_write_word(state, 1032, 0xffff);
2321 return 0;
2323 EXPORT_SYMBOL(dib7090_slave_reset);
2325 static struct dvb_frontend_ops dib7000p_ops;
2326 struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
2328 struct dvb_frontend *demod;
2329 struct dib7000p_state *st;
2330 st = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
2331 if (st == NULL)
2332 return NULL;
2334 memcpy(&st->cfg, cfg, sizeof(struct dib7000p_config));
2335 st->i2c_adap = i2c_adap;
2336 st->i2c_addr = i2c_addr;
2337 st->gpio_val = cfg->gpio_val;
2338 st->gpio_dir = cfg->gpio_dir;
2340 /* Ensure the output mode remains at the previous default if it's
2341 * not specifically set by the caller.
2343 if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2344 st->cfg.output_mode = OUTMODE_MPEG2_FIFO;
2346 demod = &st->demod;
2347 demod->demodulator_priv = st;
2348 memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));
2349 mutex_init(&st->i2c_buffer_lock);
2351 dib7000p_write_word(st, 1287, 0x0003); /* sram lead in, rdy */
2353 if (dib7000p_identify(st) != 0)
2354 goto error;
2356 st->version = dib7000p_read_word(st, 897);
2358 /* FIXME: make sure the dev.parent field is initialized, or else
2359 request_firmware() will hit an OOPS (this should be moved somewhere
2360 more common) */
2361 st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent;
2363 /* FIXME: make sure the dev.parent field is initialized, or else
2364 request_firmware() will hit an OOPS (this should be moved somewhere
2365 more common) */
2366 st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent;
2368 dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr);
2370 /* init 7090 tuner adapter */
2371 strncpy(st->dib7090_tuner_adap.name, "DiB7090 tuner interface", sizeof(st->dib7090_tuner_adap.name));
2372 st->dib7090_tuner_adap.algo = &dib7090_tuner_xfer_algo;
2373 st->dib7090_tuner_adap.algo_data = NULL;
2374 st->dib7090_tuner_adap.dev.parent = st->i2c_adap->dev.parent;
2375 i2c_set_adapdata(&st->dib7090_tuner_adap, st);
2376 i2c_add_adapter(&st->dib7090_tuner_adap);
2378 dib7000p_demod_reset(st);
2380 if (st->version == SOC7090) {
2381 dib7090_set_output_mode(demod, st->cfg.output_mode);
2382 dib7090_set_diversity_in(demod, 0);
2385 return demod;
2387 error:
2388 kfree(st);
2389 return NULL;
2391 EXPORT_SYMBOL(dib7000p_attach);
2393 static struct dvb_frontend_ops dib7000p_ops = {
2394 .info = {
2395 .name = "DiBcom 7000PC",
2396 .type = FE_OFDM,
2397 .frequency_min = 44250000,
2398 .frequency_max = 867250000,
2399 .frequency_stepsize = 62500,
2400 .caps = FE_CAN_INVERSION_AUTO |
2401 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2402 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2403 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2404 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2407 .release = dib7000p_release,
2409 .init = dib7000p_wakeup,
2410 .sleep = dib7000p_sleep,
2412 .set_frontend = dib7000p_set_frontend,
2413 .get_tune_settings = dib7000p_fe_get_tune_settings,
2414 .get_frontend = dib7000p_get_frontend,
2416 .read_status = dib7000p_read_status,
2417 .read_ber = dib7000p_read_ber,
2418 .read_signal_strength = dib7000p_read_signal_strength,
2419 .read_snr = dib7000p_read_snr,
2420 .read_ucblocks = dib7000p_read_unc_blocks,
2423 MODULE_AUTHOR("Olivier Grenie <ogrenie@dibcom.fr>");
2424 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
2425 MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
2426 MODULE_LICENSE("GPL");