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>
13 #include "dvb_frontend.h"
18 module_param(debug
, int, 0644);
19 MODULE_PARM_DESC(debug
, "turn on debugging (default: 0)");
21 static int buggy_sfn_workaround
;
22 module_param(buggy_sfn_workaround
, int, 0644);
23 MODULE_PARM_DESC(buggy_sfn_workaround
, "Enable work-around for buggy SFNs (default: 0)");
25 #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0)
27 struct dib7000p_state
{
28 struct dvb_frontend demod
;
29 struct dib7000p_config cfg
;
32 struct i2c_adapter
*i2c_adap
;
34 struct dibx000_i2c_master i2c_master
;
39 fe_bandwidth_t current_bandwidth
;
40 struct dibx000_agc_config
*current_agc
;
52 u8 sfn_workaround_active
:1;
55 enum dib7000p_power_mode
{
56 DIB7000P_POWER_ALL
= 0,
57 DIB7000P_POWER_ANALOG_ADC
,
58 DIB7000P_POWER_INTERFACE_ONLY
,
61 static u16
dib7000p_read_word(struct dib7000p_state
*state
, u16 reg
)
63 u8 wb
[2] = { reg
>> 8, reg
& 0xff };
65 struct i2c_msg msg
[2] = {
66 { .addr
= state
->i2c_addr
>> 1, .flags
= 0, .buf
= wb
, .len
= 2 },
67 { .addr
= state
->i2c_addr
>> 1, .flags
= I2C_M_RD
, .buf
= rb
, .len
= 2 },
70 if (i2c_transfer(state
->i2c_adap
, msg
, 2) != 2)
71 dprintk("i2c read error on %d",reg
);
73 return (rb
[0] << 8) | rb
[1];
76 static int dib7000p_write_word(struct dib7000p_state
*state
, u16 reg
, u16 val
)
79 (reg
>> 8) & 0xff, reg
& 0xff,
80 (val
>> 8) & 0xff, val
& 0xff,
82 struct i2c_msg msg
= {
83 .addr
= state
->i2c_addr
>> 1, .flags
= 0, .buf
= b
, .len
= 4
85 return i2c_transfer(state
->i2c_adap
, &msg
, 1) != 1 ? -EREMOTEIO
: 0;
87 static void dib7000p_write_tab(struct dib7000p_state
*state
, u16
*buf
)
96 dib7000p_write_word(state
, r
, *n
++);
103 static int dib7000p_set_output_mode(struct dib7000p_state
*state
, int mode
)
106 u16 outreg
, fifo_threshold
, smo_mode
;
109 fifo_threshold
= 1792;
110 smo_mode
= (dib7000p_read_word(state
, 235) & 0x0010) | (1 << 1);
112 dprintk( "setting output mode for demod %p to %d",
113 &state
->demod
, mode
);
116 case OUTMODE_MPEG2_PAR_GATED_CLK
: // STBs with parallel gated clock
117 outreg
= (1 << 10); /* 0x0400 */
119 case OUTMODE_MPEG2_PAR_CONT_CLK
: // STBs with parallel continues clock
120 outreg
= (1 << 10) | (1 << 6); /* 0x0440 */
122 case OUTMODE_MPEG2_SERIAL
: // STBs with serial input
123 outreg
= (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */
125 case OUTMODE_DIVERSITY
:
126 if (state
->cfg
.hostbus_diversity
)
127 outreg
= (1 << 10) | (4 << 6); /* 0x0500 */
131 case OUTMODE_MPEG2_FIFO
: // e.g. USB feeding
132 smo_mode
|= (3 << 1);
133 fifo_threshold
= 512;
134 outreg
= (1 << 10) | (5 << 6);
136 case OUTMODE_ANALOG_ADC
:
137 outreg
= (1 << 10) | (3 << 6);
139 case OUTMODE_HIGH_Z
: // disable
143 dprintk( "Unhandled output_mode passed to be set for demod %p",&state
->demod
);
147 if (state
->cfg
.output_mpeg2_in_188_bytes
)
148 smo_mode
|= (1 << 5) ;
150 ret
|= dib7000p_write_word(state
, 235, smo_mode
);
151 ret
|= dib7000p_write_word(state
, 236, fifo_threshold
); /* synchronous fread */
152 ret
|= dib7000p_write_word(state
, 1286, outreg
); /* P_Div_active */
157 static int dib7000p_set_diversity_in(struct dvb_frontend
*demod
, int onoff
)
159 struct dib7000p_state
*state
= demod
->demodulator_priv
;
161 if (state
->div_force_off
) {
162 dprintk( "diversity combination deactivated - forced by COFDM parameters");
165 state
->div_state
= (u8
)onoff
;
168 dib7000p_write_word(state
, 204, 6);
169 dib7000p_write_word(state
, 205, 16);
170 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
171 dib7000p_write_word(state
, 207, (state
->div_sync_wait
<< 4) | (1 << 2) | (2 << 0));
173 dib7000p_write_word(state
, 204, 1);
174 dib7000p_write_word(state
, 205, 0);
175 dib7000p_write_word(state
, 207, 0);
181 static int dib7000p_set_power_mode(struct dib7000p_state
*state
, enum dib7000p_power_mode mode
)
183 /* by default everything is powered off */
184 u16 reg_774
= 0xffff, reg_775
= 0xffff, reg_776
= 0x0007, reg_899
= 0x0003,
185 reg_1280
= (0xfe00) | (dib7000p_read_word(state
, 1280) & 0x01ff);
187 /* now, depending on the requested mode, we power on */
189 /* power up everything in the demod */
190 case DIB7000P_POWER_ALL
:
191 reg_774
= 0x0000; reg_775
= 0x0000; reg_776
= 0x0; reg_899
= 0x0; reg_1280
&= 0x01ff;
194 case DIB7000P_POWER_ANALOG_ADC
:
195 /* dem, cfg, iqc, sad, agc */
196 reg_774
&= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
198 reg_776
&= ~((1 << 0));
200 reg_1280
&= ~((1 << 11));
201 /* fall through wanted to enable the interfaces */
203 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
204 case DIB7000P_POWER_INTERFACE_ONLY
: /* TODO power up either SDIO or I2C */
205 reg_1280
&= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
208 /* TODO following stuff is just converted from the dib7000-driver - check when is used what */
211 dib7000p_write_word(state
, 774, reg_774
);
212 dib7000p_write_word(state
, 775, reg_775
);
213 dib7000p_write_word(state
, 776, reg_776
);
214 dib7000p_write_word(state
, 899, reg_899
);
215 dib7000p_write_word(state
, 1280, reg_1280
);
220 static void dib7000p_set_adc_state(struct dib7000p_state
*state
, enum dibx000_adc_states no
)
222 u16 reg_908
= dib7000p_read_word(state
, 908),
223 reg_909
= dib7000p_read_word(state
, 909);
226 case DIBX000_SLOW_ADC_ON
:
227 reg_909
|= (1 << 1) | (1 << 0);
228 dib7000p_write_word(state
, 909, reg_909
);
229 reg_909
&= ~(1 << 1);
232 case DIBX000_SLOW_ADC_OFF
:
233 reg_909
|= (1 << 1) | (1 << 0);
241 case DIBX000_ADC_OFF
: // leave the VBG voltage on
242 reg_908
|= (1 << 14) | (1 << 13) | (1 << 12);
243 reg_909
|= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
246 case DIBX000_VBG_ENABLE
:
247 reg_908
&= ~(1 << 15);
250 case DIBX000_VBG_DISABLE
:
251 reg_908
|= (1 << 15);
258 // dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
260 dib7000p_write_word(state
, 908, reg_908
);
261 dib7000p_write_word(state
, 909, reg_909
);
264 static int dib7000p_set_bandwidth(struct dib7000p_state
*state
, u32 bw
)
268 // store the current bandwidth for later use
269 state
->current_bandwidth
= bw
;
271 if (state
->timf
== 0) {
272 dprintk( "using default timf");
273 timf
= state
->cfg
.bw
->timf
;
275 dprintk( "using updated timf");
279 timf
= timf
* (bw
/ 50) / 160;
281 dib7000p_write_word(state
, 23, (u16
) ((timf
>> 16) & 0xffff));
282 dib7000p_write_word(state
, 24, (u16
) ((timf
) & 0xffff));
287 static int dib7000p_sad_calib(struct dib7000p_state
*state
)
290 // dib7000p_write_word(state, 72, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth
291 dib7000p_write_word(state
, 73, (0 << 1) | (0 << 0));
292 dib7000p_write_word(state
, 74, 776); // 0.625*3.3 / 4096
294 /* do the calibration */
295 dib7000p_write_word(state
, 73, (1 << 0));
296 dib7000p_write_word(state
, 73, (0 << 0));
303 int dib7000p_set_wbd_ref(struct dvb_frontend
*demod
, u16 value
)
305 struct dib7000p_state
*state
= demod
->demodulator_priv
;
308 state
->wbd_ref
= value
;
309 return dib7000p_write_word(state
, 105, (dib7000p_read_word(state
, 105) & 0xf000) | value
);
312 EXPORT_SYMBOL(dib7000p_set_wbd_ref
);
313 static void dib7000p_reset_pll(struct dib7000p_state
*state
)
315 struct dibx000_bandwidth_config
*bw
= &state
->cfg
.bw
[0];
318 /* force PLL bypass */
319 clk_cfg0
= (1 << 15) | ((bw
->pll_ratio
& 0x3f) << 9) |
320 (bw
->modulo
<< 7) | (bw
->ADClkSrc
<< 6) | (bw
->IO_CLK_en_core
<< 5) |
321 (bw
->bypclk_div
<< 2) | (bw
->enable_refdiv
<< 1) | (0 << 0);
323 dib7000p_write_word(state
, 900, clk_cfg0
);
326 dib7000p_write_word(state
, 903, (bw
->pll_prediv
<< 5) | (((bw
->pll_ratio
>> 6) & 0x3) << 3) | (bw
->pll_range
<< 1) | bw
->pll_reset
);
327 clk_cfg0
= (bw
->pll_bypass
<< 15) | (clk_cfg0
& 0x7fff);
328 dib7000p_write_word(state
, 900, clk_cfg0
);
330 dib7000p_write_word(state
, 18, (u16
) (((bw
->internal
*1000) >> 16) & 0xffff));
331 dib7000p_write_word(state
, 19, (u16
) ( (bw
->internal
*1000 ) & 0xffff));
332 dib7000p_write_word(state
, 21, (u16
) ( (bw
->ifreq
>> 16) & 0xffff));
333 dib7000p_write_word(state
, 22, (u16
) ( (bw
->ifreq
) & 0xffff));
335 dib7000p_write_word(state
, 72, bw
->sad_cfg
);
338 static int dib7000p_reset_gpio(struct dib7000p_state
*st
)
340 /* reset the GPIOs */
341 dprintk( "gpio dir: %x: val: %x, pwm_pos: %x",st
->gpio_dir
, st
->gpio_val
,st
->cfg
.gpio_pwm_pos
);
343 dib7000p_write_word(st
, 1029, st
->gpio_dir
);
344 dib7000p_write_word(st
, 1030, st
->gpio_val
);
346 /* TODO 1031 is P_gpio_od */
348 dib7000p_write_word(st
, 1032, st
->cfg
.gpio_pwm_pos
);
350 dib7000p_write_word(st
, 1037, st
->cfg
.pwm_freq_div
);
354 static int dib7000p_cfg_gpio(struct dib7000p_state
*st
, u8 num
, u8 dir
, u8 val
)
356 st
->gpio_dir
= dib7000p_read_word(st
, 1029);
357 st
->gpio_dir
&= ~(1 << num
); /* reset the direction bit */
358 st
->gpio_dir
|= (dir
& 0x1) << num
; /* set the new direction */
359 dib7000p_write_word(st
, 1029, st
->gpio_dir
);
361 st
->gpio_val
= dib7000p_read_word(st
, 1030);
362 st
->gpio_val
&= ~(1 << num
); /* reset the direction bit */
363 st
->gpio_val
|= (val
& 0x01) << num
; /* set the new value */
364 dib7000p_write_word(st
, 1030, st
->gpio_val
);
369 int dib7000p_set_gpio(struct dvb_frontend
*demod
, u8 num
, u8 dir
, u8 val
)
371 struct dib7000p_state
*state
= demod
->demodulator_priv
;
372 return dib7000p_cfg_gpio(state
, num
, dir
, val
);
375 EXPORT_SYMBOL(dib7000p_set_gpio
);
376 static u16 dib7000p_defaults
[] =
379 // auto search configuration
383 0x0814, /* Equal Lock */
400 0x6680, // P_timf_alpha=6, P_corm_alpha=6, P_corm_thres=128 default: 6,4,26
402 /* set ADC level to -16 */
404 (1 << 13) - 825 - 117,
405 (1 << 13) - 837 - 117,
406 (1 << 13) - 811 - 117,
407 (1 << 13) - 766 - 117,
408 (1 << 13) - 737 - 117,
409 (1 << 13) - 693 - 117,
410 (1 << 13) - 648 - 117,
411 (1 << 13) - 619 - 117,
412 (1 << 13) - 575 - 117,
413 (1 << 13) - 531 - 117,
414 (1 << 13) - 501 - 117,
417 0x0410, // P_palf_filter_on=1, P_palf_filter_freeze=0, P_palf_alpha_regul=16
419 /* disable power smoothing */
431 1 << 13, // P_fft_freq_dir=1, P_fft_nb_to_cut=0
434 0x0ccd, // P_pha3_thres, default 0x3000
437 // 0x0010, // P_cti_use_cpe=0, P_cti_use_prog=0, P_cti_win_len=16, default: 0x0010
440 0x200f, // P_cspu_regul=512, P_cspu_win_cut=15, default: 0x2005
443 0x023d, // P_adp_regul_cnt=573, default: 410
444 0x00a4, // P_adp_noise_cnt=
445 0x00a4, // P_adp_regul_ext
446 0x7ff0, // P_adp_noise_ext
450 0x800, // P_equal_thres_wgn
453 0x0010, // P_fec_ber_rs_len=2
456 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
459 0x0006, // P_clk_cfg1
460 (3 << 10) | (1 << 6), // P_divclksel=3 P_divbitsel=1
463 0x2c8e, // Tuner IO bank: max drive (14mA) + divout pads max drive
468 static int dib7000p_demod_reset(struct dib7000p_state
*state
)
470 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
472 dib7000p_set_adc_state(state
, DIBX000_VBG_ENABLE
);
474 /* restart all parts */
475 dib7000p_write_word(state
, 770, 0xffff);
476 dib7000p_write_word(state
, 771, 0xffff);
477 dib7000p_write_word(state
, 772, 0x001f);
478 dib7000p_write_word(state
, 898, 0x0003);
479 /* except i2c, sdio, gpio - control interfaces */
480 dib7000p_write_word(state
, 1280, 0x01fc - ((1 << 7) | (1 << 6) | (1 << 5)) );
482 dib7000p_write_word(state
, 770, 0);
483 dib7000p_write_word(state
, 771, 0);
484 dib7000p_write_word(state
, 772, 0);
485 dib7000p_write_word(state
, 898, 0);
486 dib7000p_write_word(state
, 1280, 0);
489 dib7000p_reset_pll(state
);
491 if (dib7000p_reset_gpio(state
) != 0)
492 dprintk( "GPIO reset was not successful.");
494 if (dib7000p_set_output_mode(state
, OUTMODE_HIGH_Z
) != 0)
495 dprintk( "OUTPUT_MODE could not be reset.");
497 /* unforce divstr regardless whether i2c enumeration was done or not */
498 dib7000p_write_word(state
, 1285, dib7000p_read_word(state
, 1285) & ~(1 << 1) );
500 dib7000p_set_bandwidth(state
, 8000);
502 dib7000p_set_adc_state(state
, DIBX000_SLOW_ADC_ON
);
503 dib7000p_sad_calib(state
);
504 dib7000p_set_adc_state(state
, DIBX000_SLOW_ADC_OFF
);
506 // P_iqc_alpha_pha, P_iqc_alpha_amp_dcc_alpha, ...
507 if(state
->cfg
.tuner_is_baseband
)
508 dib7000p_write_word(state
, 36,0x0755);
510 dib7000p_write_word(state
, 36,0x1f55);
512 dib7000p_write_tab(state
, dib7000p_defaults
);
514 dib7000p_set_power_mode(state
, DIB7000P_POWER_INTERFACE_ONLY
);
520 static void dib7000p_pll_clk_cfg(struct dib7000p_state
*state
)
523 tmp
= dib7000p_read_word(state
, 903);
524 dib7000p_write_word(state
, 903, (tmp
| 0x1)); //pwr-up pll
525 tmp
= dib7000p_read_word(state
, 900);
526 dib7000p_write_word(state
, 900, (tmp
& 0x7fff) | (1 << 6)); //use High freq clock
529 static void dib7000p_restart_agc(struct dib7000p_state
*state
)
531 // P_restart_iqc & P_restart_agc
532 dib7000p_write_word(state
, 770, (1 << 11) | (1 << 9));
533 dib7000p_write_word(state
, 770, 0x0000);
536 static int dib7000p_update_lna(struct dib7000p_state
*state
)
540 // when there is no LNA to program return immediatly
541 if (state
->cfg
.update_lna
) {
542 // read dyn_gain here (because it is demod-dependent and not fe)
543 dyn_gain
= dib7000p_read_word(state
, 394);
544 if (state
->cfg
.update_lna(&state
->demod
,dyn_gain
)) { // LNA has changed
545 dib7000p_restart_agc(state
);
553 static int dib7000p_set_agc_config(struct dib7000p_state
*state
, u8 band
)
555 struct dibx000_agc_config
*agc
= NULL
;
557 if (state
->current_band
== band
&& state
->current_agc
!= NULL
)
559 state
->current_band
= band
;
561 for (i
= 0; i
< state
->cfg
.agc_config_count
; i
++)
562 if (state
->cfg
.agc
[i
].band_caps
& band
) {
563 agc
= &state
->cfg
.agc
[i
];
568 dprintk( "no valid AGC configuration found for band 0x%02x",band
);
572 state
->current_agc
= agc
;
575 dib7000p_write_word(state
, 75 , agc
->setup
);
576 dib7000p_write_word(state
, 76 , agc
->inv_gain
);
577 dib7000p_write_word(state
, 77 , agc
->time_stabiliz
);
578 dib7000p_write_word(state
, 100, (agc
->alpha_level
<< 12) | agc
->thlock
);
580 // Demod AGC loop configuration
581 dib7000p_write_word(state
, 101, (agc
->alpha_mant
<< 5) | agc
->alpha_exp
);
582 dib7000p_write_word(state
, 102, (agc
->beta_mant
<< 6) | agc
->beta_exp
);
585 dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d",
586 state
->wbd_ref
!= 0 ? state
->wbd_ref
: agc
->wbd_ref
, agc
->wbd_sel
, !agc
->perform_agc_softsplit
, agc
->wbd_sel
);
588 if (state
->wbd_ref
!= 0)
589 dib7000p_write_word(state
, 105, (agc
->wbd_inv
<< 12) | state
->wbd_ref
);
591 dib7000p_write_word(state
, 105, (agc
->wbd_inv
<< 12) | agc
->wbd_ref
);
593 dib7000p_write_word(state
, 106, (agc
->wbd_sel
<< 13) | (agc
->wbd_alpha
<< 9) | (agc
->perform_agc_softsplit
<< 8));
595 dib7000p_write_word(state
, 107, agc
->agc1_max
);
596 dib7000p_write_word(state
, 108, agc
->agc1_min
);
597 dib7000p_write_word(state
, 109, agc
->agc2_max
);
598 dib7000p_write_word(state
, 110, agc
->agc2_min
);
599 dib7000p_write_word(state
, 111, (agc
->agc1_pt1
<< 8) | agc
->agc1_pt2
);
600 dib7000p_write_word(state
, 112, agc
->agc1_pt3
);
601 dib7000p_write_word(state
, 113, (agc
->agc1_slope1
<< 8) | agc
->agc1_slope2
);
602 dib7000p_write_word(state
, 114, (agc
->agc2_pt1
<< 8) | agc
->agc2_pt2
);
603 dib7000p_write_word(state
, 115, (agc
->agc2_slope1
<< 8) | agc
->agc2_slope2
);
607 static int dib7000p_agc_startup(struct dvb_frontend
*demod
, struct dvb_frontend_parameters
*ch
)
609 struct dib7000p_state
*state
= demod
->demodulator_priv
;
611 u8
*agc_state
= &state
->agc_state
;
614 switch (state
->agc_state
) {
616 // set power-up level: interf+analog+AGC
617 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
618 dib7000p_set_adc_state(state
, DIBX000_ADC_ON
);
619 dib7000p_pll_clk_cfg(state
);
621 if (dib7000p_set_agc_config(state
, BAND_OF_FREQUENCY(ch
->frequency
/1000)) != 0)
629 // AGC initialization
630 if (state
->cfg
.agc_control
)
631 state
->cfg
.agc_control(&state
->demod
, 1);
633 dib7000p_write_word(state
, 78, 32768);
634 if (!state
->current_agc
->perform_agc_softsplit
) {
635 /* we are using the wbd - so slow AGC startup */
636 /* force 0 split on WBD and restart AGC */
637 dib7000p_write_word(state
, 106, (state
->current_agc
->wbd_sel
<< 13) | (state
->current_agc
->wbd_alpha
<< 9) | (1 << 8));
641 /* default AGC startup */
643 /* wait AGC rough lock time */
647 dib7000p_restart_agc(state
);
650 case 2: /* fast split search path after 5sec */
651 dib7000p_write_word(state
, 75, state
->current_agc
->setup
| (1 << 4)); /* freeze AGC loop */
652 dib7000p_write_word(state
, 106, (state
->current_agc
->wbd_sel
<< 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */
657 case 3: /* split search ended */
658 agc_split
= (u8
)dib7000p_read_word(state
, 396); /* store the split value for the next time */
659 dib7000p_write_word(state
, 78, dib7000p_read_word(state
, 394)); /* set AGC gain start value */
661 dib7000p_write_word(state
, 75, state
->current_agc
->setup
); /* std AGC loop */
662 dib7000p_write_word(state
, 106, (state
->current_agc
->wbd_sel
<< 13) | (state
->current_agc
->wbd_alpha
<< 9) | agc_split
); /* standard split search */
664 dib7000p_restart_agc(state
);
666 dprintk( "SPLIT %p: %hd", demod
, agc_split
);
672 case 4: /* LNA startup */
673 // wait AGC accurate lock time
676 if (dib7000p_update_lna(state
))
677 // wait only AGC rough lock time
679 else // nothing was done, go to the next state
684 if (state
->cfg
.agc_control
)
685 state
->cfg
.agc_control(&state
->demod
, 0);
694 static void dib7000p_update_timf(struct dib7000p_state
*state
)
696 u32 timf
= (dib7000p_read_word(state
, 427) << 16) | dib7000p_read_word(state
, 428);
697 state
->timf
= timf
* 160 / (state
->current_bandwidth
/ 50);
698 dib7000p_write_word(state
, 23, (u16
) (timf
>> 16));
699 dib7000p_write_word(state
, 24, (u16
) (timf
& 0xffff));
700 dprintk( "updated timf_frequency: %d (default: %d)",state
->timf
, state
->cfg
.bw
->timf
);
704 static void dib7000p_set_channel(struct dib7000p_state
*state
, struct dvb_frontend_parameters
*ch
, u8 seq
)
708 dib7000p_set_bandwidth(state
, BANDWIDTH_TO_KHZ(ch
->u
.ofdm
.bandwidth
));
710 /* nfft, guard, qam, alpha */
712 switch (ch
->u
.ofdm
.transmission_mode
) {
713 case TRANSMISSION_MODE_2K
: value
|= (0 << 7); break;
714 case /* 4K MODE */ 255: value
|= (2 << 7); break;
716 case TRANSMISSION_MODE_8K
: value
|= (1 << 7); break;
718 switch (ch
->u
.ofdm
.guard_interval
) {
719 case GUARD_INTERVAL_1_32
: value
|= (0 << 5); break;
720 case GUARD_INTERVAL_1_16
: value
|= (1 << 5); break;
721 case GUARD_INTERVAL_1_4
: value
|= (3 << 5); break;
723 case GUARD_INTERVAL_1_8
: value
|= (2 << 5); break;
725 switch (ch
->u
.ofdm
.constellation
) {
726 case QPSK
: value
|= (0 << 3); break;
727 case QAM_16
: value
|= (1 << 3); break;
729 case QAM_64
: value
|= (2 << 3); break;
731 switch (HIERARCHY_1
) {
732 case HIERARCHY_2
: value
|= 2; break;
733 case HIERARCHY_4
: value
|= 4; break;
735 case HIERARCHY_1
: value
|= 1; break;
737 dib7000p_write_word(state
, 0, value
);
738 dib7000p_write_word(state
, 5, (seq
<< 4) | 1); /* do not force tps, search list 0 */
740 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
744 if (ch
->u
.ofdm
.hierarchy_information
== 1)
748 switch ((ch
->u
.ofdm
.hierarchy_information
== 0 || 1 == 1) ? ch
->u
.ofdm
.code_rate_HP
: ch
->u
.ofdm
.code_rate_LP
) {
749 case FEC_2_3
: value
|= (2 << 1); break;
750 case FEC_3_4
: value
|= (3 << 1); break;
751 case FEC_5_6
: value
|= (5 << 1); break;
752 case FEC_7_8
: value
|= (7 << 1); break;
754 case FEC_1_2
: value
|= (1 << 1); break;
756 dib7000p_write_word(state
, 208, value
);
758 /* offset loop parameters */
759 dib7000p_write_word(state
, 26, 0x6680); // timf(6xxx)
760 dib7000p_write_word(state
, 32, 0x0003); // pha_off_max(xxx3)
761 dib7000p_write_word(state
, 29, 0x1273); // isi
762 dib7000p_write_word(state
, 33, 0x0005); // sfreq(xxx5)
764 /* P_dvsy_sync_wait */
765 switch (ch
->u
.ofdm
.transmission_mode
) {
766 case TRANSMISSION_MODE_8K
: value
= 256; break;
767 case /* 4K MODE */ 255: value
= 128; break;
768 case TRANSMISSION_MODE_2K
:
769 default: value
= 64; break;
771 switch (ch
->u
.ofdm
.guard_interval
) {
772 case GUARD_INTERVAL_1_16
: value
*= 2; break;
773 case GUARD_INTERVAL_1_8
: value
*= 4; break;
774 case GUARD_INTERVAL_1_4
: value
*= 8; break;
776 case GUARD_INTERVAL_1_32
: value
*= 1; break;
778 state
->div_sync_wait
= (value
* 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO
780 /* deactive the possibility of diversity reception if extended interleaver */
781 state
->div_force_off
= !1 && ch
->u
.ofdm
.transmission_mode
!= TRANSMISSION_MODE_8K
;
782 dib7000p_set_diversity_in(&state
->demod
, state
->div_state
);
784 /* channel estimation fine configuration */
785 switch (ch
->u
.ofdm
.constellation
) {
787 est
[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
788 est
[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
789 est
[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
790 est
[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
793 est
[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
794 est
[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
795 est
[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
796 est
[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
799 est
[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
800 est
[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
801 est
[2] = 0x0333; /* P_adp_regul_ext 0.1 */
802 est
[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
805 for (value
= 0; value
< 4; value
++)
806 dib7000p_write_word(state
, 187 + value
, est
[value
]);
809 static int dib7000p_autosearch_start(struct dvb_frontend
*demod
, struct dvb_frontend_parameters
*ch
)
811 struct dib7000p_state
*state
= demod
->demodulator_priv
;
812 struct dvb_frontend_parameters schan
;
816 schan
.u
.ofdm
.constellation
= QAM_64
;
817 schan
.u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_32
;
818 schan
.u
.ofdm
.transmission_mode
= TRANSMISSION_MODE_8K
;
819 schan
.u
.ofdm
.code_rate_HP
= FEC_2_3
;
820 schan
.u
.ofdm
.code_rate_LP
= FEC_3_4
;
821 schan
.u
.ofdm
.hierarchy_information
= 0;
823 dib7000p_set_channel(state
, &schan
, 7);
825 factor
= BANDWIDTH_TO_KHZ(ch
->u
.ofdm
.bandwidth
);
831 // always use the setting for 8MHz here lock_time for 7,6 MHz are longer
832 value
= 30 * state
->cfg
.bw
->internal
* factor
;
833 dib7000p_write_word(state
, 6, (u16
) ((value
>> 16) & 0xffff)); // lock0 wait time
834 dib7000p_write_word(state
, 7, (u16
) (value
& 0xffff)); // lock0 wait time
835 value
= 100 * state
->cfg
.bw
->internal
* factor
;
836 dib7000p_write_word(state
, 8, (u16
) ((value
>> 16) & 0xffff)); // lock1 wait time
837 dib7000p_write_word(state
, 9, (u16
) (value
& 0xffff)); // lock1 wait time
838 value
= 500 * state
->cfg
.bw
->internal
* factor
;
839 dib7000p_write_word(state
, 10, (u16
) ((value
>> 16) & 0xffff)); // lock2 wait time
840 dib7000p_write_word(state
, 11, (u16
) (value
& 0xffff)); // lock2 wait time
842 value
= dib7000p_read_word(state
, 0);
843 dib7000p_write_word(state
, 0, (u16
) ((1 << 9) | value
));
844 dib7000p_read_word(state
, 1284);
845 dib7000p_write_word(state
, 0, (u16
) value
);
850 static int dib7000p_autosearch_is_irq(struct dvb_frontend
*demod
)
852 struct dib7000p_state
*state
= demod
->demodulator_priv
;
853 u16 irq_pending
= dib7000p_read_word(state
, 1284);
855 if (irq_pending
& 0x1) // failed
858 if (irq_pending
& 0x2) // succeeded
861 return 0; // still pending
864 static void dib7000p_spur_protect(struct dib7000p_state
*state
, u32 rf_khz
, u32 bw
)
866 static s16 notch
[]={16143, 14402, 12238, 9713, 6902, 3888, 759, -2392};
867 static u8 sine
[] ={0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
868 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
869 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
870 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
871 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
872 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
873 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
874 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
875 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
876 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
877 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
878 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
879 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
880 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
881 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
882 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
883 255, 255, 255, 255, 255, 255};
885 u32 xtal
= state
->cfg
.bw
->xtal_hz
/ 1000;
886 int f_rel
= ( (rf_khz
+ xtal
/2) / xtal
) * xtal
- rf_khz
;
888 int coef_re
[8],coef_im
[8];
892 dprintk( "relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel
, rf_khz
, xtal
);
895 if (f_rel
< -bw_khz
/2 || f_rel
> bw_khz
/2)
900 dib7000p_write_word(state
, 142 ,0x0610);
902 for (k
= 0; k
< 8; k
++) {
903 pha
= ((f_rel
* (k
+1) * 112 * 80/bw_khz
) /1000) & 0x3ff;
908 } else if(pha
< 256) {
909 coef_re
[k
] = sine
[256-(pha
&0xff)];
910 coef_im
[k
] = sine
[pha
&0xff];
911 } else if (pha
== 256) {
914 } else if (pha
< 512) {
915 coef_re
[k
] = -sine
[pha
&0xff];
916 coef_im
[k
] = sine
[256 - (pha
&0xff)];
917 } else if (pha
== 512) {
920 } else if (pha
< 768) {
921 coef_re
[k
] = -sine
[256-(pha
&0xff)];
922 coef_im
[k
] = -sine
[pha
&0xff];
923 } else if (pha
== 768) {
927 coef_re
[k
] = sine
[pha
&0xff];
928 coef_im
[k
] = -sine
[256 - (pha
&0xff)];
931 coef_re
[k
] *= notch
[k
];
932 coef_re
[k
] += (1<<14);
933 if (coef_re
[k
] >= (1<<24))
934 coef_re
[k
] = (1<<24) - 1;
935 coef_re
[k
] /= (1<<15);
937 coef_im
[k
] *= notch
[k
];
938 coef_im
[k
] += (1<<14);
939 if (coef_im
[k
] >= (1<<24))
940 coef_im
[k
] = (1<<24)-1;
941 coef_im
[k
] /= (1<<15);
943 dprintk( "PALF COEF: %d re: %d im: %d", k
, coef_re
[k
], coef_im
[k
]);
945 dib7000p_write_word(state
, 143, (0 << 14) | (k
<< 10) | (coef_re
[k
] & 0x3ff));
946 dib7000p_write_word(state
, 144, coef_im
[k
] & 0x3ff);
947 dib7000p_write_word(state
, 143, (1 << 14) | (k
<< 10) | (coef_re
[k
] & 0x3ff));
949 dib7000p_write_word(state
,143 ,0);
952 static int dib7000p_tune(struct dvb_frontend
*demod
, struct dvb_frontend_parameters
*ch
)
954 struct dib7000p_state
*state
= demod
->demodulator_priv
;
958 dib7000p_set_channel(state
, ch
, 0);
963 dib7000p_write_word(state
, 770, 0x4000);
964 dib7000p_write_word(state
, 770, 0x0000);
967 /* 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 */
968 tmp
= (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
969 if (state
->sfn_workaround_active
) {
970 dprintk( "SFN workaround is active");
972 dib7000p_write_word(state
, 166, 0x4000); // P_pha3_force_pha_shift
974 dib7000p_write_word(state
, 166, 0x0000); // P_pha3_force_pha_shift
976 dib7000p_write_word(state
, 29, tmp
);
978 // never achieved a lock with that bandwidth so far - wait for osc-freq to update
979 if (state
->timf
== 0)
982 /* offset loop parameters */
984 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
985 tmp
= (6 << 8) | 0x80;
986 switch (ch
->u
.ofdm
.transmission_mode
) {
987 case TRANSMISSION_MODE_2K
: tmp
|= (7 << 12); break;
988 case /* 4K MODE */ 255: tmp
|= (8 << 12); break;
990 case TRANSMISSION_MODE_8K
: tmp
|= (9 << 12); break;
992 dib7000p_write_word(state
, 26, tmp
); /* timf_a(6xxx) */
994 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
996 switch (ch
->u
.ofdm
.transmission_mode
) {
997 case TRANSMISSION_MODE_2K
: tmp
|= 0x6; break;
998 case /* 4K MODE */ 255: tmp
|= 0x7; break;
1000 case TRANSMISSION_MODE_8K
: tmp
|= 0x8; break;
1002 dib7000p_write_word(state
, 32, tmp
);
1004 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1006 switch (ch
->u
.ofdm
.transmission_mode
) {
1007 case TRANSMISSION_MODE_2K
: tmp
|= 0x6; break;
1008 case /* 4K MODE */ 255: tmp
|= 0x7; break;
1010 case TRANSMISSION_MODE_8K
: tmp
|= 0x8; break;
1012 dib7000p_write_word(state
, 33, tmp
);
1014 tmp
= dib7000p_read_word(state
,509);
1015 if (!((tmp
>> 6) & 0x1)) {
1016 /* restart the fec */
1017 tmp
= dib7000p_read_word(state
,771);
1018 dib7000p_write_word(state
, 771, tmp
| (1 << 1));
1019 dib7000p_write_word(state
, 771, tmp
);
1021 tmp
= dib7000p_read_word(state
,509);
1024 // we achieved a lock - it's time to update the osc freq
1025 if ((tmp
>> 6) & 0x1)
1026 dib7000p_update_timf(state
);
1028 if (state
->cfg
.spur_protect
)
1029 dib7000p_spur_protect(state
, ch
->frequency
/1000, BANDWIDTH_TO_KHZ(ch
->u
.ofdm
.bandwidth
));
1031 dib7000p_set_bandwidth(state
, BANDWIDTH_TO_KHZ(ch
->u
.ofdm
.bandwidth
));
1035 static int dib7000p_wakeup(struct dvb_frontend
*demod
)
1037 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1038 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
1039 dib7000p_set_adc_state(state
, DIBX000_SLOW_ADC_ON
);
1043 static int dib7000p_sleep(struct dvb_frontend
*demod
)
1045 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1046 return dib7000p_set_output_mode(state
, OUTMODE_HIGH_Z
) | dib7000p_set_power_mode(state
, DIB7000P_POWER_INTERFACE_ONLY
);
1049 static int dib7000p_identify(struct dib7000p_state
*st
)
1052 dprintk( "checking demod on I2C address: %d (%x)",
1053 st
->i2c_addr
, st
->i2c_addr
);
1055 if ((value
= dib7000p_read_word(st
, 768)) != 0x01b3) {
1056 dprintk( "wrong Vendor ID (read=0x%x)",value
);
1060 if ((value
= dib7000p_read_word(st
, 769)) != 0x4000) {
1061 dprintk( "wrong Device ID (%x)",value
);
1069 static int dib7000p_get_frontend(struct dvb_frontend
* fe
,
1070 struct dvb_frontend_parameters
*fep
)
1072 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1073 u16 tps
= dib7000p_read_word(state
,463);
1075 fep
->inversion
= INVERSION_AUTO
;
1077 fep
->u
.ofdm
.bandwidth
= state
->current_bandwidth
;
1079 switch ((tps
>> 8) & 0x3) {
1080 case 0: fep
->u
.ofdm
.transmission_mode
= TRANSMISSION_MODE_2K
; break;
1081 case 1: fep
->u
.ofdm
.transmission_mode
= TRANSMISSION_MODE_8K
; break;
1082 /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */
1085 switch (tps
& 0x3) {
1086 case 0: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_32
; break;
1087 case 1: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_16
; break;
1088 case 2: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_8
; break;
1089 case 3: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_4
; break;
1092 switch ((tps
>> 14) & 0x3) {
1093 case 0: fep
->u
.ofdm
.constellation
= QPSK
; break;
1094 case 1: fep
->u
.ofdm
.constellation
= QAM_16
; break;
1096 default: fep
->u
.ofdm
.constellation
= QAM_64
; break;
1099 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1100 /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1102 fep
->u
.ofdm
.hierarchy_information
= HIERARCHY_NONE
;
1103 switch ((tps
>> 5) & 0x7) {
1104 case 1: fep
->u
.ofdm
.code_rate_HP
= FEC_1_2
; break;
1105 case 2: fep
->u
.ofdm
.code_rate_HP
= FEC_2_3
; break;
1106 case 3: fep
->u
.ofdm
.code_rate_HP
= FEC_3_4
; break;
1107 case 5: fep
->u
.ofdm
.code_rate_HP
= FEC_5_6
; break;
1109 default: fep
->u
.ofdm
.code_rate_HP
= FEC_7_8
; break;
1113 switch ((tps
>> 2) & 0x7) {
1114 case 1: fep
->u
.ofdm
.code_rate_LP
= FEC_1_2
; break;
1115 case 2: fep
->u
.ofdm
.code_rate_LP
= FEC_2_3
; break;
1116 case 3: fep
->u
.ofdm
.code_rate_LP
= FEC_3_4
; break;
1117 case 5: fep
->u
.ofdm
.code_rate_LP
= FEC_5_6
; break;
1119 default: fep
->u
.ofdm
.code_rate_LP
= FEC_7_8
; break;
1122 /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */
1127 static int dib7000p_set_frontend(struct dvb_frontend
* fe
,
1128 struct dvb_frontend_parameters
*fep
)
1130 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1133 state
->current_bandwidth
= fep
->u
.ofdm
.bandwidth
;
1134 dib7000p_set_bandwidth(state
, BANDWIDTH_TO_KHZ(fep
->u
.ofdm
.bandwidth
));
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 /* make this a config parameter */
1170 dib7000p_set_output_mode(state
, OUTMODE_MPEG2_FIFO
);
1172 return dib7000p_tune(fe
, fep
);
1175 static int dib7000p_read_status(struct dvb_frontend
*fe
, fe_status_t
*stat
)
1177 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1178 u16 lock
= dib7000p_read_word(state
, 509);
1183 *stat
|= FE_HAS_SIGNAL
;
1185 *stat
|= FE_HAS_CARRIER
;
1187 *stat
|= FE_HAS_VITERBI
;
1189 *stat
|= FE_HAS_SYNC
;
1191 *stat
|= FE_HAS_LOCK
;
1196 static int dib7000p_read_ber(struct dvb_frontend
*fe
, u32
*ber
)
1198 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1199 *ber
= (dib7000p_read_word(state
, 500) << 16) | dib7000p_read_word(state
, 501);
1203 static int dib7000p_read_unc_blocks(struct dvb_frontend
*fe
, u32
*unc
)
1205 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1206 *unc
= dib7000p_read_word(state
, 506);
1210 static int dib7000p_read_signal_strength(struct dvb_frontend
*fe
, u16
*strength
)
1212 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1213 u16 val
= dib7000p_read_word(state
, 394);
1214 *strength
= 65535 - val
;
1218 static int dib7000p_read_snr(struct dvb_frontend
* fe
, u16
*snr
)
1224 static int dib7000p_fe_get_tune_settings(struct dvb_frontend
* fe
, struct dvb_frontend_tune_settings
*tune
)
1226 tune
->min_delay_ms
= 1000;
1230 static void dib7000p_release(struct dvb_frontend
*demod
)
1232 struct dib7000p_state
*st
= demod
->demodulator_priv
;
1233 dibx000_exit_i2c_master(&st
->i2c_master
);
1237 int dib7000pc_detection(struct i2c_adapter
*i2c_adap
)
1240 struct i2c_msg msg
[2] = {
1241 { .addr
= 18 >> 1, .flags
= 0, .buf
= tx
, .len
= 2 },
1242 { .addr
= 18 >> 1, .flags
= I2C_M_RD
, .buf
= rx
, .len
= 2 },
1248 if (i2c_transfer(i2c_adap
, msg
, 2) == 2)
1249 if (rx
[0] == 0x01 && rx
[1] == 0xb3) {
1250 dprintk("-D- DiB7000PC detected");
1254 msg
[0].addr
= msg
[1].addr
= 0x40;
1256 if (i2c_transfer(i2c_adap
, msg
, 2) == 2)
1257 if (rx
[0] == 0x01 && rx
[1] == 0xb3) {
1258 dprintk("-D- DiB7000PC detected");
1262 dprintk("-D- DiB7000PC not detected");
1265 EXPORT_SYMBOL(dib7000pc_detection
);
1267 struct i2c_adapter
* dib7000p_get_i2c_master(struct dvb_frontend
*demod
, enum dibx000_i2c_interface intf
, int gating
)
1269 struct dib7000p_state
*st
= demod
->demodulator_priv
;
1270 return dibx000_get_i2c_adapter(&st
->i2c_master
, intf
, gating
);
1272 EXPORT_SYMBOL(dib7000p_get_i2c_master
);
1274 int dib7000p_i2c_enumeration(struct i2c_adapter
*i2c
, int no_of_demods
, u8 default_addr
, struct dib7000p_config cfg
[])
1276 struct dib7000p_state st
= { .i2c_adap
= i2c
};
1280 for (k
= no_of_demods
-1; k
>= 0; k
--) {
1283 /* designated i2c address */
1284 new_addr
= (0x40 + k
) << 1;
1285 st
.i2c_addr
= new_addr
;
1286 if (dib7000p_identify(&st
) != 0) {
1287 st
.i2c_addr
= default_addr
;
1288 if (dib7000p_identify(&st
) != 0) {
1289 dprintk("DiB7000P #%d: not identified\n", k
);
1294 /* start diversity to pull_down div_str - just for i2c-enumeration */
1295 dib7000p_set_output_mode(&st
, OUTMODE_DIVERSITY
);
1297 /* set new i2c address and force divstart */
1298 dib7000p_write_word(&st
, 1285, (new_addr
<< 2) | 0x2);
1300 dprintk("IC %d initialized (to i2c_address 0x%x)", k
, new_addr
);
1303 for (k
= 0; k
< no_of_demods
; k
++) {
1305 st
.i2c_addr
= (0x40 + k
) << 1;
1308 dib7000p_write_word(&st
, 1285, st
.i2c_addr
<< 2);
1310 /* deactivate div - it was just for i2c-enumeration */
1311 dib7000p_set_output_mode(&st
, OUTMODE_HIGH_Z
);
1316 EXPORT_SYMBOL(dib7000p_i2c_enumeration
);
1318 static struct dvb_frontend_ops dib7000p_ops
;
1319 struct dvb_frontend
* dib7000p_attach(struct i2c_adapter
*i2c_adap
, u8 i2c_addr
, struct dib7000p_config
*cfg
)
1321 struct dvb_frontend
*demod
;
1322 struct dib7000p_state
*st
;
1323 st
= kzalloc(sizeof(struct dib7000p_state
), GFP_KERNEL
);
1327 memcpy(&st
->cfg
, cfg
, sizeof(struct dib7000p_config
));
1328 st
->i2c_adap
= i2c_adap
;
1329 st
->i2c_addr
= i2c_addr
;
1330 st
->gpio_val
= cfg
->gpio_val
;
1331 st
->gpio_dir
= cfg
->gpio_dir
;
1334 demod
->demodulator_priv
= st
;
1335 memcpy(&st
->demod
.ops
, &dib7000p_ops
, sizeof(struct dvb_frontend_ops
));
1337 if (dib7000p_identify(st
) != 0)
1340 dibx000_init_i2c_master(&st
->i2c_master
, DIB7000P
, st
->i2c_adap
, st
->i2c_addr
);
1342 dib7000p_demod_reset(st
);
1350 EXPORT_SYMBOL(dib7000p_attach
);
1352 static struct dvb_frontend_ops dib7000p_ops
= {
1354 .name
= "DiBcom 7000PC",
1356 .frequency_min
= 44250000,
1357 .frequency_max
= 867250000,
1358 .frequency_stepsize
= 62500,
1359 .caps
= FE_CAN_INVERSION_AUTO
|
1360 FE_CAN_FEC_1_2
| FE_CAN_FEC_2_3
| FE_CAN_FEC_3_4
|
1361 FE_CAN_FEC_5_6
| FE_CAN_FEC_7_8
| FE_CAN_FEC_AUTO
|
1362 FE_CAN_QPSK
| FE_CAN_QAM_16
| FE_CAN_QAM_64
| FE_CAN_QAM_AUTO
|
1363 FE_CAN_TRANSMISSION_MODE_AUTO
|
1364 FE_CAN_GUARD_INTERVAL_AUTO
|
1366 FE_CAN_HIERARCHY_AUTO
,
1369 .release
= dib7000p_release
,
1371 .init
= dib7000p_wakeup
,
1372 .sleep
= dib7000p_sleep
,
1374 .set_frontend
= dib7000p_set_frontend
,
1375 .get_tune_settings
= dib7000p_fe_get_tune_settings
,
1376 .get_frontend
= dib7000p_get_frontend
,
1378 .read_status
= dib7000p_read_status
,
1379 .read_ber
= dib7000p_read_ber
,
1380 .read_signal_strength
= dib7000p_read_signal_strength
,
1381 .read_snr
= dib7000p_read_snr
,
1382 .read_ucblocks
= dib7000p_read_unc_blocks
,
1385 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
1386 MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
1387 MODULE_LICENSE("GPL");