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