V4L/DVB (5954): Sync with DiBcom Driver Release 2.1.3 + some improvements
[linux-2.6/zen-sources.git] / drivers / media / dvb / frontends / dib7000p.c
blob156c53ab56dbd2471a87b9aac4d3755c63e96d18
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/i2c.h>
13 #include "dvb_frontend.h"
15 #include "dib7000p.h"
17 static int debug;
18 module_param(debug, int, 0644);
19 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
21 #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0)
23 struct dib7000p_state {
24 struct dvb_frontend demod;
25 struct dib7000p_config cfg;
27 u8 i2c_addr;
28 struct i2c_adapter *i2c_adap;
30 struct dibx000_i2c_master i2c_master;
32 u16 wbd_ref;
34 u8 current_band;
35 fe_bandwidth_t current_bandwidth;
36 struct dibx000_agc_config *current_agc;
37 u32 timf;
39 uint8_t div_force_off : 1;
40 uint8_t div_state : 1;
41 uint16_t div_sync_wait;
43 u8 agc_state;
45 u16 gpio_dir;
46 u16 gpio_val;
49 enum dib7000p_power_mode {
50 DIB7000P_POWER_ALL = 0,
51 DIB7000P_POWER_ANALOG_ADC,
52 DIB7000P_POWER_INTERFACE_ONLY,
55 static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
57 u8 wb[2] = { reg >> 8, reg & 0xff };
58 u8 rb[2];
59 struct i2c_msg msg[2] = {
60 { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 },
61 { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
64 if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
65 dprintk("i2c read error on %d",reg);
67 return (rb[0] << 8) | rb[1];
70 static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
72 u8 b[4] = {
73 (reg >> 8) & 0xff, reg & 0xff,
74 (val >> 8) & 0xff, val & 0xff,
76 struct i2c_msg msg = {
77 .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
79 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
81 static void dib7000p_write_tab(struct dib7000p_state *state, u16 *buf)
83 u16 l = 0, r, *n;
84 n = buf;
85 l = *n++;
86 while (l) {
87 r = *n++;
89 do {
90 dib7000p_write_word(state, r, *n++);
91 r++;
92 } while (--l);
93 l = *n++;
97 static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
99 int ret = 0;
100 u16 outreg, fifo_threshold, smo_mode;
102 outreg = 0;
103 fifo_threshold = 1792;
104 smo_mode = (dib7000p_read_word(state, 235) & 0x0010) | (1 << 1);
106 dprintk( "setting output mode for demod %p to %d",
107 &state->demod, mode);
109 switch (mode) {
110 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
111 outreg = (1 << 10); /* 0x0400 */
112 break;
113 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
114 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
115 break;
116 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
117 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */
118 break;
119 case OUTMODE_DIVERSITY:
120 if (state->cfg.hostbus_diversity)
121 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
122 else
123 outreg = (1 << 11);
124 break;
125 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
126 smo_mode |= (3 << 1);
127 fifo_threshold = 512;
128 outreg = (1 << 10) | (5 << 6);
129 break;
130 case OUTMODE_ANALOG_ADC:
131 outreg = (1 << 10) | (3 << 6);
132 break;
133 case OUTMODE_HIGH_Z: // disable
134 outreg = 0;
135 break;
136 default:
137 dprintk( "Unhandled output_mode passed to be set for demod %p",&state->demod);
138 break;
141 if (state->cfg.output_mpeg2_in_188_bytes)
142 smo_mode |= (1 << 5) ;
144 ret |= dib7000p_write_word(state, 235, smo_mode);
145 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
146 ret |= dib7000p_write_word(state, 1286, outreg); /* P_Div_active */
148 return ret;
151 static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
153 struct dib7000p_state *state = demod->demodulator_priv;
155 if (state->div_force_off) {
156 dprintk( "diversity combination deactivated - forced by COFDM parameters");
157 onoff = 0;
159 state->div_state = (uint8_t)onoff;
161 if (onoff) {
162 dib7000p_write_word(state, 204, 6);
163 dib7000p_write_word(state, 205, 16);
164 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
165 dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
166 } else {
167 dib7000p_write_word(state, 204, 1);
168 dib7000p_write_word(state, 205, 0);
169 dib7000p_write_word(state, 207, 0);
172 return 0;
175 static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode)
177 /* by default everything is powered off */
178 u16 reg_774 = 0xffff, reg_775 = 0xffff, reg_776 = 0x0007, reg_899 = 0x0003,
179 reg_1280 = (0xfe00) | (dib7000p_read_word(state, 1280) & 0x01ff);
181 /* now, depending on the requested mode, we power on */
182 switch (mode) {
183 /* power up everything in the demod */
184 case DIB7000P_POWER_ALL:
185 reg_774 = 0x0000; reg_775 = 0x0000; reg_776 = 0x0; reg_899 = 0x0; reg_1280 &= 0x01ff;
186 break;
188 case DIB7000P_POWER_ANALOG_ADC:
189 /* dem, cfg, iqc, sad, agc */
190 reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
191 /* nud */
192 reg_776 &= ~((1 << 0));
193 /* Dout */
194 reg_1280 &= ~((1 << 11));
195 /* fall through wanted to enable the interfaces */
197 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
198 case DIB7000P_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C */
199 reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
200 break;
202 /* TODO following stuff is just converted from the dib7000-driver - check when is used what */
205 dib7000p_write_word(state, 774, reg_774);
206 dib7000p_write_word(state, 775, reg_775);
207 dib7000p_write_word(state, 776, reg_776);
208 dib7000p_write_word(state, 899, reg_899);
209 dib7000p_write_word(state, 1280, reg_1280);
211 return 0;
214 static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no)
216 u16 reg_908 = dib7000p_read_word(state, 908),
217 reg_909 = dib7000p_read_word(state, 909);
219 switch (no) {
220 case DIBX000_SLOW_ADC_ON:
221 reg_909 |= (1 << 1) | (1 << 0);
222 dib7000p_write_word(state, 909, reg_909);
223 reg_909 &= ~(1 << 1);
224 break;
226 case DIBX000_SLOW_ADC_OFF:
227 reg_909 |= (1 << 1) | (1 << 0);
228 break;
230 case DIBX000_ADC_ON:
231 reg_908 &= 0x0fff;
232 reg_909 &= 0x0003;
233 break;
235 case DIBX000_ADC_OFF: // leave the VBG voltage on
236 reg_908 |= (1 << 14) | (1 << 13) | (1 << 12);
237 reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
238 break;
240 case DIBX000_VBG_ENABLE:
241 reg_908 &= ~(1 << 15);
242 break;
244 case DIBX000_VBG_DISABLE:
245 reg_908 |= (1 << 15);
246 break;
248 default:
249 break;
252 // dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
254 dib7000p_write_word(state, 908, reg_908);
255 dib7000p_write_word(state, 909, reg_909);
258 static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
260 u32 timf;
262 // store the current bandwidth for later use
263 state->current_bandwidth = bw;
265 if (state->timf == 0) {
266 dprintk( "using default timf");
267 timf = state->cfg.bw->timf;
268 } else {
269 dprintk( "using updated timf");
270 timf = state->timf;
273 timf = timf * (bw / 50) / 160;
275 dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
276 dib7000p_write_word(state, 24, (u16) ((timf ) & 0xffff));
278 return 0;
281 static int dib7000p_sad_calib(struct dib7000p_state *state)
283 /* internal */
284 // dib7000p_write_word(state, 72, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth
285 dib7000p_write_word(state, 73, (0 << 1) | (0 << 0));
286 dib7000p_write_word(state, 74, 776); // 0.625*3.3 / 4096
288 /* do the calibration */
289 dib7000p_write_word(state, 73, (1 << 0));
290 dib7000p_write_word(state, 73, (0 << 0));
292 msleep(1);
294 return 0;
297 static void dib7000p_reset_pll(struct dib7000p_state *state)
299 struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
300 u16 clk_cfg0;
302 /* force PLL bypass */
303 clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) |
304 (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) |
305 (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0);
307 dib7000p_write_word(state, 900, clk_cfg0);
309 /* P_pll_cfg */
310 dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset);
311 clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff);
312 dib7000p_write_word(state, 900, clk_cfg0);
314 dib7000p_write_word(state, 18, (u16) (((bw->internal*1000) >> 16) & 0xffff));
315 dib7000p_write_word(state, 19, (u16) ( (bw->internal*1000 ) & 0xffff));
316 dib7000p_write_word(state, 21, (u16) ( (bw->ifreq >> 16) & 0xffff));
317 dib7000p_write_word(state, 22, (u16) ( (bw->ifreq ) & 0xffff));
319 dib7000p_write_word(state, 72, bw->sad_cfg);
322 static int dib7000p_reset_gpio(struct dib7000p_state *st)
324 /* reset the GPIOs */
325 dprintk( "gpio dir: %x: val: %x, pwm_pos: %x",st->gpio_dir, st->gpio_val,st->cfg.gpio_pwm_pos);
327 dib7000p_write_word(st, 1029, st->gpio_dir);
328 dib7000p_write_word(st, 1030, st->gpio_val);
330 /* TODO 1031 is P_gpio_od */
332 dib7000p_write_word(st, 1032, st->cfg.gpio_pwm_pos);
334 dib7000p_write_word(st, 1037, st->cfg.pwm_freq_div);
335 return 0;
338 static u16 dib7000p_defaults[] =
341 // auto search configuration
342 3, 2,
343 0x0004,
344 0x1000,
345 0x0814, /* Equal Lock */
347 12, 6,
348 0x001b,
349 0x7740,
350 0x005b,
351 0x8d80,
352 0x01c9,
353 0xc380,
354 0x0000,
355 0x0080,
356 0x0000,
357 0x0090,
358 0x0001,
359 0xd4c0,
361 1, 26,
362 0x6680, // P_timf_alpha=6, P_corm_alpha=6, P_corm_thres=128 default: 6,4,26
364 /* set ADC level to -16 */
365 11, 79,
366 (1 << 13) - 825 - 117,
367 (1 << 13) - 837 - 117,
368 (1 << 13) - 811 - 117,
369 (1 << 13) - 766 - 117,
370 (1 << 13) - 737 - 117,
371 (1 << 13) - 693 - 117,
372 (1 << 13) - 648 - 117,
373 (1 << 13) - 619 - 117,
374 (1 << 13) - 575 - 117,
375 (1 << 13) - 531 - 117,
376 (1 << 13) - 501 - 117,
378 1, 142,
379 0x0410, // P_palf_filter_on=1, P_palf_filter_freeze=0, P_palf_alpha_regul=16
381 /* disable power smoothing */
382 8, 145,
392 1, 154,
393 1 << 13, // P_fft_freq_dir=1, P_fft_nb_to_cut=0
395 1, 168,
396 0x0ccd, // P_pha3_thres, default 0x3000
398 // 1, 169,
399 // 0x0010, // P_cti_use_cpe=0, P_cti_use_prog=0, P_cti_win_len=16, default: 0x0010
401 1, 183,
402 0x200f, // P_cspu_regul=512, P_cspu_win_cut=15, default: 0x2005
404 5, 187,
405 0x023d, // P_adp_regul_cnt=573, default: 410
406 0x00a4, // P_adp_noise_cnt=
407 0x00a4, // P_adp_regul_ext
408 0x7ff0, // P_adp_noise_ext
409 0x3ccc, // P_adp_fil
411 1, 198,
412 0x800, // P_equal_thres_wgn
414 1, 222,
415 0x0010, // P_fec_ber_rs_len=2
417 1, 235,
418 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
420 2, 901,
421 0x0006, // P_clk_cfg1
422 (3 << 10) | (1 << 6), // P_divclksel=3 P_divbitsel=1
424 1, 905,
425 0x2c8e, // Tuner IO bank: max drive (14mA) + divout pads max drive
430 static int dib7000p_demod_reset(struct dib7000p_state *state)
432 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
434 dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE);
436 /* restart all parts */
437 dib7000p_write_word(state, 770, 0xffff);
438 dib7000p_write_word(state, 771, 0xffff);
439 dib7000p_write_word(state, 772, 0x001f);
440 dib7000p_write_word(state, 898, 0x0003);
441 /* except i2c, sdio, gpio - control interfaces */
442 dib7000p_write_word(state, 1280, 0x01fc - ((1 << 7) | (1 << 6) | (1 << 5)) );
444 dib7000p_write_word(state, 770, 0);
445 dib7000p_write_word(state, 771, 0);
446 dib7000p_write_word(state, 772, 0);
447 dib7000p_write_word(state, 898, 0);
448 dib7000p_write_word(state, 1280, 0);
450 /* default */
451 dib7000p_reset_pll(state);
453 if (dib7000p_reset_gpio(state) != 0)
454 dprintk( "GPIO reset was not successful.");
456 if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
457 dprintk( "OUTPUT_MODE could not be reset.");
459 /* unforce divstr regardless whether i2c enumeration was done or not */
460 dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1) );
462 dib7000p_set_bandwidth(state, 8000);
464 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
465 dib7000p_sad_calib(state);
466 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
468 // P_iqc_alpha_pha, P_iqc_alpha_amp_dcc_alpha, ...
469 if(state->cfg.tuner_is_baseband)
470 dib7000p_write_word(state, 36,0x0755);
471 else
472 dib7000p_write_word(state, 36,0x1f55);
474 dib7000p_write_tab(state, dib7000p_defaults);
476 dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
479 return 0;
482 static void dib7000p_pll_clk_cfg(struct dib7000p_state *state)
484 u16 tmp = 0;
485 tmp = dib7000p_read_word(state, 903);
486 dib7000p_write_word(state, 903, (tmp | 0x1)); //pwr-up pll
487 tmp = dib7000p_read_word(state, 900);
488 dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6)); //use High freq clock
491 static void dib7000p_restart_agc(struct dib7000p_state *state)
493 // P_restart_iqc & P_restart_agc
494 dib7000p_write_word(state, 770, (1 << 11) | (1 << 9));
495 dib7000p_write_word(state, 770, 0x0000);
498 static int dib7000p_update_lna(struct dib7000p_state *state)
500 u16 dyn_gain;
502 // when there is no LNA to program return immediatly
503 if (state->cfg.update_lna) {
504 // read dyn_gain here (because it is demod-dependent and not tuner)
505 dyn_gain = dib7000p_read_word(state, 394);
506 if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed
507 dib7000p_restart_agc(state);
508 return 1;
512 return 0;
515 static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
517 struct dibx000_agc_config *agc = NULL;
518 int i;
519 if (state->current_band == band && state->current_agc != NULL)
520 return 0;
521 state->current_band = band;
523 for (i = 0; i < state->cfg.agc_config_count; i++)
524 if (state->cfg.agc[i].band_caps & band) {
525 agc = &state->cfg.agc[i];
526 break;
529 if (agc == NULL) {
530 dprintk( "no valid AGC configuration found for band 0x%02x",band);
531 return -EINVAL;
534 state->current_agc = agc;
536 /* AGC */
537 dib7000p_write_word(state, 75 , agc->setup );
538 dib7000p_write_word(state, 76 , agc->inv_gain );
539 dib7000p_write_word(state, 77 , agc->time_stabiliz );
540 dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);
542 // Demod AGC loop configuration
543 dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);
544 dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp);
546 /* AGC continued */
547 dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d",
548 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
550 if (state->wbd_ref != 0)
551 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref);
552 else
553 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref);
555 dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
557 dib7000p_write_word(state, 107, agc->agc1_max);
558 dib7000p_write_word(state, 108, agc->agc1_min);
559 dib7000p_write_word(state, 109, agc->agc2_max);
560 dib7000p_write_word(state, 110, agc->agc2_min);
561 dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
562 dib7000p_write_word(state, 112, agc->agc1_pt3);
563 dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
564 dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
565 dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
566 return 0;
569 static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
571 struct dib7000p_state *state = demod->demodulator_priv;
572 int ret = -1;
573 u8 *agc_state = &state->agc_state;
574 u8 agc_split;
576 switch (state->agc_state) {
577 case 0:
578 // set power-up level: interf+analog+AGC
579 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
580 dib7000p_set_adc_state(state, DIBX000_ADC_ON);
581 dib7000p_pll_clk_cfg(state);
583 if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0)
584 return -1;
586 ret = 7;
587 (*agc_state)++;
588 break;
590 case 1:
591 // AGC initialization
592 if (state->cfg.agc_control)
593 state->cfg.agc_control(&state->demod, 1);
595 dib7000p_write_word(state, 78, 32768);
596 if (!state->current_agc->perform_agc_softsplit) {
597 /* we are using the wbd - so slow AGC startup */
598 /* force 0 split on WBD and restart AGC */
599 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));
600 (*agc_state)++;
601 ret = 5;
602 } else {
603 /* default AGC startup */
604 (*agc_state) = 4;
605 /* wait AGC rough lock time */
606 ret = 7;
609 dib7000p_restart_agc(state);
610 break;
612 case 2: /* fast split search path after 5sec */
613 dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4)); /* freeze AGC loop */
614 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */
615 (*agc_state)++;
616 ret = 14;
617 break;
619 case 3: /* split search ended */
620 agc_split = (uint8_t)dib7000p_read_word(state, 396); /* store the split value for the next time */
621 dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */
623 dib7000p_write_word(state, 75, state->current_agc->setup); /* std AGC loop */
624 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
626 dib7000p_restart_agc(state);
628 dprintk( "SPLIT %p: %hd", demod, agc_split);
630 (*agc_state)++;
631 ret = 5;
632 break;
634 case 4: /* LNA startup */
635 // wait AGC accurate lock time
636 ret = 7;
638 if (dib7000p_update_lna(state))
639 // wait only AGC rough lock time
640 ret = 5;
641 else // nothing was done, go to the next state
642 (*agc_state)++;
643 break;
645 case 5:
646 if (state->cfg.agc_control)
647 state->cfg.agc_control(&state->demod, 0);
648 (*agc_state)++;
649 break;
650 default:
651 break;
653 return ret;
656 static void dib7000p_update_timf(struct dib7000p_state *state)
658 u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428);
659 state->timf = timf * 160 / (state->current_bandwidth / 50);
660 dib7000p_write_word(state, 23, (u16) (timf >> 16));
661 dib7000p_write_word(state, 24, (u16) (timf & 0xffff));
662 dprintk( "updated timf_frequency: %d (default: %d)",state->timf, state->cfg.bw->timf);
666 static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq)
668 u16 value, est[4];
670 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
672 /* nfft, guard, qam, alpha */
673 value = 0;
674 switch (ch->u.ofdm.transmission_mode) {
675 case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
676 case /* 4K MODE */ 255: value |= (2 << 7); break;
677 default:
678 case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
680 switch (ch->u.ofdm.guard_interval) {
681 case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
682 case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
683 case GUARD_INTERVAL_1_4: value |= (3 << 5); break;
684 default:
685 case GUARD_INTERVAL_1_8: value |= (2 << 5); break;
687 switch (ch->u.ofdm.constellation) {
688 case QPSK: value |= (0 << 3); break;
689 case QAM_16: value |= (1 << 3); break;
690 default:
691 case QAM_64: value |= (2 << 3); break;
693 switch (HIERARCHY_1) {
694 case HIERARCHY_2: value |= 2; break;
695 case HIERARCHY_4: value |= 4; break;
696 default:
697 case HIERARCHY_1: value |= 1; break;
699 dib7000p_write_word(state, 0, value);
700 dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */
702 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
703 value = 0;
704 if (1 != 0)
705 value |= (1 << 6);
706 if (ch->u.ofdm.hierarchy_information == 1)
707 value |= (1 << 4);
708 if (1 == 1)
709 value |= 1;
710 switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
711 case FEC_2_3: value |= (2 << 1); break;
712 case FEC_3_4: value |= (3 << 1); break;
713 case FEC_5_6: value |= (5 << 1); break;
714 case FEC_7_8: value |= (7 << 1); break;
715 default:
716 case FEC_1_2: value |= (1 << 1); break;
718 dib7000p_write_word(state, 208, value);
720 /* offset loop parameters */
721 dib7000p_write_word(state, 26, 0x6680); // timf(6xxx)
722 dib7000p_write_word(state, 29, 0x1273); // isi inh1273 on1073
723 dib7000p_write_word(state, 32, 0x0003); // pha_off_max(xxx3)
724 dib7000p_write_word(state, 33, 0x0005); // sfreq(xxx5)
726 /* P_dvsy_sync_wait */
727 switch (ch->u.ofdm.transmission_mode) {
728 case TRANSMISSION_MODE_8K: value = 256; break;
729 case /* 4K MODE */ 255: value = 128; break;
730 case TRANSMISSION_MODE_2K:
731 default: value = 64; break;
733 switch (ch->u.ofdm.guard_interval) {
734 case GUARD_INTERVAL_1_16: value *= 2; break;
735 case GUARD_INTERVAL_1_8: value *= 4; break;
736 case GUARD_INTERVAL_1_4: value *= 8; break;
737 default:
738 case GUARD_INTERVAL_1_32: value *= 1; break;
740 state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO
742 /* deactive the possibility of diversity reception if extended interleaver */
743 state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K;
744 dib7000p_set_diversity_in(&state->demod, state->div_state);
746 /* channel estimation fine configuration */
747 switch (ch->u.ofdm.constellation) {
748 case QAM_64:
749 est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
750 est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
751 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
752 est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
753 break;
754 case QAM_16:
755 est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
756 est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
757 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
758 est[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
759 break;
760 default:
761 est[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
762 est[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
763 est[2] = 0x0333; /* P_adp_regul_ext 0.1 */
764 est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
765 break;
767 for (value = 0; value < 4; value++)
768 dib7000p_write_word(state, 187 + value, est[value]);
771 static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
773 struct dib7000p_state *state = demod->demodulator_priv;
774 struct dvb_frontend_parameters schan;
775 u32 value, factor;
777 schan = *ch;
778 schan.u.ofdm.constellation = QAM_64;
779 schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
780 schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
781 schan.u.ofdm.code_rate_HP = FEC_2_3;
782 schan.u.ofdm.code_rate_LP = FEC_3_4;
783 schan.u.ofdm.hierarchy_information = 0;
785 dib7000p_set_channel(state, &schan, 7);
787 factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth);
788 if (factor >= 5000)
789 factor = 1;
790 else
791 factor = 6;
793 // always use the setting for 8MHz here lock_time for 7,6 MHz are longer
794 value = 30 * state->cfg.bw->internal * factor;
795 dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff)); // lock0 wait time
796 dib7000p_write_word(state, 7, (u16) (value & 0xffff)); // lock0 wait time
797 value = 100 * state->cfg.bw->internal * factor;
798 dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff)); // lock1 wait time
799 dib7000p_write_word(state, 9, (u16) (value & 0xffff)); // lock1 wait time
800 value = 500 * state->cfg.bw->internal * factor;
801 dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
802 dib7000p_write_word(state, 11, (u16) (value & 0xffff)); // lock2 wait time
804 value = dib7000p_read_word(state, 0);
805 dib7000p_write_word(state, 0, (u16) ((1 << 9) | value));
806 dib7000p_read_word(state, 1284);
807 dib7000p_write_word(state, 0, (u16) value);
809 return 0;
812 static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod)
814 struct dib7000p_state *state = demod->demodulator_priv;
815 u16 irq_pending = dib7000p_read_word(state, 1284);
817 if (irq_pending & 0x1) // failed
818 return 1;
820 if (irq_pending & 0x2) // succeeded
821 return 2;
823 return 0; // still pending
826 static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw)
828 static s16 notch[]={16143, 14402, 12238, 9713, 6902, 3888, 759, -2392};
829 static u8 sine [] ={0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
830 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
831 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
832 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
833 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
834 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
835 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
836 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
837 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
838 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
839 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
840 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
841 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
842 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
843 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
844 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
845 255, 255, 255, 255, 255, 255};
847 u32 xtal = state->cfg.bw->xtal_hz / 1000;
848 int f_rel = ( (rf_khz + xtal/2) / xtal) * xtal - rf_khz;
849 int k;
850 int coef_re[8],coef_im[8];
851 int bw_khz = bw;
852 u32 pha;
854 dprintk( "relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal);
857 if (f_rel < -bw_khz/2 || f_rel > bw_khz/2)
858 return;
860 bw_khz /= 100;
862 dib7000p_write_word(state, 142 ,0x0610);
864 for (k = 0; k < 8; k++) {
865 pha = ((f_rel * (k+1) * 112 * 80/bw_khz) /1000) & 0x3ff;
867 if (pha==0) {
868 coef_re[k] = 256;
869 coef_im[k] = 0;
870 } else if(pha < 256) {
871 coef_re[k] = sine[256-(pha&0xff)];
872 coef_im[k] = sine[pha&0xff];
873 } else if (pha == 256) {
874 coef_re[k] = 0;
875 coef_im[k] = 256;
876 } else if (pha < 512) {
877 coef_re[k] = -sine[pha&0xff];
878 coef_im[k] = sine[256 - (pha&0xff)];
879 } else if (pha == 512) {
880 coef_re[k] = -256;
881 coef_im[k] = 0;
882 } else if (pha < 768) {
883 coef_re[k] = -sine[256-(pha&0xff)];
884 coef_im[k] = -sine[pha&0xff];
885 } else if (pha == 768) {
886 coef_re[k] = 0;
887 coef_im[k] = -256;
888 } else {
889 coef_re[k] = sine[pha&0xff];
890 coef_im[k] = -sine[256 - (pha&0xff)];
893 coef_re[k] *= notch[k];
894 coef_re[k] += (1<<14);
895 if (coef_re[k] >= (1<<24))
896 coef_re[k] = (1<<24) - 1;
897 coef_re[k] /= (1<<15);
899 coef_im[k] *= notch[k];
900 coef_im[k] += (1<<14);
901 if (coef_im[k] >= (1<<24))
902 coef_im[k] = (1<<24)-1;
903 coef_im[k] /= (1<<15);
905 dprintk( "PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]);
907 dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
908 dib7000p_write_word(state, 144, coef_im[k] & 0x3ff);
909 dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
911 dib7000p_write_word(state,143 ,0);
914 static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
916 struct dib7000p_state *state = demod->demodulator_priv;
917 u16 tmp = 0;
919 if (ch != NULL)
920 dib7000p_set_channel(state, ch, 0);
921 else
922 return -EINVAL;
924 // restart demod
925 dib7000p_write_word(state, 770, 0x4000);
926 dib7000p_write_word(state, 770, 0x0000);
927 msleep(45);
929 /* 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 */
930 dib7000p_write_word(state, 29, (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3));
932 // never achieved a lock with that bandwidth so far - wait for osc-freq to update
933 if (state->timf == 0)
934 msleep(200);
936 /* offset loop parameters */
938 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
939 tmp = (6 << 8) | 0x80;
940 switch (ch->u.ofdm.transmission_mode) {
941 case TRANSMISSION_MODE_2K: tmp |= (7 << 12); break;
942 case /* 4K MODE */ 255: tmp |= (8 << 12); break;
943 default:
944 case TRANSMISSION_MODE_8K: tmp |= (9 << 12); break;
946 dib7000p_write_word(state, 26, tmp); /* timf_a(6xxx) */
948 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
949 tmp = (0 << 4);
950 switch (ch->u.ofdm.transmission_mode) {
951 case TRANSMISSION_MODE_2K: tmp |= 0x6; break;
952 case /* 4K MODE */ 255: tmp |= 0x7; break;
953 default:
954 case TRANSMISSION_MODE_8K: tmp |= 0x8; break;
956 dib7000p_write_word(state, 32, tmp);
958 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
959 tmp = (0 << 4);
960 switch (ch->u.ofdm.transmission_mode) {
961 case TRANSMISSION_MODE_2K: tmp |= 0x6; break;
962 case /* 4K MODE */ 255: tmp |= 0x7; break;
963 default:
964 case TRANSMISSION_MODE_8K: tmp |= 0x8; break;
966 dib7000p_write_word(state, 33, tmp);
968 tmp = dib7000p_read_word(state,509);
969 if (!((tmp >> 6) & 0x1)) {
970 /* restart the fec */
971 tmp = dib7000p_read_word(state,771);
972 dib7000p_write_word(state, 771, tmp | (1 << 1));
973 dib7000p_write_word(state, 771, tmp);
974 msleep(10);
975 tmp = dib7000p_read_word(state,509);
978 // we achieved a lock - it's time to update the osc freq
979 if ((tmp >> 6) & 0x1)
980 dib7000p_update_timf(state);
982 if (state->cfg.spur_protect)
983 dib7000p_spur_protect(state, ch->frequency/1000, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
985 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
986 return 0;
989 static int dib7000p_wakeup(struct dvb_frontend *demod)
991 struct dib7000p_state *state = demod->demodulator_priv;
992 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
993 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
994 return 0;
997 static int dib7000p_sleep(struct dvb_frontend *demod)
999 struct dib7000p_state *state = demod->demodulator_priv;
1000 return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1003 static int dib7000p_identify(struct dib7000p_state *st)
1005 u16 value;
1006 dprintk( "checking demod on I2C address: %d (%x)",
1007 st->i2c_addr, st->i2c_addr);
1009 if ((value = dib7000p_read_word(st, 768)) != 0x01b3) {
1010 dprintk( "wrong Vendor ID (read=0x%x)",value);
1011 return -EREMOTEIO;
1014 if ((value = dib7000p_read_word(st, 769)) != 0x4000) {
1015 dprintk( "wrong Device ID (%x)",value);
1016 return -EREMOTEIO;
1019 return 0;
1023 static int dib7000p_get_frontend(struct dvb_frontend* fe,
1024 struct dvb_frontend_parameters *fep)
1026 struct dib7000p_state *state = fe->demodulator_priv;
1027 u16 tps = dib7000p_read_word(state,463);
1029 fep->inversion = INVERSION_AUTO;
1031 fep->u.ofdm.bandwidth = state->current_bandwidth;
1033 switch ((tps >> 8) & 0x3) {
1034 case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break;
1035 case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break;
1036 /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */
1039 switch (tps & 0x3) {
1040 case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break;
1041 case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break;
1042 case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break;
1043 case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break;
1046 switch ((tps >> 14) & 0x3) {
1047 case 0: fep->u.ofdm.constellation = QPSK; break;
1048 case 1: fep->u.ofdm.constellation = QAM_16; break;
1049 case 2:
1050 default: fep->u.ofdm.constellation = QAM_64; break;
1053 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1054 /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1056 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
1057 switch ((tps >> 5) & 0x7) {
1058 case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break;
1059 case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break;
1060 case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break;
1061 case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break;
1062 case 7:
1063 default: fep->u.ofdm.code_rate_HP = FEC_7_8; break;
1067 switch ((tps >> 2) & 0x7) {
1068 case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break;
1069 case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break;
1070 case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break;
1071 case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break;
1072 case 7:
1073 default: fep->u.ofdm.code_rate_LP = FEC_7_8; break;
1076 /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */
1078 return 0;
1081 static int dib7000p_set_frontend(struct dvb_frontend* fe,
1082 struct dvb_frontend_parameters *fep)
1084 struct dib7000p_state *state = fe->demodulator_priv;
1085 int time;
1087 state->current_bandwidth = fep->u.ofdm.bandwidth;
1088 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth));
1090 if (fe->ops.tuner_ops.set_params)
1091 fe->ops.tuner_ops.set_params(fe, fep);
1093 /* start up the AGC */
1094 state->agc_state = 0;
1095 do {
1096 time = dib7000p_agc_startup(fe, fep);
1097 if (time != -1)
1098 msleep(time);
1099 } while (time != -1);
1101 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
1102 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ||
1103 fep->u.ofdm.constellation == QAM_AUTO ||
1104 fep->u.ofdm.code_rate_HP == FEC_AUTO) {
1105 int i = 800, found;
1107 dib7000p_autosearch_start(fe, fep);
1108 do {
1109 msleep(1);
1110 found = dib7000p_autosearch_is_irq(fe);
1111 } while (found == 0 && i--);
1113 dprintk("autosearch returns: %d",found);
1114 if (found == 0 || found == 1)
1115 return 0; // no channel found
1117 dib7000p_get_frontend(fe, fep);
1120 /* make this a config parameter */
1121 dib7000p_set_output_mode(state, OUTMODE_MPEG2_FIFO);
1123 return dib7000p_tune(fe, fep);
1126 static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t *stat)
1128 struct dib7000p_state *state = fe->demodulator_priv;
1129 u16 lock = dib7000p_read_word(state, 509);
1131 *stat = 0;
1133 if (lock & 0x8000)
1134 *stat |= FE_HAS_SIGNAL;
1135 if (lock & 0x3000)
1136 *stat |= FE_HAS_CARRIER;
1137 if (lock & 0x0100)
1138 *stat |= FE_HAS_VITERBI;
1139 if (lock & 0x0010)
1140 *stat |= FE_HAS_SYNC;
1141 if (lock & 0x0008)
1142 *stat |= FE_HAS_LOCK;
1144 return 0;
1147 static int dib7000p_read_ber(struct dvb_frontend *fe, u32 *ber)
1149 struct dib7000p_state *state = fe->demodulator_priv;
1150 *ber = (dib7000p_read_word(state, 500) << 16) | dib7000p_read_word(state, 501);
1151 return 0;
1154 static int dib7000p_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
1156 struct dib7000p_state *state = fe->demodulator_priv;
1157 *unc = dib7000p_read_word(state, 506);
1158 return 0;
1161 static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1163 struct dib7000p_state *state = fe->demodulator_priv;
1164 u16 val = dib7000p_read_word(state, 394);
1165 *strength = 65535 - val;
1166 return 0;
1169 static int dib7000p_read_snr(struct dvb_frontend* fe, u16 *snr)
1171 *snr = 0x0000;
1172 return 0;
1175 static int dib7000p_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
1177 tune->min_delay_ms = 1000;
1178 return 0;
1181 static void dib7000p_release(struct dvb_frontend *demod)
1183 struct dib7000p_state *st = demod->demodulator_priv;
1184 dibx000_exit_i2c_master(&st->i2c_master);
1185 kfree(st);
1188 int dib7000pc_detection(struct i2c_adapter *i2c_adap)
1190 u8 tx[2], rx[2];
1191 struct i2c_msg msg[2] = {
1192 { .addr = 18 >> 1, .flags = 0, .buf = tx, .len = 2 },
1193 { .addr = 18 >> 1, .flags = I2C_M_RD, .buf = rx, .len = 2 },
1196 tx[0] = 0x03;
1197 tx[1] = 0x00;
1199 if (i2c_transfer(i2c_adap, msg, 2) == 2)
1200 if (rx[0] == 0x01 && rx[1] == 0xb3) {
1201 dprintk("-D- DiB7000PC detected");
1202 return 1;
1205 msg[0].addr = msg[1].addr = 0x40;
1207 if (i2c_transfer(i2c_adap, msg, 2) == 2)
1208 if (rx[0] == 0x01 && rx[1] == 0xb3) {
1209 dprintk("-D- DiB7000PC detected");
1210 return 1;
1213 dprintk("-D- DiB7000PC not detected");
1214 return 0;
1216 EXPORT_SYMBOL(dib7000pc_detection);
1218 struct i2c_adapter * dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
1220 struct dib7000p_state *st = demod->demodulator_priv;
1221 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1223 EXPORT_SYMBOL(dib7000p_get_i2c_master);
1225 int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
1227 struct dib7000p_state st = { .i2c_adap = i2c };
1228 int k = 0;
1229 u8 new_addr = 0;
1231 for (k = no_of_demods-1; k >= 0; k--) {
1232 st.cfg = cfg[k];
1234 /* designated i2c address */
1235 new_addr = (0x40 + k) << 1;
1236 st.i2c_addr = new_addr;
1237 if (dib7000p_identify(&st) != 0) {
1238 st.i2c_addr = default_addr;
1239 if (dib7000p_identify(&st) != 0) {
1240 dprintk("DiB7000P #%d: not identified\n", k);
1241 return -EIO;
1245 /* start diversity to pull_down div_str - just for i2c-enumeration */
1246 dib7000p_set_output_mode(&st, OUTMODE_DIVERSITY);
1248 /* set new i2c address and force divstart */
1249 dib7000p_write_word(&st, 1285, (new_addr << 2) | 0x2);
1251 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
1254 for (k = 0; k < no_of_demods; k++) {
1255 st.cfg = cfg[k];
1256 st.i2c_addr = (0x40 + k) << 1;
1258 // unforce divstr
1259 dib7000p_write_word(&st, 1285, st.i2c_addr << 2);
1261 /* deactivate div - it was just for i2c-enumeration */
1262 dib7000p_set_output_mode(&st, OUTMODE_HIGH_Z);
1265 return 0;
1267 EXPORT_SYMBOL(dib7000p_i2c_enumeration);
1269 static struct dvb_frontend_ops dib7000p_ops;
1270 struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
1272 struct dvb_frontend *demod;
1273 struct dib7000p_state *st;
1274 st = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
1275 if (st == NULL)
1276 return NULL;
1278 memcpy(&st->cfg, cfg, sizeof(struct dib7000p_config));
1279 st->i2c_adap = i2c_adap;
1280 st->i2c_addr = i2c_addr;
1281 st->gpio_val = cfg->gpio_val;
1282 st->gpio_dir = cfg->gpio_dir;
1284 demod = &st->demod;
1285 demod->demodulator_priv = st;
1286 memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));
1288 if (dib7000p_identify(st) != 0)
1289 goto error;
1291 dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr);
1293 dib7000p_demod_reset(st);
1295 return demod;
1297 error:
1298 kfree(st);
1299 return NULL;
1301 EXPORT_SYMBOL(dib7000p_attach);
1303 static struct dvb_frontend_ops dib7000p_ops = {
1304 .info = {
1305 .name = "DiBcom 7000PC",
1306 .type = FE_OFDM,
1307 .frequency_min = 44250000,
1308 .frequency_max = 867250000,
1309 .frequency_stepsize = 62500,
1310 .caps = FE_CAN_INVERSION_AUTO |
1311 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1312 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1313 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1314 FE_CAN_TRANSMISSION_MODE_AUTO |
1315 FE_CAN_GUARD_INTERVAL_AUTO |
1316 FE_CAN_RECOVER |
1317 FE_CAN_HIERARCHY_AUTO,
1320 .release = dib7000p_release,
1322 .init = dib7000p_wakeup,
1323 .sleep = dib7000p_sleep,
1325 .set_frontend = dib7000p_set_frontend,
1326 .get_tune_settings = dib7000p_fe_get_tune_settings,
1327 .get_frontend = dib7000p_get_frontend,
1329 .read_status = dib7000p_read_status,
1330 .read_ber = dib7000p_read_ber,
1331 .read_signal_strength = dib7000p_read_signal_strength,
1332 .read_snr = dib7000p_read_snr,
1333 .read_ucblocks = dib7000p_read_unc_blocks,
1336 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
1337 MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
1338 MODULE_LICENSE("GPL");