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 reg_909
|= (state
->cfg
.disable_sample_and_hold
& 1) << 4;
264 reg_908
|= (state
->cfg
.enable_current_mirror
& 1) << 7;
266 dib7000p_write_word(state
, 908, reg_908
);
267 dib7000p_write_word(state
, 909, reg_909
);
270 static int dib7000p_set_bandwidth(struct dib7000p_state
*state
, u32 bw
)
274 // store the current bandwidth for later use
275 state
->current_bandwidth
= bw
;
277 if (state
->timf
== 0) {
278 dprintk( "using default timf");
279 timf
= state
->cfg
.bw
->timf
;
281 dprintk( "using updated timf");
285 timf
= timf
* (bw
/ 50) / 160;
287 dib7000p_write_word(state
, 23, (u16
) ((timf
>> 16) & 0xffff));
288 dib7000p_write_word(state
, 24, (u16
) ((timf
) & 0xffff));
293 static int dib7000p_sad_calib(struct dib7000p_state
*state
)
296 // dib7000p_write_word(state, 72, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth
297 dib7000p_write_word(state
, 73, (0 << 1) | (0 << 0));
298 dib7000p_write_word(state
, 74, 776); // 0.625*3.3 / 4096
300 /* do the calibration */
301 dib7000p_write_word(state
, 73, (1 << 0));
302 dib7000p_write_word(state
, 73, (0 << 0));
309 int dib7000p_set_wbd_ref(struct dvb_frontend
*demod
, u16 value
)
311 struct dib7000p_state
*state
= demod
->demodulator_priv
;
314 state
->wbd_ref
= value
;
315 return dib7000p_write_word(state
, 105, (dib7000p_read_word(state
, 105) & 0xf000) | value
);
318 EXPORT_SYMBOL(dib7000p_set_wbd_ref
);
319 static void dib7000p_reset_pll(struct dib7000p_state
*state
)
321 struct dibx000_bandwidth_config
*bw
= &state
->cfg
.bw
[0];
324 /* force PLL bypass */
325 clk_cfg0
= (1 << 15) | ((bw
->pll_ratio
& 0x3f) << 9) |
326 (bw
->modulo
<< 7) | (bw
->ADClkSrc
<< 6) | (bw
->IO_CLK_en_core
<< 5) |
327 (bw
->bypclk_div
<< 2) | (bw
->enable_refdiv
<< 1) | (0 << 0);
329 dib7000p_write_word(state
, 900, clk_cfg0
);
332 dib7000p_write_word(state
, 903, (bw
->pll_prediv
<< 5) | (((bw
->pll_ratio
>> 6) & 0x3) << 3) | (bw
->pll_range
<< 1) | bw
->pll_reset
);
333 clk_cfg0
= (bw
->pll_bypass
<< 15) | (clk_cfg0
& 0x7fff);
334 dib7000p_write_word(state
, 900, clk_cfg0
);
336 dib7000p_write_word(state
, 18, (u16
) (((bw
->internal
*1000) >> 16) & 0xffff));
337 dib7000p_write_word(state
, 19, (u16
) ( (bw
->internal
*1000 ) & 0xffff));
338 dib7000p_write_word(state
, 21, (u16
) ( (bw
->ifreq
>> 16) & 0xffff));
339 dib7000p_write_word(state
, 22, (u16
) ( (bw
->ifreq
) & 0xffff));
341 dib7000p_write_word(state
, 72, bw
->sad_cfg
);
344 static int dib7000p_reset_gpio(struct dib7000p_state
*st
)
346 /* reset the GPIOs */
347 dprintk( "gpio dir: %x: val: %x, pwm_pos: %x",st
->gpio_dir
, st
->gpio_val
,st
->cfg
.gpio_pwm_pos
);
349 dib7000p_write_word(st
, 1029, st
->gpio_dir
);
350 dib7000p_write_word(st
, 1030, st
->gpio_val
);
352 /* TODO 1031 is P_gpio_od */
354 dib7000p_write_word(st
, 1032, st
->cfg
.gpio_pwm_pos
);
356 dib7000p_write_word(st
, 1037, st
->cfg
.pwm_freq_div
);
360 static int dib7000p_cfg_gpio(struct dib7000p_state
*st
, u8 num
, u8 dir
, u8 val
)
362 st
->gpio_dir
= dib7000p_read_word(st
, 1029);
363 st
->gpio_dir
&= ~(1 << num
); /* reset the direction bit */
364 st
->gpio_dir
|= (dir
& 0x1) << num
; /* set the new direction */
365 dib7000p_write_word(st
, 1029, st
->gpio_dir
);
367 st
->gpio_val
= dib7000p_read_word(st
, 1030);
368 st
->gpio_val
&= ~(1 << num
); /* reset the direction bit */
369 st
->gpio_val
|= (val
& 0x01) << num
; /* set the new value */
370 dib7000p_write_word(st
, 1030, st
->gpio_val
);
375 int dib7000p_set_gpio(struct dvb_frontend
*demod
, u8 num
, u8 dir
, u8 val
)
377 struct dib7000p_state
*state
= demod
->demodulator_priv
;
378 return dib7000p_cfg_gpio(state
, num
, dir
, val
);
381 EXPORT_SYMBOL(dib7000p_set_gpio
);
382 static u16 dib7000p_defaults
[] =
385 // auto search configuration
389 0x0814, /* Equal Lock */
406 0x6680, // P_timf_alpha=6, P_corm_alpha=6, P_corm_thres=128 default: 6,4,26
408 /* set ADC level to -16 */
410 (1 << 13) - 825 - 117,
411 (1 << 13) - 837 - 117,
412 (1 << 13) - 811 - 117,
413 (1 << 13) - 766 - 117,
414 (1 << 13) - 737 - 117,
415 (1 << 13) - 693 - 117,
416 (1 << 13) - 648 - 117,
417 (1 << 13) - 619 - 117,
418 (1 << 13) - 575 - 117,
419 (1 << 13) - 531 - 117,
420 (1 << 13) - 501 - 117,
423 0x0410, // P_palf_filter_on=1, P_palf_filter_freeze=0, P_palf_alpha_regul=16
425 /* disable power smoothing */
437 1 << 13, // P_fft_freq_dir=1, P_fft_nb_to_cut=0
440 0x0ccd, // P_pha3_thres, default 0x3000
443 // 0x0010, // P_cti_use_cpe=0, P_cti_use_prog=0, P_cti_win_len=16, default: 0x0010
446 0x200f, // P_cspu_regul=512, P_cspu_win_cut=15, default: 0x2005
449 0x023d, // P_adp_regul_cnt=573, default: 410
450 0x00a4, // P_adp_noise_cnt=
451 0x00a4, // P_adp_regul_ext
452 0x7ff0, // P_adp_noise_ext
456 0x800, // P_equal_thres_wgn
459 0x0010, // P_fec_ber_rs_len=2
462 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
465 0x0006, // P_clk_cfg1
466 (3 << 10) | (1 << 6), // P_divclksel=3 P_divbitsel=1
469 0x2c8e, // Tuner IO bank: max drive (14mA) + divout pads max drive
474 static int dib7000p_demod_reset(struct dib7000p_state
*state
)
476 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
478 dib7000p_set_adc_state(state
, DIBX000_VBG_ENABLE
);
480 /* restart all parts */
481 dib7000p_write_word(state
, 770, 0xffff);
482 dib7000p_write_word(state
, 771, 0xffff);
483 dib7000p_write_word(state
, 772, 0x001f);
484 dib7000p_write_word(state
, 898, 0x0003);
485 /* except i2c, sdio, gpio - control interfaces */
486 dib7000p_write_word(state
, 1280, 0x01fc - ((1 << 7) | (1 << 6) | (1 << 5)) );
488 dib7000p_write_word(state
, 770, 0);
489 dib7000p_write_word(state
, 771, 0);
490 dib7000p_write_word(state
, 772, 0);
491 dib7000p_write_word(state
, 898, 0);
492 dib7000p_write_word(state
, 1280, 0);
495 dib7000p_reset_pll(state
);
497 if (dib7000p_reset_gpio(state
) != 0)
498 dprintk( "GPIO reset was not successful.");
500 if (dib7000p_set_output_mode(state
, OUTMODE_HIGH_Z
) != 0)
501 dprintk( "OUTPUT_MODE could not be reset.");
503 /* unforce divstr regardless whether i2c enumeration was done or not */
504 dib7000p_write_word(state
, 1285, dib7000p_read_word(state
, 1285) & ~(1 << 1) );
506 dib7000p_set_bandwidth(state
, 8000);
508 dib7000p_set_adc_state(state
, DIBX000_SLOW_ADC_ON
);
509 dib7000p_sad_calib(state
);
510 dib7000p_set_adc_state(state
, DIBX000_SLOW_ADC_OFF
);
512 // P_iqc_alpha_pha, P_iqc_alpha_amp_dcc_alpha, ...
513 if(state
->cfg
.tuner_is_baseband
)
514 dib7000p_write_word(state
, 36,0x0755);
516 dib7000p_write_word(state
, 36,0x1f55);
518 dib7000p_write_tab(state
, dib7000p_defaults
);
520 dib7000p_set_power_mode(state
, DIB7000P_POWER_INTERFACE_ONLY
);
526 static void dib7000p_pll_clk_cfg(struct dib7000p_state
*state
)
529 tmp
= dib7000p_read_word(state
, 903);
530 dib7000p_write_word(state
, 903, (tmp
| 0x1)); //pwr-up pll
531 tmp
= dib7000p_read_word(state
, 900);
532 dib7000p_write_word(state
, 900, (tmp
& 0x7fff) | (1 << 6)); //use High freq clock
535 static void dib7000p_restart_agc(struct dib7000p_state
*state
)
537 // P_restart_iqc & P_restart_agc
538 dib7000p_write_word(state
, 770, (1 << 11) | (1 << 9));
539 dib7000p_write_word(state
, 770, 0x0000);
542 static int dib7000p_update_lna(struct dib7000p_state
*state
)
546 // when there is no LNA to program return immediatly
547 if (state
->cfg
.update_lna
) {
548 // read dyn_gain here (because it is demod-dependent and not fe)
549 dyn_gain
= dib7000p_read_word(state
, 394);
550 if (state
->cfg
.update_lna(&state
->demod
,dyn_gain
)) { // LNA has changed
551 dib7000p_restart_agc(state
);
559 static int dib7000p_set_agc_config(struct dib7000p_state
*state
, u8 band
)
561 struct dibx000_agc_config
*agc
= NULL
;
563 if (state
->current_band
== band
&& state
->current_agc
!= NULL
)
565 state
->current_band
= band
;
567 for (i
= 0; i
< state
->cfg
.agc_config_count
; i
++)
568 if (state
->cfg
.agc
[i
].band_caps
& band
) {
569 agc
= &state
->cfg
.agc
[i
];
574 dprintk( "no valid AGC configuration found for band 0x%02x",band
);
578 state
->current_agc
= agc
;
581 dib7000p_write_word(state
, 75 , agc
->setup
);
582 dib7000p_write_word(state
, 76 , agc
->inv_gain
);
583 dib7000p_write_word(state
, 77 , agc
->time_stabiliz
);
584 dib7000p_write_word(state
, 100, (agc
->alpha_level
<< 12) | agc
->thlock
);
586 // Demod AGC loop configuration
587 dib7000p_write_word(state
, 101, (agc
->alpha_mant
<< 5) | agc
->alpha_exp
);
588 dib7000p_write_word(state
, 102, (agc
->beta_mant
<< 6) | agc
->beta_exp
);
591 dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d",
592 state
->wbd_ref
!= 0 ? state
->wbd_ref
: agc
->wbd_ref
, agc
->wbd_sel
, !agc
->perform_agc_softsplit
, agc
->wbd_sel
);
594 if (state
->wbd_ref
!= 0)
595 dib7000p_write_word(state
, 105, (agc
->wbd_inv
<< 12) | state
->wbd_ref
);
597 dib7000p_write_word(state
, 105, (agc
->wbd_inv
<< 12) | agc
->wbd_ref
);
599 dib7000p_write_word(state
, 106, (agc
->wbd_sel
<< 13) | (agc
->wbd_alpha
<< 9) | (agc
->perform_agc_softsplit
<< 8));
601 dib7000p_write_word(state
, 107, agc
->agc1_max
);
602 dib7000p_write_word(state
, 108, agc
->agc1_min
);
603 dib7000p_write_word(state
, 109, agc
->agc2_max
);
604 dib7000p_write_word(state
, 110, agc
->agc2_min
);
605 dib7000p_write_word(state
, 111, (agc
->agc1_pt1
<< 8) | agc
->agc1_pt2
);
606 dib7000p_write_word(state
, 112, agc
->agc1_pt3
);
607 dib7000p_write_word(state
, 113, (agc
->agc1_slope1
<< 8) | agc
->agc1_slope2
);
608 dib7000p_write_word(state
, 114, (agc
->agc2_pt1
<< 8) | agc
->agc2_pt2
);
609 dib7000p_write_word(state
, 115, (agc
->agc2_slope1
<< 8) | agc
->agc2_slope2
);
613 static int dib7000p_agc_startup(struct dvb_frontend
*demod
, struct dvb_frontend_parameters
*ch
)
615 struct dib7000p_state
*state
= demod
->demodulator_priv
;
617 u8
*agc_state
= &state
->agc_state
;
620 switch (state
->agc_state
) {
622 // set power-up level: interf+analog+AGC
623 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
624 dib7000p_set_adc_state(state
, DIBX000_ADC_ON
);
625 dib7000p_pll_clk_cfg(state
);
627 if (dib7000p_set_agc_config(state
, BAND_OF_FREQUENCY(ch
->frequency
/1000)) != 0)
635 // AGC initialization
636 if (state
->cfg
.agc_control
)
637 state
->cfg
.agc_control(&state
->demod
, 1);
639 dib7000p_write_word(state
, 78, 32768);
640 if (!state
->current_agc
->perform_agc_softsplit
) {
641 /* we are using the wbd - so slow AGC startup */
642 /* force 0 split on WBD and restart AGC */
643 dib7000p_write_word(state
, 106, (state
->current_agc
->wbd_sel
<< 13) | (state
->current_agc
->wbd_alpha
<< 9) | (1 << 8));
647 /* default AGC startup */
649 /* wait AGC rough lock time */
653 dib7000p_restart_agc(state
);
656 case 2: /* fast split search path after 5sec */
657 dib7000p_write_word(state
, 75, state
->current_agc
->setup
| (1 << 4)); /* freeze AGC loop */
658 dib7000p_write_word(state
, 106, (state
->current_agc
->wbd_sel
<< 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */
663 case 3: /* split search ended */
664 agc_split
= (u8
)dib7000p_read_word(state
, 396); /* store the split value for the next time */
665 dib7000p_write_word(state
, 78, dib7000p_read_word(state
, 394)); /* set AGC gain start value */
667 dib7000p_write_word(state
, 75, state
->current_agc
->setup
); /* std AGC loop */
668 dib7000p_write_word(state
, 106, (state
->current_agc
->wbd_sel
<< 13) | (state
->current_agc
->wbd_alpha
<< 9) | agc_split
); /* standard split search */
670 dib7000p_restart_agc(state
);
672 dprintk( "SPLIT %p: %hd", demod
, agc_split
);
678 case 4: /* LNA startup */
679 // wait AGC accurate lock time
682 if (dib7000p_update_lna(state
))
683 // wait only AGC rough lock time
685 else // nothing was done, go to the next state
690 if (state
->cfg
.agc_control
)
691 state
->cfg
.agc_control(&state
->demod
, 0);
700 static void dib7000p_update_timf(struct dib7000p_state
*state
)
702 u32 timf
= (dib7000p_read_word(state
, 427) << 16) | dib7000p_read_word(state
, 428);
703 state
->timf
= timf
* 160 / (state
->current_bandwidth
/ 50);
704 dib7000p_write_word(state
, 23, (u16
) (timf
>> 16));
705 dib7000p_write_word(state
, 24, (u16
) (timf
& 0xffff));
706 dprintk( "updated timf_frequency: %d (default: %d)",state
->timf
, state
->cfg
.bw
->timf
);
710 static void dib7000p_set_channel(struct dib7000p_state
*state
, struct dvb_frontend_parameters
*ch
, u8 seq
)
714 dib7000p_set_bandwidth(state
, BANDWIDTH_TO_KHZ(ch
->u
.ofdm
.bandwidth
));
716 /* nfft, guard, qam, alpha */
718 switch (ch
->u
.ofdm
.transmission_mode
) {
719 case TRANSMISSION_MODE_2K
: value
|= (0 << 7); break;
720 case /* 4K MODE */ 255: value
|= (2 << 7); break;
722 case TRANSMISSION_MODE_8K
: value
|= (1 << 7); break;
724 switch (ch
->u
.ofdm
.guard_interval
) {
725 case GUARD_INTERVAL_1_32
: value
|= (0 << 5); break;
726 case GUARD_INTERVAL_1_16
: value
|= (1 << 5); break;
727 case GUARD_INTERVAL_1_4
: value
|= (3 << 5); break;
729 case GUARD_INTERVAL_1_8
: value
|= (2 << 5); break;
731 switch (ch
->u
.ofdm
.constellation
) {
732 case QPSK
: value
|= (0 << 3); break;
733 case QAM_16
: value
|= (1 << 3); break;
735 case QAM_64
: value
|= (2 << 3); break;
737 switch (HIERARCHY_1
) {
738 case HIERARCHY_2
: value
|= 2; break;
739 case HIERARCHY_4
: value
|= 4; break;
741 case HIERARCHY_1
: value
|= 1; break;
743 dib7000p_write_word(state
, 0, value
);
744 dib7000p_write_word(state
, 5, (seq
<< 4) | 1); /* do not force tps, search list 0 */
746 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
750 if (ch
->u
.ofdm
.hierarchy_information
== 1)
754 switch ((ch
->u
.ofdm
.hierarchy_information
== 0 || 1 == 1) ? ch
->u
.ofdm
.code_rate_HP
: ch
->u
.ofdm
.code_rate_LP
) {
755 case FEC_2_3
: value
|= (2 << 1); break;
756 case FEC_3_4
: value
|= (3 << 1); break;
757 case FEC_5_6
: value
|= (5 << 1); break;
758 case FEC_7_8
: value
|= (7 << 1); break;
760 case FEC_1_2
: value
|= (1 << 1); break;
762 dib7000p_write_word(state
, 208, value
);
764 /* offset loop parameters */
765 dib7000p_write_word(state
, 26, 0x6680); // timf(6xxx)
766 dib7000p_write_word(state
, 32, 0x0003); // pha_off_max(xxx3)
767 dib7000p_write_word(state
, 29, 0x1273); // isi
768 dib7000p_write_word(state
, 33, 0x0005); // sfreq(xxx5)
770 /* P_dvsy_sync_wait */
771 switch (ch
->u
.ofdm
.transmission_mode
) {
772 case TRANSMISSION_MODE_8K
: value
= 256; break;
773 case /* 4K MODE */ 255: value
= 128; break;
774 case TRANSMISSION_MODE_2K
:
775 default: value
= 64; break;
777 switch (ch
->u
.ofdm
.guard_interval
) {
778 case GUARD_INTERVAL_1_16
: value
*= 2; break;
779 case GUARD_INTERVAL_1_8
: value
*= 4; break;
780 case GUARD_INTERVAL_1_4
: value
*= 8; break;
782 case GUARD_INTERVAL_1_32
: value
*= 1; break;
784 if (state
->cfg
.diversity_delay
== 0)
785 state
->div_sync_wait
= (value
* 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo
787 state
->div_sync_wait
= (value
* 3) / 2 + state
->cfg
.diversity_delay
; // add 50% SFN margin + compensate for one DVSY-fifo
789 /* deactive the possibility of diversity reception if extended interleaver */
790 state
->div_force_off
= !1 && ch
->u
.ofdm
.transmission_mode
!= TRANSMISSION_MODE_8K
;
791 dib7000p_set_diversity_in(&state
->demod
, state
->div_state
);
793 /* channel estimation fine configuration */
794 switch (ch
->u
.ofdm
.constellation
) {
796 est
[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
797 est
[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
798 est
[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
799 est
[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
802 est
[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
803 est
[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
804 est
[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
805 est
[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
808 est
[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
809 est
[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
810 est
[2] = 0x0333; /* P_adp_regul_ext 0.1 */
811 est
[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
814 for (value
= 0; value
< 4; value
++)
815 dib7000p_write_word(state
, 187 + value
, est
[value
]);
818 static int dib7000p_autosearch_start(struct dvb_frontend
*demod
, struct dvb_frontend_parameters
*ch
)
820 struct dib7000p_state
*state
= demod
->demodulator_priv
;
821 struct dvb_frontend_parameters schan
;
825 schan
.u
.ofdm
.constellation
= QAM_64
;
826 schan
.u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_32
;
827 schan
.u
.ofdm
.transmission_mode
= TRANSMISSION_MODE_8K
;
828 schan
.u
.ofdm
.code_rate_HP
= FEC_2_3
;
829 schan
.u
.ofdm
.code_rate_LP
= FEC_3_4
;
830 schan
.u
.ofdm
.hierarchy_information
= 0;
832 dib7000p_set_channel(state
, &schan
, 7);
834 factor
= BANDWIDTH_TO_KHZ(ch
->u
.ofdm
.bandwidth
);
840 // always use the setting for 8MHz here lock_time for 7,6 MHz are longer
841 value
= 30 * state
->cfg
.bw
->internal
* factor
;
842 dib7000p_write_word(state
, 6, (u16
) ((value
>> 16) & 0xffff)); // lock0 wait time
843 dib7000p_write_word(state
, 7, (u16
) (value
& 0xffff)); // lock0 wait time
844 value
= 100 * state
->cfg
.bw
->internal
* factor
;
845 dib7000p_write_word(state
, 8, (u16
) ((value
>> 16) & 0xffff)); // lock1 wait time
846 dib7000p_write_word(state
, 9, (u16
) (value
& 0xffff)); // lock1 wait time
847 value
= 500 * state
->cfg
.bw
->internal
* factor
;
848 dib7000p_write_word(state
, 10, (u16
) ((value
>> 16) & 0xffff)); // lock2 wait time
849 dib7000p_write_word(state
, 11, (u16
) (value
& 0xffff)); // lock2 wait time
851 value
= dib7000p_read_word(state
, 0);
852 dib7000p_write_word(state
, 0, (u16
) ((1 << 9) | value
));
853 dib7000p_read_word(state
, 1284);
854 dib7000p_write_word(state
, 0, (u16
) value
);
859 static int dib7000p_autosearch_is_irq(struct dvb_frontend
*demod
)
861 struct dib7000p_state
*state
= demod
->demodulator_priv
;
862 u16 irq_pending
= dib7000p_read_word(state
, 1284);
864 if (irq_pending
& 0x1) // failed
867 if (irq_pending
& 0x2) // succeeded
870 return 0; // still pending
873 static void dib7000p_spur_protect(struct dib7000p_state
*state
, u32 rf_khz
, u32 bw
)
875 static s16 notch
[]={16143, 14402, 12238, 9713, 6902, 3888, 759, -2392};
876 static u8 sine
[] ={0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
877 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
878 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
879 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
880 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
881 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
882 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
883 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
884 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
885 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
886 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
887 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
888 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
889 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
890 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
891 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
892 255, 255, 255, 255, 255, 255};
894 u32 xtal
= state
->cfg
.bw
->xtal_hz
/ 1000;
895 int f_rel
= DIV_ROUND_CLOSEST(rf_khz
, xtal
) * xtal
- rf_khz
;
897 int coef_re
[8],coef_im
[8];
901 dprintk( "relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel
, rf_khz
, xtal
);
904 if (f_rel
< -bw_khz
/2 || f_rel
> bw_khz
/2)
909 dib7000p_write_word(state
, 142 ,0x0610);
911 for (k
= 0; k
< 8; k
++) {
912 pha
= ((f_rel
* (k
+1) * 112 * 80/bw_khz
) /1000) & 0x3ff;
917 } else if(pha
< 256) {
918 coef_re
[k
] = sine
[256-(pha
&0xff)];
919 coef_im
[k
] = sine
[pha
&0xff];
920 } else if (pha
== 256) {
923 } else if (pha
< 512) {
924 coef_re
[k
] = -sine
[pha
&0xff];
925 coef_im
[k
] = sine
[256 - (pha
&0xff)];
926 } else if (pha
== 512) {
929 } else if (pha
< 768) {
930 coef_re
[k
] = -sine
[256-(pha
&0xff)];
931 coef_im
[k
] = -sine
[pha
&0xff];
932 } else if (pha
== 768) {
936 coef_re
[k
] = sine
[pha
&0xff];
937 coef_im
[k
] = -sine
[256 - (pha
&0xff)];
940 coef_re
[k
] *= notch
[k
];
941 coef_re
[k
] += (1<<14);
942 if (coef_re
[k
] >= (1<<24))
943 coef_re
[k
] = (1<<24) - 1;
944 coef_re
[k
] /= (1<<15);
946 coef_im
[k
] *= notch
[k
];
947 coef_im
[k
] += (1<<14);
948 if (coef_im
[k
] >= (1<<24))
949 coef_im
[k
] = (1<<24)-1;
950 coef_im
[k
] /= (1<<15);
952 dprintk( "PALF COEF: %d re: %d im: %d", k
, coef_re
[k
], coef_im
[k
]);
954 dib7000p_write_word(state
, 143, (0 << 14) | (k
<< 10) | (coef_re
[k
] & 0x3ff));
955 dib7000p_write_word(state
, 144, coef_im
[k
] & 0x3ff);
956 dib7000p_write_word(state
, 143, (1 << 14) | (k
<< 10) | (coef_re
[k
] & 0x3ff));
958 dib7000p_write_word(state
,143 ,0);
961 static int dib7000p_tune(struct dvb_frontend
*demod
, struct dvb_frontend_parameters
*ch
)
963 struct dib7000p_state
*state
= demod
->demodulator_priv
;
967 dib7000p_set_channel(state
, ch
, 0);
972 dib7000p_write_word(state
, 770, 0x4000);
973 dib7000p_write_word(state
, 770, 0x0000);
976 /* 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 */
977 tmp
= (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
978 if (state
->sfn_workaround_active
) {
979 dprintk( "SFN workaround is active");
981 dib7000p_write_word(state
, 166, 0x4000); // P_pha3_force_pha_shift
983 dib7000p_write_word(state
, 166, 0x0000); // P_pha3_force_pha_shift
985 dib7000p_write_word(state
, 29, tmp
);
987 // never achieved a lock with that bandwidth so far - wait for osc-freq to update
988 if (state
->timf
== 0)
991 /* offset loop parameters */
993 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
994 tmp
= (6 << 8) | 0x80;
995 switch (ch
->u
.ofdm
.transmission_mode
) {
996 case TRANSMISSION_MODE_2K
: tmp
|= (7 << 12); break;
997 case /* 4K MODE */ 255: tmp
|= (8 << 12); break;
999 case TRANSMISSION_MODE_8K
: tmp
|= (9 << 12); break;
1001 dib7000p_write_word(state
, 26, tmp
); /* timf_a(6xxx) */
1003 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1005 switch (ch
->u
.ofdm
.transmission_mode
) {
1006 case TRANSMISSION_MODE_2K
: tmp
|= 0x6; break;
1007 case /* 4K MODE */ 255: tmp
|= 0x7; break;
1009 case TRANSMISSION_MODE_8K
: tmp
|= 0x8; break;
1011 dib7000p_write_word(state
, 32, tmp
);
1013 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1015 switch (ch
->u
.ofdm
.transmission_mode
) {
1016 case TRANSMISSION_MODE_2K
: tmp
|= 0x6; break;
1017 case /* 4K MODE */ 255: tmp
|= 0x7; break;
1019 case TRANSMISSION_MODE_8K
: tmp
|= 0x8; break;
1021 dib7000p_write_word(state
, 33, tmp
);
1023 tmp
= dib7000p_read_word(state
,509);
1024 if (!((tmp
>> 6) & 0x1)) {
1025 /* restart the fec */
1026 tmp
= dib7000p_read_word(state
,771);
1027 dib7000p_write_word(state
, 771, tmp
| (1 << 1));
1028 dib7000p_write_word(state
, 771, tmp
);
1030 tmp
= dib7000p_read_word(state
,509);
1033 // we achieved a lock - it's time to update the osc freq
1034 if ((tmp
>> 6) & 0x1)
1035 dib7000p_update_timf(state
);
1037 if (state
->cfg
.spur_protect
)
1038 dib7000p_spur_protect(state
, ch
->frequency
/1000, BANDWIDTH_TO_KHZ(ch
->u
.ofdm
.bandwidth
));
1040 dib7000p_set_bandwidth(state
, BANDWIDTH_TO_KHZ(ch
->u
.ofdm
.bandwidth
));
1044 static int dib7000p_wakeup(struct dvb_frontend
*demod
)
1046 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1047 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
1048 dib7000p_set_adc_state(state
, DIBX000_SLOW_ADC_ON
);
1052 static int dib7000p_sleep(struct dvb_frontend
*demod
)
1054 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1055 return dib7000p_set_output_mode(state
, OUTMODE_HIGH_Z
) | dib7000p_set_power_mode(state
, DIB7000P_POWER_INTERFACE_ONLY
);
1058 static int dib7000p_identify(struct dib7000p_state
*st
)
1061 dprintk( "checking demod on I2C address: %d (%x)",
1062 st
->i2c_addr
, st
->i2c_addr
);
1064 if ((value
= dib7000p_read_word(st
, 768)) != 0x01b3) {
1065 dprintk( "wrong Vendor ID (read=0x%x)",value
);
1069 if ((value
= dib7000p_read_word(st
, 769)) != 0x4000) {
1070 dprintk( "wrong Device ID (%x)",value
);
1078 static int dib7000p_get_frontend(struct dvb_frontend
* fe
,
1079 struct dvb_frontend_parameters
*fep
)
1081 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1082 u16 tps
= dib7000p_read_word(state
,463);
1084 fep
->inversion
= INVERSION_AUTO
;
1086 fep
->u
.ofdm
.bandwidth
= BANDWIDTH_TO_INDEX(state
->current_bandwidth
);
1088 switch ((tps
>> 8) & 0x3) {
1089 case 0: fep
->u
.ofdm
.transmission_mode
= TRANSMISSION_MODE_2K
; break;
1090 case 1: fep
->u
.ofdm
.transmission_mode
= TRANSMISSION_MODE_8K
; break;
1091 /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */
1094 switch (tps
& 0x3) {
1095 case 0: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_32
; break;
1096 case 1: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_16
; break;
1097 case 2: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_8
; break;
1098 case 3: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_4
; break;
1101 switch ((tps
>> 14) & 0x3) {
1102 case 0: fep
->u
.ofdm
.constellation
= QPSK
; break;
1103 case 1: fep
->u
.ofdm
.constellation
= QAM_16
; break;
1105 default: fep
->u
.ofdm
.constellation
= QAM_64
; break;
1108 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1109 /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1111 fep
->u
.ofdm
.hierarchy_information
= HIERARCHY_NONE
;
1112 switch ((tps
>> 5) & 0x7) {
1113 case 1: fep
->u
.ofdm
.code_rate_HP
= FEC_1_2
; break;
1114 case 2: fep
->u
.ofdm
.code_rate_HP
= FEC_2_3
; break;
1115 case 3: fep
->u
.ofdm
.code_rate_HP
= FEC_3_4
; break;
1116 case 5: fep
->u
.ofdm
.code_rate_HP
= FEC_5_6
; break;
1118 default: fep
->u
.ofdm
.code_rate_HP
= FEC_7_8
; break;
1122 switch ((tps
>> 2) & 0x7) {
1123 case 1: fep
->u
.ofdm
.code_rate_LP
= FEC_1_2
; break;
1124 case 2: fep
->u
.ofdm
.code_rate_LP
= FEC_2_3
; break;
1125 case 3: fep
->u
.ofdm
.code_rate_LP
= FEC_3_4
; break;
1126 case 5: fep
->u
.ofdm
.code_rate_LP
= FEC_5_6
; break;
1128 default: fep
->u
.ofdm
.code_rate_LP
= FEC_7_8
; break;
1131 /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */
1136 static int dib7000p_set_frontend(struct dvb_frontend
* fe
,
1137 struct dvb_frontend_parameters
*fep
)
1139 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1142 dib7000p_set_output_mode(state
, OUTMODE_HIGH_Z
);
1144 /* maybe the parameter has been changed */
1145 state
->sfn_workaround_active
= buggy_sfn_workaround
;
1147 if (fe
->ops
.tuner_ops
.set_params
)
1148 fe
->ops
.tuner_ops
.set_params(fe
, fep
);
1150 /* start up the AGC */
1151 state
->agc_state
= 0;
1153 time
= dib7000p_agc_startup(fe
, fep
);
1156 } while (time
!= -1);
1158 if (fep
->u
.ofdm
.transmission_mode
== TRANSMISSION_MODE_AUTO
||
1159 fep
->u
.ofdm
.guard_interval
== GUARD_INTERVAL_AUTO
||
1160 fep
->u
.ofdm
.constellation
== QAM_AUTO
||
1161 fep
->u
.ofdm
.code_rate_HP
== FEC_AUTO
) {
1164 dib7000p_autosearch_start(fe
, fep
);
1167 found
= dib7000p_autosearch_is_irq(fe
);
1168 } while (found
== 0 && i
--);
1170 dprintk("autosearch returns: %d",found
);
1171 if (found
== 0 || found
== 1)
1172 return 0; // no channel found
1174 dib7000p_get_frontend(fe
, fep
);
1177 ret
= dib7000p_tune(fe
, fep
);
1179 /* make this a config parameter */
1180 dib7000p_set_output_mode(state
, state
->cfg
.output_mode
);
1184 static int dib7000p_read_status(struct dvb_frontend
*fe
, fe_status_t
*stat
)
1186 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1187 u16 lock
= dib7000p_read_word(state
, 509);
1192 *stat
|= FE_HAS_SIGNAL
;
1194 *stat
|= FE_HAS_CARRIER
;
1196 *stat
|= FE_HAS_VITERBI
;
1198 *stat
|= FE_HAS_SYNC
;
1199 if ((lock
& 0x0038) == 0x38)
1200 *stat
|= FE_HAS_LOCK
;
1205 static int dib7000p_read_ber(struct dvb_frontend
*fe
, u32
*ber
)
1207 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1208 *ber
= (dib7000p_read_word(state
, 500) << 16) | dib7000p_read_word(state
, 501);
1212 static int dib7000p_read_unc_blocks(struct dvb_frontend
*fe
, u32
*unc
)
1214 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1215 *unc
= dib7000p_read_word(state
, 506);
1219 static int dib7000p_read_signal_strength(struct dvb_frontend
*fe
, u16
*strength
)
1221 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1222 u16 val
= dib7000p_read_word(state
, 394);
1223 *strength
= 65535 - val
;
1227 static int dib7000p_read_snr(struct dvb_frontend
* fe
, u16
*snr
)
1229 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1231 s32 signal_mant
, signal_exp
, noise_mant
, noise_exp
;
1234 val
= dib7000p_read_word(state
, 479);
1235 noise_mant
= (val
>> 4) & 0xff;
1236 noise_exp
= ((val
& 0xf) << 2);
1237 val
= dib7000p_read_word(state
, 480);
1238 noise_exp
+= ((val
>> 14) & 0x3);
1239 if ((noise_exp
& 0x20) != 0)
1242 signal_mant
= (val
>> 6) & 0xFF;
1243 signal_exp
= (val
& 0x3F);
1244 if ((signal_exp
& 0x20) != 0)
1247 if (signal_mant
!= 0)
1248 result
= intlog10(2) * 10 * signal_exp
+ 10 *
1249 intlog10(signal_mant
);
1251 result
= intlog10(2) * 10 * signal_exp
- 100;
1253 if (noise_mant
!= 0)
1254 result
-= intlog10(2) * 10 * noise_exp
+ 10 *
1255 intlog10(noise_mant
);
1257 result
-= intlog10(2) * 10 * noise_exp
- 100;
1259 *snr
= result
/ ((1 << 24) / 10);
1263 static int dib7000p_fe_get_tune_settings(struct dvb_frontend
* fe
, struct dvb_frontend_tune_settings
*tune
)
1265 tune
->min_delay_ms
= 1000;
1269 static void dib7000p_release(struct dvb_frontend
*demod
)
1271 struct dib7000p_state
*st
= demod
->demodulator_priv
;
1272 dibx000_exit_i2c_master(&st
->i2c_master
);
1276 int dib7000pc_detection(struct i2c_adapter
*i2c_adap
)
1279 struct i2c_msg msg
[2] = {
1280 { .addr
= 18 >> 1, .flags
= 0, .buf
= tx
, .len
= 2 },
1281 { .addr
= 18 >> 1, .flags
= I2C_M_RD
, .buf
= rx
, .len
= 2 },
1287 if (i2c_transfer(i2c_adap
, msg
, 2) == 2)
1288 if (rx
[0] == 0x01 && rx
[1] == 0xb3) {
1289 dprintk("-D- DiB7000PC detected");
1293 msg
[0].addr
= msg
[1].addr
= 0x40;
1295 if (i2c_transfer(i2c_adap
, msg
, 2) == 2)
1296 if (rx
[0] == 0x01 && rx
[1] == 0xb3) {
1297 dprintk("-D- DiB7000PC detected");
1301 dprintk("-D- DiB7000PC not detected");
1304 EXPORT_SYMBOL(dib7000pc_detection
);
1306 struct i2c_adapter
* dib7000p_get_i2c_master(struct dvb_frontend
*demod
, enum dibx000_i2c_interface intf
, int gating
)
1308 struct dib7000p_state
*st
= demod
->demodulator_priv
;
1309 return dibx000_get_i2c_adapter(&st
->i2c_master
, intf
, gating
);
1311 EXPORT_SYMBOL(dib7000p_get_i2c_master
);
1313 int dib7000p_pid_filter_ctrl(struct dvb_frontend
*fe
, u8 onoff
)
1315 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1316 u16 val
= dib7000p_read_word(state
, 235) & 0xffef;
1317 val
|= (onoff
& 0x1) << 4;
1318 dprintk("PID filter enabled %d", onoff
);
1319 return dib7000p_write_word(state
, 235, val
);
1321 EXPORT_SYMBOL(dib7000p_pid_filter_ctrl
);
1323 int dib7000p_pid_filter(struct dvb_frontend
*fe
, u8 id
, u16 pid
, u8 onoff
)
1325 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1326 dprintk("PID filter: index %x, PID %d, OnOff %d", id
, pid
, onoff
);
1327 return dib7000p_write_word(state
, 241 + id
, onoff
? (1 << 13) | pid
: 0);
1329 EXPORT_SYMBOL(dib7000p_pid_filter
);
1331 int dib7000p_i2c_enumeration(struct i2c_adapter
*i2c
, int no_of_demods
, u8 default_addr
, struct dib7000p_config cfg
[])
1333 struct dib7000p_state
*dpst
;
1337 dpst
= kzalloc(sizeof(struct dib7000p_state
), GFP_KERNEL
);
1341 dpst
->i2c_adap
= i2c
;
1343 for (k
= no_of_demods
-1; k
>= 0; k
--) {
1346 /* designated i2c address */
1347 new_addr
= (0x40 + k
) << 1;
1348 dpst
->i2c_addr
= new_addr
;
1349 dib7000p_write_word(dpst
, 1287, 0x0003); /* sram lead in, rdy */
1350 if (dib7000p_identify(dpst
) != 0) {
1351 dpst
->i2c_addr
= default_addr
;
1352 dib7000p_write_word(dpst
, 1287, 0x0003); /* sram lead in, rdy */
1353 if (dib7000p_identify(dpst
) != 0) {
1354 dprintk("DiB7000P #%d: not identified\n", k
);
1360 /* start diversity to pull_down div_str - just for i2c-enumeration */
1361 dib7000p_set_output_mode(dpst
, OUTMODE_DIVERSITY
);
1363 /* set new i2c address and force divstart */
1364 dib7000p_write_word(dpst
, 1285, (new_addr
<< 2) | 0x2);
1366 dprintk("IC %d initialized (to i2c_address 0x%x)", k
, new_addr
);
1369 for (k
= 0; k
< no_of_demods
; k
++) {
1371 dpst
->i2c_addr
= (0x40 + k
) << 1;
1374 dib7000p_write_word(dpst
, 1285, dpst
->i2c_addr
<< 2);
1376 /* deactivate div - it was just for i2c-enumeration */
1377 dib7000p_set_output_mode(dpst
, OUTMODE_HIGH_Z
);
1383 EXPORT_SYMBOL(dib7000p_i2c_enumeration
);
1385 static struct dvb_frontend_ops dib7000p_ops
;
1386 struct dvb_frontend
* dib7000p_attach(struct i2c_adapter
*i2c_adap
, u8 i2c_addr
, struct dib7000p_config
*cfg
)
1388 struct dvb_frontend
*demod
;
1389 struct dib7000p_state
*st
;
1390 st
= kzalloc(sizeof(struct dib7000p_state
), GFP_KERNEL
);
1394 memcpy(&st
->cfg
, cfg
, sizeof(struct dib7000p_config
));
1395 st
->i2c_adap
= i2c_adap
;
1396 st
->i2c_addr
= i2c_addr
;
1397 st
->gpio_val
= cfg
->gpio_val
;
1398 st
->gpio_dir
= cfg
->gpio_dir
;
1400 /* Ensure the output mode remains at the previous default if it's
1401 * not specifically set by the caller.
1403 if ((st
->cfg
.output_mode
!= OUTMODE_MPEG2_SERIAL
) &&
1404 (st
->cfg
.output_mode
!= OUTMODE_MPEG2_PAR_GATED_CLK
))
1405 st
->cfg
.output_mode
= OUTMODE_MPEG2_FIFO
;
1408 demod
->demodulator_priv
= st
;
1409 memcpy(&st
->demod
.ops
, &dib7000p_ops
, sizeof(struct dvb_frontend_ops
));
1411 dib7000p_write_word(st
, 1287, 0x0003); /* sram lead in, rdy */
1413 if (dib7000p_identify(st
) != 0)
1416 /* FIXME: make sure the dev.parent field is initialized, or else
1417 request_firmware() will hit an OOPS (this should be moved somewhere
1419 st
->i2c_master
.gated_tuner_i2c_adap
.dev
.parent
= i2c_adap
->dev
.parent
;
1421 dibx000_init_i2c_master(&st
->i2c_master
, DIB7000P
, st
->i2c_adap
, st
->i2c_addr
);
1423 dib7000p_demod_reset(st
);
1431 EXPORT_SYMBOL(dib7000p_attach
);
1433 static struct dvb_frontend_ops dib7000p_ops
= {
1435 .name
= "DiBcom 7000PC",
1437 .frequency_min
= 44250000,
1438 .frequency_max
= 867250000,
1439 .frequency_stepsize
= 62500,
1440 .caps
= FE_CAN_INVERSION_AUTO
|
1441 FE_CAN_FEC_1_2
| FE_CAN_FEC_2_3
| FE_CAN_FEC_3_4
|
1442 FE_CAN_FEC_5_6
| FE_CAN_FEC_7_8
| FE_CAN_FEC_AUTO
|
1443 FE_CAN_QPSK
| FE_CAN_QAM_16
| FE_CAN_QAM_64
| FE_CAN_QAM_AUTO
|
1444 FE_CAN_TRANSMISSION_MODE_AUTO
|
1445 FE_CAN_GUARD_INTERVAL_AUTO
|
1447 FE_CAN_HIERARCHY_AUTO
,
1450 .release
= dib7000p_release
,
1452 .init
= dib7000p_wakeup
,
1453 .sleep
= dib7000p_sleep
,
1455 .set_frontend
= dib7000p_set_frontend
,
1456 .get_tune_settings
= dib7000p_fe_get_tune_settings
,
1457 .get_frontend
= dib7000p_get_frontend
,
1459 .read_status
= dib7000p_read_status
,
1460 .read_ber
= dib7000p_read_ber
,
1461 .read_signal_strength
= dib7000p_read_signal_strength
,
1462 .read_snr
= dib7000p_read_snr
,
1463 .read_ucblocks
= dib7000p_read_unc_blocks
,
1466 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
1467 MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
1468 MODULE_LICENSE("GPL");