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/i2c.h>
14 #include "dvb_frontend.h"
19 module_param(debug
, int, 0644);
20 MODULE_PARM_DESC(debug
, "turn on debugging (default: 0)");
22 static int buggy_sfn_workaround
;
23 module_param(buggy_sfn_workaround
, int, 0644);
24 MODULE_PARM_DESC(buggy_sfn_workaround
, "Enable work-around for buggy SFNs (default: 0)");
26 #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0)
28 struct dib7000p_state
{
29 struct dvb_frontend demod
;
30 struct dib7000p_config cfg
;
33 struct i2c_adapter
*i2c_adap
;
35 struct dibx000_i2c_master i2c_master
;
40 u32 current_bandwidth
;
41 struct dibx000_agc_config
*current_agc
;
53 u8 sfn_workaround_active
:1;
56 enum dib7000p_power_mode
{
57 DIB7000P_POWER_ALL
= 0,
58 DIB7000P_POWER_ANALOG_ADC
,
59 DIB7000P_POWER_INTERFACE_ONLY
,
62 static u16
dib7000p_read_word(struct dib7000p_state
*state
, u16 reg
)
64 u8 wb
[2] = { reg
>> 8, reg
& 0xff };
66 struct i2c_msg msg
[2] = {
67 { .addr
= state
->i2c_addr
>> 1, .flags
= 0, .buf
= wb
, .len
= 2 },
68 { .addr
= state
->i2c_addr
>> 1, .flags
= I2C_M_RD
, .buf
= rb
, .len
= 2 },
71 if (i2c_transfer(state
->i2c_adap
, msg
, 2) != 2)
72 dprintk("i2c read error on %d",reg
);
74 return (rb
[0] << 8) | rb
[1];
77 static int dib7000p_write_word(struct dib7000p_state
*state
, u16 reg
, u16 val
)
80 (reg
>> 8) & 0xff, reg
& 0xff,
81 (val
>> 8) & 0xff, val
& 0xff,
83 struct i2c_msg msg
= {
84 .addr
= state
->i2c_addr
>> 1, .flags
= 0, .buf
= b
, .len
= 4
86 return i2c_transfer(state
->i2c_adap
, &msg
, 1) != 1 ? -EREMOTEIO
: 0;
88 static void dib7000p_write_tab(struct dib7000p_state
*state
, u16
*buf
)
97 dib7000p_write_word(state
, r
, *n
++);
104 static int dib7000p_set_output_mode(struct dib7000p_state
*state
, int mode
)
107 u16 outreg
, fifo_threshold
, smo_mode
;
110 fifo_threshold
= 1792;
111 smo_mode
= (dib7000p_read_word(state
, 235) & 0x0010) | (1 << 1);
113 dprintk( "setting output mode for demod %p to %d",
114 &state
->demod
, mode
);
117 case OUTMODE_MPEG2_PAR_GATED_CLK
: // STBs with parallel gated clock
118 outreg
= (1 << 10); /* 0x0400 */
120 case OUTMODE_MPEG2_PAR_CONT_CLK
: // STBs with parallel continues clock
121 outreg
= (1 << 10) | (1 << 6); /* 0x0440 */
123 case OUTMODE_MPEG2_SERIAL
: // STBs with serial input
124 outreg
= (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */
126 case OUTMODE_DIVERSITY
:
127 if (state
->cfg
.hostbus_diversity
)
128 outreg
= (1 << 10) | (4 << 6); /* 0x0500 */
132 case OUTMODE_MPEG2_FIFO
: // e.g. USB feeding
133 smo_mode
|= (3 << 1);
134 fifo_threshold
= 512;
135 outreg
= (1 << 10) | (5 << 6);
137 case OUTMODE_ANALOG_ADC
:
138 outreg
= (1 << 10) | (3 << 6);
140 case OUTMODE_HIGH_Z
: // disable
144 dprintk( "Unhandled output_mode passed to be set for demod %p",&state
->demod
);
148 if (state
->cfg
.output_mpeg2_in_188_bytes
)
149 smo_mode
|= (1 << 5) ;
151 ret
|= dib7000p_write_word(state
, 235, smo_mode
);
152 ret
|= dib7000p_write_word(state
, 236, fifo_threshold
); /* synchronous fread */
153 ret
|= dib7000p_write_word(state
, 1286, outreg
); /* P_Div_active */
158 static int dib7000p_set_diversity_in(struct dvb_frontend
*demod
, int onoff
)
160 struct dib7000p_state
*state
= demod
->demodulator_priv
;
162 if (state
->div_force_off
) {
163 dprintk( "diversity combination deactivated - forced by COFDM parameters");
166 state
->div_state
= (u8
)onoff
;
169 dib7000p_write_word(state
, 204, 6);
170 dib7000p_write_word(state
, 205, 16);
171 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
172 dib7000p_write_word(state
, 207, (state
->div_sync_wait
<< 4) | (1 << 2) | (2 << 0));
174 dib7000p_write_word(state
, 204, 1);
175 dib7000p_write_word(state
, 205, 0);
176 dib7000p_write_word(state
, 207, 0);
182 static int dib7000p_set_power_mode(struct dib7000p_state
*state
, enum dib7000p_power_mode mode
)
184 /* by default everything is powered off */
185 u16 reg_774
= 0xffff, reg_775
= 0xffff, reg_776
= 0x0007, reg_899
= 0x0003,
186 reg_1280
= (0xfe00) | (dib7000p_read_word(state
, 1280) & 0x01ff);
188 /* now, depending on the requested mode, we power on */
190 /* power up everything in the demod */
191 case DIB7000P_POWER_ALL
:
192 reg_774
= 0x0000; reg_775
= 0x0000; reg_776
= 0x0; reg_899
= 0x0; reg_1280
&= 0x01ff;
195 case DIB7000P_POWER_ANALOG_ADC
:
196 /* dem, cfg, iqc, sad, agc */
197 reg_774
&= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
199 reg_776
&= ~((1 << 0));
201 reg_1280
&= ~((1 << 11));
202 /* fall through wanted to enable the interfaces */
204 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
205 case DIB7000P_POWER_INTERFACE_ONLY
: /* TODO power up either SDIO or I2C */
206 reg_1280
&= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
209 /* TODO following stuff is just converted from the dib7000-driver - check when is used what */
212 dib7000p_write_word(state
, 774, reg_774
);
213 dib7000p_write_word(state
, 775, reg_775
);
214 dib7000p_write_word(state
, 776, reg_776
);
215 dib7000p_write_word(state
, 899, reg_899
);
216 dib7000p_write_word(state
, 1280, reg_1280
);
221 static void dib7000p_set_adc_state(struct dib7000p_state
*state
, enum dibx000_adc_states no
)
223 u16 reg_908
= dib7000p_read_word(state
, 908),
224 reg_909
= dib7000p_read_word(state
, 909);
227 case DIBX000_SLOW_ADC_ON
:
228 reg_909
|= (1 << 1) | (1 << 0);
229 dib7000p_write_word(state
, 909, reg_909
);
230 reg_909
&= ~(1 << 1);
233 case DIBX000_SLOW_ADC_OFF
:
234 reg_909
|= (1 << 1) | (1 << 0);
242 case DIBX000_ADC_OFF
: // leave the VBG voltage on
243 reg_908
|= (1 << 14) | (1 << 13) | (1 << 12);
244 reg_909
|= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
247 case DIBX000_VBG_ENABLE
:
248 reg_908
&= ~(1 << 15);
251 case DIBX000_VBG_DISABLE
:
252 reg_908
|= (1 << 15);
259 // dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
261 dib7000p_write_word(state
, 908, reg_908
);
262 dib7000p_write_word(state
, 909, reg_909
);
265 static int dib7000p_set_bandwidth(struct dib7000p_state
*state
, u32 bw
)
269 // store the current bandwidth for later use
270 state
->current_bandwidth
= bw
;
272 if (state
->timf
== 0) {
273 dprintk( "using default timf");
274 timf
= state
->cfg
.bw
->timf
;
276 dprintk( "using updated timf");
280 timf
= timf
* (bw
/ 50) / 160;
282 dib7000p_write_word(state
, 23, (u16
) ((timf
>> 16) & 0xffff));
283 dib7000p_write_word(state
, 24, (u16
) ((timf
) & 0xffff));
288 static int dib7000p_sad_calib(struct dib7000p_state
*state
)
291 // dib7000p_write_word(state, 72, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth
292 dib7000p_write_word(state
, 73, (0 << 1) | (0 << 0));
293 dib7000p_write_word(state
, 74, 776); // 0.625*3.3 / 4096
295 /* do the calibration */
296 dib7000p_write_word(state
, 73, (1 << 0));
297 dib7000p_write_word(state
, 73, (0 << 0));
304 int dib7000p_set_wbd_ref(struct dvb_frontend
*demod
, u16 value
)
306 struct dib7000p_state
*state
= demod
->demodulator_priv
;
309 state
->wbd_ref
= value
;
310 return dib7000p_write_word(state
, 105, (dib7000p_read_word(state
, 105) & 0xf000) | value
);
313 EXPORT_SYMBOL(dib7000p_set_wbd_ref
);
314 static void dib7000p_reset_pll(struct dib7000p_state
*state
)
316 struct dibx000_bandwidth_config
*bw
= &state
->cfg
.bw
[0];
319 /* force PLL bypass */
320 clk_cfg0
= (1 << 15) | ((bw
->pll_ratio
& 0x3f) << 9) |
321 (bw
->modulo
<< 7) | (bw
->ADClkSrc
<< 6) | (bw
->IO_CLK_en_core
<< 5) |
322 (bw
->bypclk_div
<< 2) | (bw
->enable_refdiv
<< 1) | (0 << 0);
324 dib7000p_write_word(state
, 900, clk_cfg0
);
327 dib7000p_write_word(state
, 903, (bw
->pll_prediv
<< 5) | (((bw
->pll_ratio
>> 6) & 0x3) << 3) | (bw
->pll_range
<< 1) | bw
->pll_reset
);
328 clk_cfg0
= (bw
->pll_bypass
<< 15) | (clk_cfg0
& 0x7fff);
329 dib7000p_write_word(state
, 900, clk_cfg0
);
331 dib7000p_write_word(state
, 18, (u16
) (((bw
->internal
*1000) >> 16) & 0xffff));
332 dib7000p_write_word(state
, 19, (u16
) ( (bw
->internal
*1000 ) & 0xffff));
333 dib7000p_write_word(state
, 21, (u16
) ( (bw
->ifreq
>> 16) & 0xffff));
334 dib7000p_write_word(state
, 22, (u16
) ( (bw
->ifreq
) & 0xffff));
336 dib7000p_write_word(state
, 72, bw
->sad_cfg
);
339 static int dib7000p_reset_gpio(struct dib7000p_state
*st
)
341 /* reset the GPIOs */
342 dprintk( "gpio dir: %x: val: %x, pwm_pos: %x",st
->gpio_dir
, st
->gpio_val
,st
->cfg
.gpio_pwm_pos
);
344 dib7000p_write_word(st
, 1029, st
->gpio_dir
);
345 dib7000p_write_word(st
, 1030, st
->gpio_val
);
347 /* TODO 1031 is P_gpio_od */
349 dib7000p_write_word(st
, 1032, st
->cfg
.gpio_pwm_pos
);
351 dib7000p_write_word(st
, 1037, st
->cfg
.pwm_freq_div
);
355 static int dib7000p_cfg_gpio(struct dib7000p_state
*st
, u8 num
, u8 dir
, u8 val
)
357 st
->gpio_dir
= dib7000p_read_word(st
, 1029);
358 st
->gpio_dir
&= ~(1 << num
); /* reset the direction bit */
359 st
->gpio_dir
|= (dir
& 0x1) << num
; /* set the new direction */
360 dib7000p_write_word(st
, 1029, st
->gpio_dir
);
362 st
->gpio_val
= dib7000p_read_word(st
, 1030);
363 st
->gpio_val
&= ~(1 << num
); /* reset the direction bit */
364 st
->gpio_val
|= (val
& 0x01) << num
; /* set the new value */
365 dib7000p_write_word(st
, 1030, st
->gpio_val
);
370 int dib7000p_set_gpio(struct dvb_frontend
*demod
, u8 num
, u8 dir
, u8 val
)
372 struct dib7000p_state
*state
= demod
->demodulator_priv
;
373 return dib7000p_cfg_gpio(state
, num
, dir
, val
);
376 EXPORT_SYMBOL(dib7000p_set_gpio
);
377 static u16 dib7000p_defaults
[] =
380 // auto search configuration
384 0x0814, /* Equal Lock */
401 0x6680, // P_timf_alpha=6, P_corm_alpha=6, P_corm_thres=128 default: 6,4,26
403 /* set ADC level to -16 */
405 (1 << 13) - 825 - 117,
406 (1 << 13) - 837 - 117,
407 (1 << 13) - 811 - 117,
408 (1 << 13) - 766 - 117,
409 (1 << 13) - 737 - 117,
410 (1 << 13) - 693 - 117,
411 (1 << 13) - 648 - 117,
412 (1 << 13) - 619 - 117,
413 (1 << 13) - 575 - 117,
414 (1 << 13) - 531 - 117,
415 (1 << 13) - 501 - 117,
418 0x0410, // P_palf_filter_on=1, P_palf_filter_freeze=0, P_palf_alpha_regul=16
420 /* disable power smoothing */
432 1 << 13, // P_fft_freq_dir=1, P_fft_nb_to_cut=0
435 0x0ccd, // P_pha3_thres, default 0x3000
438 // 0x0010, // P_cti_use_cpe=0, P_cti_use_prog=0, P_cti_win_len=16, default: 0x0010
441 0x200f, // P_cspu_regul=512, P_cspu_win_cut=15, default: 0x2005
444 0x023d, // P_adp_regul_cnt=573, default: 410
445 0x00a4, // P_adp_noise_cnt=
446 0x00a4, // P_adp_regul_ext
447 0x7ff0, // P_adp_noise_ext
451 0x800, // P_equal_thres_wgn
454 0x0010, // P_fec_ber_rs_len=2
457 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
460 0x0006, // P_clk_cfg1
461 (3 << 10) | (1 << 6), // P_divclksel=3 P_divbitsel=1
464 0x2c8e, // Tuner IO bank: max drive (14mA) + divout pads max drive
469 static int dib7000p_demod_reset(struct dib7000p_state
*state
)
471 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
473 dib7000p_set_adc_state(state
, DIBX000_VBG_ENABLE
);
475 /* restart all parts */
476 dib7000p_write_word(state
, 770, 0xffff);
477 dib7000p_write_word(state
, 771, 0xffff);
478 dib7000p_write_word(state
, 772, 0x001f);
479 dib7000p_write_word(state
, 898, 0x0003);
480 /* except i2c, sdio, gpio - control interfaces */
481 dib7000p_write_word(state
, 1280, 0x01fc - ((1 << 7) | (1 << 6) | (1 << 5)) );
483 dib7000p_write_word(state
, 770, 0);
484 dib7000p_write_word(state
, 771, 0);
485 dib7000p_write_word(state
, 772, 0);
486 dib7000p_write_word(state
, 898, 0);
487 dib7000p_write_word(state
, 1280, 0);
490 dib7000p_reset_pll(state
);
492 if (dib7000p_reset_gpio(state
) != 0)
493 dprintk( "GPIO reset was not successful.");
495 if (dib7000p_set_output_mode(state
, OUTMODE_HIGH_Z
) != 0)
496 dprintk( "OUTPUT_MODE could not be reset.");
498 /* unforce divstr regardless whether i2c enumeration was done or not */
499 dib7000p_write_word(state
, 1285, dib7000p_read_word(state
, 1285) & ~(1 << 1) );
501 dib7000p_set_bandwidth(state
, 8000);
503 dib7000p_set_adc_state(state
, DIBX000_SLOW_ADC_ON
);
504 dib7000p_sad_calib(state
);
505 dib7000p_set_adc_state(state
, DIBX000_SLOW_ADC_OFF
);
507 // P_iqc_alpha_pha, P_iqc_alpha_amp_dcc_alpha, ...
508 if(state
->cfg
.tuner_is_baseband
)
509 dib7000p_write_word(state
, 36,0x0755);
511 dib7000p_write_word(state
, 36,0x1f55);
513 dib7000p_write_tab(state
, dib7000p_defaults
);
515 dib7000p_set_power_mode(state
, DIB7000P_POWER_INTERFACE_ONLY
);
521 static void dib7000p_pll_clk_cfg(struct dib7000p_state
*state
)
524 tmp
= dib7000p_read_word(state
, 903);
525 dib7000p_write_word(state
, 903, (tmp
| 0x1)); //pwr-up pll
526 tmp
= dib7000p_read_word(state
, 900);
527 dib7000p_write_word(state
, 900, (tmp
& 0x7fff) | (1 << 6)); //use High freq clock
530 static void dib7000p_restart_agc(struct dib7000p_state
*state
)
532 // P_restart_iqc & P_restart_agc
533 dib7000p_write_word(state
, 770, (1 << 11) | (1 << 9));
534 dib7000p_write_word(state
, 770, 0x0000);
537 static int dib7000p_update_lna(struct dib7000p_state
*state
)
541 // when there is no LNA to program return immediatly
542 if (state
->cfg
.update_lna
) {
543 // read dyn_gain here (because it is demod-dependent and not fe)
544 dyn_gain
= dib7000p_read_word(state
, 394);
545 if (state
->cfg
.update_lna(&state
->demod
,dyn_gain
)) { // LNA has changed
546 dib7000p_restart_agc(state
);
554 static int dib7000p_set_agc_config(struct dib7000p_state
*state
, u8 band
)
556 struct dibx000_agc_config
*agc
= NULL
;
558 if (state
->current_band
== band
&& state
->current_agc
!= NULL
)
560 state
->current_band
= band
;
562 for (i
= 0; i
< state
->cfg
.agc_config_count
; i
++)
563 if (state
->cfg
.agc
[i
].band_caps
& band
) {
564 agc
= &state
->cfg
.agc
[i
];
569 dprintk( "no valid AGC configuration found for band 0x%02x",band
);
573 state
->current_agc
= agc
;
576 dib7000p_write_word(state
, 75 , agc
->setup
);
577 dib7000p_write_word(state
, 76 , agc
->inv_gain
);
578 dib7000p_write_word(state
, 77 , agc
->time_stabiliz
);
579 dib7000p_write_word(state
, 100, (agc
->alpha_level
<< 12) | agc
->thlock
);
581 // Demod AGC loop configuration
582 dib7000p_write_word(state
, 101, (agc
->alpha_mant
<< 5) | agc
->alpha_exp
);
583 dib7000p_write_word(state
, 102, (agc
->beta_mant
<< 6) | agc
->beta_exp
);
586 dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d",
587 state
->wbd_ref
!= 0 ? state
->wbd_ref
: agc
->wbd_ref
, agc
->wbd_sel
, !agc
->perform_agc_softsplit
, agc
->wbd_sel
);
589 if (state
->wbd_ref
!= 0)
590 dib7000p_write_word(state
, 105, (agc
->wbd_inv
<< 12) | state
->wbd_ref
);
592 dib7000p_write_word(state
, 105, (agc
->wbd_inv
<< 12) | agc
->wbd_ref
);
594 dib7000p_write_word(state
, 106, (agc
->wbd_sel
<< 13) | (agc
->wbd_alpha
<< 9) | (agc
->perform_agc_softsplit
<< 8));
596 dib7000p_write_word(state
, 107, agc
->agc1_max
);
597 dib7000p_write_word(state
, 108, agc
->agc1_min
);
598 dib7000p_write_word(state
, 109, agc
->agc2_max
);
599 dib7000p_write_word(state
, 110, agc
->agc2_min
);
600 dib7000p_write_word(state
, 111, (agc
->agc1_pt1
<< 8) | agc
->agc1_pt2
);
601 dib7000p_write_word(state
, 112, agc
->agc1_pt3
);
602 dib7000p_write_word(state
, 113, (agc
->agc1_slope1
<< 8) | agc
->agc1_slope2
);
603 dib7000p_write_word(state
, 114, (agc
->agc2_pt1
<< 8) | agc
->agc2_pt2
);
604 dib7000p_write_word(state
, 115, (agc
->agc2_slope1
<< 8) | agc
->agc2_slope2
);
608 static int dib7000p_agc_startup(struct dvb_frontend
*demod
, struct dvb_frontend_parameters
*ch
)
610 struct dib7000p_state
*state
= demod
->demodulator_priv
;
612 u8
*agc_state
= &state
->agc_state
;
615 switch (state
->agc_state
) {
617 // set power-up level: interf+analog+AGC
618 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
619 dib7000p_set_adc_state(state
, DIBX000_ADC_ON
);
620 dib7000p_pll_clk_cfg(state
);
622 if (dib7000p_set_agc_config(state
, BAND_OF_FREQUENCY(ch
->frequency
/1000)) != 0)
630 // AGC initialization
631 if (state
->cfg
.agc_control
)
632 state
->cfg
.agc_control(&state
->demod
, 1);
634 dib7000p_write_word(state
, 78, 32768);
635 if (!state
->current_agc
->perform_agc_softsplit
) {
636 /* we are using the wbd - so slow AGC startup */
637 /* force 0 split on WBD and restart AGC */
638 dib7000p_write_word(state
, 106, (state
->current_agc
->wbd_sel
<< 13) | (state
->current_agc
->wbd_alpha
<< 9) | (1 << 8));
642 /* default AGC startup */
644 /* wait AGC rough lock time */
648 dib7000p_restart_agc(state
);
651 case 2: /* fast split search path after 5sec */
652 dib7000p_write_word(state
, 75, state
->current_agc
->setup
| (1 << 4)); /* freeze AGC loop */
653 dib7000p_write_word(state
, 106, (state
->current_agc
->wbd_sel
<< 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */
658 case 3: /* split search ended */
659 agc_split
= (u8
)dib7000p_read_word(state
, 396); /* store the split value for the next time */
660 dib7000p_write_word(state
, 78, dib7000p_read_word(state
, 394)); /* set AGC gain start value */
662 dib7000p_write_word(state
, 75, state
->current_agc
->setup
); /* std AGC loop */
663 dib7000p_write_word(state
, 106, (state
->current_agc
->wbd_sel
<< 13) | (state
->current_agc
->wbd_alpha
<< 9) | agc_split
); /* standard split search */
665 dib7000p_restart_agc(state
);
667 dprintk( "SPLIT %p: %hd", demod
, agc_split
);
673 case 4: /* LNA startup */
674 // wait AGC accurate lock time
677 if (dib7000p_update_lna(state
))
678 // wait only AGC rough lock time
680 else // nothing was done, go to the next state
685 if (state
->cfg
.agc_control
)
686 state
->cfg
.agc_control(&state
->demod
, 0);
695 static void dib7000p_update_timf(struct dib7000p_state
*state
)
697 u32 timf
= (dib7000p_read_word(state
, 427) << 16) | dib7000p_read_word(state
, 428);
698 state
->timf
= timf
* 160 / (state
->current_bandwidth
/ 50);
699 dib7000p_write_word(state
, 23, (u16
) (timf
>> 16));
700 dib7000p_write_word(state
, 24, (u16
) (timf
& 0xffff));
701 dprintk( "updated timf_frequency: %d (default: %d)",state
->timf
, state
->cfg
.bw
->timf
);
705 static void dib7000p_set_channel(struct dib7000p_state
*state
, struct dvb_frontend_parameters
*ch
, u8 seq
)
709 dib7000p_set_bandwidth(state
, BANDWIDTH_TO_KHZ(ch
->u
.ofdm
.bandwidth
));
711 /* nfft, guard, qam, alpha */
713 switch (ch
->u
.ofdm
.transmission_mode
) {
714 case TRANSMISSION_MODE_2K
: value
|= (0 << 7); break;
715 case /* 4K MODE */ 255: value
|= (2 << 7); break;
717 case TRANSMISSION_MODE_8K
: value
|= (1 << 7); break;
719 switch (ch
->u
.ofdm
.guard_interval
) {
720 case GUARD_INTERVAL_1_32
: value
|= (0 << 5); break;
721 case GUARD_INTERVAL_1_16
: value
|= (1 << 5); break;
722 case GUARD_INTERVAL_1_4
: value
|= (3 << 5); break;
724 case GUARD_INTERVAL_1_8
: value
|= (2 << 5); break;
726 switch (ch
->u
.ofdm
.constellation
) {
727 case QPSK
: value
|= (0 << 3); break;
728 case QAM_16
: value
|= (1 << 3); break;
730 case QAM_64
: value
|= (2 << 3); break;
732 switch (HIERARCHY_1
) {
733 case HIERARCHY_2
: value
|= 2; break;
734 case HIERARCHY_4
: value
|= 4; break;
736 case HIERARCHY_1
: value
|= 1; break;
738 dib7000p_write_word(state
, 0, value
);
739 dib7000p_write_word(state
, 5, (seq
<< 4) | 1); /* do not force tps, search list 0 */
741 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
745 if (ch
->u
.ofdm
.hierarchy_information
== 1)
749 switch ((ch
->u
.ofdm
.hierarchy_information
== 0 || 1 == 1) ? ch
->u
.ofdm
.code_rate_HP
: ch
->u
.ofdm
.code_rate_LP
) {
750 case FEC_2_3
: value
|= (2 << 1); break;
751 case FEC_3_4
: value
|= (3 << 1); break;
752 case FEC_5_6
: value
|= (5 << 1); break;
753 case FEC_7_8
: value
|= (7 << 1); break;
755 case FEC_1_2
: value
|= (1 << 1); break;
757 dib7000p_write_word(state
, 208, value
);
759 /* offset loop parameters */
760 dib7000p_write_word(state
, 26, 0x6680); // timf(6xxx)
761 dib7000p_write_word(state
, 32, 0x0003); // pha_off_max(xxx3)
762 dib7000p_write_word(state
, 29, 0x1273); // isi
763 dib7000p_write_word(state
, 33, 0x0005); // sfreq(xxx5)
765 /* P_dvsy_sync_wait */
766 switch (ch
->u
.ofdm
.transmission_mode
) {
767 case TRANSMISSION_MODE_8K
: value
= 256; break;
768 case /* 4K MODE */ 255: value
= 128; break;
769 case TRANSMISSION_MODE_2K
:
770 default: value
= 64; break;
772 switch (ch
->u
.ofdm
.guard_interval
) {
773 case GUARD_INTERVAL_1_16
: value
*= 2; break;
774 case GUARD_INTERVAL_1_8
: value
*= 4; break;
775 case GUARD_INTERVAL_1_4
: value
*= 8; break;
777 case GUARD_INTERVAL_1_32
: value
*= 1; break;
779 state
->div_sync_wait
= (value
* 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO
781 /* deactive the possibility of diversity reception if extended interleaver */
782 state
->div_force_off
= !1 && ch
->u
.ofdm
.transmission_mode
!= TRANSMISSION_MODE_8K
;
783 dib7000p_set_diversity_in(&state
->demod
, state
->div_state
);
785 /* channel estimation fine configuration */
786 switch (ch
->u
.ofdm
.constellation
) {
788 est
[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
789 est
[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
790 est
[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
791 est
[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
794 est
[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
795 est
[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
796 est
[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
797 est
[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
800 est
[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
801 est
[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
802 est
[2] = 0x0333; /* P_adp_regul_ext 0.1 */
803 est
[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
806 for (value
= 0; value
< 4; value
++)
807 dib7000p_write_word(state
, 187 + value
, est
[value
]);
810 static int dib7000p_autosearch_start(struct dvb_frontend
*demod
, struct dvb_frontend_parameters
*ch
)
812 struct dib7000p_state
*state
= demod
->demodulator_priv
;
813 struct dvb_frontend_parameters schan
;
817 schan
.u
.ofdm
.constellation
= QAM_64
;
818 schan
.u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_32
;
819 schan
.u
.ofdm
.transmission_mode
= TRANSMISSION_MODE_8K
;
820 schan
.u
.ofdm
.code_rate_HP
= FEC_2_3
;
821 schan
.u
.ofdm
.code_rate_LP
= FEC_3_4
;
822 schan
.u
.ofdm
.hierarchy_information
= 0;
824 dib7000p_set_channel(state
, &schan
, 7);
826 factor
= BANDWIDTH_TO_KHZ(ch
->u
.ofdm
.bandwidth
);
832 // always use the setting for 8MHz here lock_time for 7,6 MHz are longer
833 value
= 30 * state
->cfg
.bw
->internal
* factor
;
834 dib7000p_write_word(state
, 6, (u16
) ((value
>> 16) & 0xffff)); // lock0 wait time
835 dib7000p_write_word(state
, 7, (u16
) (value
& 0xffff)); // lock0 wait time
836 value
= 100 * state
->cfg
.bw
->internal
* factor
;
837 dib7000p_write_word(state
, 8, (u16
) ((value
>> 16) & 0xffff)); // lock1 wait time
838 dib7000p_write_word(state
, 9, (u16
) (value
& 0xffff)); // lock1 wait time
839 value
= 500 * state
->cfg
.bw
->internal
* factor
;
840 dib7000p_write_word(state
, 10, (u16
) ((value
>> 16) & 0xffff)); // lock2 wait time
841 dib7000p_write_word(state
, 11, (u16
) (value
& 0xffff)); // lock2 wait time
843 value
= dib7000p_read_word(state
, 0);
844 dib7000p_write_word(state
, 0, (u16
) ((1 << 9) | value
));
845 dib7000p_read_word(state
, 1284);
846 dib7000p_write_word(state
, 0, (u16
) value
);
851 static int dib7000p_autosearch_is_irq(struct dvb_frontend
*demod
)
853 struct dib7000p_state
*state
= demod
->demodulator_priv
;
854 u16 irq_pending
= dib7000p_read_word(state
, 1284);
856 if (irq_pending
& 0x1) // failed
859 if (irq_pending
& 0x2) // succeeded
862 return 0; // still pending
865 static void dib7000p_spur_protect(struct dib7000p_state
*state
, u32 rf_khz
, u32 bw
)
867 static s16 notch
[]={16143, 14402, 12238, 9713, 6902, 3888, 759, -2392};
868 static u8 sine
[] ={0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
869 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
870 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
871 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
872 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
873 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
874 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
875 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
876 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
877 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
878 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
879 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
880 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
881 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
882 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
883 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
884 255, 255, 255, 255, 255, 255};
886 u32 xtal
= state
->cfg
.bw
->xtal_hz
/ 1000;
887 int f_rel
= DIV_ROUND_CLOSEST(rf_khz
, xtal
) * xtal
- rf_khz
;
889 int coef_re
[8],coef_im
[8];
893 dprintk( "relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel
, rf_khz
, xtal
);
896 if (f_rel
< -bw_khz
/2 || f_rel
> bw_khz
/2)
901 dib7000p_write_word(state
, 142 ,0x0610);
903 for (k
= 0; k
< 8; k
++) {
904 pha
= ((f_rel
* (k
+1) * 112 * 80/bw_khz
) /1000) & 0x3ff;
909 } else if(pha
< 256) {
910 coef_re
[k
] = sine
[256-(pha
&0xff)];
911 coef_im
[k
] = sine
[pha
&0xff];
912 } else if (pha
== 256) {
915 } else if (pha
< 512) {
916 coef_re
[k
] = -sine
[pha
&0xff];
917 coef_im
[k
] = sine
[256 - (pha
&0xff)];
918 } else if (pha
== 512) {
921 } else if (pha
< 768) {
922 coef_re
[k
] = -sine
[256-(pha
&0xff)];
923 coef_im
[k
] = -sine
[pha
&0xff];
924 } else if (pha
== 768) {
928 coef_re
[k
] = sine
[pha
&0xff];
929 coef_im
[k
] = -sine
[256 - (pha
&0xff)];
932 coef_re
[k
] *= notch
[k
];
933 coef_re
[k
] += (1<<14);
934 if (coef_re
[k
] >= (1<<24))
935 coef_re
[k
] = (1<<24) - 1;
936 coef_re
[k
] /= (1<<15);
938 coef_im
[k
] *= notch
[k
];
939 coef_im
[k
] += (1<<14);
940 if (coef_im
[k
] >= (1<<24))
941 coef_im
[k
] = (1<<24)-1;
942 coef_im
[k
] /= (1<<15);
944 dprintk( "PALF COEF: %d re: %d im: %d", k
, coef_re
[k
], coef_im
[k
]);
946 dib7000p_write_word(state
, 143, (0 << 14) | (k
<< 10) | (coef_re
[k
] & 0x3ff));
947 dib7000p_write_word(state
, 144, coef_im
[k
] & 0x3ff);
948 dib7000p_write_word(state
, 143, (1 << 14) | (k
<< 10) | (coef_re
[k
] & 0x3ff));
950 dib7000p_write_word(state
,143 ,0);
953 static int dib7000p_tune(struct dvb_frontend
*demod
, struct dvb_frontend_parameters
*ch
)
955 struct dib7000p_state
*state
= demod
->demodulator_priv
;
959 dib7000p_set_channel(state
, ch
, 0);
964 dib7000p_write_word(state
, 770, 0x4000);
965 dib7000p_write_word(state
, 770, 0x0000);
968 /* 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 */
969 tmp
= (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
970 if (state
->sfn_workaround_active
) {
971 dprintk( "SFN workaround is active");
973 dib7000p_write_word(state
, 166, 0x4000); // P_pha3_force_pha_shift
975 dib7000p_write_word(state
, 166, 0x0000); // P_pha3_force_pha_shift
977 dib7000p_write_word(state
, 29, tmp
);
979 // never achieved a lock with that bandwidth so far - wait for osc-freq to update
980 if (state
->timf
== 0)
983 /* offset loop parameters */
985 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
986 tmp
= (6 << 8) | 0x80;
987 switch (ch
->u
.ofdm
.transmission_mode
) {
988 case TRANSMISSION_MODE_2K
: tmp
|= (7 << 12); break;
989 case /* 4K MODE */ 255: tmp
|= (8 << 12); break;
991 case TRANSMISSION_MODE_8K
: tmp
|= (9 << 12); break;
993 dib7000p_write_word(state
, 26, tmp
); /* timf_a(6xxx) */
995 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
997 switch (ch
->u
.ofdm
.transmission_mode
) {
998 case TRANSMISSION_MODE_2K
: tmp
|= 0x6; break;
999 case /* 4K MODE */ 255: tmp
|= 0x7; break;
1001 case TRANSMISSION_MODE_8K
: tmp
|= 0x8; break;
1003 dib7000p_write_word(state
, 32, tmp
);
1005 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1007 switch (ch
->u
.ofdm
.transmission_mode
) {
1008 case TRANSMISSION_MODE_2K
: tmp
|= 0x6; break;
1009 case /* 4K MODE */ 255: tmp
|= 0x7; break;
1011 case TRANSMISSION_MODE_8K
: tmp
|= 0x8; break;
1013 dib7000p_write_word(state
, 33, tmp
);
1015 tmp
= dib7000p_read_word(state
,509);
1016 if (!((tmp
>> 6) & 0x1)) {
1017 /* restart the fec */
1018 tmp
= dib7000p_read_word(state
,771);
1019 dib7000p_write_word(state
, 771, tmp
| (1 << 1));
1020 dib7000p_write_word(state
, 771, tmp
);
1022 tmp
= dib7000p_read_word(state
,509);
1025 // we achieved a lock - it's time to update the osc freq
1026 if ((tmp
>> 6) & 0x1)
1027 dib7000p_update_timf(state
);
1029 if (state
->cfg
.spur_protect
)
1030 dib7000p_spur_protect(state
, ch
->frequency
/1000, BANDWIDTH_TO_KHZ(ch
->u
.ofdm
.bandwidth
));
1032 dib7000p_set_bandwidth(state
, BANDWIDTH_TO_KHZ(ch
->u
.ofdm
.bandwidth
));
1036 static int dib7000p_wakeup(struct dvb_frontend
*demod
)
1038 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1039 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
1040 dib7000p_set_adc_state(state
, DIBX000_SLOW_ADC_ON
);
1044 static int dib7000p_sleep(struct dvb_frontend
*demod
)
1046 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1047 return dib7000p_set_output_mode(state
, OUTMODE_HIGH_Z
) | dib7000p_set_power_mode(state
, DIB7000P_POWER_INTERFACE_ONLY
);
1050 static int dib7000p_identify(struct dib7000p_state
*st
)
1053 dprintk( "checking demod on I2C address: %d (%x)",
1054 st
->i2c_addr
, st
->i2c_addr
);
1056 if ((value
= dib7000p_read_word(st
, 768)) != 0x01b3) {
1057 dprintk( "wrong Vendor ID (read=0x%x)",value
);
1061 if ((value
= dib7000p_read_word(st
, 769)) != 0x4000) {
1062 dprintk( "wrong Device ID (%x)",value
);
1070 static int dib7000p_get_frontend(struct dvb_frontend
* fe
,
1071 struct dvb_frontend_parameters
*fep
)
1073 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1074 u16 tps
= dib7000p_read_word(state
,463);
1076 fep
->inversion
= INVERSION_AUTO
;
1078 fep
->u
.ofdm
.bandwidth
= BANDWIDTH_TO_INDEX(state
->current_bandwidth
);
1080 switch ((tps
>> 8) & 0x3) {
1081 case 0: fep
->u
.ofdm
.transmission_mode
= TRANSMISSION_MODE_2K
; break;
1082 case 1: fep
->u
.ofdm
.transmission_mode
= TRANSMISSION_MODE_8K
; break;
1083 /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */
1086 switch (tps
& 0x3) {
1087 case 0: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_32
; break;
1088 case 1: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_16
; break;
1089 case 2: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_8
; break;
1090 case 3: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_4
; break;
1093 switch ((tps
>> 14) & 0x3) {
1094 case 0: fep
->u
.ofdm
.constellation
= QPSK
; break;
1095 case 1: fep
->u
.ofdm
.constellation
= QAM_16
; break;
1097 default: fep
->u
.ofdm
.constellation
= QAM_64
; break;
1100 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1101 /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1103 fep
->u
.ofdm
.hierarchy_information
= HIERARCHY_NONE
;
1104 switch ((tps
>> 5) & 0x7) {
1105 case 1: fep
->u
.ofdm
.code_rate_HP
= FEC_1_2
; break;
1106 case 2: fep
->u
.ofdm
.code_rate_HP
= FEC_2_3
; break;
1107 case 3: fep
->u
.ofdm
.code_rate_HP
= FEC_3_4
; break;
1108 case 5: fep
->u
.ofdm
.code_rate_HP
= FEC_5_6
; break;
1110 default: fep
->u
.ofdm
.code_rate_HP
= FEC_7_8
; break;
1114 switch ((tps
>> 2) & 0x7) {
1115 case 1: fep
->u
.ofdm
.code_rate_LP
= FEC_1_2
; break;
1116 case 2: fep
->u
.ofdm
.code_rate_LP
= FEC_2_3
; break;
1117 case 3: fep
->u
.ofdm
.code_rate_LP
= FEC_3_4
; break;
1118 case 5: fep
->u
.ofdm
.code_rate_LP
= FEC_5_6
; break;
1120 default: fep
->u
.ofdm
.code_rate_LP
= FEC_7_8
; break;
1123 /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */
1128 static int dib7000p_set_frontend(struct dvb_frontend
* fe
,
1129 struct dvb_frontend_parameters
*fep
)
1131 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1134 dib7000p_set_output_mode(state
, OUTMODE_HIGH_Z
);
1136 /* maybe the parameter has been changed */
1137 state
->sfn_workaround_active
= buggy_sfn_workaround
;
1139 if (fe
->ops
.tuner_ops
.set_params
)
1140 fe
->ops
.tuner_ops
.set_params(fe
, fep
);
1142 /* start up the AGC */
1143 state
->agc_state
= 0;
1145 time
= dib7000p_agc_startup(fe
, fep
);
1148 } while (time
!= -1);
1150 if (fep
->u
.ofdm
.transmission_mode
== TRANSMISSION_MODE_AUTO
||
1151 fep
->u
.ofdm
.guard_interval
== GUARD_INTERVAL_AUTO
||
1152 fep
->u
.ofdm
.constellation
== QAM_AUTO
||
1153 fep
->u
.ofdm
.code_rate_HP
== FEC_AUTO
) {
1156 dib7000p_autosearch_start(fe
, fep
);
1159 found
= dib7000p_autosearch_is_irq(fe
);
1160 } while (found
== 0 && i
--);
1162 dprintk("autosearch returns: %d",found
);
1163 if (found
== 0 || found
== 1)
1164 return 0; // no channel found
1166 dib7000p_get_frontend(fe
, fep
);
1169 ret
= dib7000p_tune(fe
, fep
);
1171 /* make this a config parameter */
1172 dib7000p_set_output_mode(state
, state
->cfg
.output_mode
);
1176 static int dib7000p_read_status(struct dvb_frontend
*fe
, fe_status_t
*stat
)
1178 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1179 u16 lock
= dib7000p_read_word(state
, 509);
1184 *stat
|= FE_HAS_SIGNAL
;
1186 *stat
|= FE_HAS_CARRIER
;
1188 *stat
|= FE_HAS_VITERBI
;
1190 *stat
|= FE_HAS_SYNC
;
1192 *stat
|= FE_HAS_LOCK
;
1197 static int dib7000p_read_ber(struct dvb_frontend
*fe
, u32
*ber
)
1199 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1200 *ber
= (dib7000p_read_word(state
, 500) << 16) | dib7000p_read_word(state
, 501);
1204 static int dib7000p_read_unc_blocks(struct dvb_frontend
*fe
, u32
*unc
)
1206 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1207 *unc
= dib7000p_read_word(state
, 506);
1211 static int dib7000p_read_signal_strength(struct dvb_frontend
*fe
, u16
*strength
)
1213 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1214 u16 val
= dib7000p_read_word(state
, 394);
1215 *strength
= 65535 - val
;
1219 static int dib7000p_read_snr(struct dvb_frontend
* fe
, u16
*snr
)
1221 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1223 s32 signal_mant
, signal_exp
, noise_mant
, noise_exp
;
1226 val
= dib7000p_read_word(state
, 479);
1227 noise_mant
= (val
>> 4) & 0xff;
1228 noise_exp
= ((val
& 0xf) << 2);
1229 val
= dib7000p_read_word(state
, 480);
1230 noise_exp
+= ((val
>> 14) & 0x3);
1231 if ((noise_exp
& 0x20) != 0)
1234 signal_mant
= (val
>> 6) & 0xFF;
1235 signal_exp
= (val
& 0x3F);
1236 if ((signal_exp
& 0x20) != 0)
1239 if (signal_mant
!= 0)
1240 result
= intlog10(2) * 10 * signal_exp
+ 10 *
1241 intlog10(signal_mant
);
1243 result
= intlog10(2) * 10 * signal_exp
- 100;
1245 if (noise_mant
!= 0)
1246 result
-= intlog10(2) * 10 * noise_exp
+ 10 *
1247 intlog10(noise_mant
);
1249 result
-= intlog10(2) * 10 * noise_exp
- 100;
1251 *snr
= result
/ ((1 << 24) / 10);
1255 static int dib7000p_fe_get_tune_settings(struct dvb_frontend
* fe
, struct dvb_frontend_tune_settings
*tune
)
1257 tune
->min_delay_ms
= 1000;
1261 static void dib7000p_release(struct dvb_frontend
*demod
)
1263 struct dib7000p_state
*st
= demod
->demodulator_priv
;
1264 dibx000_exit_i2c_master(&st
->i2c_master
);
1268 int dib7000pc_detection(struct i2c_adapter
*i2c_adap
)
1271 struct i2c_msg msg
[2] = {
1272 { .addr
= 18 >> 1, .flags
= 0, .buf
= tx
, .len
= 2 },
1273 { .addr
= 18 >> 1, .flags
= I2C_M_RD
, .buf
= rx
, .len
= 2 },
1279 if (i2c_transfer(i2c_adap
, msg
, 2) == 2)
1280 if (rx
[0] == 0x01 && rx
[1] == 0xb3) {
1281 dprintk("-D- DiB7000PC detected");
1285 msg
[0].addr
= msg
[1].addr
= 0x40;
1287 if (i2c_transfer(i2c_adap
, msg
, 2) == 2)
1288 if (rx
[0] == 0x01 && rx
[1] == 0xb3) {
1289 dprintk("-D- DiB7000PC detected");
1293 dprintk("-D- DiB7000PC not detected");
1296 EXPORT_SYMBOL(dib7000pc_detection
);
1298 struct i2c_adapter
* dib7000p_get_i2c_master(struct dvb_frontend
*demod
, enum dibx000_i2c_interface intf
, int gating
)
1300 struct dib7000p_state
*st
= demod
->demodulator_priv
;
1301 return dibx000_get_i2c_adapter(&st
->i2c_master
, intf
, gating
);
1303 EXPORT_SYMBOL(dib7000p_get_i2c_master
);
1305 int dib7000p_i2c_enumeration(struct i2c_adapter
*i2c
, int no_of_demods
, u8 default_addr
, struct dib7000p_config cfg
[])
1307 struct dib7000p_state st
= { .i2c_adap
= i2c
};
1311 for (k
= no_of_demods
-1; k
>= 0; k
--) {
1314 /* designated i2c address */
1315 new_addr
= (0x40 + k
) << 1;
1316 st
.i2c_addr
= new_addr
;
1317 if (dib7000p_identify(&st
) != 0) {
1318 st
.i2c_addr
= default_addr
;
1319 if (dib7000p_identify(&st
) != 0) {
1320 dprintk("DiB7000P #%d: not identified\n", k
);
1325 /* start diversity to pull_down div_str - just for i2c-enumeration */
1326 dib7000p_set_output_mode(&st
, OUTMODE_DIVERSITY
);
1328 /* set new i2c address and force divstart */
1329 dib7000p_write_word(&st
, 1285, (new_addr
<< 2) | 0x2);
1331 dprintk("IC %d initialized (to i2c_address 0x%x)", k
, new_addr
);
1334 for (k
= 0; k
< no_of_demods
; k
++) {
1336 st
.i2c_addr
= (0x40 + k
) << 1;
1339 dib7000p_write_word(&st
, 1285, st
.i2c_addr
<< 2);
1341 /* deactivate div - it was just for i2c-enumeration */
1342 dib7000p_set_output_mode(&st
, OUTMODE_HIGH_Z
);
1347 EXPORT_SYMBOL(dib7000p_i2c_enumeration
);
1349 static struct dvb_frontend_ops dib7000p_ops
;
1350 struct dvb_frontend
* dib7000p_attach(struct i2c_adapter
*i2c_adap
, u8 i2c_addr
, struct dib7000p_config
*cfg
)
1352 struct dvb_frontend
*demod
;
1353 struct dib7000p_state
*st
;
1354 st
= kzalloc(sizeof(struct dib7000p_state
), GFP_KERNEL
);
1358 memcpy(&st
->cfg
, cfg
, sizeof(struct dib7000p_config
));
1359 st
->i2c_adap
= i2c_adap
;
1360 st
->i2c_addr
= i2c_addr
;
1361 st
->gpio_val
= cfg
->gpio_val
;
1362 st
->gpio_dir
= cfg
->gpio_dir
;
1364 /* Ensure the output mode remains at the previous default if it's
1365 * not specifically set by the caller.
1367 if ((st
->cfg
.output_mode
!= OUTMODE_MPEG2_SERIAL
) &&
1368 (st
->cfg
.output_mode
!= OUTMODE_MPEG2_PAR_GATED_CLK
))
1369 st
->cfg
.output_mode
= OUTMODE_MPEG2_FIFO
;
1372 demod
->demodulator_priv
= st
;
1373 memcpy(&st
->demod
.ops
, &dib7000p_ops
, sizeof(struct dvb_frontend_ops
));
1375 if (dib7000p_identify(st
) != 0)
1378 dibx000_init_i2c_master(&st
->i2c_master
, DIB7000P
, st
->i2c_adap
, st
->i2c_addr
);
1380 dib7000p_demod_reset(st
);
1388 EXPORT_SYMBOL(dib7000p_attach
);
1390 static struct dvb_frontend_ops dib7000p_ops
= {
1392 .name
= "DiBcom 7000PC",
1394 .frequency_min
= 44250000,
1395 .frequency_max
= 867250000,
1396 .frequency_stepsize
= 62500,
1397 .caps
= FE_CAN_INVERSION_AUTO
|
1398 FE_CAN_FEC_1_2
| FE_CAN_FEC_2_3
| FE_CAN_FEC_3_4
|
1399 FE_CAN_FEC_5_6
| FE_CAN_FEC_7_8
| FE_CAN_FEC_AUTO
|
1400 FE_CAN_QPSK
| FE_CAN_QAM_16
| FE_CAN_QAM_64
| FE_CAN_QAM_AUTO
|
1401 FE_CAN_TRANSMISSION_MODE_AUTO
|
1402 FE_CAN_GUARD_INTERVAL_AUTO
|
1404 FE_CAN_HIERARCHY_AUTO
,
1407 .release
= dib7000p_release
,
1409 .init
= dib7000p_wakeup
,
1410 .sleep
= dib7000p_sleep
,
1412 .set_frontend
= dib7000p_set_frontend
,
1413 .get_tune_settings
= dib7000p_fe_get_tune_settings
,
1414 .get_frontend
= dib7000p_get_frontend
,
1416 .read_status
= dib7000p_read_status
,
1417 .read_ber
= dib7000p_read_ber
,
1418 .read_signal_strength
= dib7000p_read_signal_strength
,
1419 .read_snr
= dib7000p_read_snr
,
1420 .read_ucblocks
= dib7000p_read_unc_blocks
,
1423 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
1424 MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
1425 MODULE_LICENSE("GPL");