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>
15 #include "dvb_frontend.h"
20 module_param(debug
, int, 0644);
21 MODULE_PARM_DESC(debug
, "turn on debugging (default: 0)");
23 static int buggy_sfn_workaround
;
24 module_param(buggy_sfn_workaround
, int, 0644);
25 MODULE_PARM_DESC(buggy_sfn_workaround
, "Enable work-around for buggy SFNs (default: 0)");
27 #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0)
29 struct dib7000p_state
{
30 struct dvb_frontend demod
;
31 struct dib7000p_config cfg
;
34 struct i2c_adapter
*i2c_adap
;
36 struct dibx000_i2c_master i2c_master
;
41 u32 current_bandwidth
;
42 struct dibx000_agc_config
*current_agc
;
54 u8 sfn_workaround_active
:1;
57 enum dib7000p_power_mode
{
58 DIB7000P_POWER_ALL
= 0,
59 DIB7000P_POWER_ANALOG_ADC
,
60 DIB7000P_POWER_INTERFACE_ONLY
,
63 static u16
dib7000p_read_word(struct dib7000p_state
*state
, u16 reg
)
65 u8 wb
[2] = { reg
>> 8, reg
& 0xff };
67 struct i2c_msg msg
[2] = {
68 { .addr
= state
->i2c_addr
>> 1, .flags
= 0, .buf
= wb
, .len
= 2 },
69 { .addr
= state
->i2c_addr
>> 1, .flags
= I2C_M_RD
, .buf
= rb
, .len
= 2 },
72 if (i2c_transfer(state
->i2c_adap
, msg
, 2) != 2)
73 dprintk("i2c read error on %d",reg
);
75 return (rb
[0] << 8) | rb
[1];
78 static int dib7000p_write_word(struct dib7000p_state
*state
, u16 reg
, u16 val
)
81 (reg
>> 8) & 0xff, reg
& 0xff,
82 (val
>> 8) & 0xff, val
& 0xff,
84 struct i2c_msg msg
= {
85 .addr
= state
->i2c_addr
>> 1, .flags
= 0, .buf
= b
, .len
= 4
87 return i2c_transfer(state
->i2c_adap
, &msg
, 1) != 1 ? -EREMOTEIO
: 0;
89 static void dib7000p_write_tab(struct dib7000p_state
*state
, u16
*buf
)
98 dib7000p_write_word(state
, r
, *n
++);
105 static int dib7000p_set_output_mode(struct dib7000p_state
*state
, int mode
)
108 u16 outreg
, fifo_threshold
, smo_mode
;
111 fifo_threshold
= 1792;
112 smo_mode
= (dib7000p_read_word(state
, 235) & 0x0050) | (1 << 1);
114 dprintk( "setting output mode for demod %p to %d",
115 &state
->demod
, mode
);
118 case OUTMODE_MPEG2_PAR_GATED_CLK
: // STBs with parallel gated clock
119 outreg
= (1 << 10); /* 0x0400 */
121 case OUTMODE_MPEG2_PAR_CONT_CLK
: // STBs with parallel continues clock
122 outreg
= (1 << 10) | (1 << 6); /* 0x0440 */
124 case OUTMODE_MPEG2_SERIAL
: // STBs with serial input
125 outreg
= (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */
127 case OUTMODE_DIVERSITY
:
128 if (state
->cfg
.hostbus_diversity
)
129 outreg
= (1 << 10) | (4 << 6); /* 0x0500 */
133 case OUTMODE_MPEG2_FIFO
: // e.g. USB feeding
134 smo_mode
|= (3 << 1);
135 fifo_threshold
= 512;
136 outreg
= (1 << 10) | (5 << 6);
138 case OUTMODE_ANALOG_ADC
:
139 outreg
= (1 << 10) | (3 << 6);
141 case OUTMODE_HIGH_Z
: // disable
145 dprintk( "Unhandled output_mode passed to be set for demod %p",&state
->demod
);
149 if (state
->cfg
.output_mpeg2_in_188_bytes
)
150 smo_mode
|= (1 << 5) ;
152 ret
|= dib7000p_write_word(state
, 235, smo_mode
);
153 ret
|= dib7000p_write_word(state
, 236, fifo_threshold
); /* synchronous fread */
154 ret
|= dib7000p_write_word(state
, 1286, outreg
); /* P_Div_active */
159 static int dib7000p_set_diversity_in(struct dvb_frontend
*demod
, int onoff
)
161 struct dib7000p_state
*state
= demod
->demodulator_priv
;
163 if (state
->div_force_off
) {
164 dprintk( "diversity combination deactivated - forced by COFDM parameters");
166 dib7000p_write_word(state
, 207, 0);
168 dib7000p_write_word(state
, 207, (state
->div_sync_wait
<< 4) | (1 << 2) | (2 << 0));
170 state
->div_state
= (u8
)onoff
;
173 dib7000p_write_word(state
, 204, 6);
174 dib7000p_write_word(state
, 205, 16);
175 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
177 dib7000p_write_word(state
, 204, 1);
178 dib7000p_write_word(state
, 205, 0);
184 static int dib7000p_set_power_mode(struct dib7000p_state
*state
, enum dib7000p_power_mode mode
)
186 /* by default everything is powered off */
187 u16 reg_774
= 0xffff, reg_775
= 0xffff, reg_776
= 0x0007, reg_899
= 0x0003,
188 reg_1280
= (0xfe00) | (dib7000p_read_word(state
, 1280) & 0x01ff);
190 /* now, depending on the requested mode, we power on */
192 /* power up everything in the demod */
193 case DIB7000P_POWER_ALL
:
194 reg_774
= 0x0000; reg_775
= 0x0000; reg_776
= 0x0; reg_899
= 0x0; reg_1280
&= 0x01ff;
197 case DIB7000P_POWER_ANALOG_ADC
:
198 /* dem, cfg, iqc, sad, agc */
199 reg_774
&= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
201 reg_776
&= ~((1 << 0));
203 reg_1280
&= ~((1 << 11));
204 /* fall through wanted to enable the interfaces */
206 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
207 case DIB7000P_POWER_INTERFACE_ONLY
: /* TODO power up either SDIO or I2C */
208 reg_1280
&= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
211 /* TODO following stuff is just converted from the dib7000-driver - check when is used what */
214 dib7000p_write_word(state
, 774, reg_774
);
215 dib7000p_write_word(state
, 775, reg_775
);
216 dib7000p_write_word(state
, 776, reg_776
);
217 dib7000p_write_word(state
, 899, reg_899
);
218 dib7000p_write_word(state
, 1280, reg_1280
);
223 static void dib7000p_set_adc_state(struct dib7000p_state
*state
, enum dibx000_adc_states no
)
225 u16 reg_908
= dib7000p_read_word(state
, 908),
226 reg_909
= dib7000p_read_word(state
, 909);
229 case DIBX000_SLOW_ADC_ON
:
230 reg_909
|= (1 << 1) | (1 << 0);
231 dib7000p_write_word(state
, 909, reg_909
);
232 reg_909
&= ~(1 << 1);
235 case DIBX000_SLOW_ADC_OFF
:
236 reg_909
|= (1 << 1) | (1 << 0);
244 case DIBX000_ADC_OFF
: // leave the VBG voltage on
245 reg_908
|= (1 << 14) | (1 << 13) | (1 << 12);
246 reg_909
|= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
249 case DIBX000_VBG_ENABLE
:
250 reg_908
&= ~(1 << 15);
253 case DIBX000_VBG_DISABLE
:
254 reg_908
|= (1 << 15);
261 // dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
263 dib7000p_write_word(state
, 908, reg_908
);
264 dib7000p_write_word(state
, 909, reg_909
);
267 static int dib7000p_set_bandwidth(struct dib7000p_state
*state
, u32 bw
)
271 // store the current bandwidth for later use
272 state
->current_bandwidth
= bw
;
274 if (state
->timf
== 0) {
275 dprintk( "using default timf");
276 timf
= state
->cfg
.bw
->timf
;
278 dprintk( "using updated timf");
282 timf
= timf
* (bw
/ 50) / 160;
284 dib7000p_write_word(state
, 23, (u16
) ((timf
>> 16) & 0xffff));
285 dib7000p_write_word(state
, 24, (u16
) ((timf
) & 0xffff));
290 static int dib7000p_sad_calib(struct dib7000p_state
*state
)
293 // dib7000p_write_word(state, 72, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth
294 dib7000p_write_word(state
, 73, (0 << 1) | (0 << 0));
295 dib7000p_write_word(state
, 74, 776); // 0.625*3.3 / 4096
297 /* do the calibration */
298 dib7000p_write_word(state
, 73, (1 << 0));
299 dib7000p_write_word(state
, 73, (0 << 0));
306 int dib7000p_set_wbd_ref(struct dvb_frontend
*demod
, u16 value
)
308 struct dib7000p_state
*state
= demod
->demodulator_priv
;
311 state
->wbd_ref
= value
;
312 return dib7000p_write_word(state
, 105, (dib7000p_read_word(state
, 105) & 0xf000) | value
);
315 EXPORT_SYMBOL(dib7000p_set_wbd_ref
);
316 static void dib7000p_reset_pll(struct dib7000p_state
*state
)
318 struct dibx000_bandwidth_config
*bw
= &state
->cfg
.bw
[0];
321 /* force PLL bypass */
322 clk_cfg0
= (1 << 15) | ((bw
->pll_ratio
& 0x3f) << 9) |
323 (bw
->modulo
<< 7) | (bw
->ADClkSrc
<< 6) | (bw
->IO_CLK_en_core
<< 5) |
324 (bw
->bypclk_div
<< 2) | (bw
->enable_refdiv
<< 1) | (0 << 0);
326 dib7000p_write_word(state
, 900, clk_cfg0
);
329 dib7000p_write_word(state
, 903, (bw
->pll_prediv
<< 5) | (((bw
->pll_ratio
>> 6) & 0x3) << 3) | (bw
->pll_range
<< 1) | bw
->pll_reset
);
330 clk_cfg0
= (bw
->pll_bypass
<< 15) | (clk_cfg0
& 0x7fff);
331 dib7000p_write_word(state
, 900, clk_cfg0
);
333 dib7000p_write_word(state
, 18, (u16
) (((bw
->internal
*1000) >> 16) & 0xffff));
334 dib7000p_write_word(state
, 19, (u16
) ( (bw
->internal
*1000 ) & 0xffff));
335 dib7000p_write_word(state
, 21, (u16
) ( (bw
->ifreq
>> 16) & 0xffff));
336 dib7000p_write_word(state
, 22, (u16
) ( (bw
->ifreq
) & 0xffff));
338 dib7000p_write_word(state
, 72, bw
->sad_cfg
);
341 static int dib7000p_reset_gpio(struct dib7000p_state
*st
)
343 /* reset the GPIOs */
344 dprintk( "gpio dir: %x: val: %x, pwm_pos: %x",st
->gpio_dir
, st
->gpio_val
,st
->cfg
.gpio_pwm_pos
);
346 dib7000p_write_word(st
, 1029, st
->gpio_dir
);
347 dib7000p_write_word(st
, 1030, st
->gpio_val
);
349 /* TODO 1031 is P_gpio_od */
351 dib7000p_write_word(st
, 1032, st
->cfg
.gpio_pwm_pos
);
353 dib7000p_write_word(st
, 1037, st
->cfg
.pwm_freq_div
);
357 static int dib7000p_cfg_gpio(struct dib7000p_state
*st
, u8 num
, u8 dir
, u8 val
)
359 st
->gpio_dir
= dib7000p_read_word(st
, 1029);
360 st
->gpio_dir
&= ~(1 << num
); /* reset the direction bit */
361 st
->gpio_dir
|= (dir
& 0x1) << num
; /* set the new direction */
362 dib7000p_write_word(st
, 1029, st
->gpio_dir
);
364 st
->gpio_val
= dib7000p_read_word(st
, 1030);
365 st
->gpio_val
&= ~(1 << num
); /* reset the direction bit */
366 st
->gpio_val
|= (val
& 0x01) << num
; /* set the new value */
367 dib7000p_write_word(st
, 1030, st
->gpio_val
);
372 int dib7000p_set_gpio(struct dvb_frontend
*demod
, u8 num
, u8 dir
, u8 val
)
374 struct dib7000p_state
*state
= demod
->demodulator_priv
;
375 return dib7000p_cfg_gpio(state
, num
, dir
, val
);
378 EXPORT_SYMBOL(dib7000p_set_gpio
);
379 static u16 dib7000p_defaults
[] =
382 // auto search configuration
386 0x0814, /* Equal Lock */
403 0x6680, // P_timf_alpha=6, P_corm_alpha=6, P_corm_thres=128 default: 6,4,26
405 /* set ADC level to -16 */
407 (1 << 13) - 825 - 117,
408 (1 << 13) - 837 - 117,
409 (1 << 13) - 811 - 117,
410 (1 << 13) - 766 - 117,
411 (1 << 13) - 737 - 117,
412 (1 << 13) - 693 - 117,
413 (1 << 13) - 648 - 117,
414 (1 << 13) - 619 - 117,
415 (1 << 13) - 575 - 117,
416 (1 << 13) - 531 - 117,
417 (1 << 13) - 501 - 117,
420 0x0410, // P_palf_filter_on=1, P_palf_filter_freeze=0, P_palf_alpha_regul=16
422 /* disable power smoothing */
434 1 << 13, // P_fft_freq_dir=1, P_fft_nb_to_cut=0
437 0x0ccd, // P_pha3_thres, default 0x3000
440 // 0x0010, // P_cti_use_cpe=0, P_cti_use_prog=0, P_cti_win_len=16, default: 0x0010
443 0x200f, // P_cspu_regul=512, P_cspu_win_cut=15, default: 0x2005
446 0x023d, // P_adp_regul_cnt=573, default: 410
447 0x00a4, // P_adp_noise_cnt=
448 0x00a4, // P_adp_regul_ext
449 0x7ff0, // P_adp_noise_ext
453 0x800, // P_equal_thres_wgn
456 0x0010, // P_fec_ber_rs_len=2
459 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
462 0x0006, // P_clk_cfg1
463 (3 << 10) | (1 << 6), // P_divclksel=3 P_divbitsel=1
466 0x2c8e, // Tuner IO bank: max drive (14mA) + divout pads max drive
471 static int dib7000p_demod_reset(struct dib7000p_state
*state
)
473 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
475 dib7000p_set_adc_state(state
, DIBX000_VBG_ENABLE
);
477 /* restart all parts */
478 dib7000p_write_word(state
, 770, 0xffff);
479 dib7000p_write_word(state
, 771, 0xffff);
480 dib7000p_write_word(state
, 772, 0x001f);
481 dib7000p_write_word(state
, 898, 0x0003);
482 /* except i2c, sdio, gpio - control interfaces */
483 dib7000p_write_word(state
, 1280, 0x01fc - ((1 << 7) | (1 << 6) | (1 << 5)) );
485 dib7000p_write_word(state
, 770, 0);
486 dib7000p_write_word(state
, 771, 0);
487 dib7000p_write_word(state
, 772, 0);
488 dib7000p_write_word(state
, 898, 0);
489 dib7000p_write_word(state
, 1280, 0);
492 dib7000p_reset_pll(state
);
494 if (dib7000p_reset_gpio(state
) != 0)
495 dprintk( "GPIO reset was not successful.");
497 if (dib7000p_set_output_mode(state
, OUTMODE_HIGH_Z
) != 0)
498 dprintk( "OUTPUT_MODE could not be reset.");
500 /* unforce divstr regardless whether i2c enumeration was done or not */
501 dib7000p_write_word(state
, 1285, dib7000p_read_word(state
, 1285) & ~(1 << 1) );
503 dib7000p_set_bandwidth(state
, 8000);
505 dib7000p_set_adc_state(state
, DIBX000_SLOW_ADC_ON
);
506 dib7000p_sad_calib(state
);
507 dib7000p_set_adc_state(state
, DIBX000_SLOW_ADC_OFF
);
509 // P_iqc_alpha_pha, P_iqc_alpha_amp_dcc_alpha, ...
510 if(state
->cfg
.tuner_is_baseband
)
511 dib7000p_write_word(state
, 36,0x0755);
513 dib7000p_write_word(state
, 36,0x1f55);
515 dib7000p_write_tab(state
, dib7000p_defaults
);
517 dib7000p_set_power_mode(state
, DIB7000P_POWER_INTERFACE_ONLY
);
523 static void dib7000p_pll_clk_cfg(struct dib7000p_state
*state
)
526 tmp
= dib7000p_read_word(state
, 903);
527 dib7000p_write_word(state
, 903, (tmp
| 0x1)); //pwr-up pll
528 tmp
= dib7000p_read_word(state
, 900);
529 dib7000p_write_word(state
, 900, (tmp
& 0x7fff) | (1 << 6)); //use High freq clock
532 static void dib7000p_restart_agc(struct dib7000p_state
*state
)
534 // P_restart_iqc & P_restart_agc
535 dib7000p_write_word(state
, 770, (1 << 11) | (1 << 9));
536 dib7000p_write_word(state
, 770, 0x0000);
539 static int dib7000p_update_lna(struct dib7000p_state
*state
)
543 // when there is no LNA to program return immediatly
544 if (state
->cfg
.update_lna
) {
545 // read dyn_gain here (because it is demod-dependent and not fe)
546 dyn_gain
= dib7000p_read_word(state
, 394);
547 if (state
->cfg
.update_lna(&state
->demod
,dyn_gain
)) { // LNA has changed
548 dib7000p_restart_agc(state
);
556 static int dib7000p_set_agc_config(struct dib7000p_state
*state
, u8 band
)
558 struct dibx000_agc_config
*agc
= NULL
;
560 if (state
->current_band
== band
&& state
->current_agc
!= NULL
)
562 state
->current_band
= band
;
564 for (i
= 0; i
< state
->cfg
.agc_config_count
; i
++)
565 if (state
->cfg
.agc
[i
].band_caps
& band
) {
566 agc
= &state
->cfg
.agc
[i
];
571 dprintk( "no valid AGC configuration found for band 0x%02x",band
);
575 state
->current_agc
= agc
;
578 dib7000p_write_word(state
, 75 , agc
->setup
);
579 dib7000p_write_word(state
, 76 , agc
->inv_gain
);
580 dib7000p_write_word(state
, 77 , agc
->time_stabiliz
);
581 dib7000p_write_word(state
, 100, (agc
->alpha_level
<< 12) | agc
->thlock
);
583 // Demod AGC loop configuration
584 dib7000p_write_word(state
, 101, (agc
->alpha_mant
<< 5) | agc
->alpha_exp
);
585 dib7000p_write_word(state
, 102, (agc
->beta_mant
<< 6) | agc
->beta_exp
);
588 dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d",
589 state
->wbd_ref
!= 0 ? state
->wbd_ref
: agc
->wbd_ref
, agc
->wbd_sel
, !agc
->perform_agc_softsplit
, agc
->wbd_sel
);
591 if (state
->wbd_ref
!= 0)
592 dib7000p_write_word(state
, 105, (agc
->wbd_inv
<< 12) | state
->wbd_ref
);
594 dib7000p_write_word(state
, 105, (agc
->wbd_inv
<< 12) | agc
->wbd_ref
);
596 dib7000p_write_word(state
, 106, (agc
->wbd_sel
<< 13) | (agc
->wbd_alpha
<< 9) | (agc
->perform_agc_softsplit
<< 8));
598 dib7000p_write_word(state
, 107, agc
->agc1_max
);
599 dib7000p_write_word(state
, 108, agc
->agc1_min
);
600 dib7000p_write_word(state
, 109, agc
->agc2_max
);
601 dib7000p_write_word(state
, 110, agc
->agc2_min
);
602 dib7000p_write_word(state
, 111, (agc
->agc1_pt1
<< 8) | agc
->agc1_pt2
);
603 dib7000p_write_word(state
, 112, agc
->agc1_pt3
);
604 dib7000p_write_word(state
, 113, (agc
->agc1_slope1
<< 8) | agc
->agc1_slope2
);
605 dib7000p_write_word(state
, 114, (agc
->agc2_pt1
<< 8) | agc
->agc2_pt2
);
606 dib7000p_write_word(state
, 115, (agc
->agc2_slope1
<< 8) | agc
->agc2_slope2
);
610 static int dib7000p_agc_startup(struct dvb_frontend
*demod
, struct dvb_frontend_parameters
*ch
)
612 struct dib7000p_state
*state
= demod
->demodulator_priv
;
614 u8
*agc_state
= &state
->agc_state
;
617 switch (state
->agc_state
) {
619 // set power-up level: interf+analog+AGC
620 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
621 dib7000p_set_adc_state(state
, DIBX000_ADC_ON
);
622 dib7000p_pll_clk_cfg(state
);
624 if (dib7000p_set_agc_config(state
, BAND_OF_FREQUENCY(ch
->frequency
/1000)) != 0)
632 // AGC initialization
633 if (state
->cfg
.agc_control
)
634 state
->cfg
.agc_control(&state
->demod
, 1);
636 dib7000p_write_word(state
, 78, 32768);
637 if (!state
->current_agc
->perform_agc_softsplit
) {
638 /* we are using the wbd - so slow AGC startup */
639 /* force 0 split on WBD and restart AGC */
640 dib7000p_write_word(state
, 106, (state
->current_agc
->wbd_sel
<< 13) | (state
->current_agc
->wbd_alpha
<< 9) | (1 << 8));
644 /* default AGC startup */
646 /* wait AGC rough lock time */
650 dib7000p_restart_agc(state
);
653 case 2: /* fast split search path after 5sec */
654 dib7000p_write_word(state
, 75, state
->current_agc
->setup
| (1 << 4)); /* freeze AGC loop */
655 dib7000p_write_word(state
, 106, (state
->current_agc
->wbd_sel
<< 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */
660 case 3: /* split search ended */
661 agc_split
= (u8
)dib7000p_read_word(state
, 396); /* store the split value for the next time */
662 dib7000p_write_word(state
, 78, dib7000p_read_word(state
, 394)); /* set AGC gain start value */
664 dib7000p_write_word(state
, 75, state
->current_agc
->setup
); /* std AGC loop */
665 dib7000p_write_word(state
, 106, (state
->current_agc
->wbd_sel
<< 13) | (state
->current_agc
->wbd_alpha
<< 9) | agc_split
); /* standard split search */
667 dib7000p_restart_agc(state
);
669 dprintk( "SPLIT %p: %hd", demod
, agc_split
);
675 case 4: /* LNA startup */
676 // wait AGC accurate lock time
679 if (dib7000p_update_lna(state
))
680 // wait only AGC rough lock time
682 else // nothing was done, go to the next state
687 if (state
->cfg
.agc_control
)
688 state
->cfg
.agc_control(&state
->demod
, 0);
697 static void dib7000p_update_timf(struct dib7000p_state
*state
)
699 u32 timf
= (dib7000p_read_word(state
, 427) << 16) | dib7000p_read_word(state
, 428);
700 state
->timf
= timf
* 160 / (state
->current_bandwidth
/ 50);
701 dib7000p_write_word(state
, 23, (u16
) (timf
>> 16));
702 dib7000p_write_word(state
, 24, (u16
) (timf
& 0xffff));
703 dprintk( "updated timf_frequency: %d (default: %d)",state
->timf
, state
->cfg
.bw
->timf
);
707 static void dib7000p_set_channel(struct dib7000p_state
*state
, struct dvb_frontend_parameters
*ch
, u8 seq
)
711 dib7000p_set_bandwidth(state
, BANDWIDTH_TO_KHZ(ch
->u
.ofdm
.bandwidth
));
713 /* nfft, guard, qam, alpha */
715 switch (ch
->u
.ofdm
.transmission_mode
) {
716 case TRANSMISSION_MODE_2K
: value
|= (0 << 7); break;
717 case /* 4K MODE */ 255: value
|= (2 << 7); break;
719 case TRANSMISSION_MODE_8K
: value
|= (1 << 7); break;
721 switch (ch
->u
.ofdm
.guard_interval
) {
722 case GUARD_INTERVAL_1_32
: value
|= (0 << 5); break;
723 case GUARD_INTERVAL_1_16
: value
|= (1 << 5); break;
724 case GUARD_INTERVAL_1_4
: value
|= (3 << 5); break;
726 case GUARD_INTERVAL_1_8
: value
|= (2 << 5); break;
728 switch (ch
->u
.ofdm
.constellation
) {
729 case QPSK
: value
|= (0 << 3); break;
730 case QAM_16
: value
|= (1 << 3); break;
732 case QAM_64
: value
|= (2 << 3); break;
734 switch (HIERARCHY_1
) {
735 case HIERARCHY_2
: value
|= 2; break;
736 case HIERARCHY_4
: value
|= 4; break;
738 case HIERARCHY_1
: value
|= 1; break;
740 dib7000p_write_word(state
, 0, value
);
741 dib7000p_write_word(state
, 5, (seq
<< 4) | 1); /* do not force tps, search list 0 */
743 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
747 if (ch
->u
.ofdm
.hierarchy_information
== 1)
751 switch ((ch
->u
.ofdm
.hierarchy_information
== 0 || 1 == 1) ? ch
->u
.ofdm
.code_rate_HP
: ch
->u
.ofdm
.code_rate_LP
) {
752 case FEC_2_3
: value
|= (2 << 1); break;
753 case FEC_3_4
: value
|= (3 << 1); break;
754 case FEC_5_6
: value
|= (5 << 1); break;
755 case FEC_7_8
: value
|= (7 << 1); break;
757 case FEC_1_2
: value
|= (1 << 1); break;
759 dib7000p_write_word(state
, 208, value
);
761 /* offset loop parameters */
762 dib7000p_write_word(state
, 26, 0x6680); // timf(6xxx)
763 dib7000p_write_word(state
, 32, 0x0003); // pha_off_max(xxx3)
764 dib7000p_write_word(state
, 29, 0x1273); // isi
765 dib7000p_write_word(state
, 33, 0x0005); // sfreq(xxx5)
767 /* P_dvsy_sync_wait */
768 switch (ch
->u
.ofdm
.transmission_mode
) {
769 case TRANSMISSION_MODE_8K
: value
= 256; break;
770 case /* 4K MODE */ 255: value
= 128; break;
771 case TRANSMISSION_MODE_2K
:
772 default: value
= 64; break;
774 switch (ch
->u
.ofdm
.guard_interval
) {
775 case GUARD_INTERVAL_1_16
: value
*= 2; break;
776 case GUARD_INTERVAL_1_8
: value
*= 4; break;
777 case GUARD_INTERVAL_1_4
: value
*= 8; break;
779 case GUARD_INTERVAL_1_32
: value
*= 1; break;
781 state
->div_sync_wait
= (value
* 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO
783 /* deactive the possibility of diversity reception if extended interleaver */
784 state
->div_force_off
= !1 && ch
->u
.ofdm
.transmission_mode
!= TRANSMISSION_MODE_8K
;
785 dib7000p_set_diversity_in(&state
->demod
, state
->div_state
);
787 /* channel estimation fine configuration */
788 switch (ch
->u
.ofdm
.constellation
) {
790 est
[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
791 est
[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
792 est
[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
793 est
[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
796 est
[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
797 est
[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
798 est
[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
799 est
[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
802 est
[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
803 est
[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
804 est
[2] = 0x0333; /* P_adp_regul_ext 0.1 */
805 est
[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
808 for (value
= 0; value
< 4; value
++)
809 dib7000p_write_word(state
, 187 + value
, est
[value
]);
812 static int dib7000p_autosearch_start(struct dvb_frontend
*demod
, struct dvb_frontend_parameters
*ch
)
814 struct dib7000p_state
*state
= demod
->demodulator_priv
;
815 struct dvb_frontend_parameters schan
;
819 schan
.u
.ofdm
.constellation
= QAM_64
;
820 schan
.u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_32
;
821 schan
.u
.ofdm
.transmission_mode
= TRANSMISSION_MODE_8K
;
822 schan
.u
.ofdm
.code_rate_HP
= FEC_2_3
;
823 schan
.u
.ofdm
.code_rate_LP
= FEC_3_4
;
824 schan
.u
.ofdm
.hierarchy_information
= 0;
826 dib7000p_set_channel(state
, &schan
, 7);
828 factor
= BANDWIDTH_TO_KHZ(ch
->u
.ofdm
.bandwidth
);
834 // always use the setting for 8MHz here lock_time for 7,6 MHz are longer
835 value
= 30 * state
->cfg
.bw
->internal
* factor
;
836 dib7000p_write_word(state
, 6, (u16
) ((value
>> 16) & 0xffff)); // lock0 wait time
837 dib7000p_write_word(state
, 7, (u16
) (value
& 0xffff)); // lock0 wait time
838 value
= 100 * state
->cfg
.bw
->internal
* factor
;
839 dib7000p_write_word(state
, 8, (u16
) ((value
>> 16) & 0xffff)); // lock1 wait time
840 dib7000p_write_word(state
, 9, (u16
) (value
& 0xffff)); // lock1 wait time
841 value
= 500 * state
->cfg
.bw
->internal
* factor
;
842 dib7000p_write_word(state
, 10, (u16
) ((value
>> 16) & 0xffff)); // lock2 wait time
843 dib7000p_write_word(state
, 11, (u16
) (value
& 0xffff)); // lock2 wait time
845 value
= dib7000p_read_word(state
, 0);
846 dib7000p_write_word(state
, 0, (u16
) ((1 << 9) | value
));
847 dib7000p_read_word(state
, 1284);
848 dib7000p_write_word(state
, 0, (u16
) value
);
853 static int dib7000p_autosearch_is_irq(struct dvb_frontend
*demod
)
855 struct dib7000p_state
*state
= demod
->demodulator_priv
;
856 u16 irq_pending
= dib7000p_read_word(state
, 1284);
858 if (irq_pending
& 0x1) // failed
861 if (irq_pending
& 0x2) // succeeded
864 return 0; // still pending
867 static void dib7000p_spur_protect(struct dib7000p_state
*state
, u32 rf_khz
, u32 bw
)
869 static s16 notch
[]={16143, 14402, 12238, 9713, 6902, 3888, 759, -2392};
870 static u8 sine
[] ={0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
871 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
872 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
873 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
874 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
875 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
876 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
877 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
878 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
879 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
880 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
881 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
882 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
883 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
884 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
885 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
886 255, 255, 255, 255, 255, 255};
888 u32 xtal
= state
->cfg
.bw
->xtal_hz
/ 1000;
889 int f_rel
= DIV_ROUND_CLOSEST(rf_khz
, xtal
) * xtal
- rf_khz
;
891 int coef_re
[8],coef_im
[8];
895 dprintk( "relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel
, rf_khz
, xtal
);
898 if (f_rel
< -bw_khz
/2 || f_rel
> bw_khz
/2)
903 dib7000p_write_word(state
, 142 ,0x0610);
905 for (k
= 0; k
< 8; k
++) {
906 pha
= ((f_rel
* (k
+1) * 112 * 80/bw_khz
) /1000) & 0x3ff;
911 } else if(pha
< 256) {
912 coef_re
[k
] = sine
[256-(pha
&0xff)];
913 coef_im
[k
] = sine
[pha
&0xff];
914 } else if (pha
== 256) {
917 } else if (pha
< 512) {
918 coef_re
[k
] = -sine
[pha
&0xff];
919 coef_im
[k
] = sine
[256 - (pha
&0xff)];
920 } else if (pha
== 512) {
923 } else if (pha
< 768) {
924 coef_re
[k
] = -sine
[256-(pha
&0xff)];
925 coef_im
[k
] = -sine
[pha
&0xff];
926 } else if (pha
== 768) {
930 coef_re
[k
] = sine
[pha
&0xff];
931 coef_im
[k
] = -sine
[256 - (pha
&0xff)];
934 coef_re
[k
] *= notch
[k
];
935 coef_re
[k
] += (1<<14);
936 if (coef_re
[k
] >= (1<<24))
937 coef_re
[k
] = (1<<24) - 1;
938 coef_re
[k
] /= (1<<15);
940 coef_im
[k
] *= notch
[k
];
941 coef_im
[k
] += (1<<14);
942 if (coef_im
[k
] >= (1<<24))
943 coef_im
[k
] = (1<<24)-1;
944 coef_im
[k
] /= (1<<15);
946 dprintk( "PALF COEF: %d re: %d im: %d", k
, coef_re
[k
], coef_im
[k
]);
948 dib7000p_write_word(state
, 143, (0 << 14) | (k
<< 10) | (coef_re
[k
] & 0x3ff));
949 dib7000p_write_word(state
, 144, coef_im
[k
] & 0x3ff);
950 dib7000p_write_word(state
, 143, (1 << 14) | (k
<< 10) | (coef_re
[k
] & 0x3ff));
952 dib7000p_write_word(state
,143 ,0);
955 static int dib7000p_tune(struct dvb_frontend
*demod
, struct dvb_frontend_parameters
*ch
)
957 struct dib7000p_state
*state
= demod
->demodulator_priv
;
961 dib7000p_set_channel(state
, ch
, 0);
966 dib7000p_write_word(state
, 770, 0x4000);
967 dib7000p_write_word(state
, 770, 0x0000);
970 /* 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 */
971 tmp
= (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
972 if (state
->sfn_workaround_active
) {
973 dprintk( "SFN workaround is active");
975 dib7000p_write_word(state
, 166, 0x4000); // P_pha3_force_pha_shift
977 dib7000p_write_word(state
, 166, 0x0000); // P_pha3_force_pha_shift
979 dib7000p_write_word(state
, 29, tmp
);
981 // never achieved a lock with that bandwidth so far - wait for osc-freq to update
982 if (state
->timf
== 0)
985 /* offset loop parameters */
987 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
988 tmp
= (6 << 8) | 0x80;
989 switch (ch
->u
.ofdm
.transmission_mode
) {
990 case TRANSMISSION_MODE_2K
: tmp
|= (7 << 12); break;
991 case /* 4K MODE */ 255: tmp
|= (8 << 12); break;
993 case TRANSMISSION_MODE_8K
: tmp
|= (9 << 12); break;
995 dib7000p_write_word(state
, 26, tmp
); /* timf_a(6xxx) */
997 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
999 switch (ch
->u
.ofdm
.transmission_mode
) {
1000 case TRANSMISSION_MODE_2K
: tmp
|= 0x6; break;
1001 case /* 4K MODE */ 255: tmp
|= 0x7; break;
1003 case TRANSMISSION_MODE_8K
: tmp
|= 0x8; break;
1005 dib7000p_write_word(state
, 32, tmp
);
1007 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1009 switch (ch
->u
.ofdm
.transmission_mode
) {
1010 case TRANSMISSION_MODE_2K
: tmp
|= 0x6; break;
1011 case /* 4K MODE */ 255: tmp
|= 0x7; break;
1013 case TRANSMISSION_MODE_8K
: tmp
|= 0x8; break;
1015 dib7000p_write_word(state
, 33, tmp
);
1017 tmp
= dib7000p_read_word(state
,509);
1018 if (!((tmp
>> 6) & 0x1)) {
1019 /* restart the fec */
1020 tmp
= dib7000p_read_word(state
,771);
1021 dib7000p_write_word(state
, 771, tmp
| (1 << 1));
1022 dib7000p_write_word(state
, 771, tmp
);
1024 tmp
= dib7000p_read_word(state
,509);
1027 // we achieved a lock - it's time to update the osc freq
1028 if ((tmp
>> 6) & 0x1)
1029 dib7000p_update_timf(state
);
1031 if (state
->cfg
.spur_protect
)
1032 dib7000p_spur_protect(state
, ch
->frequency
/1000, BANDWIDTH_TO_KHZ(ch
->u
.ofdm
.bandwidth
));
1034 dib7000p_set_bandwidth(state
, BANDWIDTH_TO_KHZ(ch
->u
.ofdm
.bandwidth
));
1038 static int dib7000p_wakeup(struct dvb_frontend
*demod
)
1040 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1041 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
1042 dib7000p_set_adc_state(state
, DIBX000_SLOW_ADC_ON
);
1046 static int dib7000p_sleep(struct dvb_frontend
*demod
)
1048 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1049 return dib7000p_set_output_mode(state
, OUTMODE_HIGH_Z
) | dib7000p_set_power_mode(state
, DIB7000P_POWER_INTERFACE_ONLY
);
1052 static int dib7000p_identify(struct dib7000p_state
*st
)
1055 dprintk( "checking demod on I2C address: %d (%x)",
1056 st
->i2c_addr
, st
->i2c_addr
);
1058 if ((value
= dib7000p_read_word(st
, 768)) != 0x01b3) {
1059 dprintk( "wrong Vendor ID (read=0x%x)",value
);
1063 if ((value
= dib7000p_read_word(st
, 769)) != 0x4000) {
1064 dprintk( "wrong Device ID (%x)",value
);
1072 static int dib7000p_get_frontend(struct dvb_frontend
* fe
,
1073 struct dvb_frontend_parameters
*fep
)
1075 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1076 u16 tps
= dib7000p_read_word(state
,463);
1078 fep
->inversion
= INVERSION_AUTO
;
1080 fep
->u
.ofdm
.bandwidth
= BANDWIDTH_TO_INDEX(state
->current_bandwidth
);
1082 switch ((tps
>> 8) & 0x3) {
1083 case 0: fep
->u
.ofdm
.transmission_mode
= TRANSMISSION_MODE_2K
; break;
1084 case 1: fep
->u
.ofdm
.transmission_mode
= TRANSMISSION_MODE_8K
; break;
1085 /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */
1088 switch (tps
& 0x3) {
1089 case 0: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_32
; break;
1090 case 1: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_16
; break;
1091 case 2: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_8
; break;
1092 case 3: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_4
; break;
1095 switch ((tps
>> 14) & 0x3) {
1096 case 0: fep
->u
.ofdm
.constellation
= QPSK
; break;
1097 case 1: fep
->u
.ofdm
.constellation
= QAM_16
; break;
1099 default: fep
->u
.ofdm
.constellation
= QAM_64
; break;
1102 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1103 /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1105 fep
->u
.ofdm
.hierarchy_information
= HIERARCHY_NONE
;
1106 switch ((tps
>> 5) & 0x7) {
1107 case 1: fep
->u
.ofdm
.code_rate_HP
= FEC_1_2
; break;
1108 case 2: fep
->u
.ofdm
.code_rate_HP
= FEC_2_3
; break;
1109 case 3: fep
->u
.ofdm
.code_rate_HP
= FEC_3_4
; break;
1110 case 5: fep
->u
.ofdm
.code_rate_HP
= FEC_5_6
; break;
1112 default: fep
->u
.ofdm
.code_rate_HP
= FEC_7_8
; break;
1116 switch ((tps
>> 2) & 0x7) {
1117 case 1: fep
->u
.ofdm
.code_rate_LP
= FEC_1_2
; break;
1118 case 2: fep
->u
.ofdm
.code_rate_LP
= FEC_2_3
; break;
1119 case 3: fep
->u
.ofdm
.code_rate_LP
= FEC_3_4
; break;
1120 case 5: fep
->u
.ofdm
.code_rate_LP
= FEC_5_6
; break;
1122 default: fep
->u
.ofdm
.code_rate_LP
= FEC_7_8
; break;
1125 /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */
1130 static int dib7000p_set_frontend(struct dvb_frontend
* fe
,
1131 struct dvb_frontend_parameters
*fep
)
1133 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1136 dib7000p_set_output_mode(state
, OUTMODE_HIGH_Z
);
1138 /* maybe the parameter has been changed */
1139 state
->sfn_workaround_active
= buggy_sfn_workaround
;
1141 if (fe
->ops
.tuner_ops
.set_params
)
1142 fe
->ops
.tuner_ops
.set_params(fe
, fep
);
1144 /* start up the AGC */
1145 state
->agc_state
= 0;
1147 time
= dib7000p_agc_startup(fe
, fep
);
1150 } while (time
!= -1);
1152 if (fep
->u
.ofdm
.transmission_mode
== TRANSMISSION_MODE_AUTO
||
1153 fep
->u
.ofdm
.guard_interval
== GUARD_INTERVAL_AUTO
||
1154 fep
->u
.ofdm
.constellation
== QAM_AUTO
||
1155 fep
->u
.ofdm
.code_rate_HP
== FEC_AUTO
) {
1158 dib7000p_autosearch_start(fe
, fep
);
1161 found
= dib7000p_autosearch_is_irq(fe
);
1162 } while (found
== 0 && i
--);
1164 dprintk("autosearch returns: %d",found
);
1165 if (found
== 0 || found
== 1)
1166 return 0; // no channel found
1168 dib7000p_get_frontend(fe
, fep
);
1171 ret
= dib7000p_tune(fe
, fep
);
1173 /* make this a config parameter */
1174 dib7000p_set_output_mode(state
, state
->cfg
.output_mode
);
1178 static int dib7000p_read_status(struct dvb_frontend
*fe
, fe_status_t
*stat
)
1180 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1181 u16 lock
= dib7000p_read_word(state
, 509);
1186 *stat
|= FE_HAS_SIGNAL
;
1188 *stat
|= FE_HAS_CARRIER
;
1190 *stat
|= FE_HAS_VITERBI
;
1192 *stat
|= FE_HAS_SYNC
;
1193 if ((lock
& 0x0038) == 0x38)
1194 *stat
|= FE_HAS_LOCK
;
1199 static int dib7000p_read_ber(struct dvb_frontend
*fe
, u32
*ber
)
1201 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1202 *ber
= (dib7000p_read_word(state
, 500) << 16) | dib7000p_read_word(state
, 501);
1206 static int dib7000p_read_unc_blocks(struct dvb_frontend
*fe
, u32
*unc
)
1208 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1209 *unc
= dib7000p_read_word(state
, 506);
1213 static int dib7000p_read_signal_strength(struct dvb_frontend
*fe
, u16
*strength
)
1215 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1216 u16 val
= dib7000p_read_word(state
, 394);
1217 *strength
= 65535 - val
;
1221 static int dib7000p_read_snr(struct dvb_frontend
* fe
, u16
*snr
)
1223 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1225 s32 signal_mant
, signal_exp
, noise_mant
, noise_exp
;
1228 val
= dib7000p_read_word(state
, 479);
1229 noise_mant
= (val
>> 4) & 0xff;
1230 noise_exp
= ((val
& 0xf) << 2);
1231 val
= dib7000p_read_word(state
, 480);
1232 noise_exp
+= ((val
>> 14) & 0x3);
1233 if ((noise_exp
& 0x20) != 0)
1236 signal_mant
= (val
>> 6) & 0xFF;
1237 signal_exp
= (val
& 0x3F);
1238 if ((signal_exp
& 0x20) != 0)
1241 if (signal_mant
!= 0)
1242 result
= intlog10(2) * 10 * signal_exp
+ 10 *
1243 intlog10(signal_mant
);
1245 result
= intlog10(2) * 10 * signal_exp
- 100;
1247 if (noise_mant
!= 0)
1248 result
-= intlog10(2) * 10 * noise_exp
+ 10 *
1249 intlog10(noise_mant
);
1251 result
-= intlog10(2) * 10 * noise_exp
- 100;
1253 *snr
= result
/ ((1 << 24) / 10);
1257 static int dib7000p_fe_get_tune_settings(struct dvb_frontend
* fe
, struct dvb_frontend_tune_settings
*tune
)
1259 tune
->min_delay_ms
= 1000;
1263 static void dib7000p_release(struct dvb_frontend
*demod
)
1265 struct dib7000p_state
*st
= demod
->demodulator_priv
;
1266 dibx000_exit_i2c_master(&st
->i2c_master
);
1270 int dib7000pc_detection(struct i2c_adapter
*i2c_adap
)
1273 struct i2c_msg msg
[2] = {
1274 { .addr
= 18 >> 1, .flags
= 0, .buf
= tx
, .len
= 2 },
1275 { .addr
= 18 >> 1, .flags
= I2C_M_RD
, .buf
= rx
, .len
= 2 },
1281 if (i2c_transfer(i2c_adap
, msg
, 2) == 2)
1282 if (rx
[0] == 0x01 && rx
[1] == 0xb3) {
1283 dprintk("-D- DiB7000PC detected");
1287 msg
[0].addr
= msg
[1].addr
= 0x40;
1289 if (i2c_transfer(i2c_adap
, msg
, 2) == 2)
1290 if (rx
[0] == 0x01 && rx
[1] == 0xb3) {
1291 dprintk("-D- DiB7000PC detected");
1295 dprintk("-D- DiB7000PC not detected");
1298 EXPORT_SYMBOL(dib7000pc_detection
);
1300 struct i2c_adapter
* dib7000p_get_i2c_master(struct dvb_frontend
*demod
, enum dibx000_i2c_interface intf
, int gating
)
1302 struct dib7000p_state
*st
= demod
->demodulator_priv
;
1303 return dibx000_get_i2c_adapter(&st
->i2c_master
, intf
, gating
);
1305 EXPORT_SYMBOL(dib7000p_get_i2c_master
);
1307 int dib7000p_pid_filter_ctrl(struct dvb_frontend
*fe
, u8 onoff
)
1309 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1310 u16 val
= dib7000p_read_word(state
, 235) & 0xffef;
1311 val
|= (onoff
& 0x1) << 4;
1312 dprintk("PID filter enabled %d", onoff
);
1313 return dib7000p_write_word(state
, 235, val
);
1315 EXPORT_SYMBOL(dib7000p_pid_filter_ctrl
);
1317 int dib7000p_pid_filter(struct dvb_frontend
*fe
, u8 id
, u16 pid
, u8 onoff
)
1319 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1320 dprintk("PID filter: index %x, PID %d, OnOff %d", id
, pid
, onoff
);
1321 return dib7000p_write_word(state
, 241 + id
, onoff
? (1 << 13) | pid
: 0);
1323 EXPORT_SYMBOL(dib7000p_pid_filter
);
1325 int dib7000p_i2c_enumeration(struct i2c_adapter
*i2c
, int no_of_demods
, u8 default_addr
, struct dib7000p_config cfg
[])
1327 struct dib7000p_state st
= { .i2c_adap
= i2c
};
1331 for (k
= no_of_demods
-1; k
>= 0; k
--) {
1334 /* designated i2c address */
1335 new_addr
= (0x40 + k
) << 1;
1336 st
.i2c_addr
= new_addr
;
1337 dib7000p_write_word(&st
, 1287, 0x0003); /* sram lead in, rdy */
1338 if (dib7000p_identify(&st
) != 0) {
1339 st
.i2c_addr
= default_addr
;
1340 dib7000p_write_word(&st
, 1287, 0x0003); /* sram lead in, rdy */
1341 if (dib7000p_identify(&st
) != 0) {
1342 dprintk("DiB7000P #%d: not identified\n", k
);
1347 /* start diversity to pull_down div_str - just for i2c-enumeration */
1348 dib7000p_set_output_mode(&st
, OUTMODE_DIVERSITY
);
1350 /* set new i2c address and force divstart */
1351 dib7000p_write_word(&st
, 1285, (new_addr
<< 2) | 0x2);
1353 dprintk("IC %d initialized (to i2c_address 0x%x)", k
, new_addr
);
1356 for (k
= 0; k
< no_of_demods
; k
++) {
1358 st
.i2c_addr
= (0x40 + k
) << 1;
1361 dib7000p_write_word(&st
, 1285, st
.i2c_addr
<< 2);
1363 /* deactivate div - it was just for i2c-enumeration */
1364 dib7000p_set_output_mode(&st
, OUTMODE_HIGH_Z
);
1369 EXPORT_SYMBOL(dib7000p_i2c_enumeration
);
1371 static struct dvb_frontend_ops dib7000p_ops
;
1372 struct dvb_frontend
* dib7000p_attach(struct i2c_adapter
*i2c_adap
, u8 i2c_addr
, struct dib7000p_config
*cfg
)
1374 struct dvb_frontend
*demod
;
1375 struct dib7000p_state
*st
;
1376 st
= kzalloc(sizeof(struct dib7000p_state
), GFP_KERNEL
);
1380 memcpy(&st
->cfg
, cfg
, sizeof(struct dib7000p_config
));
1381 st
->i2c_adap
= i2c_adap
;
1382 st
->i2c_addr
= i2c_addr
;
1383 st
->gpio_val
= cfg
->gpio_val
;
1384 st
->gpio_dir
= cfg
->gpio_dir
;
1386 /* Ensure the output mode remains at the previous default if it's
1387 * not specifically set by the caller.
1389 if ((st
->cfg
.output_mode
!= OUTMODE_MPEG2_SERIAL
) &&
1390 (st
->cfg
.output_mode
!= OUTMODE_MPEG2_PAR_GATED_CLK
))
1391 st
->cfg
.output_mode
= OUTMODE_MPEG2_FIFO
;
1394 demod
->demodulator_priv
= st
;
1395 memcpy(&st
->demod
.ops
, &dib7000p_ops
, sizeof(struct dvb_frontend_ops
));
1397 dib7000p_write_word(st
, 1287, 0x0003); /* sram lead in, rdy */
1399 if (dib7000p_identify(st
) != 0)
1402 /* FIXME: make sure the dev.parent field is initialized, or else
1403 request_firmware() will hit an OOPS (this should be moved somewhere
1405 st
->i2c_master
.gated_tuner_i2c_adap
.dev
.parent
= i2c_adap
->dev
.parent
;
1407 dibx000_init_i2c_master(&st
->i2c_master
, DIB7000P
, st
->i2c_adap
, st
->i2c_addr
);
1409 dib7000p_demod_reset(st
);
1417 EXPORT_SYMBOL(dib7000p_attach
);
1419 static struct dvb_frontend_ops dib7000p_ops
= {
1421 .name
= "DiBcom 7000PC",
1423 .frequency_min
= 44250000,
1424 .frequency_max
= 867250000,
1425 .frequency_stepsize
= 62500,
1426 .caps
= FE_CAN_INVERSION_AUTO
|
1427 FE_CAN_FEC_1_2
| FE_CAN_FEC_2_3
| FE_CAN_FEC_3_4
|
1428 FE_CAN_FEC_5_6
| FE_CAN_FEC_7_8
| FE_CAN_FEC_AUTO
|
1429 FE_CAN_QPSK
| FE_CAN_QAM_16
| FE_CAN_QAM_64
| FE_CAN_QAM_AUTO
|
1430 FE_CAN_TRANSMISSION_MODE_AUTO
|
1431 FE_CAN_GUARD_INTERVAL_AUTO
|
1433 FE_CAN_HIERARCHY_AUTO
,
1436 .release
= dib7000p_release
,
1438 .init
= dib7000p_wakeup
,
1439 .sleep
= dib7000p_sleep
,
1441 .set_frontend
= dib7000p_set_frontend
,
1442 .get_tune_settings
= dib7000p_fe_get_tune_settings
,
1443 .get_frontend
= dib7000p_get_frontend
,
1445 .read_status
= dib7000p_read_status
,
1446 .read_ber
= dib7000p_read_ber
,
1447 .read_signal_strength
= dib7000p_read_signal_strength
,
1448 .read_snr
= dib7000p_read_snr
,
1449 .read_ucblocks
= dib7000p_read_unc_blocks
,
1452 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
1453 MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
1454 MODULE_LICENSE("GPL");