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.
10 #include <linux/kernel.h>
11 #include <linux/slab.h>
12 #include <linux/i2c.h>
13 #include <linux/mutex.h>
16 #include "dvb_frontend.h"
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)
31 struct i2c_adapter *i2c_adap;
35 struct dib7000p_state {
36 struct dvb_frontend demod;
37 struct dib7000p_config cfg;
40 struct i2c_adapter *i2c_adap;
42 struct dibx000_i2c_master i2c_master;
47 u32 current_bandwidth;
48 struct dibx000_agc_config *current_agc;
60 u8 sfn_workaround_active:1;
62 #define SOC7090 0x7090
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;
77 enum dib7000p_power_mode {
78 DIB7000P_POWER_ALL = 0,
79 DIB7000P_POWER_ANALOG_ADC,
80 DIB7000P_POWER_INTERFACE_ONLY,
83 /* dib7090 specific fonctions */
84 static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode);
85 static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff);
86 static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode);
87 static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode);
89 static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
93 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
94 dprintk("could not acquire lock");
98 state->i2c_write_buffer[0] = reg >> 8;
99 state->i2c_write_buffer[1] = reg & 0xff;
101 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
102 state->msg[0].addr = state->i2c_addr >> 1;
103 state->msg[0].flags = 0;
104 state->msg[0].buf = state->i2c_write_buffer;
105 state->msg[0].len = 2;
106 state->msg[1].addr = state->i2c_addr >> 1;
107 state->msg[1].flags = I2C_M_RD;
108 state->msg[1].buf = state->i2c_read_buffer;
109 state->msg[1].len = 2;
111 if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
112 dprintk("i2c read error on %d", reg);
114 ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
115 mutex_unlock(&state->i2c_buffer_lock);
119 static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
123 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
124 dprintk("could not acquire lock");
128 state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
129 state->i2c_write_buffer[1] = reg & 0xff;
130 state->i2c_write_buffer[2] = (val >> 8) & 0xff;
131 state->i2c_write_buffer[3] = val & 0xff;
133 memset(&state->msg[0], 0, sizeof(struct i2c_msg));
134 state->msg[0].addr = state->i2c_addr >> 1;
135 state->msg[0].flags = 0;
136 state->msg[0].buf = state->i2c_write_buffer;
137 state->msg[0].len = 4;
139 ret = (i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ?
141 mutex_unlock(&state->i2c_buffer_lock);
145 static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf)
154 dib7000p_write_word(state, r, *n++);
161 static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
164 u16 outreg, fifo_threshold, smo_mode;
167 fifo_threshold = 1792;
168 smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
170 dprintk("setting output mode for demod %p to %d", &state->demod, mode);
173 case OUTMODE_MPEG2_PAR_GATED_CLK:
174 outreg = (1 << 10); /* 0x0400 */
176 case OUTMODE_MPEG2_PAR_CONT_CLK:
177 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
179 case OUTMODE_MPEG2_SERIAL:
180 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */
182 case OUTMODE_DIVERSITY:
183 if (state->cfg.hostbus_diversity)
184 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
188 case OUTMODE_MPEG2_FIFO:
189 smo_mode |= (3 << 1);
190 fifo_threshold = 512;
191 outreg = (1 << 10) | (5 << 6);
193 case OUTMODE_ANALOG_ADC:
194 outreg = (1 << 10) | (3 << 6);
200 dprintk("Unhandled output_mode passed to be set for demod %p", &state->demod);
204 if (state->cfg.output_mpeg2_in_188_bytes)
205 smo_mode |= (1 << 5);
207 ret |= dib7000p_write_word(state, 235, smo_mode);
208 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
209 if (state->version != SOC7090)
210 ret |= dib7000p_write_word(state, 1286, outreg); /* P_Div_active */
215 static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
217 struct dib7000p_state *state = demod->demodulator_priv;
219 if (state->div_force_off) {
220 dprintk("diversity combination deactivated - forced by COFDM parameters");
222 dib7000p_write_word(state, 207, 0);
224 dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
226 state->div_state = (u8) onoff;
229 dib7000p_write_word(state, 204, 6);
230 dib7000p_write_word(state, 205, 16);
231 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
233 dib7000p_write_word(state, 204, 1);
234 dib7000p_write_word(state, 205, 0);
240 static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode)
242 /* by default everything is powered off */
243 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0x0007, reg_899 = 0x0003, reg_1280 = (0xfe00) | (dib7000p_read_word(state, 1280) & 0x01ff);
245 /* now, depending on the requested mode, we power on */
247 /* power up everything in the demod */
248 case DIB7000P_POWER_ALL:
253 if (state->version == SOC7090)
259 case DIB7000P_POWER_ANALOG_ADC:
260 /* dem, cfg, iqc, sad, agc */
261 reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
263 reg_776 &= ~((1 << 0));
265 if (state->version != SOC7090)
266 reg_1280 &= ~((1 << 11));
267 reg_1280 &= ~(1 << 6);
268 /* fall through wanted to enable the interfaces */
270 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
271 case DIB7000P_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C */
272 if (state->version == SOC7090)
273 reg_1280 &= ~((1 << 7) | (1 << 5));
275 reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
278 /* TODO following stuff is just converted from the dib7000-driver - check when is used what */
281 dib7000p_write_word(state, 774, reg_774);
282 dib7000p_write_word(state, 775, reg_775);
283 dib7000p_write_word(state, 776, reg_776);
284 dib7000p_write_word(state, 1280, reg_1280);
285 if (state->version != SOC7090)
286 dib7000p_write_word(state, 899, reg_899);
291 static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no)
293 u16 reg_908 = 0, reg_909 = 0;
296 if (state->version != SOC7090) {
297 reg_908 = dib7000p_read_word(state, 908);
298 reg_909 = dib7000p_read_word(state, 909);
302 case DIBX000_SLOW_ADC_ON:
303 if (state->version == SOC7090) {
304 reg = dib7000p_read_word(state, 1925);
306 dib7000p_write_word(state, 1925, reg | (1 << 4) | (1 << 2)); /* en_slowAdc = 1 & reset_sladc = 1 */
308 reg = dib7000p_read_word(state, 1925); /* read acces to make it works... strange ... */
310 dib7000p_write_word(state, 1925, reg & ~(1 << 4)); /* en_slowAdc = 1 & reset_sladc = 0 */
312 reg = dib7000p_read_word(state, 72) & ~((0x3 << 14) | (0x3 << 12));
313 dib7000p_write_word(state, 72, reg | (1 << 14) | (3 << 12) | 524); /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ; (Vin2 = Vcm) */
315 reg_909 |= (1 << 1) | (1 << 0);
316 dib7000p_write_word(state, 909, reg_909);
317 reg_909 &= ~(1 << 1);
321 case DIBX000_SLOW_ADC_OFF:
322 if (state->version == SOC7090) {
323 reg = dib7000p_read_word(state, 1925);
324 dib7000p_write_word(state, 1925, (reg & ~(1 << 2)) | (1 << 4)); /* reset_sladc = 1 en_slowAdc = 0 */
326 reg_909 |= (1 << 1) | (1 << 0);
334 case DIBX000_ADC_OFF:
335 reg_908 |= (1 << 14) | (1 << 13) | (1 << 12);
336 reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
339 case DIBX000_VBG_ENABLE:
340 reg_908 &= ~(1 << 15);
343 case DIBX000_VBG_DISABLE:
344 reg_908 |= (1 << 15);
351 // dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
353 reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4;
354 reg_908 |= (state->cfg.enable_current_mirror & 1) << 7;
356 if (state->version != SOC7090) {
357 dib7000p_write_word(state, 908, reg_908);
358 dib7000p_write_word(state, 909, reg_909);
362 static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
366 // store the current bandwidth for later use
367 state->current_bandwidth = bw;
369 if (state->timf == 0) {
370 dprintk("using default timf");
371 timf = state->cfg.bw->timf;
373 dprintk("using updated timf");
377 timf = timf * (bw / 50) / 160;
379 dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
380 dib7000p_write_word(state, 24, (u16) ((timf) & 0xffff));
385 static int dib7000p_sad_calib(struct dib7000p_state *state)
388 dib7000p_write_word(state, 73, (0 << 1) | (0 << 0));
390 if (state->version == SOC7090)
391 dib7000p_write_word(state, 74, 2048);
393 dib7000p_write_word(state, 74, 776);
395 /* do the calibration */
396 dib7000p_write_word(state, 73, (1 << 0));
397 dib7000p_write_word(state, 73, (0 << 0));
404 int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
406 struct dib7000p_state *state = demod->demodulator_priv;
409 state->wbd_ref = value;
410 return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value);
412 EXPORT_SYMBOL(dib7000p_set_wbd_ref);
414 int dib7000p_get_agc_values(struct dvb_frontend *fe,
415 u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd)
417 struct dib7000p_state *state = fe->demodulator_priv;
419 if (agc_global != NULL)
420 *agc_global = dib7000p_read_word(state, 394);
422 *agc1 = dib7000p_read_word(state, 392);
424 *agc2 = dib7000p_read_word(state, 393);
426 *wbd = dib7000p_read_word(state, 397);
430 EXPORT_SYMBOL(dib7000p_get_agc_values);
432 static void dib7000p_reset_pll(struct dib7000p_state *state)
434 struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
437 if (state->version == SOC7090) {
438 dib7000p_write_word(state, 1856, (!bw->pll_reset << 13) | (bw->pll_range << 12) | (bw->pll_ratio << 6) | (bw->pll_prediv));
440 while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
443 dib7000p_write_word(state, 1857, dib7000p_read_word(state, 1857) | (!bw->pll_bypass << 15));
445 /* force PLL bypass */
446 clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) |
447 (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0);
449 dib7000p_write_word(state, 900, clk_cfg0);
452 dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset);
453 clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff);
454 dib7000p_write_word(state, 900, clk_cfg0);
457 dib7000p_write_word(state, 18, (u16) (((bw->internal * 1000) >> 16) & 0xffff));
458 dib7000p_write_word(state, 19, (u16) ((bw->internal * 1000) & 0xffff));
459 dib7000p_write_word(state, 21, (u16) ((bw->ifreq >> 16) & 0xffff));
460 dib7000p_write_word(state, 22, (u16) ((bw->ifreq) & 0xffff));
462 dib7000p_write_word(state, 72, bw->sad_cfg);
465 static u32 dib7000p_get_internal_freq(struct dib7000p_state *state)
467 u32 internal = (u32) dib7000p_read_word(state, 18) << 16;
468 internal |= (u32) dib7000p_read_word(state, 19);
474 int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
476 struct dib7000p_state *state = fe->demodulator_priv;
477 u16 reg_1857, reg_1856 = dib7000p_read_word(state, 1856);
481 /* get back old values */
482 prediv = reg_1856 & 0x3f;
483 loopdiv = (reg_1856 >> 6) & 0x3f;
485 if ((bw != NULL) && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) {
486 dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio);
488 reg_1857 = dib7000p_read_word(state, 1857);
489 dib7000p_write_word(state, 1857, reg_1857 & ~(1 << 15));
491 dib7000p_write_word(state, 1856, reg_1856 | ((bw->pll_ratio & 0x3f) << 6) | (bw->pll_prediv & 0x3f));
493 /* write new system clk into P_sec_len */
494 internal = dib7000p_get_internal_freq(state);
495 xtal = (internal / loopdiv) * prediv;
496 internal = 1000 * (xtal / bw->pll_prediv) * bw->pll_ratio; /* new internal */
497 dib7000p_write_word(state, 18, (u16) ((internal >> 16) & 0xffff));
498 dib7000p_write_word(state, 19, (u16) (internal & 0xffff));
500 dib7000p_write_word(state, 1857, reg_1857 | (1 << 15));
502 while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
503 dprintk("Waiting for PLL to lock");
509 EXPORT_SYMBOL(dib7000p_update_pll);
511 static int dib7000p_reset_gpio(struct dib7000p_state *st)
513 /* reset the GPIOs */
514 dprintk("gpio dir: %x: val: %x, pwm_pos: %x", st->gpio_dir, st->gpio_val, st->cfg.gpio_pwm_pos);
516 dib7000p_write_word(st, 1029, st->gpio_dir);
517 dib7000p_write_word(st, 1030, st->gpio_val);
519 /* TODO 1031 is P_gpio_od */
521 dib7000p_write_word(st, 1032, st->cfg.gpio_pwm_pos);
523 dib7000p_write_word(st, 1037, st->cfg.pwm_freq_div);
527 static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val)
529 st->gpio_dir = dib7000p_read_word(st, 1029);
530 st->gpio_dir &= ~(1 << num); /* reset the direction bit */
531 st->gpio_dir |= (dir & 0x1) << num; /* set the new direction */
532 dib7000p_write_word(st, 1029, st->gpio_dir);
534 st->gpio_val = dib7000p_read_word(st, 1030);
535 st->gpio_val &= ~(1 << num); /* reset the direction bit */
536 st->gpio_val |= (val & 0x01) << num; /* set the new value */
537 dib7000p_write_word(st, 1030, st->gpio_val);
542 int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val)
544 struct dib7000p_state *state = demod->demodulator_priv;
545 return dib7000p_cfg_gpio(state, num, dir, val);
547 EXPORT_SYMBOL(dib7000p_set_gpio);
549 static u16 dib7000p_defaults[] = {
550 // auto search configuration
553 (1<<3)|(1<<11)|(1<<12)|(1<<13),
554 0x0814, /* Equal Lock */
573 /* set ADC level to -16 */
575 (1 << 13) - 825 - 117,
576 (1 << 13) - 837 - 117,
577 (1 << 13) - 811 - 117,
578 (1 << 13) - 766 - 117,
579 (1 << 13) - 737 - 117,
580 (1 << 13) - 693 - 117,
581 (1 << 13) - 648 - 117,
582 (1 << 13) - 619 - 117,
583 (1 << 13) - 575 - 117,
584 (1 << 13) - 531 - 117,
585 (1 << 13) - 501 - 117,
590 /* disable power smoothing */
632 static int dib7000p_demod_reset(struct dib7000p_state *state)
634 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
636 if (state->version == SOC7090)
637 dibx000_reset_i2c_master(&state->i2c_master);
639 dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE);
641 /* restart all parts */
642 dib7000p_write_word(state, 770, 0xffff);
643 dib7000p_write_word(state, 771, 0xffff);
644 dib7000p_write_word(state, 772, 0x001f);
645 dib7000p_write_word(state, 1280, 0x001f - ((1 << 4) | (1 << 3)));
647 dib7000p_write_word(state, 770, 0);
648 dib7000p_write_word(state, 771, 0);
649 dib7000p_write_word(state, 772, 0);
650 dib7000p_write_word(state, 1280, 0);
652 if (state->version != SOC7090) {
653 dib7000p_write_word(state, 898, 0x0003);
654 dib7000p_write_word(state, 898, 0);
658 dib7000p_reset_pll(state);
660 if (dib7000p_reset_gpio(state) != 0)
661 dprintk("GPIO reset was not successful.");
663 if (state->version == SOC7090) {
664 dib7000p_write_word(state, 899, 0);
667 dib7000p_write_word(state, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */
668 dib7000p_write_word(state, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */
669 dib7000p_write_word(state, 44, 300); /* 300 fag P_iqc_dect_min = +280 */
670 dib7000p_write_word(state, 273, (0<<6) | 30);
672 if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
673 dprintk("OUTPUT_MODE could not be reset.");
675 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
676 dib7000p_sad_calib(state);
677 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
679 /* unforce divstr regardless whether i2c enumeration was done or not */
680 dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1));
682 dib7000p_set_bandwidth(state, 8000);
684 if (state->version == SOC7090) {
685 dib7000p_write_word(state, 36, 0x0755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */
687 if (state->cfg.tuner_is_baseband)
688 dib7000p_write_word(state, 36, 0x0755);
690 dib7000p_write_word(state, 36, 0x1f55);
693 dib7000p_write_tab(state, dib7000p_defaults);
694 if (state->version != SOC7090) {
695 dib7000p_write_word(state, 901, 0x0006);
696 dib7000p_write_word(state, 902, (3 << 10) | (1 << 6));
697 dib7000p_write_word(state, 905, 0x2c8e);
700 dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
705 static void dib7000p_pll_clk_cfg(struct dib7000p_state *state)
708 tmp = dib7000p_read_word(state, 903);
709 dib7000p_write_word(state, 903, (tmp | 0x1));
710 tmp = dib7000p_read_word(state, 900);
711 dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6));
714 static void dib7000p_restart_agc(struct dib7000p_state *state)
716 // P_restart_iqc & P_restart_agc
717 dib7000p_write_word(state, 770, (1 << 11) | (1 << 9));
718 dib7000p_write_word(state, 770, 0x0000);
721 static int dib7000p_update_lna(struct dib7000p_state *state)
725 if (state->cfg.update_lna) {
726 dyn_gain = dib7000p_read_word(state, 394);
727 if (state->cfg.update_lna(&state->demod, dyn_gain)) {
728 dib7000p_restart_agc(state);
736 static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
738 struct dibx000_agc_config *agc = NULL;
740 if (state->current_band == band && state->current_agc != NULL)
742 state->current_band = band;
744 for (i = 0; i < state->cfg.agc_config_count; i++)
745 if (state->cfg.agc[i].band_caps & band) {
746 agc = &state->cfg.agc[i];
751 dprintk("no valid AGC configuration found for band 0x%02x", band);
755 state->current_agc = agc;
758 dib7000p_write_word(state, 75, agc->setup);
759 dib7000p_write_word(state, 76, agc->inv_gain);
760 dib7000p_write_word(state, 77, agc->time_stabiliz);
761 dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);
763 // Demod AGC loop configuration
764 dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);
765 dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp);
768 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
769 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
771 if (state->wbd_ref != 0)
772 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref);
774 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref);
776 dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
778 dib7000p_write_word(state, 107, agc->agc1_max);
779 dib7000p_write_word(state, 108, agc->agc1_min);
780 dib7000p_write_word(state, 109, agc->agc2_max);
781 dib7000p_write_word(state, 110, agc->agc2_min);
782 dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
783 dib7000p_write_word(state, 112, agc->agc1_pt3);
784 dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
785 dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
786 dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
790 static void dib7000p_set_dds(struct dib7000p_state *state, s32 offset_khz)
792 u32 internal = dib7000p_get_internal_freq(state);
793 s32 unit_khz_dds_val = 67108864 / (internal); /* 2**26 / Fsampling is the unit 1KHz offset */
794 u32 abs_offset_khz = ABS(offset_khz);
795 u32 dds = state->cfg.bw->ifreq & 0x1ffffff;
796 u8 invert = !!(state->cfg.bw->ifreq & (1 << 25));
798 dprintk("setting a frequency offset of %dkHz internal freq = %d invert = %d", offset_khz, internal, invert);
801 unit_khz_dds_val *= -1;
805 dds -= (abs_offset_khz * unit_khz_dds_val); /* /100 because of /100 on the unit_khz_dds_val line calc for better accuracy */
807 dds += (abs_offset_khz * unit_khz_dds_val);
809 if (abs_offset_khz <= (internal / 2)) { /* Max dds offset is the half of the demod freq */
810 dib7000p_write_word(state, 21, (u16) (((dds >> 16) & 0x1ff) | (0 << 10) | (invert << 9)));
811 dib7000p_write_word(state, 22, (u16) (dds & 0xffff));
815 static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
817 struct dib7000p_state *state = demod->demodulator_priv;
819 u8 *agc_state = &state->agc_state;
822 u32 upd_demod_gain_period = 0x1000;
824 switch (state->agc_state) {
826 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
827 if (state->version == SOC7090) {
828 reg = dib7000p_read_word(state, 0x79b) & 0xff00;
829 dib7000p_write_word(state, 0x79a, upd_demod_gain_period & 0xFFFF); /* lsb */
830 dib7000p_write_word(state, 0x79b, reg | (1 << 14) | ((upd_demod_gain_period >> 16) & 0xFF));
832 /* enable adc i & q */
833 reg = dib7000p_read_word(state, 0x780);
834 dib7000p_write_word(state, 0x780, (reg | (0x3)) & (~(1 << 7)));
836 dib7000p_set_adc_state(state, DIBX000_ADC_ON);
837 dib7000p_pll_clk_cfg(state);
840 if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency / 1000)) != 0)
843 dib7000p_set_dds(state, 0);
849 if (state->cfg.agc_control)
850 state->cfg.agc_control(&state->demod, 1);
852 dib7000p_write_word(state, 78, 32768);
853 if (!state->current_agc->perform_agc_softsplit) {
854 /* we are using the wbd - so slow AGC startup */
855 /* force 0 split on WBD and restart AGC */
856 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));
860 /* default AGC startup */
862 /* wait AGC rough lock time */
866 dib7000p_restart_agc(state);
869 case 2: /* fast split search path after 5sec */
870 dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4)); /* freeze AGC loop */
871 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */
876 case 3: /* split search ended */
877 agc_split = (u8) dib7000p_read_word(state, 396); /* store the split value for the next time */
878 dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */
880 dib7000p_write_word(state, 75, state->current_agc->setup); /* std AGC loop */
881 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
883 dib7000p_restart_agc(state);
885 dprintk("SPLIT %p: %hd", demod, agc_split);
891 case 4: /* LNA startup */
894 if (dib7000p_update_lna(state))
901 if (state->cfg.agc_control)
902 state->cfg.agc_control(&state->demod, 0);
911 static void dib7000p_update_timf(struct dib7000p_state *state)
913 u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428);
914 state->timf = timf * 160 / (state->current_bandwidth / 50);
915 dib7000p_write_word(state, 23, (u16) (timf >> 16));
916 dib7000p_write_word(state, 24, (u16) (timf & 0xffff));
917 dprintk("updated timf_frequency: %d (default: %d)", state->timf, state->cfg.bw->timf);
921 u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
923 struct dib7000p_state *state = fe->demodulator_priv;
928 case DEMOD_TIMF_UPDATE:
929 dib7000p_update_timf(state);
934 dib7000p_set_bandwidth(state, state->current_bandwidth);
937 EXPORT_SYMBOL(dib7000p_ctrl_timf);
939 static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq)
943 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
945 /* nfft, guard, qam, alpha */
947 switch (ch->u.ofdm.transmission_mode) {
948 case TRANSMISSION_MODE_2K:
951 case TRANSMISSION_MODE_4K:
955 case TRANSMISSION_MODE_8K:
959 switch (ch->u.ofdm.guard_interval) {
960 case GUARD_INTERVAL_1_32:
963 case GUARD_INTERVAL_1_16:
966 case GUARD_INTERVAL_1_4:
970 case GUARD_INTERVAL_1_8:
974 switch (ch->u.ofdm.constellation) {
986 switch (HIERARCHY_1) {
998 dib7000p_write_word(state, 0, value);
999 dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */
1001 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
1005 if (ch->u.ofdm.hierarchy_information == 1)
1009 switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
1027 dib7000p_write_word(state, 208, value);
1029 /* offset loop parameters */
1030 dib7000p_write_word(state, 26, 0x6680);
1031 dib7000p_write_word(state, 32, 0x0003);
1032 dib7000p_write_word(state, 29, 0x1273);
1033 dib7000p_write_word(state, 33, 0x0005);
1035 /* P_dvsy_sync_wait */
1036 switch (ch->u.ofdm.transmission_mode) {
1037 case TRANSMISSION_MODE_8K:
1040 case TRANSMISSION_MODE_4K:
1043 case TRANSMISSION_MODE_2K:
1048 switch (ch->u.ofdm.guard_interval) {
1049 case GUARD_INTERVAL_1_16:
1052 case GUARD_INTERVAL_1_8:
1055 case GUARD_INTERVAL_1_4:
1059 case GUARD_INTERVAL_1_32:
1063 if (state->cfg.diversity_delay == 0)
1064 state->div_sync_wait = (value * 3) / 2 + 48;
1066 state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay;
1068 /* deactive the possibility of diversity reception if extended interleaver */
1069 state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K;
1070 dib7000p_set_diversity_in(&state->demod, state->div_state);
1072 /* channel estimation fine configuration */
1073 switch (ch->u.ofdm.constellation) {
1075 est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
1076 est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
1077 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1078 est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
1081 est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
1082 est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
1083 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1084 est[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
1087 est[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
1088 est[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
1089 est[2] = 0x0333; /* P_adp_regul_ext 0.1 */
1090 est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
1093 for (value = 0; value < 4; value++)
1094 dib7000p_write_word(state, 187 + value, est[value]);
1097 static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
1099 struct dib7000p_state *state = demod->demodulator_priv;
1100 struct dvb_frontend_parameters schan;
1102 u32 internal = dib7000p_get_internal_freq(state);
1105 schan.u.ofdm.constellation = QAM_64;
1106 schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
1107 schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
1108 schan.u.ofdm.code_rate_HP = FEC_2_3;
1109 schan.u.ofdm.code_rate_LP = FEC_3_4;
1110 schan.u.ofdm.hierarchy_information = 0;
1112 dib7000p_set_channel(state, &schan, 7);
1114 factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth);
1115 if (factor >= 5000) {
1116 if (state->version == SOC7090)
1123 value = 30 * internal * factor;
1124 dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff));
1125 dib7000p_write_word(state, 7, (u16) (value & 0xffff));
1126 value = 100 * internal * factor;
1127 dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff));
1128 dib7000p_write_word(state, 9, (u16) (value & 0xffff));
1129 value = 500 * internal * factor;
1130 dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff));
1131 dib7000p_write_word(state, 11, (u16) (value & 0xffff));
1133 value = dib7000p_read_word(state, 0);
1134 dib7000p_write_word(state, 0, (u16) ((1 << 9) | value));
1135 dib7000p_read_word(state, 1284);
1136 dib7000p_write_word(state, 0, (u16) value);
1141 static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod)
1143 struct dib7000p_state *state = demod->demodulator_priv;
1144 u16 irq_pending = dib7000p_read_word(state, 1284);
1146 if (irq_pending & 0x1)
1149 if (irq_pending & 0x2)
1155 static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw)
1157 static s16 notch[] = { 16143, 14402, 12238, 9713, 6902, 3888, 759, -2392 };
1158 static u8 sine[] = { 0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
1159 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
1160 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
1161 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
1162 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
1163 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
1164 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
1165 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
1166 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
1167 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
1168 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
1169 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
1170 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
1171 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
1172 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
1173 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1174 255, 255, 255, 255, 255, 255
1177 u32 xtal = state->cfg.bw->xtal_hz / 1000;
1178 int f_rel = DIV_ROUND_CLOSEST(rf_khz, xtal) * xtal - rf_khz;
1180 int coef_re[8], coef_im[8];
1184 dprintk("relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal);
1186 if (f_rel < -bw_khz / 2 || f_rel > bw_khz / 2)
1191 dib7000p_write_word(state, 142, 0x0610);
1193 for (k = 0; k < 8; k++) {
1194 pha = ((f_rel * (k + 1) * 112 * 80 / bw_khz) / 1000) & 0x3ff;
1199 } else if (pha < 256) {
1200 coef_re[k] = sine[256 - (pha & 0xff)];
1201 coef_im[k] = sine[pha & 0xff];
1202 } else if (pha == 256) {
1205 } else if (pha < 512) {
1206 coef_re[k] = -sine[pha & 0xff];
1207 coef_im[k] = sine[256 - (pha & 0xff)];
1208 } else if (pha == 512) {
1211 } else if (pha < 768) {
1212 coef_re[k] = -sine[256 - (pha & 0xff)];
1213 coef_im[k] = -sine[pha & 0xff];
1214 } else if (pha == 768) {
1218 coef_re[k] = sine[pha & 0xff];
1219 coef_im[k] = -sine[256 - (pha & 0xff)];
1222 coef_re[k] *= notch[k];
1223 coef_re[k] += (1 << 14);
1224 if (coef_re[k] >= (1 << 24))
1225 coef_re[k] = (1 << 24) - 1;
1226 coef_re[k] /= (1 << 15);
1228 coef_im[k] *= notch[k];
1229 coef_im[k] += (1 << 14);
1230 if (coef_im[k] >= (1 << 24))
1231 coef_im[k] = (1 << 24) - 1;
1232 coef_im[k] /= (1 << 15);
1234 dprintk("PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]);
1236 dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
1237 dib7000p_write_word(state, 144, coef_im[k] & 0x3ff);
1238 dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
1240 dib7000p_write_word(state, 143, 0);
1243 static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
1245 struct dib7000p_state *state = demod->demodulator_priv;
1249 dib7000p_set_channel(state, ch, 0);
1254 dib7000p_write_word(state, 770, 0x4000);
1255 dib7000p_write_word(state, 770, 0x0000);
1258 /* 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 */
1259 tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
1260 if (state->sfn_workaround_active) {
1261 dprintk("SFN workaround is active");
1263 dib7000p_write_word(state, 166, 0x4000);
1265 dib7000p_write_word(state, 166, 0x0000);
1267 dib7000p_write_word(state, 29, tmp);
1269 // never achieved a lock with that bandwidth so far - wait for osc-freq to update
1270 if (state->timf == 0)
1273 /* offset loop parameters */
1275 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
1276 tmp = (6 << 8) | 0x80;
1277 switch (ch->u.ofdm.transmission_mode) {
1278 case TRANSMISSION_MODE_2K:
1281 case TRANSMISSION_MODE_4K:
1285 case TRANSMISSION_MODE_8K:
1289 dib7000p_write_word(state, 26, tmp); /* timf_a(6xxx) */
1291 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1293 switch (ch->u.ofdm.transmission_mode) {
1294 case TRANSMISSION_MODE_2K:
1297 case TRANSMISSION_MODE_4K:
1301 case TRANSMISSION_MODE_8K:
1305 dib7000p_write_word(state, 32, tmp);
1307 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1309 switch (ch->u.ofdm.transmission_mode) {
1310 case TRANSMISSION_MODE_2K:
1313 case TRANSMISSION_MODE_4K:
1317 case TRANSMISSION_MODE_8K:
1321 dib7000p_write_word(state, 33, tmp);
1323 tmp = dib7000p_read_word(state, 509);
1324 if (!((tmp >> 6) & 0x1)) {
1325 /* restart the fec */
1326 tmp = dib7000p_read_word(state, 771);
1327 dib7000p_write_word(state, 771, tmp | (1 << 1));
1328 dib7000p_write_word(state, 771, tmp);
1330 tmp = dib7000p_read_word(state, 509);
1332 // we achieved a lock - it's time to update the osc freq
1333 if ((tmp >> 6) & 0x1) {
1334 dib7000p_update_timf(state);
1335 /* P_timf_alpha += 2 */
1336 tmp = dib7000p_read_word(state, 26);
1337 dib7000p_write_word(state, 26, (tmp & ~(0xf << 12)) | ((((tmp >> 12) & 0xf) + 5) << 12));
1340 if (state->cfg.spur_protect)
1341 dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1343 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1347 static int dib7000p_wakeup(struct dvb_frontend *demod)
1349 struct dib7000p_state *state = demod->demodulator_priv;
1350 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
1351 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
1352 if (state->version == SOC7090)
1353 dib7000p_sad_calib(state);
1357 static int dib7000p_sleep(struct dvb_frontend *demod)
1359 struct dib7000p_state *state = demod->demodulator_priv;
1360 if (state->version == SOC7090)
1361 return dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1362 return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1365 static int dib7000p_identify(struct dib7000p_state *st)
1368 dprintk("checking demod on I2C address: %d (%x)", st->i2c_addr, st->i2c_addr);
1370 if ((value = dib7000p_read_word(st, 768)) != 0x01b3) {
1371 dprintk("wrong Vendor ID (read=0x%x)", value);
1375 if ((value = dib7000p_read_word(st, 769)) != 0x4000) {
1376 dprintk("wrong Device ID (%x)", value);
1383 static int dib7000p_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1385 struct dib7000p_state *state = fe->demodulator_priv;
1386 u16 tps = dib7000p_read_word(state, 463);
1388 fep->inversion = INVERSION_AUTO;
1390 fep->u.ofdm.bandwidth = BANDWIDTH_TO_INDEX(state->current_bandwidth);
1392 switch ((tps >> 8) & 0x3) {
1394 fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
1397 fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
1399 /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */
1402 switch (tps & 0x3) {
1404 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
1407 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
1410 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
1413 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
1417 switch ((tps >> 14) & 0x3) {
1419 fep->u.ofdm.constellation = QPSK;
1422 fep->u.ofdm.constellation = QAM_16;
1426 fep->u.ofdm.constellation = QAM_64;
1430 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1431 /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1433 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
1434 switch ((tps >> 5) & 0x7) {
1436 fep->u.ofdm.code_rate_HP = FEC_1_2;
1439 fep->u.ofdm.code_rate_HP = FEC_2_3;
1442 fep->u.ofdm.code_rate_HP = FEC_3_4;
1445 fep->u.ofdm.code_rate_HP = FEC_5_6;
1449 fep->u.ofdm.code_rate_HP = FEC_7_8;
1454 switch ((tps >> 2) & 0x7) {
1456 fep->u.ofdm.code_rate_LP = FEC_1_2;
1459 fep->u.ofdm.code_rate_LP = FEC_2_3;
1462 fep->u.ofdm.code_rate_LP = FEC_3_4;
1465 fep->u.ofdm.code_rate_LP = FEC_5_6;
1469 fep->u.ofdm.code_rate_LP = FEC_7_8;
1473 /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */
1478 static int dib7000p_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1480 struct dib7000p_state *state = fe->demodulator_priv;
1483 if (state->version == SOC7090)
1484 dib7090_set_diversity_in(fe, 0);
1486 dib7000p_set_output_mode(state, OUTMODE_HIGH_Z);
1488 /* maybe the parameter has been changed */
1489 state->sfn_workaround_active = buggy_sfn_workaround;
1491 if (fe->ops.tuner_ops.set_params)
1492 fe->ops.tuner_ops.set_params(fe);
1494 /* start up the AGC */
1495 state->agc_state = 0;
1497 time = dib7000p_agc_startup(fe, fep);
1500 } while (time != -1);
1502 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
1503 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || fep->u.ofdm.constellation == QAM_AUTO || fep->u.ofdm.code_rate_HP == FEC_AUTO) {
1506 dib7000p_autosearch_start(fe, fep);
1509 found = dib7000p_autosearch_is_irq(fe);
1510 } while (found == 0 && i--);
1512 dprintk("autosearch returns: %d", found);
1513 if (found == 0 || found == 1)
1516 dib7000p_get_frontend(fe, fep);
1519 ret = dib7000p_tune(fe, fep);
1521 /* make this a config parameter */
1522 if (state->version == SOC7090) {
1523 dib7090_set_output_mode(fe, state->cfg.output_mode);
1524 if (state->cfg.enMpegOutput == 0) {
1525 dib7090_setDibTxMux(state, MPEG_ON_DIBTX);
1526 dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS);
1529 dib7000p_set_output_mode(state, state->cfg.output_mode);
1534 static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t * stat)
1536 struct dib7000p_state *state = fe->demodulator_priv;
1537 u16 lock = dib7000p_read_word(state, 509);
1542 *stat |= FE_HAS_SIGNAL;
1544 *stat |= FE_HAS_CARRIER;
1546 *stat |= FE_HAS_VITERBI;
1548 *stat |= FE_HAS_SYNC;
1549 if ((lock & 0x0038) == 0x38)
1550 *stat |= FE_HAS_LOCK;
1555 static int dib7000p_read_ber(struct dvb_frontend *fe, u32 * ber)
1557 struct dib7000p_state *state = fe->demodulator_priv;
1558 *ber = (dib7000p_read_word(state, 500) << 16) | dib7000p_read_word(state, 501);
1562 static int dib7000p_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
1564 struct dib7000p_state *state = fe->demodulator_priv;
1565 *unc = dib7000p_read_word(state, 506);
1569 static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
1571 struct dib7000p_state *state = fe->demodulator_priv;
1572 u16 val = dib7000p_read_word(state, 394);
1573 *strength = 65535 - val;
1577 static int dib7000p_read_snr(struct dvb_frontend *fe, u16 * snr)
1579 struct dib7000p_state *state = fe->demodulator_priv;
1581 s32 signal_mant, signal_exp, noise_mant, noise_exp;
1584 val = dib7000p_read_word(state, 479);
1585 noise_mant = (val >> 4) & 0xff;
1586 noise_exp = ((val & 0xf) << 2);
1587 val = dib7000p_read_word(state, 480);
1588 noise_exp += ((val >> 14) & 0x3);
1589 if ((noise_exp & 0x20) != 0)
1592 signal_mant = (val >> 6) & 0xFF;
1593 signal_exp = (val & 0x3F);
1594 if ((signal_exp & 0x20) != 0)
1597 if (signal_mant != 0)
1598 result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
1600 result = intlog10(2) * 10 * signal_exp - 100;
1602 if (noise_mant != 0)
1603 result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
1605 result -= intlog10(2) * 10 * noise_exp - 100;
1607 *snr = result / ((1 << 24) / 10);
1611 static int dib7000p_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
1613 tune->min_delay_ms = 1000;
1617 static void dib7000p_release(struct dvb_frontend *demod)
1619 struct dib7000p_state *st = demod->demodulator_priv;
1620 dibx000_exit_i2c_master(&st->i2c_master);
1621 i2c_del_adapter(&st->dib7090_tuner_adap);
1625 int dib7000pc_detection(struct i2c_adapter *i2c_adap)
1628 struct i2c_msg msg[2] = {
1629 {.addr = 18 >> 1, .flags = 0, .len = 2},
1630 {.addr = 18 >> 1, .flags = I2C_M_RD, .len = 2},
1634 tx = kzalloc(2*sizeof(u8), GFP_KERNEL);
1637 rx = kzalloc(2*sizeof(u8), GFP_KERNEL);
1640 goto rx_memory_error;
1649 if (i2c_transfer(i2c_adap, msg, 2) == 2)
1650 if (rx[0] == 0x01 && rx[1] == 0xb3) {
1651 dprintk("-D- DiB7000PC detected");
1655 msg[0].addr = msg[1].addr = 0x40;
1657 if (i2c_transfer(i2c_adap, msg, 2) == 2)
1658 if (rx[0] == 0x01 && rx[1] == 0xb3) {
1659 dprintk("-D- DiB7000PC detected");
1663 dprintk("-D- DiB7000PC not detected");
1670 EXPORT_SYMBOL(dib7000pc_detection);
1672 struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
1674 struct dib7000p_state *st = demod->demodulator_priv;
1675 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1677 EXPORT_SYMBOL(dib7000p_get_i2c_master);
1679 int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1681 struct dib7000p_state *state = fe->demodulator_priv;
1682 u16 val = dib7000p_read_word(state, 235) & 0xffef;
1683 val |= (onoff & 0x1) << 4;
1684 dprintk("PID filter enabled %d", onoff);
1685 return dib7000p_write_word(state, 235, val);
1687 EXPORT_SYMBOL(dib7000p_pid_filter_ctrl);
1689 int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1691 struct dib7000p_state *state = fe->demodulator_priv;
1692 dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
1693 return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0);
1695 EXPORT_SYMBOL(dib7000p_pid_filter);
1697 int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
1699 struct dib7000p_state *dpst;
1703 dpst = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
1707 dpst->i2c_adap = i2c;
1708 mutex_init(&dpst->i2c_buffer_lock);
1710 for (k = no_of_demods - 1; k >= 0; k--) {
1713 /* designated i2c address */
1714 if (cfg[k].default_i2c_addr != 0)
1715 new_addr = cfg[k].default_i2c_addr + (k << 1);
1717 new_addr = (0x40 + k) << 1;
1718 dpst->i2c_addr = new_addr;
1719 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */
1720 if (dib7000p_identify(dpst) != 0) {
1721 dpst->i2c_addr = default_addr;
1722 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */
1723 if (dib7000p_identify(dpst) != 0) {
1724 dprintk("DiB7000P #%d: not identified\n", k);
1730 /* start diversity to pull_down div_str - just for i2c-enumeration */
1731 dib7000p_set_output_mode(dpst, OUTMODE_DIVERSITY);
1733 /* set new i2c address and force divstart */
1734 dib7000p_write_word(dpst, 1285, (new_addr << 2) | 0x2);
1736 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
1739 for (k = 0; k < no_of_demods; k++) {
1741 if (cfg[k].default_i2c_addr != 0)
1742 dpst->i2c_addr = (cfg[k].default_i2c_addr + k) << 1;
1744 dpst->i2c_addr = (0x40 + k) << 1;
1747 dib7000p_write_word(dpst, 1285, dpst->i2c_addr << 2);
1749 /* deactivate div - it was just for i2c-enumeration */
1750 dib7000p_set_output_mode(dpst, OUTMODE_HIGH_Z);
1756 EXPORT_SYMBOL(dib7000p_i2c_enumeration);
1758 static const s32 lut_1000ln_mant[] = {
1759 6908, 6956, 7003, 7047, 7090, 7131, 7170, 7208, 7244, 7279, 7313, 7346, 7377, 7408, 7438, 7467, 7495, 7523, 7549, 7575, 7600
1762 static s32 dib7000p_get_adc_power(struct dvb_frontend *fe)
1764 struct dib7000p_state *state = fe->demodulator_priv;
1765 u32 tmp_val = 0, exp = 0, mant = 0;
1770 buf[0] = dib7000p_read_word(state, 0x184);
1771 buf[1] = dib7000p_read_word(state, 0x185);
1772 pow_i = (buf[0] << 16) | buf[1];
1773 dprintk("raw pow_i = %d", pow_i);
1776 while (tmp_val >>= 1)
1779 mant = (pow_i * 1000 / (1 << exp));
1780 dprintk(" mant = %d exp = %d", mant / 1000, exp);
1782 ix = (u8) ((mant - 1000) / 100); /* index of the LUT */
1783 dprintk(" ix = %d", ix);
1785 pow_i = (lut_1000ln_mant[ix] + 693 * (exp - 20) - 6908);
1786 pow_i = (pow_i << 8) / 1000;
1787 dprintk(" pow_i = %d", pow_i);
1792 static int map_addr_to_serpar_number(struct i2c_msg *msg)
1794 if ((msg->buf[0] <= 15))
1796 else if (msg->buf[0] == 17)
1798 else if (msg->buf[0] == 16)
1800 else if (msg->buf[0] == 19)
1802 else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
1804 else if (msg->buf[0] == 28)
1811 static int w7090p_tuner_write_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1813 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1816 u16 serpar_num = msg[0].buf[0];
1818 while (n_overflow == 1 && i) {
1819 n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
1822 dprintk("Tuner ITF: write busy (overflow)");
1824 dib7000p_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
1825 dib7000p_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
1830 static int w7090p_tuner_read_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1832 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1833 u8 n_overflow = 1, n_empty = 1;
1835 u16 serpar_num = msg[0].buf[0];
1838 while (n_overflow == 1 && i) {
1839 n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
1842 dprintk("TunerITF: read busy (overflow)");
1844 dib7000p_write_word(state, 1985, (0 << 6) | (serpar_num & 0x3f));
1847 while (n_empty == 1 && i) {
1848 n_empty = dib7000p_read_word(state, 1984) & 0x1;
1851 dprintk("TunerITF: read busy (empty)");
1853 read_word = dib7000p_read_word(state, 1987);
1854 msg[1].buf[0] = (read_word >> 8) & 0xff;
1855 msg[1].buf[1] = (read_word) & 0xff;
1860 static int w7090p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1862 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... */
1863 if (num == 1) { /* write */
1864 return w7090p_tuner_write_serpar(i2c_adap, msg, 1);
1866 return w7090p_tuner_read_serpar(i2c_adap, msg, 2);
1872 static int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap,
1873 struct i2c_msg msg[], int num, u16 apb_address)
1875 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1878 if (num == 1) { /* write */
1879 dib7000p_write_word(state, apb_address, ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
1881 word = dib7000p_read_word(state, apb_address);
1882 msg[1].buf[0] = (word >> 8) & 0xff;
1883 msg[1].buf[1] = (word) & 0xff;
1889 static int dib7090_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1891 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1893 u16 apb_address = 0, word;
1895 switch (msg[0].buf[0]) {
1981 i = ((dib7000p_read_word(state, 72) >> 12) & 0x3);
1982 word = dib7000p_read_word(state, 384 + i);
1983 msg[1].buf[0] = (word >> 8) & 0xff;
1984 msg[1].buf[1] = (word) & 0xff;
1987 if (num == 1) { /* write */
1988 word = (u16) ((msg[0].buf[1] << 8) | msg[0].buf[2]);
1990 word = (dib7000p_read_word(state, 72) & ~(3 << 12)) | (word << 12);
1991 dib7000p_write_word(state, 72, word); /* Set the proper input */
1996 if (apb_address != 0) /* R/W acces via APB */
1997 return dib7090p_rw_on_apb(i2c_adap, msg, num, apb_address);
1998 else /* R/W access via SERPAR */
1999 return w7090p_tuner_rw_serpar(i2c_adap, msg, num);
2004 static u32 dib7000p_i2c_func(struct i2c_adapter *adapter)
2006 return I2C_FUNC_I2C;
2009 static struct i2c_algorithm dib7090_tuner_xfer_algo = {
2010 .master_xfer = dib7090_tuner_xfer,
2011 .functionality = dib7000p_i2c_func,
2014 struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
2016 struct dib7000p_state *st = fe->demodulator_priv;
2017 return &st->dib7090_tuner_adap;
2019 EXPORT_SYMBOL(dib7090_get_i2c_tuner);
2021 static int dib7090_host_bus_drive(struct dib7000p_state *state, u8 drive)
2025 /* drive host bus 2, 3, 4 */
2026 reg = dib7000p_read_word(state, 1798) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
2027 reg |= (drive << 12) | (drive << 6) | drive;
2028 dib7000p_write_word(state, 1798, reg);
2030 /* drive host bus 5,6 */
2031 reg = dib7000p_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
2032 reg |= (drive << 8) | (drive << 2);
2033 dib7000p_write_word(state, 1799, reg);
2035 /* drive host bus 7, 8, 9 */
2036 reg = dib7000p_read_word(state, 1800) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
2037 reg |= (drive << 12) | (drive << 6) | drive;
2038 dib7000p_write_word(state, 1800, reg);
2040 /* drive host bus 10, 11 */
2041 reg = dib7000p_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
2042 reg |= (drive << 8) | (drive << 2);
2043 dib7000p_write_word(state, 1801, reg);
2045 /* drive host bus 12, 13, 14 */
2046 reg = dib7000p_read_word(state, 1802) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
2047 reg |= (drive << 12) | (drive << 6) | drive;
2048 dib7000p_write_word(state, 1802, reg);
2053 static u32 dib7090_calcSyncFreq(u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 syncSize)
2056 u32 nom = (insertExtSynchro * P_Kin + syncSize);
2058 u32 syncFreq = ((nom << quantif) / denom);
2060 if ((syncFreq & ((1 << quantif) - 1)) != 0)
2061 syncFreq = (syncFreq >> quantif) + 1;
2063 syncFreq = (syncFreq >> quantif);
2066 syncFreq = syncFreq - 1;
2071 static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize)
2073 dprintk("Configure DibStream Tx");
2075 dib7000p_write_word(state, 1615, 1);
2076 dib7000p_write_word(state, 1603, P_Kin);
2077 dib7000p_write_word(state, 1605, P_Kout);
2078 dib7000p_write_word(state, 1606, insertExtSynchro);
2079 dib7000p_write_word(state, 1608, synchroMode);
2080 dib7000p_write_word(state, 1609, (syncWord >> 16) & 0xffff);
2081 dib7000p_write_word(state, 1610, syncWord & 0xffff);
2082 dib7000p_write_word(state, 1612, syncSize);
2083 dib7000p_write_word(state, 1615, 0);
2088 static int dib7090_cfg_DibRx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 synchroMode, u32 insertExtSynchro, u32 syncWord, u32 syncSize,
2093 dprintk("Configure DibStream Rx");
2094 if ((P_Kin != 0) && (P_Kout != 0)) {
2095 syncFreq = dib7090_calcSyncFreq(P_Kin, P_Kout, insertExtSynchro, syncSize);
2096 dib7000p_write_word(state, 1542, syncFreq);
2098 dib7000p_write_word(state, 1554, 1);
2099 dib7000p_write_word(state, 1536, P_Kin);
2100 dib7000p_write_word(state, 1537, P_Kout);
2101 dib7000p_write_word(state, 1539, synchroMode);
2102 dib7000p_write_word(state, 1540, (syncWord >> 16) & 0xffff);
2103 dib7000p_write_word(state, 1541, syncWord & 0xffff);
2104 dib7000p_write_word(state, 1543, syncSize);
2105 dib7000p_write_word(state, 1544, dataOutRate);
2106 dib7000p_write_word(state, 1554, 0);
2111 static void dib7090_enMpegMux(struct dib7000p_state *state, int onoff)
2113 u16 reg_1287 = dib7000p_read_word(state, 1287);
2117 reg_1287 &= ~(1<<7);
2124 dib7000p_write_word(state, 1287, reg_1287);
2127 static void dib7090_configMpegMux(struct dib7000p_state *state,
2128 u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
2130 dprintk("Enable Mpeg mux");
2132 dib7090_enMpegMux(state, 0);
2134 /* If the input mode is MPEG do not divide the serial clock */
2135 if ((enSerialMode == 1) && (state->input_mode_mpeg == 1))
2136 enSerialClkDiv2 = 0;
2138 dib7000p_write_word(state, 1287, ((pulseWidth & 0x1f) << 2)
2139 | ((enSerialMode & 0x1) << 1)
2140 | (enSerialClkDiv2 & 0x1));
2142 dib7090_enMpegMux(state, 1);
2145 static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode)
2147 u16 reg_1288 = dib7000p_read_word(state, 1288) & ~(0x7 << 7);
2151 dprintk("SET MPEG ON DIBSTREAM TX");
2152 dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
2156 dprintk("SET DIV_OUT ON DIBSTREAM TX");
2157 dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
2161 dprintk("SET ADC_OUT ON DIBSTREAM TX");
2162 dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
2168 dib7000p_write_word(state, 1288, reg_1288);
2171 static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode)
2173 u16 reg_1288 = dib7000p_read_word(state, 1288) & ~(0x7 << 4);
2176 case DEMOUT_ON_HOSTBUS:
2177 dprintk("SET DEM OUT OLD INTERF ON HOST BUS");
2178 dib7090_enMpegMux(state, 0);
2181 case DIBTX_ON_HOSTBUS:
2182 dprintk("SET DIBSTREAM TX ON HOST BUS");
2183 dib7090_enMpegMux(state, 0);
2186 case MPEG_ON_HOSTBUS:
2187 dprintk("SET MPEG MUX ON HOST BUS");
2193 dib7000p_write_word(state, 1288, reg_1288);
2196 int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff)
2198 struct dib7000p_state *state = fe->demodulator_priv;
2202 case 0: /* only use the internal way - not the diversity input */
2203 dprintk("%s mode OFF : by default Enable Mpeg INPUT", __func__);
2204 dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0);
2206 /* Do not divide the serial clock of MPEG MUX */
2207 /* in SERIAL MODE in case input mode MPEG is used */
2208 reg_1287 = dib7000p_read_word(state, 1287);
2209 /* enSerialClkDiv2 == 1 ? */
2210 if ((reg_1287 & 0x1) == 1) {
2211 /* force enSerialClkDiv2 = 0 */
2213 dib7000p_write_word(state, 1287, reg_1287);
2215 state->input_mode_mpeg = 1;
2217 case 1: /* both ways */
2218 case 2: /* only the diversity input */
2219 dprintk("%s ON : Enable diversity INPUT", __func__);
2220 dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
2221 state->input_mode_mpeg = 0;
2225 dib7000p_set_diversity_in(&state->demod, onoff);
2229 static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode)
2231 struct dib7000p_state *state = fe->demodulator_priv;
2233 u16 outreg, smo_mode, fifo_threshold;
2234 u8 prefer_mpeg_mux_use = 1;
2237 dib7090_host_bus_drive(state, 1);
2239 fifo_threshold = 1792;
2240 smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
2241 outreg = dib7000p_read_word(state, 1286) & ~((1 << 10) | (0x7 << 6) | (1 << 1));
2244 case OUTMODE_HIGH_Z:
2248 case OUTMODE_MPEG2_SERIAL:
2249 if (prefer_mpeg_mux_use) {
2250 dprintk("setting output mode TS_SERIAL using Mpeg Mux");
2251 dib7090_configMpegMux(state, 3, 1, 1);
2252 dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS);
2253 } else {/* Use Smooth block */
2254 dprintk("setting output mode TS_SERIAL using Smooth bloc");
2255 dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
2256 outreg |= (2<<6) | (0 << 1);
2260 case OUTMODE_MPEG2_PAR_GATED_CLK:
2261 if (prefer_mpeg_mux_use) {
2262 dprintk("setting output mode TS_PARALLEL_GATED using Mpeg Mux");
2263 dib7090_configMpegMux(state, 2, 0, 0);
2264 dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS);
2265 } else { /* Use Smooth block */
2266 dprintk("setting output mode TS_PARALLEL_GATED using Smooth block");
2267 dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
2272 case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */
2273 dprintk("setting output mode TS_PARALLEL_CONT using Smooth block");
2274 dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
2278 case OUTMODE_MPEG2_FIFO: /* Using Smooth block because not supported by new Mpeg Mux bloc */
2279 dprintk("setting output mode TS_FIFO using Smooth block");
2280 dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
2282 smo_mode |= (3 << 1);
2283 fifo_threshold = 512;
2286 case OUTMODE_DIVERSITY:
2287 dprintk("setting output mode MODE_DIVERSITY");
2288 dib7090_setDibTxMux(state, DIV_ON_DIBTX);
2289 dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS);
2292 case OUTMODE_ANALOG_ADC:
2293 dprintk("setting output mode MODE_ANALOG_ADC");
2294 dib7090_setDibTxMux(state, ADC_ON_DIBTX);
2295 dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS);
2298 if (mode != OUTMODE_HIGH_Z)
2299 outreg |= (1 << 10);
2301 if (state->cfg.output_mpeg2_in_188_bytes)
2302 smo_mode |= (1 << 5);
2304 ret |= dib7000p_write_word(state, 235, smo_mode);
2305 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
2306 ret |= dib7000p_write_word(state, 1286, outreg);
2311 int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
2313 struct dib7000p_state *state = fe->demodulator_priv;
2316 dprintk("sleep dib7090: %d", onoff);
2318 en_cur_state = dib7000p_read_word(state, 1922);
2320 if (en_cur_state > 0xff)
2321 state->tuner_enable = en_cur_state;
2324 en_cur_state &= 0x00ff;
2326 if (state->tuner_enable != 0)
2327 en_cur_state = state->tuner_enable;
2330 dib7000p_write_word(state, 1922, en_cur_state);
2334 EXPORT_SYMBOL(dib7090_tuner_sleep);
2336 int dib7090_get_adc_power(struct dvb_frontend *fe)
2338 return dib7000p_get_adc_power(fe);
2340 EXPORT_SYMBOL(dib7090_get_adc_power);
2342 int dib7090_slave_reset(struct dvb_frontend *fe)
2344 struct dib7000p_state *state = fe->demodulator_priv;
2347 reg = dib7000p_read_word(state, 1794);
2348 dib7000p_write_word(state, 1794, reg | (4 << 12));
2350 dib7000p_write_word(state, 1032, 0xffff);
2353 EXPORT_SYMBOL(dib7090_slave_reset);
2355 static struct dvb_frontend_ops dib7000p_ops;
2356 struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
2358 struct dvb_frontend *demod;
2359 struct dib7000p_state *st;
2360 st = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
2364 memcpy(&st->cfg, cfg, sizeof(struct dib7000p_config));
2365 st->i2c_adap = i2c_adap;
2366 st->i2c_addr = i2c_addr;
2367 st->gpio_val = cfg->gpio_val;
2368 st->gpio_dir = cfg->gpio_dir;
2370 /* Ensure the output mode remains at the previous default if it's
2371 * not specifically set by the caller.
2373 if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2374 st->cfg.output_mode = OUTMODE_MPEG2_FIFO;
2377 demod->demodulator_priv = st;
2378 memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));
2379 mutex_init(&st->i2c_buffer_lock);
2381 dib7000p_write_word(st, 1287, 0x0003); /* sram lead in, rdy */
2383 if (dib7000p_identify(st) != 0)
2386 st->version = dib7000p_read_word(st, 897);
2388 /* FIXME: make sure the dev.parent field is initialized, or else
2389 request_firmware() will hit an OOPS (this should be moved somewhere
2391 st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent;
2393 /* FIXME: make sure the dev.parent field is initialized, or else
2394 request_firmware() will hit an OOPS (this should be moved somewhere
2396 st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent;
2398 dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr);
2400 /* init 7090 tuner adapter */
2401 strncpy(st->dib7090_tuner_adap.name, "DiB7090 tuner interface", sizeof(st->dib7090_tuner_adap.name));
2402 st->dib7090_tuner_adap.algo = &dib7090_tuner_xfer_algo;
2403 st->dib7090_tuner_adap.algo_data = NULL;
2404 st->dib7090_tuner_adap.dev.parent = st->i2c_adap->dev.parent;
2405 i2c_set_adapdata(&st->dib7090_tuner_adap, st);
2406 i2c_add_adapter(&st->dib7090_tuner_adap);
2408 dib7000p_demod_reset(st);
2410 if (st->version == SOC7090) {
2411 dib7090_set_output_mode(demod, st->cfg.output_mode);
2412 dib7090_set_diversity_in(demod, 0);
2421 EXPORT_SYMBOL(dib7000p_attach);
2423 static struct dvb_frontend_ops dib7000p_ops = {
2425 .name = "DiBcom 7000PC",
2427 .frequency_min = 44250000,
2428 .frequency_max = 867250000,
2429 .frequency_stepsize = 62500,
2430 .caps = FE_CAN_INVERSION_AUTO |
2431 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2432 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2433 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2434 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2437 .release = dib7000p_release,
2439 .init = dib7000p_wakeup,
2440 .sleep = dib7000p_sleep,
2442 .set_frontend_legacy = dib7000p_set_frontend,
2443 .get_tune_settings = dib7000p_fe_get_tune_settings,
2444 .get_frontend = dib7000p_get_frontend,
2446 .read_status = dib7000p_read_status,
2447 .read_ber = dib7000p_read_ber,
2448 .read_signal_strength = dib7000p_read_signal_strength,
2449 .read_snr = dib7000p_read_snr,
2450 .read_ucblocks = dib7000p_read_unc_blocks,
2455 MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
2456 MODULE_LICENSE("GPL");