2 * Linux-DVB Driver for DiBcom's DiB7000M and
3 * first generation DiB7000P-demodulator-family.
5 * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, version 2.
12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14 #include <linux/kernel.h>
15 #include <linux/slab.h>
16 #include <linux/i2c.h>
17 #include <linux/mutex.h>
19 #include "dvb_frontend.h"
24 module_param(debug
, int, 0644);
25 MODULE_PARM_DESC(debug
, "turn on debugging (default: 0)");
27 #define dprintk(fmt, arg...) do { \
29 printk(KERN_DEBUG pr_fmt("%s: " fmt), \
33 struct dib7000m_state
{
34 struct dvb_frontend demod
;
35 struct dib7000m_config cfg
;
38 struct i2c_adapter
*i2c_adap
;
40 struct dibx000_i2c_master i2c_master
;
42 /* offset is 1 in case of the 7000MC */
48 u32 current_bandwidth
;
49 struct dibx000_agc_config
*current_agc
;
62 /* for the I2C transfer */
63 struct i2c_msg msg
[2];
64 u8 i2c_write_buffer
[4];
65 u8 i2c_read_buffer
[2];
66 struct mutex i2c_buffer_lock
;
69 enum dib7000m_power_mode
{
70 DIB7000M_POWER_ALL
= 0,
73 DIB7000M_POWER_INTERF_ANALOG_AGC
,
74 DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD
,
75 DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD
,
76 DIB7000M_POWER_INTERFACE_ONLY
,
79 static u16
dib7000m_read_word(struct dib7000m_state
*state
, u16 reg
)
83 if (mutex_lock_interruptible(&state
->i2c_buffer_lock
) < 0) {
84 dprintk("could not acquire lock\n");
88 state
->i2c_write_buffer
[0] = (reg
>> 8) | 0x80;
89 state
->i2c_write_buffer
[1] = reg
& 0xff;
91 memset(state
->msg
, 0, 2 * sizeof(struct i2c_msg
));
92 state
->msg
[0].addr
= state
->i2c_addr
>> 1;
93 state
->msg
[0].flags
= 0;
94 state
->msg
[0].buf
= state
->i2c_write_buffer
;
95 state
->msg
[0].len
= 2;
96 state
->msg
[1].addr
= state
->i2c_addr
>> 1;
97 state
->msg
[1].flags
= I2C_M_RD
;
98 state
->msg
[1].buf
= state
->i2c_read_buffer
;
99 state
->msg
[1].len
= 2;
101 if (i2c_transfer(state
->i2c_adap
, state
->msg
, 2) != 2)
102 dprintk("i2c read error on %d\n", reg
);
104 ret
= (state
->i2c_read_buffer
[0] << 8) | state
->i2c_read_buffer
[1];
105 mutex_unlock(&state
->i2c_buffer_lock
);
110 static int dib7000m_write_word(struct dib7000m_state
*state
, u16 reg
, u16 val
)
114 if (mutex_lock_interruptible(&state
->i2c_buffer_lock
) < 0) {
115 dprintk("could not acquire lock\n");
119 state
->i2c_write_buffer
[0] = (reg
>> 8) & 0xff;
120 state
->i2c_write_buffer
[1] = reg
& 0xff;
121 state
->i2c_write_buffer
[2] = (val
>> 8) & 0xff;
122 state
->i2c_write_buffer
[3] = val
& 0xff;
124 memset(&state
->msg
[0], 0, sizeof(struct i2c_msg
));
125 state
->msg
[0].addr
= state
->i2c_addr
>> 1;
126 state
->msg
[0].flags
= 0;
127 state
->msg
[0].buf
= state
->i2c_write_buffer
;
128 state
->msg
[0].len
= 4;
130 ret
= (i2c_transfer(state
->i2c_adap
, state
->msg
, 1) != 1 ?
132 mutex_unlock(&state
->i2c_buffer_lock
);
135 static void dib7000m_write_tab(struct dib7000m_state
*state
, u16
*buf
)
143 if (state
->reg_offs
&& (r
>= 112 && r
<= 331)) // compensate for 7000MC
147 dib7000m_write_word(state
, r
, *n
++);
154 static int dib7000m_set_output_mode(struct dib7000m_state
*state
, int mode
)
157 u16 outreg
, fifo_threshold
, smo_mode
,
158 sram
= 0x0005; /* by default SRAM output is disabled */
161 fifo_threshold
= 1792;
162 smo_mode
= (dib7000m_read_word(state
, 294 + state
->reg_offs
) & 0x0010) | (1 << 1);
164 dprintk("setting output mode for demod %p to %d\n", &state
->demod
, mode
);
167 case OUTMODE_MPEG2_PAR_GATED_CLK
: // STBs with parallel gated clock
168 outreg
= (1 << 10); /* 0x0400 */
170 case OUTMODE_MPEG2_PAR_CONT_CLK
: // STBs with parallel continues clock
171 outreg
= (1 << 10) | (1 << 6); /* 0x0440 */
173 case OUTMODE_MPEG2_SERIAL
: // STBs with serial input
174 outreg
= (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
176 case OUTMODE_DIVERSITY
:
177 if (state
->cfg
.hostbus_diversity
)
178 outreg
= (1 << 10) | (4 << 6); /* 0x0500 */
182 case OUTMODE_MPEG2_FIFO
: // e.g. USB feeding
183 smo_mode
|= (3 << 1);
184 fifo_threshold
= 512;
185 outreg
= (1 << 10) | (5 << 6);
187 case OUTMODE_HIGH_Z
: // disable
191 dprintk("Unhandled output_mode passed to be set for demod %p\n", &state
->demod
);
195 if (state
->cfg
.output_mpeg2_in_188_bytes
)
196 smo_mode
|= (1 << 5) ;
198 ret
|= dib7000m_write_word(state
, 294 + state
->reg_offs
, smo_mode
);
199 ret
|= dib7000m_write_word(state
, 295 + state
->reg_offs
, fifo_threshold
); /* synchronous fread */
200 ret
|= dib7000m_write_word(state
, 1795, outreg
);
201 ret
|= dib7000m_write_word(state
, 1805, sram
);
203 if (state
->revision
== 0x4003) {
204 u16 clk_cfg1
= dib7000m_read_word(state
, 909) & 0xfffd;
205 if (mode
== OUTMODE_DIVERSITY
)
206 clk_cfg1
|= (1 << 1); // P_O_CLK_en
207 dib7000m_write_word(state
, 909, clk_cfg1
);
212 static void dib7000m_set_power_mode(struct dib7000m_state
*state
, enum dib7000m_power_mode mode
)
214 /* by default everything is going to be powered off */
215 u16 reg_903
= 0xffff, reg_904
= 0xffff, reg_905
= 0xffff, reg_906
= 0x3fff;
218 /* now, depending on the requested mode, we power on */
220 /* power up everything in the demod */
221 case DIB7000M_POWER_ALL
:
222 reg_903
= 0x0000; reg_904
= 0x0000; reg_905
= 0x0000; reg_906
= 0x0000;
225 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO or SRAM) */
226 case DIB7000M_POWER_INTERFACE_ONLY
: /* TODO power up either SDIO or I2C or SRAM */
227 reg_905
&= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 2));
230 case DIB7000M_POWER_INTERF_ANALOG_AGC
:
231 reg_903
&= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10));
232 reg_905
&= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 2));
233 reg_906
&= ~((1 << 0));
236 case DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD
:
237 reg_903
= 0x0000; reg_904
= 0x801f; reg_905
= 0x0000; reg_906
= 0x0000;
240 case DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD
:
241 reg_903
= 0x0000; reg_904
= 0x8000; reg_905
= 0x010b; reg_906
= 0x0000;
243 case DIB7000M_POWER_NO
:
247 /* always power down unused parts */
248 if (!state
->cfg
.mobile_mode
)
249 reg_904
|= (1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) | (1 << 1);
251 /* P_sdio_select_clk = 0 on MC and after*/
252 if (state
->revision
!= 0x4000)
255 if (state
->revision
== 0x4003)
258 dib7000m_write_word(state
, 903 + offset
, reg_903
);
259 dib7000m_write_word(state
, 904 + offset
, reg_904
);
260 dib7000m_write_word(state
, 905 + offset
, reg_905
);
261 dib7000m_write_word(state
, 906 + offset
, reg_906
);
264 static int dib7000m_set_adc_state(struct dib7000m_state
*state
, enum dibx000_adc_states no
)
267 u16 reg_913
= dib7000m_read_word(state
, 913),
268 reg_914
= dib7000m_read_word(state
, 914);
271 case DIBX000_SLOW_ADC_ON
:
272 reg_914
|= (1 << 1) | (1 << 0);
273 ret
|= dib7000m_write_word(state
, 914, reg_914
);
274 reg_914
&= ~(1 << 1);
277 case DIBX000_SLOW_ADC_OFF
:
278 reg_914
|= (1 << 1) | (1 << 0);
282 if (state
->revision
== 0x4000) { // workaround for PA/MA
284 dib7000m_write_word(state
, 913, 0);
285 dib7000m_write_word(state
, 914, reg_914
& 0x3);
286 // power-down bandgag
287 dib7000m_write_word(state
, 913, (1 << 15));
288 dib7000m_write_word(state
, 914, reg_914
& 0x3);
295 case DIBX000_ADC_OFF
: // leave the VBG voltage on
296 reg_913
|= (1 << 14) | (1 << 13) | (1 << 12);
297 reg_914
|= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
300 case DIBX000_VBG_ENABLE
:
301 reg_913
&= ~(1 << 15);
304 case DIBX000_VBG_DISABLE
:
305 reg_913
|= (1 << 15);
312 // dprintk("913: %x, 914: %x\n", reg_913, reg_914);
313 ret
|= dib7000m_write_word(state
, 913, reg_913
);
314 ret
|= dib7000m_write_word(state
, 914, reg_914
);
319 static int dib7000m_set_bandwidth(struct dib7000m_state
*state
, u32 bw
)
326 // store the current bandwidth for later use
327 state
->current_bandwidth
= bw
;
329 if (state
->timf
== 0) {
330 dprintk("using default timf\n");
331 timf
= state
->timf_default
;
333 dprintk("using updated timf\n");
337 timf
= timf
* (bw
/ 50) / 160;
339 dib7000m_write_word(state
, 23, (u16
) ((timf
>> 16) & 0xffff));
340 dib7000m_write_word(state
, 24, (u16
) ((timf
) & 0xffff));
345 static int dib7000m_set_diversity_in(struct dvb_frontend
*demod
, int onoff
)
347 struct dib7000m_state
*state
= demod
->demodulator_priv
;
349 if (state
->div_force_off
) {
350 dprintk("diversity combination deactivated - forced by COFDM parameters\n");
353 state
->div_state
= (u8
)onoff
;
356 dib7000m_write_word(state
, 263 + state
->reg_offs
, 6);
357 dib7000m_write_word(state
, 264 + state
->reg_offs
, 6);
358 dib7000m_write_word(state
, 266 + state
->reg_offs
, (state
->div_sync_wait
<< 4) | (1 << 2) | (2 << 0));
360 dib7000m_write_word(state
, 263 + state
->reg_offs
, 1);
361 dib7000m_write_word(state
, 264 + state
->reg_offs
, 0);
362 dib7000m_write_word(state
, 266 + state
->reg_offs
, 0);
368 static int dib7000m_sad_calib(struct dib7000m_state
*state
)
372 // dib7000m_write_word(state, 928, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth
373 dib7000m_write_word(state
, 929, (0 << 1) | (0 << 0));
374 dib7000m_write_word(state
, 930, 776); // 0.625*3.3 / 4096
376 /* do the calibration */
377 dib7000m_write_word(state
, 929, (1 << 0));
378 dib7000m_write_word(state
, 929, (0 << 0));
385 static void dib7000m_reset_pll_common(struct dib7000m_state
*state
, const struct dibx000_bandwidth_config
*bw
)
387 dib7000m_write_word(state
, 18, (u16
) (((bw
->internal
*1000) >> 16) & 0xffff));
388 dib7000m_write_word(state
, 19, (u16
) ( (bw
->internal
*1000) & 0xffff));
389 dib7000m_write_word(state
, 21, (u16
) ( (bw
->ifreq
>> 16) & 0xffff));
390 dib7000m_write_word(state
, 22, (u16
) ( bw
->ifreq
& 0xffff));
392 dib7000m_write_word(state
, 928, bw
->sad_cfg
);
395 static void dib7000m_reset_pll(struct dib7000m_state
*state
)
397 const struct dibx000_bandwidth_config
*bw
= state
->cfg
.bw
;
401 reg_907
= (bw
->pll_bypass
<< 15) | (bw
->modulo
<< 7) |
402 (bw
->ADClkSrc
<< 6) | (bw
->IO_CLK_en_core
<< 5) | (bw
->bypclk_div
<< 2) |
403 (bw
->enable_refdiv
<< 1) | (0 << 0);
404 reg_910
= (((bw
->pll_ratio
>> 6) & 0x3) << 3) | (bw
->pll_range
<< 1) | bw
->pll_reset
;
406 // for this oscillator frequency should be 30 MHz for the Master (default values in the board_parameters give that value)
407 // this is only working only for 30 MHz crystals
408 if (!state
->cfg
.quartz_direct
) {
409 reg_910
|= (1 << 5); // forcing the predivider to 1
411 // if the previous front-end is baseband, its output frequency is 15 MHz (prev freq divided by 2)
412 if(state
->cfg
.input_clk_is_div_2
)
413 reg_907
|= (16 << 9);
414 else // otherwise the previous front-end puts out its input (default 30MHz) - no extra division necessary
417 reg_907
|= (bw
->pll_ratio
& 0x3f) << 9;
418 reg_910
|= (bw
->pll_prediv
<< 5);
421 dib7000m_write_word(state
, 910, reg_910
); // pll cfg
422 dib7000m_write_word(state
, 907, reg_907
); // clk cfg0
423 dib7000m_write_word(state
, 908, 0x0006); // clk_cfg1
425 dib7000m_reset_pll_common(state
, bw
);
428 static void dib7000mc_reset_pll(struct dib7000m_state
*state
)
430 const struct dibx000_bandwidth_config
*bw
= state
->cfg
.bw
;
434 dib7000m_write_word(state
, 907, (bw
->pll_prediv
<< 8) | (bw
->pll_ratio
<< 0));
437 //dib7000m_write_word(state, 908, (1 << 14) | (3 << 12) |(0 << 11) |
438 clk_cfg1
= (0 << 14) | (3 << 12) |(0 << 11) |
439 (bw
->IO_CLK_en_core
<< 10) | (bw
->bypclk_div
<< 5) | (bw
->enable_refdiv
<< 4) |
440 (1 << 3) | (bw
->pll_range
<< 1) | (bw
->pll_reset
<< 0);
441 dib7000m_write_word(state
, 908, clk_cfg1
);
442 clk_cfg1
= (clk_cfg1
& 0xfff7) | (bw
->pll_bypass
<< 3);
443 dib7000m_write_word(state
, 908, clk_cfg1
);
446 dib7000m_write_word(state
, 910, (1 << 12) | (2 << 10) | (bw
->modulo
<< 8) | (bw
->ADClkSrc
<< 7));
448 dib7000m_reset_pll_common(state
, bw
);
451 static int dib7000m_reset_gpio(struct dib7000m_state
*st
)
453 /* reset the GPIOs */
454 dib7000m_write_word(st
, 773, st
->cfg
.gpio_dir
);
455 dib7000m_write_word(st
, 774, st
->cfg
.gpio_val
);
457 /* TODO 782 is P_gpio_od */
459 dib7000m_write_word(st
, 775, st
->cfg
.gpio_pwm_pos
);
461 dib7000m_write_word(st
, 780, st
->cfg
.pwm_freq_div
);
465 static u16 dib7000m_defaults_common
[] =
468 // auto search configuration
489 0x6680, // P_corm_thres Lock algorithms configuration
492 0x0410, // P_palf_alpha_regul, P_palf_filter_freeze, P_palf_filter_on
505 8192, // P_fft_nb_to_cut
508 0x0ccd, // P_pha3_thres
509 0, // P_cti_use_cpe, P_cti_use_prog
512 0x200f, // P_cspu_regul, P_cspu_win_cut
515 0x023d, // P_adp_regul_cnt
516 0x00a4, // P_adp_noise_cnt
517 0x00a4, // P_adp_regul_ext
518 0x7ff0, // P_adp_noise_ext
522 0, // P_2d_byp_ti_num
525 0x800, // P_equal_thres_wgn
534 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
539 static u16 dib7000m_defaults
[] =
542 /* set ADC level to -16 */
544 (1 << 13) - 825 - 117,
545 (1 << 13) - 837 - 117,
546 (1 << 13) - 811 - 117,
547 (1 << 13) - 766 - 117,
548 (1 << 13) - 737 - 117,
549 (1 << 13) - 693 - 117,
550 (1 << 13) - 648 - 117,
551 (1 << 13) - 619 - 117,
552 (1 << 13) - 575 - 117,
553 (1 << 13) - 531 - 117,
554 (1 << 13) - 501 - 117,
556 // Tuner IO bank: max drive (14mA)
566 static int dib7000m_demod_reset(struct dib7000m_state
*state
)
568 dib7000m_set_power_mode(state
, DIB7000M_POWER_ALL
);
570 /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
571 dib7000m_set_adc_state(state
, DIBX000_VBG_ENABLE
);
573 /* restart all parts */
574 dib7000m_write_word(state
, 898, 0xffff);
575 dib7000m_write_word(state
, 899, 0xffff);
576 dib7000m_write_word(state
, 900, 0xff0f);
577 dib7000m_write_word(state
, 901, 0xfffc);
579 dib7000m_write_word(state
, 898, 0);
580 dib7000m_write_word(state
, 899, 0);
581 dib7000m_write_word(state
, 900, 0);
582 dib7000m_write_word(state
, 901, 0);
584 if (state
->revision
== 0x4000)
585 dib7000m_reset_pll(state
);
587 dib7000mc_reset_pll(state
);
589 if (dib7000m_reset_gpio(state
) != 0)
590 dprintk("GPIO reset was not successful.\n");
592 if (dib7000m_set_output_mode(state
, OUTMODE_HIGH_Z
) != 0)
593 dprintk("OUTPUT_MODE could not be reset.\n");
595 /* unforce divstr regardless whether i2c enumeration was done or not */
596 dib7000m_write_word(state
, 1794, dib7000m_read_word(state
, 1794) & ~(1 << 1) );
598 dib7000m_set_bandwidth(state
, 8000);
600 dib7000m_set_adc_state(state
, DIBX000_SLOW_ADC_ON
);
601 dib7000m_sad_calib(state
);
602 dib7000m_set_adc_state(state
, DIBX000_SLOW_ADC_OFF
);
604 if (state
->cfg
.dvbt_mode
)
605 dib7000m_write_word(state
, 1796, 0x0); // select DVB-T output
607 if (state
->cfg
.mobile_mode
)
608 dib7000m_write_word(state
, 261 + state
->reg_offs
, 2);
610 dib7000m_write_word(state
, 224 + state
->reg_offs
, 1);
612 // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
613 if(state
->cfg
.tuner_is_baseband
)
614 dib7000m_write_word(state
, 36, 0x0755);
616 dib7000m_write_word(state
, 36, 0x1f55);
618 // P_divclksel=3 P_divbitsel=1
619 if (state
->revision
== 0x4000)
620 dib7000m_write_word(state
, 909, (3 << 10) | (1 << 6));
622 dib7000m_write_word(state
, 909, (3 << 4) | 1);
624 dib7000m_write_tab(state
, dib7000m_defaults_common
);
625 dib7000m_write_tab(state
, dib7000m_defaults
);
627 dib7000m_set_power_mode(state
, DIB7000M_POWER_INTERFACE_ONLY
);
629 state
->internal_clk
= state
->cfg
.bw
->internal
;
634 static void dib7000m_restart_agc(struct dib7000m_state
*state
)
636 // P_restart_iqc & P_restart_agc
637 dib7000m_write_word(state
, 898, 0x0c00);
638 dib7000m_write_word(state
, 898, 0x0000);
641 static int dib7000m_agc_soft_split(struct dib7000m_state
*state
)
643 u16 agc
,split_offset
;
645 if(!state
->current_agc
|| !state
->current_agc
->perform_agc_softsplit
|| state
->current_agc
->split
.max
== 0)
649 agc
= dib7000m_read_word(state
, 390);
651 if (agc
> state
->current_agc
->split
.min_thres
)
652 split_offset
= state
->current_agc
->split
.min
;
653 else if (agc
< state
->current_agc
->split
.max_thres
)
654 split_offset
= state
->current_agc
->split
.max
;
656 split_offset
= state
->current_agc
->split
.max
*
657 (agc
- state
->current_agc
->split
.min_thres
) /
658 (state
->current_agc
->split
.max_thres
- state
->current_agc
->split
.min_thres
);
660 dprintk("AGC split_offset: %d\n", split_offset
);
662 // P_agc_force_split and P_agc_split_offset
663 return dib7000m_write_word(state
, 103, (dib7000m_read_word(state
, 103) & 0xff00) | split_offset
);
666 static int dib7000m_update_lna(struct dib7000m_state
*state
)
670 if (state
->cfg
.update_lna
) {
671 // read dyn_gain here (because it is demod-dependent and not fe)
672 dyn_gain
= dib7000m_read_word(state
, 390);
674 if (state
->cfg
.update_lna(&state
->demod
,dyn_gain
)) { // LNA has changed
675 dib7000m_restart_agc(state
);
682 static int dib7000m_set_agc_config(struct dib7000m_state
*state
, u8 band
)
684 struct dibx000_agc_config
*agc
= NULL
;
686 if (state
->current_band
== band
&& state
->current_agc
!= NULL
)
688 state
->current_band
= band
;
690 for (i
= 0; i
< state
->cfg
.agc_config_count
; i
++)
691 if (state
->cfg
.agc
[i
].band_caps
& band
) {
692 agc
= &state
->cfg
.agc
[i
];
697 dprintk("no valid AGC configuration found for band 0x%02x\n", band
);
701 state
->current_agc
= agc
;
704 dib7000m_write_word(state
, 72 , agc
->setup
);
705 dib7000m_write_word(state
, 73 , agc
->inv_gain
);
706 dib7000m_write_word(state
, 74 , agc
->time_stabiliz
);
707 dib7000m_write_word(state
, 97 , (agc
->alpha_level
<< 12) | agc
->thlock
);
709 // Demod AGC loop configuration
710 dib7000m_write_word(state
, 98, (agc
->alpha_mant
<< 5) | agc
->alpha_exp
);
711 dib7000m_write_word(state
, 99, (agc
->beta_mant
<< 6) | agc
->beta_exp
);
713 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d\n",
714 state
->wbd_ref
!= 0 ? state
->wbd_ref
: agc
->wbd_ref
, agc
->wbd_sel
, !agc
->perform_agc_softsplit
, agc
->wbd_sel
);
717 if (state
->wbd_ref
!= 0)
718 dib7000m_write_word(state
, 102, state
->wbd_ref
);
720 dib7000m_write_word(state
, 102, agc
->wbd_ref
);
722 dib7000m_write_word(state
, 103, (agc
->wbd_alpha
<< 9) | (agc
->perform_agc_softsplit
<< 8) );
723 dib7000m_write_word(state
, 104, agc
->agc1_max
);
724 dib7000m_write_word(state
, 105, agc
->agc1_min
);
725 dib7000m_write_word(state
, 106, agc
->agc2_max
);
726 dib7000m_write_word(state
, 107, agc
->agc2_min
);
727 dib7000m_write_word(state
, 108, (agc
->agc1_pt1
<< 8) | agc
->agc1_pt2
);
728 dib7000m_write_word(state
, 109, (agc
->agc1_slope1
<< 8) | agc
->agc1_slope2
);
729 dib7000m_write_word(state
, 110, (agc
->agc2_pt1
<< 8) | agc
->agc2_pt2
);
730 dib7000m_write_word(state
, 111, (agc
->agc2_slope1
<< 8) | agc
->agc2_slope2
);
732 if (state
->revision
> 0x4000) { // settings for the MC
733 dib7000m_write_word(state
, 71, agc
->agc1_pt3
);
734 // dprintk("929: %x %d %d\n",
735 // (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2), agc->wbd_inv, agc->wbd_sel);
736 dib7000m_write_word(state
, 929, (dib7000m_read_word(state
, 929) & 0xffe3) | (agc
->wbd_inv
<< 4) | (agc
->wbd_sel
<< 2));
738 // wrong default values
739 u16 b
[9] = { 676, 696, 717, 737, 758, 778, 799, 819, 840 };
740 for (i
= 0; i
< 9; i
++)
741 dib7000m_write_word(state
, 88 + i
, b
[i
]);
746 static void dib7000m_update_timf(struct dib7000m_state
*state
)
748 u32 timf
= (dib7000m_read_word(state
, 436) << 16) | dib7000m_read_word(state
, 437);
749 state
->timf
= timf
* 160 / (state
->current_bandwidth
/ 50);
750 dib7000m_write_word(state
, 23, (u16
) (timf
>> 16));
751 dib7000m_write_word(state
, 24, (u16
) (timf
& 0xffff));
752 dprintk("updated timf_frequency: %d (default: %d)\n", state
->timf
, state
->timf_default
);
755 static int dib7000m_agc_startup(struct dvb_frontend
*demod
)
757 struct dtv_frontend_properties
*ch
= &demod
->dtv_property_cache
;
758 struct dib7000m_state
*state
= demod
->demodulator_priv
;
759 u16 cfg_72
= dib7000m_read_word(state
, 72);
761 u8
*agc_state
= &state
->agc_state
;
764 switch (state
->agc_state
) {
766 // set power-up level: interf+analog+AGC
767 dib7000m_set_power_mode(state
, DIB7000M_POWER_INTERF_ANALOG_AGC
);
768 dib7000m_set_adc_state(state
, DIBX000_ADC_ON
);
770 if (dib7000m_set_agc_config(state
, BAND_OF_FREQUENCY(ch
->frequency
/1000)) != 0)
773 ret
= 7; /* ADC power up */
778 /* AGC initialization */
779 if (state
->cfg
.agc_control
)
780 state
->cfg
.agc_control(&state
->demod
, 1);
782 dib7000m_write_word(state
, 75, 32768);
783 if (!state
->current_agc
->perform_agc_softsplit
) {
784 /* we are using the wbd - so slow AGC startup */
785 dib7000m_write_word(state
, 103, 1 << 8); /* force 0 split on WBD and restart AGC */
789 /* default AGC startup */
791 /* wait AGC rough lock time */
795 dib7000m_restart_agc(state
);
798 case 2: /* fast split search path after 5sec */
799 dib7000m_write_word(state
, 72, cfg_72
| (1 << 4)); /* freeze AGC loop */
800 dib7000m_write_word(state
, 103, 2 << 9); /* fast split search 0.25kHz */
805 case 3: /* split search ended */
806 agc_split
= (u8
)dib7000m_read_word(state
, 392); /* store the split value for the next time */
807 dib7000m_write_word(state
, 75, dib7000m_read_word(state
, 390)); /* set AGC gain start value */
809 dib7000m_write_word(state
, 72, cfg_72
& ~(1 << 4)); /* std AGC loop */
810 dib7000m_write_word(state
, 103, (state
->current_agc
->wbd_alpha
<< 9) | agc_split
); /* standard split search */
812 dib7000m_restart_agc(state
);
814 dprintk("SPLIT %p: %hd\n", demod
, agc_split
);
820 case 4: /* LNA startup */
821 /* wait AGC accurate lock time */
824 if (dib7000m_update_lna(state
))
825 // wait only AGC rough lock time
832 dib7000m_agc_soft_split(state
);
834 if (state
->cfg
.agc_control
)
835 state
->cfg
.agc_control(&state
->demod
, 0);
846 static void dib7000m_set_channel(struct dib7000m_state
*state
, struct dtv_frontend_properties
*ch
,
851 dib7000m_set_bandwidth(state
, BANDWIDTH_TO_KHZ(ch
->bandwidth_hz
));
853 /* nfft, guard, qam, alpha */
855 switch (ch
->transmission_mode
) {
856 case TRANSMISSION_MODE_2K
: value
|= (0 << 7); break;
857 case TRANSMISSION_MODE_4K
: value
|= (2 << 7); break;
859 case TRANSMISSION_MODE_8K
: value
|= (1 << 7); break;
861 switch (ch
->guard_interval
) {
862 case GUARD_INTERVAL_1_32
: value
|= (0 << 5); break;
863 case GUARD_INTERVAL_1_16
: value
|= (1 << 5); break;
864 case GUARD_INTERVAL_1_4
: value
|= (3 << 5); break;
866 case GUARD_INTERVAL_1_8
: value
|= (2 << 5); break;
868 switch (ch
->modulation
) {
869 case QPSK
: value
|= (0 << 3); break;
870 case QAM_16
: value
|= (1 << 3); break;
872 case QAM_64
: value
|= (2 << 3); break;
874 switch (HIERARCHY_1
) {
875 case HIERARCHY_2
: value
|= 2; break;
876 case HIERARCHY_4
: value
|= 4; break;
878 case HIERARCHY_1
: value
|= 1; break;
880 dib7000m_write_word(state
, 0, value
);
881 dib7000m_write_word(state
, 5, (seq
<< 4));
883 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
887 if (ch
->hierarchy
== 1)
891 switch ((ch
->hierarchy
== 0 || 1 == 1) ? ch
->code_rate_HP
: ch
->code_rate_LP
) {
892 case FEC_2_3
: value
|= (2 << 1); break;
893 case FEC_3_4
: value
|= (3 << 1); break;
894 case FEC_5_6
: value
|= (5 << 1); break;
895 case FEC_7_8
: value
|= (7 << 1); break;
897 case FEC_1_2
: value
|= (1 << 1); break;
899 dib7000m_write_word(state
, 267 + state
->reg_offs
, value
);
901 /* offset loop parameters */
903 /* P_timf_alpha = 6, P_corm_alpha=6, P_corm_thres=0x80 */
904 dib7000m_write_word(state
, 26, (6 << 12) | (6 << 8) | 0x80);
906 /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=1, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */
907 dib7000m_write_word(state
, 29, (0 << 14) | (4 << 10) | (1 << 9) | (3 << 5) | (1 << 4) | (0x3));
909 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max=3 */
910 dib7000m_write_word(state
, 32, (0 << 4) | 0x3);
912 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step=5 */
913 dib7000m_write_word(state
, 33, (0 << 4) | 0x5);
915 /* P_dvsy_sync_wait */
916 switch (ch
->transmission_mode
) {
917 case TRANSMISSION_MODE_8K
: value
= 256; break;
918 case TRANSMISSION_MODE_4K
: value
= 128; break;
919 case TRANSMISSION_MODE_2K
:
920 default: value
= 64; break;
922 switch (ch
->guard_interval
) {
923 case GUARD_INTERVAL_1_16
: value
*= 2; break;
924 case GUARD_INTERVAL_1_8
: value
*= 4; break;
925 case GUARD_INTERVAL_1_4
: value
*= 8; break;
927 case GUARD_INTERVAL_1_32
: value
*= 1; break;
929 state
->div_sync_wait
= (value
* 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO
931 /* deactive the possibility of diversity reception if extended interleave - not for 7000MC */
932 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
933 if (1 == 1 || state
->revision
> 0x4000)
934 state
->div_force_off
= 0;
936 state
->div_force_off
= 1;
937 dib7000m_set_diversity_in(&state
->demod
, state
->div_state
);
939 /* channel estimation fine configuration */
940 switch (ch
->modulation
) {
942 est
[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
943 est
[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
944 est
[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
945 est
[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
948 est
[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
949 est
[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
950 est
[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
951 est
[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
954 est
[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
955 est
[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
956 est
[2] = 0x0333; /* P_adp_regul_ext 0.1 */
957 est
[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
960 for (value
= 0; value
< 4; value
++)
961 dib7000m_write_word(state
, 214 + value
+ state
->reg_offs
, est
[value
]);
963 // set power-up level: autosearch
964 dib7000m_set_power_mode(state
, DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD
);
967 static int dib7000m_autosearch_start(struct dvb_frontend
*demod
)
969 struct dtv_frontend_properties
*ch
= &demod
->dtv_property_cache
;
970 struct dib7000m_state
*state
= demod
->demodulator_priv
;
971 struct dtv_frontend_properties schan
;
977 schan
.modulation
= QAM_64
;
978 schan
.guard_interval
= GUARD_INTERVAL_1_32
;
979 schan
.transmission_mode
= TRANSMISSION_MODE_8K
;
980 schan
.code_rate_HP
= FEC_2_3
;
981 schan
.code_rate_LP
= FEC_3_4
;
984 dib7000m_set_channel(state
, &schan
, 7);
986 factor
= BANDWIDTH_TO_KHZ(schan
.bandwidth_hz
);
992 // always use the setting for 8MHz here lock_time for 7,6 MHz are longer
993 value
= 30 * state
->internal_clk
* factor
;
994 ret
|= dib7000m_write_word(state
, 6, (u16
) ((value
>> 16) & 0xffff)); // lock0 wait time
995 ret
|= dib7000m_write_word(state
, 7, (u16
) (value
& 0xffff)); // lock0 wait time
996 value
= 100 * state
->internal_clk
* factor
;
997 ret
|= dib7000m_write_word(state
, 8, (u16
) ((value
>> 16) & 0xffff)); // lock1 wait time
998 ret
|= dib7000m_write_word(state
, 9, (u16
) (value
& 0xffff)); // lock1 wait time
999 value
= 500 * state
->internal_clk
* factor
;
1000 ret
|= dib7000m_write_word(state
, 10, (u16
) ((value
>> 16) & 0xffff)); // lock2 wait time
1001 ret
|= dib7000m_write_word(state
, 11, (u16
) (value
& 0xffff)); // lock2 wait time
1004 value
= dib7000m_read_word(state
, 0);
1005 ret
|= dib7000m_write_word(state
, 0, (u16
) (value
| (1 << 9)));
1007 /* clear n_irq_pending */
1008 if (state
->revision
== 0x4000)
1009 dib7000m_write_word(state
, 1793, 0);
1011 dib7000m_read_word(state
, 537);
1013 ret
|= dib7000m_write_word(state
, 0, (u16
) value
);
1018 static int dib7000m_autosearch_irq(struct dib7000m_state
*state
, u16 reg
)
1020 u16 irq_pending
= dib7000m_read_word(state
, reg
);
1022 if (irq_pending
& 0x1) { // failed
1023 dprintk("autosearch failed\n");
1027 if (irq_pending
& 0x2) { // succeeded
1028 dprintk("autosearch succeeded\n");
1031 return 0; // still pending
1034 static int dib7000m_autosearch_is_irq(struct dvb_frontend
*demod
)
1036 struct dib7000m_state
*state
= demod
->demodulator_priv
;
1037 if (state
->revision
== 0x4000)
1038 return dib7000m_autosearch_irq(state
, 1793);
1040 return dib7000m_autosearch_irq(state
, 537);
1043 static int dib7000m_tune(struct dvb_frontend
*demod
)
1045 struct dtv_frontend_properties
*ch
= &demod
->dtv_property_cache
;
1046 struct dib7000m_state
*state
= demod
->demodulator_priv
;
1050 // we are already tuned - just resuming from suspend
1051 dib7000m_set_channel(state
, ch
, 0);
1054 ret
|= dib7000m_write_word(state
, 898, 0x4000);
1055 ret
|= dib7000m_write_word(state
, 898, 0x0000);
1058 dib7000m_set_power_mode(state
, DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD
);
1059 /* 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 */
1060 ret
|= dib7000m_write_word(state
, 29, (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3));
1062 // never achieved a lock before - wait for timfreq to update
1063 if (state
->timf
== 0)
1067 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
1068 value
= (6 << 8) | 0x80;
1069 switch (ch
->transmission_mode
) {
1070 case TRANSMISSION_MODE_2K
: value
|= (7 << 12); break;
1071 case TRANSMISSION_MODE_4K
: value
|= (8 << 12); break;
1073 case TRANSMISSION_MODE_8K
: value
|= (9 << 12); break;
1075 ret
|= dib7000m_write_word(state
, 26, value
);
1077 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1079 switch (ch
->transmission_mode
) {
1080 case TRANSMISSION_MODE_2K
: value
|= 0x6; break;
1081 case TRANSMISSION_MODE_4K
: value
|= 0x7; break;
1083 case TRANSMISSION_MODE_8K
: value
|= 0x8; break;
1085 ret
|= dib7000m_write_word(state
, 32, value
);
1087 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1089 switch (ch
->transmission_mode
) {
1090 case TRANSMISSION_MODE_2K
: value
|= 0x6; break;
1091 case TRANSMISSION_MODE_4K
: value
|= 0x7; break;
1093 case TRANSMISSION_MODE_8K
: value
|= 0x8; break;
1095 ret
|= dib7000m_write_word(state
, 33, value
);
1097 // we achieved a lock - it's time to update the timf freq
1098 if ((dib7000m_read_word(state
, 535) >> 6) & 0x1)
1099 dib7000m_update_timf(state
);
1101 dib7000m_set_bandwidth(state
, BANDWIDTH_TO_KHZ(ch
->bandwidth_hz
));
1105 static int dib7000m_wakeup(struct dvb_frontend
*demod
)
1107 struct dib7000m_state
*state
= demod
->demodulator_priv
;
1109 dib7000m_set_power_mode(state
, DIB7000M_POWER_ALL
);
1111 if (dib7000m_set_adc_state(state
, DIBX000_SLOW_ADC_ON
) != 0)
1112 dprintk("could not start Slow ADC\n");
1117 static int dib7000m_sleep(struct dvb_frontend
*demod
)
1119 struct dib7000m_state
*st
= demod
->demodulator_priv
;
1120 dib7000m_set_output_mode(st
, OUTMODE_HIGH_Z
);
1121 dib7000m_set_power_mode(st
, DIB7000M_POWER_INTERFACE_ONLY
);
1122 return dib7000m_set_adc_state(st
, DIBX000_SLOW_ADC_OFF
) |
1123 dib7000m_set_adc_state(st
, DIBX000_ADC_OFF
);
1126 static int dib7000m_identify(struct dib7000m_state
*state
)
1130 if ((value
= dib7000m_read_word(state
, 896)) != 0x01b3) {
1131 dprintk("wrong Vendor ID (0x%x)\n", value
);
1135 state
->revision
= dib7000m_read_word(state
, 897);
1136 if (state
->revision
!= 0x4000 &&
1137 state
->revision
!= 0x4001 &&
1138 state
->revision
!= 0x4002 &&
1139 state
->revision
!= 0x4003) {
1140 dprintk("wrong Device ID (0x%x)\n", value
);
1144 /* protect this driver to be used with 7000PC */
1145 if (state
->revision
== 0x4000 && dib7000m_read_word(state
, 769) == 0x4000) {
1146 dprintk("this driver does not work with DiB7000PC\n");
1150 switch (state
->revision
) {
1151 case 0x4000: dprintk("found DiB7000MA/PA/MB/PB\n"); break;
1152 case 0x4001: state
->reg_offs
= 1; dprintk("found DiB7000HC\n"); break;
1153 case 0x4002: state
->reg_offs
= 1; dprintk("found DiB7000MC\n"); break;
1154 case 0x4003: state
->reg_offs
= 1; dprintk("found DiB9000\n"); break;
1161 static int dib7000m_get_frontend(struct dvb_frontend
* fe
,
1162 struct dtv_frontend_properties
*fep
)
1164 struct dib7000m_state
*state
= fe
->demodulator_priv
;
1165 u16 tps
= dib7000m_read_word(state
,480);
1167 fep
->inversion
= INVERSION_AUTO
;
1169 fep
->bandwidth_hz
= BANDWIDTH_TO_HZ(state
->current_bandwidth
);
1171 switch ((tps
>> 8) & 0x3) {
1172 case 0: fep
->transmission_mode
= TRANSMISSION_MODE_2K
; break;
1173 case 1: fep
->transmission_mode
= TRANSMISSION_MODE_8K
; break;
1174 /* case 2: fep->transmission_mode = TRANSMISSION_MODE_4K; break; */
1177 switch (tps
& 0x3) {
1178 case 0: fep
->guard_interval
= GUARD_INTERVAL_1_32
; break;
1179 case 1: fep
->guard_interval
= GUARD_INTERVAL_1_16
; break;
1180 case 2: fep
->guard_interval
= GUARD_INTERVAL_1_8
; break;
1181 case 3: fep
->guard_interval
= GUARD_INTERVAL_1_4
; break;
1184 switch ((tps
>> 14) & 0x3) {
1185 case 0: fep
->modulation
= QPSK
; break;
1186 case 1: fep
->modulation
= QAM_16
; break;
1188 default: fep
->modulation
= QAM_64
; break;
1191 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1192 /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1194 fep
->hierarchy
= HIERARCHY_NONE
;
1195 switch ((tps
>> 5) & 0x7) {
1196 case 1: fep
->code_rate_HP
= FEC_1_2
; break;
1197 case 2: fep
->code_rate_HP
= FEC_2_3
; break;
1198 case 3: fep
->code_rate_HP
= FEC_3_4
; break;
1199 case 5: fep
->code_rate_HP
= FEC_5_6
; break;
1201 default: fep
->code_rate_HP
= FEC_7_8
; break;
1205 switch ((tps
>> 2) & 0x7) {
1206 case 1: fep
->code_rate_LP
= FEC_1_2
; break;
1207 case 2: fep
->code_rate_LP
= FEC_2_3
; break;
1208 case 3: fep
->code_rate_LP
= FEC_3_4
; break;
1209 case 5: fep
->code_rate_LP
= FEC_5_6
; break;
1211 default: fep
->code_rate_LP
= FEC_7_8
; break;
1214 /* native interleaver: (dib7000m_read_word(state, 481) >> 5) & 0x1 */
1219 static int dib7000m_set_frontend(struct dvb_frontend
*fe
)
1221 struct dtv_frontend_properties
*fep
= &fe
->dtv_property_cache
;
1222 struct dib7000m_state
*state
= fe
->demodulator_priv
;
1225 dib7000m_set_output_mode(state
, OUTMODE_HIGH_Z
);
1227 dib7000m_set_bandwidth(state
, BANDWIDTH_TO_KHZ(fep
->bandwidth_hz
));
1229 if (fe
->ops
.tuner_ops
.set_params
)
1230 fe
->ops
.tuner_ops
.set_params(fe
);
1232 /* start up the AGC */
1233 state
->agc_state
= 0;
1235 time
= dib7000m_agc_startup(fe
);
1238 } while (time
!= -1);
1240 if (fep
->transmission_mode
== TRANSMISSION_MODE_AUTO
||
1241 fep
->guard_interval
== GUARD_INTERVAL_AUTO
||
1242 fep
->modulation
== QAM_AUTO
||
1243 fep
->code_rate_HP
== FEC_AUTO
) {
1246 dib7000m_autosearch_start(fe
);
1249 found
= dib7000m_autosearch_is_irq(fe
);
1250 } while (found
== 0 && i
--);
1252 dprintk("autosearch returns: %d\n", found
);
1253 if (found
== 0 || found
== 1)
1254 return 0; // no channel found
1256 dib7000m_get_frontend(fe
, fep
);
1259 ret
= dib7000m_tune(fe
);
1261 /* make this a config parameter */
1262 dib7000m_set_output_mode(state
, OUTMODE_MPEG2_FIFO
);
1266 static int dib7000m_read_status(struct dvb_frontend
*fe
, enum fe_status
*stat
)
1268 struct dib7000m_state
*state
= fe
->demodulator_priv
;
1269 u16 lock
= dib7000m_read_word(state
, 535);
1274 *stat
|= FE_HAS_SIGNAL
;
1276 *stat
|= FE_HAS_CARRIER
;
1278 *stat
|= FE_HAS_VITERBI
;
1280 *stat
|= FE_HAS_SYNC
;
1282 *stat
|= FE_HAS_LOCK
;
1287 static int dib7000m_read_ber(struct dvb_frontend
*fe
, u32
*ber
)
1289 struct dib7000m_state
*state
= fe
->demodulator_priv
;
1290 *ber
= (dib7000m_read_word(state
, 526) << 16) | dib7000m_read_word(state
, 527);
1294 static int dib7000m_read_unc_blocks(struct dvb_frontend
*fe
, u32
*unc
)
1296 struct dib7000m_state
*state
= fe
->demodulator_priv
;
1297 *unc
= dib7000m_read_word(state
, 534);
1301 static int dib7000m_read_signal_strength(struct dvb_frontend
*fe
, u16
*strength
)
1303 struct dib7000m_state
*state
= fe
->demodulator_priv
;
1304 u16 val
= dib7000m_read_word(state
, 390);
1305 *strength
= 65535 - val
;
1309 static int dib7000m_read_snr(struct dvb_frontend
* fe
, u16
*snr
)
1315 static int dib7000m_fe_get_tune_settings(struct dvb_frontend
* fe
, struct dvb_frontend_tune_settings
*tune
)
1317 tune
->min_delay_ms
= 1000;
1321 static void dib7000m_release(struct dvb_frontend
*demod
)
1323 struct dib7000m_state
*st
= demod
->demodulator_priv
;
1324 dibx000_exit_i2c_master(&st
->i2c_master
);
1328 struct i2c_adapter
* dib7000m_get_i2c_master(struct dvb_frontend
*demod
, enum dibx000_i2c_interface intf
, int gating
)
1330 struct dib7000m_state
*st
= demod
->demodulator_priv
;
1331 return dibx000_get_i2c_adapter(&st
->i2c_master
, intf
, gating
);
1333 EXPORT_SYMBOL(dib7000m_get_i2c_master
);
1335 int dib7000m_pid_filter_ctrl(struct dvb_frontend
*fe
, u8 onoff
)
1337 struct dib7000m_state
*state
= fe
->demodulator_priv
;
1338 u16 val
= dib7000m_read_word(state
, 294 + state
->reg_offs
) & 0xffef;
1339 val
|= (onoff
& 0x1) << 4;
1340 dprintk("PID filter enabled %d\n", onoff
);
1341 return dib7000m_write_word(state
, 294 + state
->reg_offs
, val
);
1343 EXPORT_SYMBOL(dib7000m_pid_filter_ctrl
);
1345 int dib7000m_pid_filter(struct dvb_frontend
*fe
, u8 id
, u16 pid
, u8 onoff
)
1347 struct dib7000m_state
*state
= fe
->demodulator_priv
;
1348 dprintk("PID filter: index %x, PID %d, OnOff %d\n", id
, pid
, onoff
);
1349 return dib7000m_write_word(state
, 300 + state
->reg_offs
+ id
,
1350 onoff
? (1 << 13) | pid
: 0);
1352 EXPORT_SYMBOL(dib7000m_pid_filter
);
1355 /* used with some prototype boards */
1356 int dib7000m_i2c_enumeration(struct i2c_adapter
*i2c
, int no_of_demods
,
1357 u8 default_addr
, struct dib7000m_config cfg
[])
1359 struct dib7000m_state st
= { .i2c_adap
= i2c
};
1363 for (k
= no_of_demods
-1; k
>= 0; k
--) {
1366 /* designated i2c address */
1367 new_addr
= (0x40 + k
) << 1;
1368 st
.i2c_addr
= new_addr
;
1369 if (dib7000m_identify(&st
) != 0) {
1370 st
.i2c_addr
= default_addr
;
1371 if (dib7000m_identify(&st
) != 0) {
1372 dprintk("DiB7000M #%d: not identified\n", k
);
1377 /* start diversity to pull_down div_str - just for i2c-enumeration */
1378 dib7000m_set_output_mode(&st
, OUTMODE_DIVERSITY
);
1380 dib7000m_write_word(&st
, 1796, 0x0); // select DVB-T output
1382 /* set new i2c address and force divstart */
1383 dib7000m_write_word(&st
, 1794, (new_addr
<< 2) | 0x2);
1385 dprintk("IC %d initialized (to i2c_address 0x%x)\n", k
, new_addr
);
1388 for (k
= 0; k
< no_of_demods
; k
++) {
1390 st
.i2c_addr
= (0x40 + k
) << 1;
1393 dib7000m_write_word(&st
,1794, st
.i2c_addr
<< 2);
1395 /* deactivate div - it was just for i2c-enumeration */
1396 dib7000m_set_output_mode(&st
, OUTMODE_HIGH_Z
);
1401 EXPORT_SYMBOL(dib7000m_i2c_enumeration
);
1404 static const struct dvb_frontend_ops dib7000m_ops
;
1405 struct dvb_frontend
* dib7000m_attach(struct i2c_adapter
*i2c_adap
, u8 i2c_addr
, struct dib7000m_config
*cfg
)
1407 struct dvb_frontend
*demod
;
1408 struct dib7000m_state
*st
;
1409 st
= kzalloc(sizeof(struct dib7000m_state
), GFP_KERNEL
);
1413 memcpy(&st
->cfg
, cfg
, sizeof(struct dib7000m_config
));
1414 st
->i2c_adap
= i2c_adap
;
1415 st
->i2c_addr
= i2c_addr
;
1418 demod
->demodulator_priv
= st
;
1419 memcpy(&st
->demod
.ops
, &dib7000m_ops
, sizeof(struct dvb_frontend_ops
));
1420 mutex_init(&st
->i2c_buffer_lock
);
1422 st
->timf_default
= cfg
->bw
->timf
;
1424 if (dib7000m_identify(st
) != 0)
1427 if (st
->revision
== 0x4000)
1428 dibx000_init_i2c_master(&st
->i2c_master
, DIB7000
, st
->i2c_adap
, st
->i2c_addr
);
1430 dibx000_init_i2c_master(&st
->i2c_master
, DIB7000MC
, st
->i2c_adap
, st
->i2c_addr
);
1432 dib7000m_demod_reset(st
);
1440 EXPORT_SYMBOL(dib7000m_attach
);
1442 static const struct dvb_frontend_ops dib7000m_ops
= {
1443 .delsys
= { SYS_DVBT
},
1445 .name
= "DiBcom 7000MA/MB/PA/PB/MC",
1446 .frequency_min
= 44250000,
1447 .frequency_max
= 867250000,
1448 .frequency_stepsize
= 62500,
1449 .caps
= FE_CAN_INVERSION_AUTO
|
1450 FE_CAN_FEC_1_2
| FE_CAN_FEC_2_3
| FE_CAN_FEC_3_4
|
1451 FE_CAN_FEC_5_6
| FE_CAN_FEC_7_8
| FE_CAN_FEC_AUTO
|
1452 FE_CAN_QPSK
| FE_CAN_QAM_16
| FE_CAN_QAM_64
| FE_CAN_QAM_AUTO
|
1453 FE_CAN_TRANSMISSION_MODE_AUTO
|
1454 FE_CAN_GUARD_INTERVAL_AUTO
|
1456 FE_CAN_HIERARCHY_AUTO
,
1459 .release
= dib7000m_release
,
1461 .init
= dib7000m_wakeup
,
1462 .sleep
= dib7000m_sleep
,
1464 .set_frontend
= dib7000m_set_frontend
,
1465 .get_tune_settings
= dib7000m_fe_get_tune_settings
,
1466 .get_frontend
= dib7000m_get_frontend
,
1468 .read_status
= dib7000m_read_status
,
1469 .read_ber
= dib7000m_read_ber
,
1470 .read_signal_strength
= dib7000m_read_signal_strength
,
1471 .read_snr
= dib7000m_read_snr
,
1472 .read_ucblocks
= dib7000m_read_unc_blocks
,
1475 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
1476 MODULE_DESCRIPTION("Driver for the DiBcom 7000MA/MB/PA/PB/MC COFDM demodulator");
1477 MODULE_LICENSE("GPL");