1 // SPDX-License-Identifier: GPL-2.0-only
3 * Linux-DVB Driver for DiBcom's second generation DiB7000P (PC).
5 * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10 #include <linux/kernel.h>
11 #include <linux/slab.h>
12 #include <linux/i2c.h>
13 #include <linux/mutex.h>
14 #include <asm/div64.h>
16 #include <linux/int_log.h>
17 #include <media/dvb_frontend.h>
22 module_param(debug
, int, 0644);
23 MODULE_PARM_DESC(debug
, "turn on debugging (default: 0)");
25 static int buggy_sfn_workaround
;
26 module_param(buggy_sfn_workaround
, int, 0644);
27 MODULE_PARM_DESC(buggy_sfn_workaround
, "Enable work-around for buggy SFNs (default: 0)");
29 #define dprintk(fmt, arg...) do { \
31 printk(KERN_DEBUG pr_fmt("%s: " fmt), \
35 struct dib7000p_state
{
36 struct dvb_frontend demod
;
37 struct dib7000p_config cfg
;
40 struct i2c_adapter
*i2c_adap
;
42 struct dibx000_i2c_master i2c_master
;
47 u32 current_bandwidth
;
48 struct dibx000_agc_config
*current_agc
;
60 u8 sfn_workaround_active
:1;
62 #define SOC7090 0x7090
66 struct i2c_adapter dib7090_tuner_adap
;
68 /* for the I2C transfer */
69 struct i2c_msg msg
[2];
70 u8 i2c_write_buffer
[4];
71 u8 i2c_read_buffer
[2];
72 struct mutex i2c_buffer_lock
;
78 unsigned long per_jiffies_stats
;
79 unsigned long ber_jiffies_stats
;
80 unsigned long get_stats_time
;
83 enum dib7000p_power_mode
{
84 DIB7000P_POWER_ALL
= 0,
85 DIB7000P_POWER_ANALOG_ADC
,
86 DIB7000P_POWER_INTERFACE_ONLY
,
89 /* dib7090 specific functions */
90 static int dib7090_set_output_mode(struct dvb_frontend
*fe
, int mode
);
91 static int dib7090_set_diversity_in(struct dvb_frontend
*fe
, int onoff
);
92 static void dib7090_setDibTxMux(struct dib7000p_state
*state
, int mode
);
93 static void dib7090_setHostBusMux(struct dib7000p_state
*state
, int mode
);
95 static u16
dib7000p_read_word(struct dib7000p_state
*state
, u16 reg
)
99 if (mutex_lock_interruptible(&state
->i2c_buffer_lock
) < 0) {
100 dprintk("could not acquire lock\n");
104 state
->i2c_write_buffer
[0] = reg
>> 8;
105 state
->i2c_write_buffer
[1] = reg
& 0xff;
107 memset(state
->msg
, 0, 2 * sizeof(struct i2c_msg
));
108 state
->msg
[0].addr
= state
->i2c_addr
>> 1;
109 state
->msg
[0].flags
= 0;
110 state
->msg
[0].buf
= state
->i2c_write_buffer
;
111 state
->msg
[0].len
= 2;
112 state
->msg
[1].addr
= state
->i2c_addr
>> 1;
113 state
->msg
[1].flags
= I2C_M_RD
;
114 state
->msg
[1].buf
= state
->i2c_read_buffer
;
115 state
->msg
[1].len
= 2;
117 if (i2c_transfer(state
->i2c_adap
, state
->msg
, 2) != 2)
118 dprintk("i2c read error on %d\n", reg
);
120 ret
= (state
->i2c_read_buffer
[0] << 8) | state
->i2c_read_buffer
[1];
121 mutex_unlock(&state
->i2c_buffer_lock
);
125 static int dib7000p_write_word(struct dib7000p_state
*state
, u16 reg
, u16 val
)
129 if (mutex_lock_interruptible(&state
->i2c_buffer_lock
) < 0) {
130 dprintk("could not acquire lock\n");
134 state
->i2c_write_buffer
[0] = (reg
>> 8) & 0xff;
135 state
->i2c_write_buffer
[1] = reg
& 0xff;
136 state
->i2c_write_buffer
[2] = (val
>> 8) & 0xff;
137 state
->i2c_write_buffer
[3] = val
& 0xff;
139 memset(&state
->msg
[0], 0, sizeof(struct i2c_msg
));
140 state
->msg
[0].addr
= state
->i2c_addr
>> 1;
141 state
->msg
[0].flags
= 0;
142 state
->msg
[0].buf
= state
->i2c_write_buffer
;
143 state
->msg
[0].len
= 4;
145 ret
= (i2c_transfer(state
->i2c_adap
, state
->msg
, 1) != 1 ?
147 mutex_unlock(&state
->i2c_buffer_lock
);
151 static void dib7000p_write_tab(struct dib7000p_state
*state
, u16
* buf
)
160 dib7000p_write_word(state
, r
, *n
++);
167 static int dib7000p_set_output_mode(struct dib7000p_state
*state
, int mode
)
170 u16 outreg
, fifo_threshold
, smo_mode
;
173 fifo_threshold
= 1792;
174 smo_mode
= (dib7000p_read_word(state
, 235) & 0x0050) | (1 << 1);
176 dprintk("setting output mode for demod %p to %d\n", &state
->demod
, mode
);
179 case OUTMODE_MPEG2_PAR_GATED_CLK
:
180 outreg
= (1 << 10); /* 0x0400 */
182 case OUTMODE_MPEG2_PAR_CONT_CLK
:
183 outreg
= (1 << 10) | (1 << 6); /* 0x0440 */
185 case OUTMODE_MPEG2_SERIAL
:
186 outreg
= (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */
188 case OUTMODE_DIVERSITY
:
189 if (state
->cfg
.hostbus_diversity
)
190 outreg
= (1 << 10) | (4 << 6); /* 0x0500 */
194 case OUTMODE_MPEG2_FIFO
:
195 smo_mode
|= (3 << 1);
196 fifo_threshold
= 512;
197 outreg
= (1 << 10) | (5 << 6);
199 case OUTMODE_ANALOG_ADC
:
200 outreg
= (1 << 10) | (3 << 6);
206 dprintk("Unhandled output_mode passed to be set for demod %p\n", &state
->demod
);
210 if (state
->cfg
.output_mpeg2_in_188_bytes
)
211 smo_mode
|= (1 << 5);
213 ret
|= dib7000p_write_word(state
, 235, smo_mode
);
214 ret
|= dib7000p_write_word(state
, 236, fifo_threshold
); /* synchronous fread */
215 if (state
->version
!= SOC7090
)
216 ret
|= dib7000p_write_word(state
, 1286, outreg
); /* P_Div_active */
221 static int dib7000p_set_diversity_in(struct dvb_frontend
*demod
, int onoff
)
223 struct dib7000p_state
*state
= demod
->demodulator_priv
;
225 if (state
->div_force_off
) {
226 dprintk("diversity combination deactivated - forced by COFDM parameters\n");
228 dib7000p_write_word(state
, 207, 0);
230 dib7000p_write_word(state
, 207, (state
->div_sync_wait
<< 4) | (1 << 2) | (2 << 0));
232 state
->div_state
= (u8
) onoff
;
235 dib7000p_write_word(state
, 204, 6);
236 dib7000p_write_word(state
, 205, 16);
237 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
239 dib7000p_write_word(state
, 204, 1);
240 dib7000p_write_word(state
, 205, 0);
246 static int dib7000p_set_power_mode(struct dib7000p_state
*state
, enum dib7000p_power_mode mode
)
248 /* by default everything is powered off */
249 u16 reg_774
= 0x3fff, reg_775
= 0xffff, reg_776
= 0x0007, reg_899
= 0x0003, reg_1280
= (0xfe00) | (dib7000p_read_word(state
, 1280) & 0x01ff);
251 /* now, depending on the requested mode, we power on */
253 /* power up everything in the demod */
254 case DIB7000P_POWER_ALL
:
259 if (state
->version
== SOC7090
)
265 case DIB7000P_POWER_ANALOG_ADC
:
266 /* dem, cfg, iqc, sad, agc */
267 reg_774
&= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
269 reg_776
&= ~((1 << 0));
271 if (state
->version
!= SOC7090
)
272 reg_1280
&= ~((1 << 11));
273 reg_1280
&= ~(1 << 6);
275 case DIB7000P_POWER_INTERFACE_ONLY
:
276 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
277 /* TODO power up either SDIO or I2C */
278 if (state
->version
== SOC7090
)
279 reg_1280
&= ~((1 << 7) | (1 << 5));
281 reg_1280
&= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
284 /* TODO following stuff is just converted from the dib7000-driver - check when is used what */
287 dib7000p_write_word(state
, 774, reg_774
);
288 dib7000p_write_word(state
, 775, reg_775
);
289 dib7000p_write_word(state
, 776, reg_776
);
290 dib7000p_write_word(state
, 1280, reg_1280
);
291 if (state
->version
!= SOC7090
)
292 dib7000p_write_word(state
, 899, reg_899
);
297 static void dib7000p_set_adc_state(struct dib7000p_state
*state
, enum dibx000_adc_states no
)
299 u16 reg_908
= 0, reg_909
= 0;
302 if (state
->version
!= SOC7090
) {
303 reg_908
= dib7000p_read_word(state
, 908);
304 reg_909
= dib7000p_read_word(state
, 909);
308 case DIBX000_SLOW_ADC_ON
:
309 if (state
->version
== SOC7090
) {
310 reg
= dib7000p_read_word(state
, 1925);
312 dib7000p_write_word(state
, 1925, reg
| (1 << 4) | (1 << 2)); /* en_slowAdc = 1 & reset_sladc = 1 */
314 reg
= dib7000p_read_word(state
, 1925); /* read access to make it works... strange ... */
316 dib7000p_write_word(state
, 1925, reg
& ~(1 << 4)); /* en_slowAdc = 1 & reset_sladc = 0 */
318 reg
= dib7000p_read_word(state
, 72) & ~((0x3 << 14) | (0x3 << 12));
319 dib7000p_write_word(state
, 72, reg
| (1 << 14) | (3 << 12) | 524); /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ; (Vin2 = Vcm) */
321 reg_909
|= (1 << 1) | (1 << 0);
322 dib7000p_write_word(state
, 909, reg_909
);
323 reg_909
&= ~(1 << 1);
327 case DIBX000_SLOW_ADC_OFF
:
328 if (state
->version
== SOC7090
) {
329 reg
= dib7000p_read_word(state
, 1925);
330 dib7000p_write_word(state
, 1925, (reg
& ~(1 << 2)) | (1 << 4)); /* reset_sladc = 1 en_slowAdc = 0 */
332 reg_909
|= (1 << 1) | (1 << 0);
340 case DIBX000_ADC_OFF
:
341 reg_908
|= (1 << 14) | (1 << 13) | (1 << 12);
342 reg_909
|= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
345 case DIBX000_VBG_ENABLE
:
346 reg_908
&= ~(1 << 15);
349 case DIBX000_VBG_DISABLE
:
350 reg_908
|= (1 << 15);
357 // dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
359 reg_909
|= (state
->cfg
.disable_sample_and_hold
& 1) << 4;
360 reg_908
|= (state
->cfg
.enable_current_mirror
& 1) << 7;
362 if (state
->version
!= SOC7090
) {
363 dib7000p_write_word(state
, 908, reg_908
);
364 dib7000p_write_word(state
, 909, reg_909
);
368 static int dib7000p_set_bandwidth(struct dib7000p_state
*state
, u32 bw
)
372 // store the current bandwidth for later use
373 state
->current_bandwidth
= bw
;
375 if (state
->timf
== 0) {
376 dprintk("using default timf\n");
377 timf
= state
->cfg
.bw
->timf
;
379 dprintk("using updated timf\n");
383 timf
= timf
* (bw
/ 50) / 160;
385 dib7000p_write_word(state
, 23, (u16
) ((timf
>> 16) & 0xffff));
386 dib7000p_write_word(state
, 24, (u16
) ((timf
) & 0xffff));
391 static int dib7000p_sad_calib(struct dib7000p_state
*state
)
394 dib7000p_write_word(state
, 73, (0 << 1) | (0 << 0));
396 if (state
->version
== SOC7090
)
397 dib7000p_write_word(state
, 74, 2048);
399 dib7000p_write_word(state
, 74, 776);
401 /* do the calibration */
402 dib7000p_write_word(state
, 73, (1 << 0));
403 dib7000p_write_word(state
, 73, (0 << 0));
410 static int dib7000p_set_wbd_ref(struct dvb_frontend
*demod
, u16 value
)
412 struct dib7000p_state
*state
= demod
->demodulator_priv
;
415 state
->wbd_ref
= value
;
416 return dib7000p_write_word(state
, 105, (dib7000p_read_word(state
, 105) & 0xf000) | value
);
419 static int dib7000p_get_agc_values(struct dvb_frontend
*fe
,
420 u16
*agc_global
, u16
*agc1
, u16
*agc2
, u16
*wbd
)
422 struct dib7000p_state
*state
= fe
->demodulator_priv
;
424 if (agc_global
!= NULL
)
425 *agc_global
= dib7000p_read_word(state
, 394);
427 *agc1
= dib7000p_read_word(state
, 392);
429 *agc2
= dib7000p_read_word(state
, 393);
431 *wbd
= dib7000p_read_word(state
, 397);
436 static int dib7000p_set_agc1_min(struct dvb_frontend
*fe
, u16 v
)
438 struct dib7000p_state
*state
= fe
->demodulator_priv
;
439 return dib7000p_write_word(state
, 108, v
);
442 static void dib7000p_reset_pll(struct dib7000p_state
*state
)
444 struct dibx000_bandwidth_config
*bw
= &state
->cfg
.bw
[0];
447 if (state
->version
== SOC7090
) {
448 dib7000p_write_word(state
, 1856, (!bw
->pll_reset
<< 13) | (bw
->pll_range
<< 12) | (bw
->pll_ratio
<< 6) | (bw
->pll_prediv
));
450 while (((dib7000p_read_word(state
, 1856) >> 15) & 0x1) != 1)
453 dib7000p_write_word(state
, 1857, dib7000p_read_word(state
, 1857) | (!bw
->pll_bypass
<< 15));
455 /* force PLL bypass */
456 clk_cfg0
= (1 << 15) | ((bw
->pll_ratio
& 0x3f) << 9) |
457 (bw
->modulo
<< 7) | (bw
->ADClkSrc
<< 6) | (bw
->IO_CLK_en_core
<< 5) | (bw
->bypclk_div
<< 2) | (bw
->enable_refdiv
<< 1) | (0 << 0);
459 dib7000p_write_word(state
, 900, clk_cfg0
);
462 dib7000p_write_word(state
, 903, (bw
->pll_prediv
<< 5) | (((bw
->pll_ratio
>> 6) & 0x3) << 3) | (bw
->pll_range
<< 1) | bw
->pll_reset
);
463 clk_cfg0
= (bw
->pll_bypass
<< 15) | (clk_cfg0
& 0x7fff);
464 dib7000p_write_word(state
, 900, clk_cfg0
);
467 dib7000p_write_word(state
, 18, (u16
) (((bw
->internal
* 1000) >> 16) & 0xffff));
468 dib7000p_write_word(state
, 19, (u16
) ((bw
->internal
* 1000) & 0xffff));
469 dib7000p_write_word(state
, 21, (u16
) ((bw
->ifreq
>> 16) & 0xffff));
470 dib7000p_write_word(state
, 22, (u16
) ((bw
->ifreq
) & 0xffff));
472 dib7000p_write_word(state
, 72, bw
->sad_cfg
);
475 static u32
dib7000p_get_internal_freq(struct dib7000p_state
*state
)
477 u32 internal
= (u32
) dib7000p_read_word(state
, 18) << 16;
478 internal
|= (u32
) dib7000p_read_word(state
, 19);
484 static int dib7000p_update_pll(struct dvb_frontend
*fe
, struct dibx000_bandwidth_config
*bw
)
486 struct dib7000p_state
*state
= fe
->demodulator_priv
;
487 u16 reg_1857
, reg_1856
= dib7000p_read_word(state
, 1856);
491 /* get back old values */
492 prediv
= reg_1856
& 0x3f;
493 loopdiv
= (reg_1856
>> 6) & 0x3f;
495 if (loopdiv
&& bw
&& (bw
->pll_prediv
!= prediv
|| bw
->pll_ratio
!= loopdiv
)) {
496 dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)\n", prediv
, bw
->pll_prediv
, loopdiv
, bw
->pll_ratio
);
498 reg_1857
= dib7000p_read_word(state
, 1857);
499 dib7000p_write_word(state
, 1857, reg_1857
& ~(1 << 15));
501 dib7000p_write_word(state
, 1856, reg_1856
| ((bw
->pll_ratio
& 0x3f) << 6) | (bw
->pll_prediv
& 0x3f));
503 /* write new system clk into P_sec_len */
504 internal
= dib7000p_get_internal_freq(state
);
505 xtal
= (internal
/ loopdiv
) * prediv
;
506 internal
= 1000 * (xtal
/ bw
->pll_prediv
) * bw
->pll_ratio
; /* new internal */
507 dib7000p_write_word(state
, 18, (u16
) ((internal
>> 16) & 0xffff));
508 dib7000p_write_word(state
, 19, (u16
) (internal
& 0xffff));
510 dib7000p_write_word(state
, 1857, reg_1857
| (1 << 15));
512 while (((dib7000p_read_word(state
, 1856) >> 15) & 0x1) != 1)
513 dprintk("Waiting for PLL to lock\n");
520 static int dib7000p_reset_gpio(struct dib7000p_state
*st
)
522 /* reset the GPIOs */
523 dprintk("gpio dir: %x: val: %x, pwm_pos: %x\n", st
->gpio_dir
, st
->gpio_val
, st
->cfg
.gpio_pwm_pos
);
525 dib7000p_write_word(st
, 1029, st
->gpio_dir
);
526 dib7000p_write_word(st
, 1030, st
->gpio_val
);
528 /* TODO 1031 is P_gpio_od */
530 dib7000p_write_word(st
, 1032, st
->cfg
.gpio_pwm_pos
);
532 dib7000p_write_word(st
, 1037, st
->cfg
.pwm_freq_div
);
536 static int dib7000p_cfg_gpio(struct dib7000p_state
*st
, u8 num
, u8 dir
, u8 val
)
538 st
->gpio_dir
= dib7000p_read_word(st
, 1029);
539 st
->gpio_dir
&= ~(1 << num
); /* reset the direction bit */
540 st
->gpio_dir
|= (dir
& 0x1) << num
; /* set the new direction */
541 dib7000p_write_word(st
, 1029, st
->gpio_dir
);
543 st
->gpio_val
= dib7000p_read_word(st
, 1030);
544 st
->gpio_val
&= ~(1 << num
); /* reset the direction bit */
545 st
->gpio_val
|= (val
& 0x01) << num
; /* set the new value */
546 dib7000p_write_word(st
, 1030, st
->gpio_val
);
551 static int dib7000p_set_gpio(struct dvb_frontend
*demod
, u8 num
, u8 dir
, u8 val
)
553 struct dib7000p_state
*state
= demod
->demodulator_priv
;
554 return dib7000p_cfg_gpio(state
, num
, dir
, val
);
557 static u16 dib7000p_defaults
[] = {
558 // auto search configuration
561 (1<<3)|(1<<11)|(1<<12)|(1<<13),
562 0x0814, /* Equal Lock */
581 /* set ADC level to -16 */
583 (1 << 13) - 825 - 117,
584 (1 << 13) - 837 - 117,
585 (1 << 13) - 811 - 117,
586 (1 << 13) - 766 - 117,
587 (1 << 13) - 737 - 117,
588 (1 << 13) - 693 - 117,
589 (1 << 13) - 648 - 117,
590 (1 << 13) - 619 - 117,
591 (1 << 13) - 575 - 117,
592 (1 << 13) - 531 - 117,
593 (1 << 13) - 501 - 117,
598 /* disable power smoothing */
640 static void dib7000p_reset_stats(struct dvb_frontend
*fe
);
642 static int dib7000p_demod_reset(struct dib7000p_state
*state
)
644 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
646 if (state
->version
== SOC7090
)
647 dibx000_reset_i2c_master(&state
->i2c_master
);
649 dib7000p_set_adc_state(state
, DIBX000_VBG_ENABLE
);
651 /* restart all parts */
652 dib7000p_write_word(state
, 770, 0xffff);
653 dib7000p_write_word(state
, 771, 0xffff);
654 dib7000p_write_word(state
, 772, 0x001f);
655 dib7000p_write_word(state
, 1280, 0x001f - ((1 << 4) | (1 << 3)));
657 dib7000p_write_word(state
, 770, 0);
658 dib7000p_write_word(state
, 771, 0);
659 dib7000p_write_word(state
, 772, 0);
660 dib7000p_write_word(state
, 1280, 0);
662 if (state
->version
!= SOC7090
) {
663 dib7000p_write_word(state
, 898, 0x0003);
664 dib7000p_write_word(state
, 898, 0);
668 dib7000p_reset_pll(state
);
670 if (dib7000p_reset_gpio(state
) != 0)
671 dprintk("GPIO reset was not successful.\n");
673 if (state
->version
== SOC7090
) {
674 dib7000p_write_word(state
, 899, 0);
677 dib7000p_write_word(state
, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */
678 dib7000p_write_word(state
, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */
679 dib7000p_write_word(state
, 44, 300); /* 300 fag P_iqc_dect_min = +280 */
680 dib7000p_write_word(state
, 273, (0<<6) | 30);
682 if (dib7000p_set_output_mode(state
, OUTMODE_HIGH_Z
) != 0)
683 dprintk("OUTPUT_MODE could not be reset.\n");
685 dib7000p_set_adc_state(state
, DIBX000_SLOW_ADC_ON
);
686 dib7000p_sad_calib(state
);
687 dib7000p_set_adc_state(state
, DIBX000_SLOW_ADC_OFF
);
689 /* unforce divstr regardless whether i2c enumeration was done or not */
690 dib7000p_write_word(state
, 1285, dib7000p_read_word(state
, 1285) & ~(1 << 1));
692 dib7000p_set_bandwidth(state
, 8000);
694 if (state
->version
== SOC7090
) {
695 dib7000p_write_word(state
, 36, 0x0755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */
697 if (state
->cfg
.tuner_is_baseband
)
698 dib7000p_write_word(state
, 36, 0x0755);
700 dib7000p_write_word(state
, 36, 0x1f55);
703 dib7000p_write_tab(state
, dib7000p_defaults
);
704 if (state
->version
!= SOC7090
) {
705 dib7000p_write_word(state
, 901, 0x0006);
706 dib7000p_write_word(state
, 902, (3 << 10) | (1 << 6));
707 dib7000p_write_word(state
, 905, 0x2c8e);
710 dib7000p_set_power_mode(state
, DIB7000P_POWER_INTERFACE_ONLY
);
715 static void dib7000p_pll_clk_cfg(struct dib7000p_state
*state
)
718 tmp
= dib7000p_read_word(state
, 903);
719 dib7000p_write_word(state
, 903, (tmp
| 0x1));
720 tmp
= dib7000p_read_word(state
, 900);
721 dib7000p_write_word(state
, 900, (tmp
& 0x7fff) | (1 << 6));
724 static void dib7000p_restart_agc(struct dib7000p_state
*state
)
726 // P_restart_iqc & P_restart_agc
727 dib7000p_write_word(state
, 770, (1 << 11) | (1 << 9));
728 dib7000p_write_word(state
, 770, 0x0000);
731 static int dib7000p_update_lna(struct dib7000p_state
*state
)
735 if (state
->cfg
.update_lna
) {
736 dyn_gain
= dib7000p_read_word(state
, 394);
737 if (state
->cfg
.update_lna(&state
->demod
, dyn_gain
)) {
738 dib7000p_restart_agc(state
);
746 static int dib7000p_set_agc_config(struct dib7000p_state
*state
, u8 band
)
748 struct dibx000_agc_config
*agc
= NULL
;
750 if (state
->current_band
== band
&& state
->current_agc
!= NULL
)
752 state
->current_band
= band
;
754 for (i
= 0; i
< state
->cfg
.agc_config_count
; i
++)
755 if (state
->cfg
.agc
[i
].band_caps
& band
) {
756 agc
= &state
->cfg
.agc
[i
];
761 dprintk("no valid AGC configuration found for band 0x%02x\n", band
);
765 state
->current_agc
= agc
;
768 dib7000p_write_word(state
, 75, agc
->setup
);
769 dib7000p_write_word(state
, 76, agc
->inv_gain
);
770 dib7000p_write_word(state
, 77, agc
->time_stabiliz
);
771 dib7000p_write_word(state
, 100, (agc
->alpha_level
<< 12) | agc
->thlock
);
773 // Demod AGC loop configuration
774 dib7000p_write_word(state
, 101, (agc
->alpha_mant
<< 5) | agc
->alpha_exp
);
775 dib7000p_write_word(state
, 102, (agc
->beta_mant
<< 6) | agc
->beta_exp
);
778 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d\n",
779 state
->wbd_ref
!= 0 ? state
->wbd_ref
: agc
->wbd_ref
, agc
->wbd_sel
, !agc
->perform_agc_softsplit
, agc
->wbd_sel
);
781 if (state
->wbd_ref
!= 0)
782 dib7000p_write_word(state
, 105, (agc
->wbd_inv
<< 12) | state
->wbd_ref
);
784 dib7000p_write_word(state
, 105, (agc
->wbd_inv
<< 12) | agc
->wbd_ref
);
786 dib7000p_write_word(state
, 106, (agc
->wbd_sel
<< 13) | (agc
->wbd_alpha
<< 9) | (agc
->perform_agc_softsplit
<< 8));
788 dib7000p_write_word(state
, 107, agc
->agc1_max
);
789 dib7000p_write_word(state
, 108, agc
->agc1_min
);
790 dib7000p_write_word(state
, 109, agc
->agc2_max
);
791 dib7000p_write_word(state
, 110, agc
->agc2_min
);
792 dib7000p_write_word(state
, 111, (agc
->agc1_pt1
<< 8) | agc
->agc1_pt2
);
793 dib7000p_write_word(state
, 112, agc
->agc1_pt3
);
794 dib7000p_write_word(state
, 113, (agc
->agc1_slope1
<< 8) | agc
->agc1_slope2
);
795 dib7000p_write_word(state
, 114, (agc
->agc2_pt1
<< 8) | agc
->agc2_pt2
);
796 dib7000p_write_word(state
, 115, (agc
->agc2_slope1
<< 8) | agc
->agc2_slope2
);
800 static int dib7000p_set_dds(struct dib7000p_state
*state
, s32 offset_khz
)
802 u32 internal
= dib7000p_get_internal_freq(state
);
803 s32 unit_khz_dds_val
;
804 u32 abs_offset_khz
= abs(offset_khz
);
805 u32 dds
= state
->cfg
.bw
->ifreq
& 0x1ffffff;
806 u8 invert
= !!(state
->cfg
.bw
->ifreq
& (1 << 25));
808 pr_warn("DIB7000P: dib7000p_get_internal_freq returned 0\n");
811 /* 2**26 / Fsampling is the unit 1KHz offset */
812 unit_khz_dds_val
= 67108864 / (internal
);
814 dprintk("setting a frequency offset of %dkHz internal freq = %d invert = %d\n", offset_khz
, internal
, invert
);
817 unit_khz_dds_val
*= -1;
821 dds
-= (abs_offset_khz
* unit_khz_dds_val
); /* /100 because of /100 on the unit_khz_dds_val line calc for better accuracy */
823 dds
+= (abs_offset_khz
* unit_khz_dds_val
);
825 if (abs_offset_khz
<= (internal
/ 2)) { /* Max dds offset is the half of the demod freq */
826 dib7000p_write_word(state
, 21, (u16
) (((dds
>> 16) & 0x1ff) | (0 << 10) | (invert
<< 9)));
827 dib7000p_write_word(state
, 22, (u16
) (dds
& 0xffff));
832 static int dib7000p_agc_startup(struct dvb_frontend
*demod
)
834 struct dtv_frontend_properties
*ch
= &demod
->dtv_property_cache
;
835 struct dib7000p_state
*state
= demod
->demodulator_priv
;
837 u8
*agc_state
= &state
->agc_state
;
840 u32 upd_demod_gain_period
= 0x1000;
841 s32 frequency_offset
= 0;
843 switch (state
->agc_state
) {
845 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
846 if (state
->version
== SOC7090
) {
847 reg
= dib7000p_read_word(state
, 0x79b) & 0xff00;
848 dib7000p_write_word(state
, 0x79a, upd_demod_gain_period
& 0xFFFF); /* lsb */
849 dib7000p_write_word(state
, 0x79b, reg
| (1 << 14) | ((upd_demod_gain_period
>> 16) & 0xFF));
851 /* enable adc i & q */
852 reg
= dib7000p_read_word(state
, 0x780);
853 dib7000p_write_word(state
, 0x780, (reg
| (0x3)) & (~(1 << 7)));
855 dib7000p_set_adc_state(state
, DIBX000_ADC_ON
);
856 dib7000p_pll_clk_cfg(state
);
859 if (dib7000p_set_agc_config(state
, BAND_OF_FREQUENCY(ch
->frequency
/ 1000)) != 0)
862 if (demod
->ops
.tuner_ops
.get_frequency
) {
865 demod
->ops
.tuner_ops
.get_frequency(demod
, &frequency_tuner
);
866 frequency_offset
= (s32
)frequency_tuner
/ 1000 - ch
->frequency
/ 1000;
869 if (dib7000p_set_dds(state
, frequency_offset
) < 0)
877 if (state
->cfg
.agc_control
)
878 state
->cfg
.agc_control(&state
->demod
, 1);
880 dib7000p_write_word(state
, 78, 32768);
881 if (!state
->current_agc
->perform_agc_softsplit
) {
882 /* we are using the wbd - so slow AGC startup */
883 /* force 0 split on WBD and restart AGC */
884 dib7000p_write_word(state
, 106, (state
->current_agc
->wbd_sel
<< 13) | (state
->current_agc
->wbd_alpha
<< 9) | (1 << 8));
888 /* default AGC startup */
890 /* wait AGC rough lock time */
894 dib7000p_restart_agc(state
);
897 case 2: /* fast split search path after 5sec */
898 dib7000p_write_word(state
, 75, state
->current_agc
->setup
| (1 << 4)); /* freeze AGC loop */
899 dib7000p_write_word(state
, 106, (state
->current_agc
->wbd_sel
<< 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */
904 case 3: /* split search ended */
905 agc_split
= (u8
) dib7000p_read_word(state
, 396); /* store the split value for the next time */
906 dib7000p_write_word(state
, 78, dib7000p_read_word(state
, 394)); /* set AGC gain start value */
908 dib7000p_write_word(state
, 75, state
->current_agc
->setup
); /* std AGC loop */
909 dib7000p_write_word(state
, 106, (state
->current_agc
->wbd_sel
<< 13) | (state
->current_agc
->wbd_alpha
<< 9) | agc_split
); /* standard split search */
911 dib7000p_restart_agc(state
);
913 dprintk("SPLIT %p: %u\n", demod
, agc_split
);
919 case 4: /* LNA startup */
922 if (dib7000p_update_lna(state
))
929 if (state
->cfg
.agc_control
)
930 state
->cfg
.agc_control(&state
->demod
, 0);
939 static void dib7000p_update_timf(struct dib7000p_state
*state
)
941 u32 timf
= (dib7000p_read_word(state
, 427) << 16) | dib7000p_read_word(state
, 428);
942 state
->timf
= timf
* 160 / (state
->current_bandwidth
/ 50);
943 dib7000p_write_word(state
, 23, (u16
) (timf
>> 16));
944 dib7000p_write_word(state
, 24, (u16
) (timf
& 0xffff));
945 dprintk("updated timf_frequency: %d (default: %d)\n", state
->timf
, state
->cfg
.bw
->timf
);
949 static u32
dib7000p_ctrl_timf(struct dvb_frontend
*fe
, u8 op
, u32 timf
)
951 struct dib7000p_state
*state
= fe
->demodulator_priv
;
956 case DEMOD_TIMF_UPDATE
:
957 dib7000p_update_timf(state
);
962 dib7000p_set_bandwidth(state
, state
->current_bandwidth
);
966 static void dib7000p_set_channel(struct dib7000p_state
*state
,
967 struct dtv_frontend_properties
*ch
, u8 seq
)
971 dib7000p_set_bandwidth(state
, BANDWIDTH_TO_KHZ(ch
->bandwidth_hz
));
973 /* nfft, guard, qam, alpha */
975 switch (ch
->transmission_mode
) {
976 case TRANSMISSION_MODE_2K
:
979 case TRANSMISSION_MODE_4K
:
983 case TRANSMISSION_MODE_8K
:
987 switch (ch
->guard_interval
) {
988 case GUARD_INTERVAL_1_32
:
991 case GUARD_INTERVAL_1_16
:
994 case GUARD_INTERVAL_1_4
:
998 case GUARD_INTERVAL_1_8
:
1002 switch (ch
->modulation
) {
1014 switch (HIERARCHY_1
) {
1026 dib7000p_write_word(state
, 0, value
);
1027 dib7000p_write_word(state
, 5, (seq
<< 4) | 1); /* do not force tps, search list 0 */
1029 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
1033 if (ch
->hierarchy
== 1)
1037 switch ((ch
->hierarchy
== 0 || 1 == 1) ? ch
->code_rate_HP
: ch
->code_rate_LP
) {
1055 dib7000p_write_word(state
, 208, value
);
1057 /* offset loop parameters */
1058 dib7000p_write_word(state
, 26, 0x6680);
1059 dib7000p_write_word(state
, 32, 0x0003);
1060 dib7000p_write_word(state
, 29, 0x1273);
1061 dib7000p_write_word(state
, 33, 0x0005);
1063 /* P_dvsy_sync_wait */
1064 switch (ch
->transmission_mode
) {
1065 case TRANSMISSION_MODE_8K
:
1068 case TRANSMISSION_MODE_4K
:
1071 case TRANSMISSION_MODE_2K
:
1076 switch (ch
->guard_interval
) {
1077 case GUARD_INTERVAL_1_16
:
1080 case GUARD_INTERVAL_1_8
:
1083 case GUARD_INTERVAL_1_4
:
1087 case GUARD_INTERVAL_1_32
:
1091 if (state
->cfg
.diversity_delay
== 0)
1092 state
->div_sync_wait
= (value
* 3) / 2 + 48;
1094 state
->div_sync_wait
= (value
* 3) / 2 + state
->cfg
.diversity_delay
;
1096 /* deactivate the possibility of diversity reception if extended interleaver */
1097 state
->div_force_off
= !1 && ch
->transmission_mode
!= TRANSMISSION_MODE_8K
;
1098 dib7000p_set_diversity_in(&state
->demod
, state
->div_state
);
1100 /* channel estimation fine configuration */
1101 switch (ch
->modulation
) {
1103 est
[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
1104 est
[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
1105 est
[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1106 est
[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
1109 est
[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
1110 est
[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
1111 est
[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1112 est
[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
1115 est
[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
1116 est
[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
1117 est
[2] = 0x0333; /* P_adp_regul_ext 0.1 */
1118 est
[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
1121 for (value
= 0; value
< 4; value
++)
1122 dib7000p_write_word(state
, 187 + value
, est
[value
]);
1125 static int dib7000p_autosearch_start(struct dvb_frontend
*demod
)
1127 struct dtv_frontend_properties
*ch
= &demod
->dtv_property_cache
;
1128 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1129 struct dtv_frontend_properties schan
;
1131 u32 internal
= dib7000p_get_internal_freq(state
);
1134 schan
.modulation
= QAM_64
;
1135 schan
.guard_interval
= GUARD_INTERVAL_1_32
;
1136 schan
.transmission_mode
= TRANSMISSION_MODE_8K
;
1137 schan
.code_rate_HP
= FEC_2_3
;
1138 schan
.code_rate_LP
= FEC_3_4
;
1139 schan
.hierarchy
= 0;
1141 dib7000p_set_channel(state
, &schan
, 7);
1143 factor
= BANDWIDTH_TO_KHZ(ch
->bandwidth_hz
);
1144 if (factor
>= 5000) {
1145 if (state
->version
== SOC7090
)
1152 value
= 30 * internal
* factor
;
1153 dib7000p_write_word(state
, 6, (u16
) ((value
>> 16) & 0xffff));
1154 dib7000p_write_word(state
, 7, (u16
) (value
& 0xffff));
1155 value
= 100 * internal
* factor
;
1156 dib7000p_write_word(state
, 8, (u16
) ((value
>> 16) & 0xffff));
1157 dib7000p_write_word(state
, 9, (u16
) (value
& 0xffff));
1158 value
= 500 * internal
* factor
;
1159 dib7000p_write_word(state
, 10, (u16
) ((value
>> 16) & 0xffff));
1160 dib7000p_write_word(state
, 11, (u16
) (value
& 0xffff));
1162 value
= dib7000p_read_word(state
, 0);
1163 dib7000p_write_word(state
, 0, (u16
) ((1 << 9) | value
));
1164 dib7000p_read_word(state
, 1284);
1165 dib7000p_write_word(state
, 0, (u16
) value
);
1170 static int dib7000p_autosearch_is_irq(struct dvb_frontend
*demod
)
1172 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1173 u16 irq_pending
= dib7000p_read_word(state
, 1284);
1175 if (irq_pending
& 0x1)
1178 if (irq_pending
& 0x2)
1184 static void dib7000p_spur_protect(struct dib7000p_state
*state
, u32 rf_khz
, u32 bw
)
1186 static const s16 notch
[] = { 16143, 14402, 12238, 9713, 6902, 3888, 759, -2392 };
1187 static const u8 sine
[] = { 0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
1188 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
1189 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
1190 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
1191 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
1192 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
1193 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
1194 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
1195 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
1196 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
1197 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
1198 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
1199 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
1200 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
1201 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
1202 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1203 255, 255, 255, 255, 255, 255
1206 u32 xtal
= state
->cfg
.bw
->xtal_hz
/ 1000;
1207 int f_rel
= DIV_ROUND_CLOSEST(rf_khz
, xtal
) * xtal
- rf_khz
;
1209 int coef_re
[8], coef_im
[8];
1213 dprintk("relative position of the Spur: %dk (RF: %dk, XTAL: %dk)\n", f_rel
, rf_khz
, xtal
);
1215 if (f_rel
< -bw_khz
/ 2 || f_rel
> bw_khz
/ 2)
1220 dib7000p_write_word(state
, 142, 0x0610);
1222 for (k
= 0; k
< 8; k
++) {
1223 pha
= ((f_rel
* (k
+ 1) * 112 * 80 / bw_khz
) / 1000) & 0x3ff;
1228 } else if (pha
< 256) {
1229 coef_re
[k
] = sine
[256 - (pha
& 0xff)];
1230 coef_im
[k
] = sine
[pha
& 0xff];
1231 } else if (pha
== 256) {
1234 } else if (pha
< 512) {
1235 coef_re
[k
] = -sine
[pha
& 0xff];
1236 coef_im
[k
] = sine
[256 - (pha
& 0xff)];
1237 } else if (pha
== 512) {
1240 } else if (pha
< 768) {
1241 coef_re
[k
] = -sine
[256 - (pha
& 0xff)];
1242 coef_im
[k
] = -sine
[pha
& 0xff];
1243 } else if (pha
== 768) {
1247 coef_re
[k
] = sine
[pha
& 0xff];
1248 coef_im
[k
] = -sine
[256 - (pha
& 0xff)];
1251 coef_re
[k
] *= notch
[k
];
1252 coef_re
[k
] += (1 << 14);
1253 if (coef_re
[k
] >= (1 << 24))
1254 coef_re
[k
] = (1 << 24) - 1;
1255 coef_re
[k
] /= (1 << 15);
1257 coef_im
[k
] *= notch
[k
];
1258 coef_im
[k
] += (1 << 14);
1259 if (coef_im
[k
] >= (1 << 24))
1260 coef_im
[k
] = (1 << 24) - 1;
1261 coef_im
[k
] /= (1 << 15);
1263 dprintk("PALF COEF: %d re: %d im: %d\n", k
, coef_re
[k
], coef_im
[k
]);
1265 dib7000p_write_word(state
, 143, (0 << 14) | (k
<< 10) | (coef_re
[k
] & 0x3ff));
1266 dib7000p_write_word(state
, 144, coef_im
[k
] & 0x3ff);
1267 dib7000p_write_word(state
, 143, (1 << 14) | (k
<< 10) | (coef_re
[k
] & 0x3ff));
1269 dib7000p_write_word(state
, 143, 0);
1272 static int dib7000p_tune(struct dvb_frontend
*demod
)
1274 struct dtv_frontend_properties
*ch
= &demod
->dtv_property_cache
;
1275 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1279 dib7000p_set_channel(state
, ch
, 0);
1284 dib7000p_write_word(state
, 770, 0x4000);
1285 dib7000p_write_word(state
, 770, 0x0000);
1288 /* 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 */
1289 tmp
= (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
1290 if (state
->sfn_workaround_active
) {
1291 dprintk("SFN workaround is active\n");
1293 dib7000p_write_word(state
, 166, 0x4000);
1295 dib7000p_write_word(state
, 166, 0x0000);
1297 dib7000p_write_word(state
, 29, tmp
);
1299 // never achieved a lock with that bandwidth so far - wait for osc-freq to update
1300 if (state
->timf
== 0)
1303 /* offset loop parameters */
1305 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
1306 tmp
= (6 << 8) | 0x80;
1307 switch (ch
->transmission_mode
) {
1308 case TRANSMISSION_MODE_2K
:
1311 case TRANSMISSION_MODE_4K
:
1315 case TRANSMISSION_MODE_8K
:
1319 dib7000p_write_word(state
, 26, tmp
); /* timf_a(6xxx) */
1321 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1323 switch (ch
->transmission_mode
) {
1324 case TRANSMISSION_MODE_2K
:
1327 case TRANSMISSION_MODE_4K
:
1331 case TRANSMISSION_MODE_8K
:
1335 dib7000p_write_word(state
, 32, tmp
);
1337 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1339 switch (ch
->transmission_mode
) {
1340 case TRANSMISSION_MODE_2K
:
1343 case TRANSMISSION_MODE_4K
:
1347 case TRANSMISSION_MODE_8K
:
1351 dib7000p_write_word(state
, 33, tmp
);
1353 tmp
= dib7000p_read_word(state
, 509);
1354 if (!((tmp
>> 6) & 0x1)) {
1355 /* restart the fec */
1356 tmp
= dib7000p_read_word(state
, 771);
1357 dib7000p_write_word(state
, 771, tmp
| (1 << 1));
1358 dib7000p_write_word(state
, 771, tmp
);
1360 tmp
= dib7000p_read_word(state
, 509);
1362 // we achieved a lock - it's time to update the osc freq
1363 if ((tmp
>> 6) & 0x1) {
1364 dib7000p_update_timf(state
);
1365 /* P_timf_alpha += 2 */
1366 tmp
= dib7000p_read_word(state
, 26);
1367 dib7000p_write_word(state
, 26, (tmp
& ~(0xf << 12)) | ((((tmp
>> 12) & 0xf) + 5) << 12));
1370 if (state
->cfg
.spur_protect
)
1371 dib7000p_spur_protect(state
, ch
->frequency
/ 1000, BANDWIDTH_TO_KHZ(ch
->bandwidth_hz
));
1373 dib7000p_set_bandwidth(state
, BANDWIDTH_TO_KHZ(ch
->bandwidth_hz
));
1375 dib7000p_reset_stats(demod
);
1380 static int dib7000p_wakeup(struct dvb_frontend
*demod
)
1382 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1383 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
1384 dib7000p_set_adc_state(state
, DIBX000_SLOW_ADC_ON
);
1385 if (state
->version
== SOC7090
)
1386 dib7000p_sad_calib(state
);
1390 static int dib7000p_sleep(struct dvb_frontend
*demod
)
1392 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1393 if (state
->version
== SOC7090
)
1394 return dib7000p_set_power_mode(state
, DIB7000P_POWER_INTERFACE_ONLY
);
1395 return dib7000p_set_output_mode(state
, OUTMODE_HIGH_Z
) | dib7000p_set_power_mode(state
, DIB7000P_POWER_INTERFACE_ONLY
);
1398 static int dib7000p_identify(struct dib7000p_state
*st
)
1401 dprintk("checking demod on I2C address: %d (%x)\n", st
->i2c_addr
, st
->i2c_addr
);
1403 if ((value
= dib7000p_read_word(st
, 768)) != 0x01b3) {
1404 dprintk("wrong Vendor ID (read=0x%x)\n", value
);
1408 if ((value
= dib7000p_read_word(st
, 769)) != 0x4000) {
1409 dprintk("wrong Device ID (%x)\n", value
);
1416 static int dib7000p_get_frontend(struct dvb_frontend
*fe
,
1417 struct dtv_frontend_properties
*fep
)
1419 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1420 u16 tps
= dib7000p_read_word(state
, 463);
1422 fep
->inversion
= INVERSION_AUTO
;
1424 fep
->bandwidth_hz
= BANDWIDTH_TO_HZ(state
->current_bandwidth
);
1426 switch ((tps
>> 8) & 0x3) {
1428 fep
->transmission_mode
= TRANSMISSION_MODE_2K
;
1431 fep
->transmission_mode
= TRANSMISSION_MODE_8K
;
1433 /* case 2: fep->transmission_mode = TRANSMISSION_MODE_4K; break; */
1436 switch (tps
& 0x3) {
1438 fep
->guard_interval
= GUARD_INTERVAL_1_32
;
1441 fep
->guard_interval
= GUARD_INTERVAL_1_16
;
1444 fep
->guard_interval
= GUARD_INTERVAL_1_8
;
1447 fep
->guard_interval
= GUARD_INTERVAL_1_4
;
1451 switch ((tps
>> 14) & 0x3) {
1453 fep
->modulation
= QPSK
;
1456 fep
->modulation
= QAM_16
;
1460 fep
->modulation
= QAM_64
;
1464 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1465 /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1467 fep
->hierarchy
= HIERARCHY_NONE
;
1468 switch ((tps
>> 5) & 0x7) {
1470 fep
->code_rate_HP
= FEC_1_2
;
1473 fep
->code_rate_HP
= FEC_2_3
;
1476 fep
->code_rate_HP
= FEC_3_4
;
1479 fep
->code_rate_HP
= FEC_5_6
;
1483 fep
->code_rate_HP
= FEC_7_8
;
1488 switch ((tps
>> 2) & 0x7) {
1490 fep
->code_rate_LP
= FEC_1_2
;
1493 fep
->code_rate_LP
= FEC_2_3
;
1496 fep
->code_rate_LP
= FEC_3_4
;
1499 fep
->code_rate_LP
= FEC_5_6
;
1503 fep
->code_rate_LP
= FEC_7_8
;
1507 /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */
1512 static int dib7000p_set_frontend(struct dvb_frontend
*fe
)
1514 struct dtv_frontend_properties
*fep
= &fe
->dtv_property_cache
;
1515 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1518 if (state
->version
== SOC7090
)
1519 dib7090_set_diversity_in(fe
, 0);
1521 dib7000p_set_output_mode(state
, OUTMODE_HIGH_Z
);
1523 /* maybe the parameter has been changed */
1524 state
->sfn_workaround_active
= buggy_sfn_workaround
;
1526 if (fe
->ops
.tuner_ops
.set_params
)
1527 fe
->ops
.tuner_ops
.set_params(fe
);
1529 /* start up the AGC */
1530 state
->agc_state
= 0;
1532 time
= dib7000p_agc_startup(fe
);
1535 } while (time
!= -1);
1537 if (fep
->transmission_mode
== TRANSMISSION_MODE_AUTO
||
1538 fep
->guard_interval
== GUARD_INTERVAL_AUTO
|| fep
->modulation
== QAM_AUTO
|| fep
->code_rate_HP
== FEC_AUTO
) {
1541 dib7000p_autosearch_start(fe
);
1544 found
= dib7000p_autosearch_is_irq(fe
);
1545 } while (found
== 0 && i
--);
1547 dprintk("autosearch returns: %d\n", found
);
1548 if (found
== 0 || found
== 1)
1551 dib7000p_get_frontend(fe
, fep
);
1554 ret
= dib7000p_tune(fe
);
1556 /* make this a config parameter */
1557 if (state
->version
== SOC7090
) {
1558 dib7090_set_output_mode(fe
, state
->cfg
.output_mode
);
1559 if (state
->cfg
.enMpegOutput
== 0) {
1560 dib7090_setDibTxMux(state
, MPEG_ON_DIBTX
);
1561 dib7090_setHostBusMux(state
, DIBTX_ON_HOSTBUS
);
1564 dib7000p_set_output_mode(state
, state
->cfg
.output_mode
);
1569 static int dib7000p_get_stats(struct dvb_frontend
*fe
, enum fe_status stat
);
1571 static int dib7000p_read_status(struct dvb_frontend
*fe
, enum fe_status
*stat
)
1573 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1574 u16 lock
= dib7000p_read_word(state
, 509);
1579 *stat
|= FE_HAS_SIGNAL
;
1581 *stat
|= FE_HAS_CARRIER
;
1583 *stat
|= FE_HAS_VITERBI
;
1585 *stat
|= FE_HAS_SYNC
;
1586 if ((lock
& 0x0038) == 0x38)
1587 *stat
|= FE_HAS_LOCK
;
1589 dib7000p_get_stats(fe
, *stat
);
1594 static int dib7000p_read_ber(struct dvb_frontend
*fe
, u32
* ber
)
1596 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1597 *ber
= (dib7000p_read_word(state
, 500) << 16) | dib7000p_read_word(state
, 501);
1601 static int dib7000p_read_unc_blocks(struct dvb_frontend
*fe
, u32
* unc
)
1603 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1604 *unc
= dib7000p_read_word(state
, 506);
1608 static int dib7000p_read_signal_strength(struct dvb_frontend
*fe
, u16
* strength
)
1610 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1611 u16 val
= dib7000p_read_word(state
, 394);
1612 *strength
= 65535 - val
;
1616 static u32
dib7000p_get_snr(struct dvb_frontend
*fe
)
1618 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1620 s32 signal_mant
, signal_exp
, noise_mant
, noise_exp
;
1623 val
= dib7000p_read_word(state
, 479);
1624 noise_mant
= (val
>> 4) & 0xff;
1625 noise_exp
= ((val
& 0xf) << 2);
1626 val
= dib7000p_read_word(state
, 480);
1627 noise_exp
+= ((val
>> 14) & 0x3);
1628 if ((noise_exp
& 0x20) != 0)
1631 signal_mant
= (val
>> 6) & 0xFF;
1632 signal_exp
= (val
& 0x3F);
1633 if ((signal_exp
& 0x20) != 0)
1636 if (signal_mant
!= 0)
1637 result
= intlog10(2) * 10 * signal_exp
+ 10 * intlog10(signal_mant
);
1639 result
= intlog10(2) * 10 * signal_exp
- 100;
1641 if (noise_mant
!= 0)
1642 result
-= intlog10(2) * 10 * noise_exp
+ 10 * intlog10(noise_mant
);
1644 result
-= intlog10(2) * 10 * noise_exp
- 100;
1649 static int dib7000p_read_snr(struct dvb_frontend
*fe
, u16
*snr
)
1653 result
= dib7000p_get_snr(fe
);
1655 *snr
= result
/ ((1 << 24) / 10);
1659 static void dib7000p_reset_stats(struct dvb_frontend
*demod
)
1661 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1662 struct dtv_frontend_properties
*c
= &demod
->dtv_property_cache
;
1665 memset(&c
->strength
, 0, sizeof(c
->strength
));
1666 memset(&c
->cnr
, 0, sizeof(c
->cnr
));
1667 memset(&c
->post_bit_error
, 0, sizeof(c
->post_bit_error
));
1668 memset(&c
->post_bit_count
, 0, sizeof(c
->post_bit_count
));
1669 memset(&c
->block_error
, 0, sizeof(c
->block_error
));
1671 c
->strength
.len
= 1;
1673 c
->block_error
.len
= 1;
1674 c
->block_count
.len
= 1;
1675 c
->post_bit_error
.len
= 1;
1676 c
->post_bit_count
.len
= 1;
1678 c
->strength
.stat
[0].scale
= FE_SCALE_DECIBEL
;
1679 c
->strength
.stat
[0].uvalue
= 0;
1681 c
->cnr
.stat
[0].scale
= FE_SCALE_NOT_AVAILABLE
;
1682 c
->block_error
.stat
[0].scale
= FE_SCALE_NOT_AVAILABLE
;
1683 c
->block_count
.stat
[0].scale
= FE_SCALE_NOT_AVAILABLE
;
1684 c
->post_bit_error
.stat
[0].scale
= FE_SCALE_NOT_AVAILABLE
;
1685 c
->post_bit_count
.stat
[0].scale
= FE_SCALE_NOT_AVAILABLE
;
1687 dib7000p_read_unc_blocks(demod
, &ucb
);
1689 state
->old_ucb
= ucb
;
1690 state
->ber_jiffies_stats
= 0;
1691 state
->per_jiffies_stats
= 0;
1694 struct linear_segments
{
1700 * Table to estimate signal strength in dBm.
1701 * This table should be empirically determinated by measuring the signal
1702 * strength generated by a RF generator directly connected into
1704 * This table was determinated by measuring the signal strength generated
1705 * by a DTA-2111 RF generator directly connected into a dib7000p device
1706 * (a Hauppauge Nova-TD stick), using a good quality 3 meters length
1707 * RC6 cable and good RC6 connectors, connected directly to antenna 1.
1708 * As the minimum output power of DTA-2111 is -31dBm, a 16 dBm attenuator
1709 * were used, for the lower power values.
1710 * The real value can actually be on other devices, or even at the
1711 * second antena input, depending on several factors, like if LNA
1712 * is enabled or not, if diversity is enabled, type of connectors, etc.
1713 * Yet, it is better to use this measure in dB than a random non-linear
1714 * percentage value, especially for antenna adjustments.
1715 * On my tests, the precision of the measure using this table is about
1716 * 0.5 dB, with sounds reasonable enough to adjust antennas.
1718 #define DB_OFFSET 131000
1720 static struct linear_segments strength_to_db_table
[] = {
1721 { 63630, DB_OFFSET
- 20500},
1722 { 62273, DB_OFFSET
- 21000},
1723 { 60162, DB_OFFSET
- 22000},
1724 { 58730, DB_OFFSET
- 23000},
1725 { 58294, DB_OFFSET
- 24000},
1726 { 57778, DB_OFFSET
- 25000},
1727 { 57320, DB_OFFSET
- 26000},
1728 { 56779, DB_OFFSET
- 27000},
1729 { 56293, DB_OFFSET
- 28000},
1730 { 55724, DB_OFFSET
- 29000},
1731 { 55145, DB_OFFSET
- 30000},
1732 { 54680, DB_OFFSET
- 31000},
1733 { 54293, DB_OFFSET
- 32000},
1734 { 53813, DB_OFFSET
- 33000},
1735 { 53427, DB_OFFSET
- 34000},
1736 { 52981, DB_OFFSET
- 35000},
1738 { 52636, DB_OFFSET
- 36000},
1739 { 52014, DB_OFFSET
- 37000},
1740 { 51674, DB_OFFSET
- 38000},
1741 { 50692, DB_OFFSET
- 39000},
1742 { 49824, DB_OFFSET
- 40000},
1743 { 49052, DB_OFFSET
- 41000},
1744 { 48436, DB_OFFSET
- 42000},
1745 { 47836, DB_OFFSET
- 43000},
1746 { 47368, DB_OFFSET
- 44000},
1747 { 46468, DB_OFFSET
- 45000},
1748 { 45597, DB_OFFSET
- 46000},
1749 { 44586, DB_OFFSET
- 47000},
1750 { 43667, DB_OFFSET
- 48000},
1751 { 42673, DB_OFFSET
- 49000},
1752 { 41816, DB_OFFSET
- 50000},
1753 { 40876, DB_OFFSET
- 51000},
1757 static u32
interpolate_value(u32 value
, struct linear_segments
*segments
,
1765 if (value
>= segments
[0].x
)
1766 return segments
[0].y
;
1767 if (value
< segments
[len
-1].x
)
1768 return segments
[len
-1].y
;
1770 for (i
= 1; i
< len
- 1; i
++) {
1771 /* If value is identical, no need to interpolate */
1772 if (value
== segments
[i
].x
)
1773 return segments
[i
].y
;
1774 if (value
> segments
[i
].x
)
1778 /* Linear interpolation between the two (x,y) points */
1779 dy
= segments
[i
- 1].y
- segments
[i
].y
;
1780 dx
= segments
[i
- 1].x
- segments
[i
].x
;
1782 tmp64
= value
- segments
[i
].x
;
1785 ret
= segments
[i
].y
+ tmp64
;
1790 /* FIXME: may require changes - this one was borrowed from dib8000 */
1791 static u32
dib7000p_get_time_us(struct dvb_frontend
*demod
)
1793 struct dtv_frontend_properties
*c
= &demod
->dtv_property_cache
;
1796 int guard
, rate_num
, rate_denum
= 1, bits_per_symbol
;
1797 int interleaving
= 0, fft_div
;
1799 switch (c
->guard_interval
) {
1800 case GUARD_INTERVAL_1_4
:
1803 case GUARD_INTERVAL_1_8
:
1806 case GUARD_INTERVAL_1_16
:
1810 case GUARD_INTERVAL_1_32
:
1815 switch (c
->transmission_mode
) {
1816 case TRANSMISSION_MODE_2K
:
1819 case TRANSMISSION_MODE_4K
:
1823 case TRANSMISSION_MODE_8K
:
1828 switch (c
->modulation
) {
1831 bits_per_symbol
= 2;
1834 bits_per_symbol
= 4;
1838 bits_per_symbol
= 6;
1842 switch ((c
->hierarchy
== 0 || 1 == 1) ? c
->code_rate_HP
: c
->code_rate_LP
) {
1866 denom
= bits_per_symbol
* rate_num
* fft_div
* 384;
1869 * FIXME: check if the math makes sense. If so, fill the
1873 /* If calculus gets wrong, wait for 1s for the next stats */
1877 /* Estimate the period for the total bit rate */
1878 time_us
= rate_denum
* (1008 * 1562500L);
1880 do_div(tmp64
, guard
);
1881 time_us
= time_us
+ tmp64
;
1882 time_us
+= denom
/ 2;
1883 do_div(time_us
, denom
);
1885 tmp
= 1008 * 96 * interleaving
;
1886 time_us
+= tmp
+ tmp
/ guard
;
1891 static int dib7000p_get_stats(struct dvb_frontend
*demod
, enum fe_status stat
)
1893 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1894 struct dtv_frontend_properties
*c
= &demod
->dtv_property_cache
;
1895 int show_per_stats
= 0;
1896 u32 time_us
= 0, val
, snr
;
1901 /* Get Signal strength */
1902 dib7000p_read_signal_strength(demod
, &strength
);
1904 db
= interpolate_value(val
,
1905 strength_to_db_table
,
1906 ARRAY_SIZE(strength_to_db_table
)) - DB_OFFSET
;
1907 c
->strength
.stat
[0].svalue
= db
;
1909 /* UCB/BER/CNR measures require lock */
1910 if (!(stat
& FE_HAS_LOCK
)) {
1912 c
->block_count
.len
= 1;
1913 c
->block_error
.len
= 1;
1914 c
->post_bit_error
.len
= 1;
1915 c
->post_bit_count
.len
= 1;
1916 c
->cnr
.stat
[0].scale
= FE_SCALE_NOT_AVAILABLE
;
1917 c
->post_bit_error
.stat
[0].scale
= FE_SCALE_NOT_AVAILABLE
;
1918 c
->post_bit_count
.stat
[0].scale
= FE_SCALE_NOT_AVAILABLE
;
1919 c
->block_error
.stat
[0].scale
= FE_SCALE_NOT_AVAILABLE
;
1920 c
->block_count
.stat
[0].scale
= FE_SCALE_NOT_AVAILABLE
;
1924 /* Check if time for stats was elapsed */
1925 if (time_after(jiffies
, state
->per_jiffies_stats
)) {
1926 state
->per_jiffies_stats
= jiffies
+ msecs_to_jiffies(1000);
1929 snr
= dib7000p_get_snr(demod
);
1931 snr
= (1000L * snr
) >> 24;
1934 c
->cnr
.stat
[0].svalue
= snr
;
1935 c
->cnr
.stat
[0].scale
= FE_SCALE_DECIBEL
;
1937 /* Get UCB measures */
1938 dib7000p_read_unc_blocks(demod
, &val
);
1939 ucb
= val
- state
->old_ucb
;
1940 if (val
< state
->old_ucb
)
1941 ucb
+= 0x100000000LL
;
1943 c
->block_error
.stat
[0].scale
= FE_SCALE_COUNTER
;
1944 c
->block_error
.stat
[0].uvalue
= ucb
;
1946 /* Estimate the number of packets based on bitrate */
1948 time_us
= dib7000p_get_time_us(demod
);
1951 blocks
= 1250000ULL * 1000000ULL;
1952 do_div(blocks
, time_us
* 8 * 204);
1953 c
->block_count
.stat
[0].scale
= FE_SCALE_COUNTER
;
1954 c
->block_count
.stat
[0].uvalue
+= blocks
;
1960 /* Get post-BER measures */
1961 if (time_after(jiffies
, state
->ber_jiffies_stats
)) {
1962 time_us
= dib7000p_get_time_us(demod
);
1963 state
->ber_jiffies_stats
= jiffies
+ msecs_to_jiffies((time_us
+ 500) / 1000);
1965 dprintk("Next all layers stats available in %u us.\n", time_us
);
1967 dib7000p_read_ber(demod
, &val
);
1968 c
->post_bit_error
.stat
[0].scale
= FE_SCALE_COUNTER
;
1969 c
->post_bit_error
.stat
[0].uvalue
+= val
;
1971 c
->post_bit_count
.stat
[0].scale
= FE_SCALE_COUNTER
;
1972 c
->post_bit_count
.stat
[0].uvalue
+= 100000000;
1975 /* Get PER measures */
1976 if (show_per_stats
) {
1977 dib7000p_read_unc_blocks(demod
, &val
);
1979 c
->block_error
.stat
[0].scale
= FE_SCALE_COUNTER
;
1980 c
->block_error
.stat
[0].uvalue
+= val
;
1982 time_us
= dib7000p_get_time_us(demod
);
1984 blocks
= 1250000ULL * 1000000ULL;
1985 do_div(blocks
, time_us
* 8 * 204);
1986 c
->block_count
.stat
[0].scale
= FE_SCALE_COUNTER
;
1987 c
->block_count
.stat
[0].uvalue
+= blocks
;
1993 static int dib7000p_fe_get_tune_settings(struct dvb_frontend
*fe
, struct dvb_frontend_tune_settings
*tune
)
1995 tune
->min_delay_ms
= 1000;
1999 static void dib7000p_release(struct dvb_frontend
*demod
)
2001 struct dib7000p_state
*st
= demod
->demodulator_priv
;
2002 dibx000_exit_i2c_master(&st
->i2c_master
);
2003 i2c_del_adapter(&st
->dib7090_tuner_adap
);
2007 static int dib7000pc_detection(struct i2c_adapter
*i2c_adap
)
2010 struct i2c_msg msg
[2] = {
2011 {.addr
= 18 >> 1, .flags
= 0, .len
= 2},
2012 {.addr
= 18 >> 1, .flags
= I2C_M_RD
, .len
= 2},
2016 tx
= kzalloc(2, GFP_KERNEL
);
2019 rx
= kzalloc(2, GFP_KERNEL
);
2022 goto rx_memory_error
;
2031 if (i2c_transfer(i2c_adap
, msg
, 2) == 2)
2032 if (rx
[0] == 0x01 && rx
[1] == 0xb3) {
2033 dprintk("-D- DiB7000PC detected\n");
2038 msg
[0].addr
= msg
[1].addr
= 0x40;
2040 if (i2c_transfer(i2c_adap
, msg
, 2) == 2)
2041 if (rx
[0] == 0x01 && rx
[1] == 0xb3) {
2042 dprintk("-D- DiB7000PC detected\n");
2047 dprintk("-D- DiB7000PC not detected\n");
2056 static struct i2c_adapter
*dib7000p_get_i2c_master(struct dvb_frontend
*demod
, enum dibx000_i2c_interface intf
, int gating
)
2058 struct dib7000p_state
*st
= demod
->demodulator_priv
;
2059 return dibx000_get_i2c_adapter(&st
->i2c_master
, intf
, gating
);
2062 static int dib7000p_pid_filter_ctrl(struct dvb_frontend
*fe
, u8 onoff
)
2064 struct dib7000p_state
*state
= fe
->demodulator_priv
;
2065 u16 val
= dib7000p_read_word(state
, 235) & 0xffef;
2066 val
|= (onoff
& 0x1) << 4;
2067 dprintk("PID filter enabled %d\n", onoff
);
2068 return dib7000p_write_word(state
, 235, val
);
2071 static int dib7000p_pid_filter(struct dvb_frontend
*fe
, u8 id
, u16 pid
, u8 onoff
)
2073 struct dib7000p_state
*state
= fe
->demodulator_priv
;
2074 dprintk("PID filter: index %x, PID %d, OnOff %d\n", id
, pid
, onoff
);
2075 return dib7000p_write_word(state
, 241 + id
, onoff
? (1 << 13) | pid
: 0);
2078 static int dib7000p_i2c_enumeration(struct i2c_adapter
*i2c
, int no_of_demods
, u8 default_addr
, struct dib7000p_config cfg
[])
2080 struct dib7000p_state
*dpst
;
2084 dpst
= kzalloc(sizeof(struct dib7000p_state
), GFP_KERNEL
);
2088 dpst
->i2c_adap
= i2c
;
2089 mutex_init(&dpst
->i2c_buffer_lock
);
2091 for (k
= no_of_demods
- 1; k
>= 0; k
--) {
2094 /* designated i2c address */
2095 if (cfg
[k
].default_i2c_addr
!= 0)
2096 new_addr
= cfg
[k
].default_i2c_addr
+ (k
<< 1);
2098 new_addr
= (0x40 + k
) << 1;
2099 dpst
->i2c_addr
= new_addr
;
2100 dib7000p_write_word(dpst
, 1287, 0x0003); /* sram lead in, rdy */
2101 if (dib7000p_identify(dpst
) != 0) {
2102 dpst
->i2c_addr
= default_addr
;
2103 dib7000p_write_word(dpst
, 1287, 0x0003); /* sram lead in, rdy */
2104 if (dib7000p_identify(dpst
) != 0) {
2105 dprintk("DiB7000P #%d: not identified\n", k
);
2111 /* start diversity to pull_down div_str - just for i2c-enumeration */
2112 dib7000p_set_output_mode(dpst
, OUTMODE_DIVERSITY
);
2114 /* set new i2c address and force divstart */
2115 dib7000p_write_word(dpst
, 1285, (new_addr
<< 2) | 0x2);
2117 dprintk("IC %d initialized (to i2c_address 0x%x)\n", k
, new_addr
);
2120 for (k
= 0; k
< no_of_demods
; k
++) {
2122 if (cfg
[k
].default_i2c_addr
!= 0)
2123 dpst
->i2c_addr
= (cfg
[k
].default_i2c_addr
+ k
) << 1;
2125 dpst
->i2c_addr
= (0x40 + k
) << 1;
2128 dib7000p_write_word(dpst
, 1285, dpst
->i2c_addr
<< 2);
2130 /* deactivate div - it was just for i2c-enumeration */
2131 dib7000p_set_output_mode(dpst
, OUTMODE_HIGH_Z
);
2138 static const s32 lut_1000ln_mant
[] = {
2139 6908, 6956, 7003, 7047, 7090, 7131, 7170, 7208, 7244, 7279, 7313, 7346, 7377, 7408, 7438, 7467, 7495, 7523, 7549, 7575, 7600
2142 static s32
dib7000p_get_adc_power(struct dvb_frontend
*fe
)
2144 struct dib7000p_state
*state
= fe
->demodulator_priv
;
2145 u32 tmp_val
= 0, exp
= 0, mant
= 0;
2150 buf
[0] = dib7000p_read_word(state
, 0x184);
2151 buf
[1] = dib7000p_read_word(state
, 0x185);
2152 pow_i
= (buf
[0] << 16) | buf
[1];
2153 dprintk("raw pow_i = %d\n", pow_i
);
2156 while (tmp_val
>>= 1)
2159 mant
= (pow_i
* 1000 / (1 << exp
));
2160 dprintk(" mant = %d exp = %d\n", mant
/ 1000, exp
);
2162 ix
= (u8
) ((mant
- 1000) / 100); /* index of the LUT */
2163 dprintk(" ix = %d\n", ix
);
2165 pow_i
= (lut_1000ln_mant
[ix
] + 693 * (exp
- 20) - 6908);
2166 pow_i
= (pow_i
<< 8) / 1000;
2167 dprintk(" pow_i = %d\n", pow_i
);
2172 static int map_addr_to_serpar_number(struct i2c_msg
*msg
)
2174 if ((msg
->buf
[0] <= 15))
2176 else if (msg
->buf
[0] == 17)
2178 else if (msg
->buf
[0] == 16)
2180 else if (msg
->buf
[0] == 19)
2182 else if (msg
->buf
[0] >= 21 && msg
->buf
[0] <= 25)
2184 else if (msg
->buf
[0] == 28)
2191 static int w7090p_tuner_write_serpar(struct i2c_adapter
*i2c_adap
, struct i2c_msg msg
[], int num
)
2193 struct dib7000p_state
*state
= i2c_get_adapdata(i2c_adap
);
2196 u16 serpar_num
= msg
[0].buf
[0];
2198 while (n_overflow
== 1 && i
) {
2199 n_overflow
= (dib7000p_read_word(state
, 1984) >> 1) & 0x1;
2202 dprintk("Tuner ITF: write busy (overflow)\n");
2204 dib7000p_write_word(state
, 1985, (1 << 6) | (serpar_num
& 0x3f));
2205 dib7000p_write_word(state
, 1986, (msg
[0].buf
[1] << 8) | msg
[0].buf
[2]);
2210 static int w7090p_tuner_read_serpar(struct i2c_adapter
*i2c_adap
, struct i2c_msg msg
[], int num
)
2212 struct dib7000p_state
*state
= i2c_get_adapdata(i2c_adap
);
2213 u8 n_overflow
= 1, n_empty
= 1;
2215 u16 serpar_num
= msg
[0].buf
[0];
2218 while (n_overflow
== 1 && i
) {
2219 n_overflow
= (dib7000p_read_word(state
, 1984) >> 1) & 0x1;
2222 dprintk("TunerITF: read busy (overflow)\n");
2224 dib7000p_write_word(state
, 1985, (0 << 6) | (serpar_num
& 0x3f));
2227 while (n_empty
== 1 && i
) {
2228 n_empty
= dib7000p_read_word(state
, 1984) & 0x1;
2231 dprintk("TunerITF: read busy (empty)\n");
2233 read_word
= dib7000p_read_word(state
, 1987);
2234 msg
[1].buf
[0] = (read_word
>> 8) & 0xff;
2235 msg
[1].buf
[1] = (read_word
) & 0xff;
2240 static int w7090p_tuner_rw_serpar(struct i2c_adapter
*i2c_adap
, struct i2c_msg msg
[], int num
)
2242 if (map_addr_to_serpar_number(&msg
[0]) == 0) { /* else = Tuner regs to ignore : DIG_CFG, CTRL_RF_LT, PLL_CFG, PWM1_REG, ADCCLK, DIG_CFG_3; SLEEP_EN... */
2243 if (num
== 1) { /* write */
2244 return w7090p_tuner_write_serpar(i2c_adap
, msg
, 1);
2246 return w7090p_tuner_read_serpar(i2c_adap
, msg
, 2);
2252 static int dib7090p_rw_on_apb(struct i2c_adapter
*i2c_adap
,
2253 struct i2c_msg msg
[], int num
, u16 apb_address
)
2255 struct dib7000p_state
*state
= i2c_get_adapdata(i2c_adap
);
2258 if (num
== 1) { /* write */
2259 dib7000p_write_word(state
, apb_address
, ((msg
[0].buf
[1] << 8) | (msg
[0].buf
[2])));
2261 word
= dib7000p_read_word(state
, apb_address
);
2262 msg
[1].buf
[0] = (word
>> 8) & 0xff;
2263 msg
[1].buf
[1] = (word
) & 0xff;
2269 static int dib7090_tuner_xfer(struct i2c_adapter
*i2c_adap
, struct i2c_msg msg
[], int num
)
2271 struct dib7000p_state
*state
= i2c_get_adapdata(i2c_adap
);
2273 u16 apb_address
= 0, word
;
2275 switch (msg
[0].buf
[0]) {
2361 i
= ((dib7000p_read_word(state
, 72) >> 12) & 0x3);
2362 word
= dib7000p_read_word(state
, 384 + i
);
2363 msg
[1].buf
[0] = (word
>> 8) & 0xff;
2364 msg
[1].buf
[1] = (word
) & 0xff;
2367 if (num
== 1) { /* write */
2368 word
= (u16
) ((msg
[0].buf
[1] << 8) | msg
[0].buf
[2]);
2370 word
= (dib7000p_read_word(state
, 72) & ~(3 << 12)) | (word
<< 12);
2371 dib7000p_write_word(state
, 72, word
); /* Set the proper input */
2376 if (apb_address
!= 0) /* R/W access via APB */
2377 return dib7090p_rw_on_apb(i2c_adap
, msg
, num
, apb_address
);
2378 else /* R/W access via SERPAR */
2379 return w7090p_tuner_rw_serpar(i2c_adap
, msg
, num
);
2384 static u32
dib7000p_i2c_func(struct i2c_adapter
*adapter
)
2386 return I2C_FUNC_I2C
;
2389 static const struct i2c_algorithm dib7090_tuner_xfer_algo
= {
2390 .master_xfer
= dib7090_tuner_xfer
,
2391 .functionality
= dib7000p_i2c_func
,
2394 static struct i2c_adapter
*dib7090_get_i2c_tuner(struct dvb_frontend
*fe
)
2396 struct dib7000p_state
*st
= fe
->demodulator_priv
;
2397 return &st
->dib7090_tuner_adap
;
2400 static int dib7090_host_bus_drive(struct dib7000p_state
*state
, u8 drive
)
2404 /* drive host bus 2, 3, 4 */
2405 reg
= dib7000p_read_word(state
, 1798) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
2406 reg
|= (drive
<< 12) | (drive
<< 6) | drive
;
2407 dib7000p_write_word(state
, 1798, reg
);
2409 /* drive host bus 5,6 */
2410 reg
= dib7000p_read_word(state
, 1799) & ~((0x7 << 2) | (0x7 << 8));
2411 reg
|= (drive
<< 8) | (drive
<< 2);
2412 dib7000p_write_word(state
, 1799, reg
);
2414 /* drive host bus 7, 8, 9 */
2415 reg
= dib7000p_read_word(state
, 1800) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
2416 reg
|= (drive
<< 12) | (drive
<< 6) | drive
;
2417 dib7000p_write_word(state
, 1800, reg
);
2419 /* drive host bus 10, 11 */
2420 reg
= dib7000p_read_word(state
, 1801) & ~((0x7 << 2) | (0x7 << 8));
2421 reg
|= (drive
<< 8) | (drive
<< 2);
2422 dib7000p_write_word(state
, 1801, reg
);
2424 /* drive host bus 12, 13, 14 */
2425 reg
= dib7000p_read_word(state
, 1802) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
2426 reg
|= (drive
<< 12) | (drive
<< 6) | drive
;
2427 dib7000p_write_word(state
, 1802, reg
);
2432 static u32
dib7090_calcSyncFreq(u32 P_Kin
, u32 P_Kout
, u32 insertExtSynchro
, u32 syncSize
)
2435 u32 nom
= (insertExtSynchro
* P_Kin
+ syncSize
);
2437 u32 syncFreq
= ((nom
<< quantif
) / denom
);
2439 if ((syncFreq
& ((1 << quantif
) - 1)) != 0)
2440 syncFreq
= (syncFreq
>> quantif
) + 1;
2442 syncFreq
= (syncFreq
>> quantif
);
2445 syncFreq
= syncFreq
- 1;
2450 static int dib7090_cfg_DibTx(struct dib7000p_state
*state
, u32 P_Kin
, u32 P_Kout
, u32 insertExtSynchro
, u32 synchroMode
, u32 syncWord
, u32 syncSize
)
2452 dprintk("Configure DibStream Tx\n");
2454 dib7000p_write_word(state
, 1615, 1);
2455 dib7000p_write_word(state
, 1603, P_Kin
);
2456 dib7000p_write_word(state
, 1605, P_Kout
);
2457 dib7000p_write_word(state
, 1606, insertExtSynchro
);
2458 dib7000p_write_word(state
, 1608, synchroMode
);
2459 dib7000p_write_word(state
, 1609, (syncWord
>> 16) & 0xffff);
2460 dib7000p_write_word(state
, 1610, syncWord
& 0xffff);
2461 dib7000p_write_word(state
, 1612, syncSize
);
2462 dib7000p_write_word(state
, 1615, 0);
2467 static int dib7090_cfg_DibRx(struct dib7000p_state
*state
, u32 P_Kin
, u32 P_Kout
, u32 synchroMode
, u32 insertExtSynchro
, u32 syncWord
, u32 syncSize
,
2472 dprintk("Configure DibStream Rx\n");
2473 if ((P_Kin
!= 0) && (P_Kout
!= 0)) {
2474 syncFreq
= dib7090_calcSyncFreq(P_Kin
, P_Kout
, insertExtSynchro
, syncSize
);
2475 dib7000p_write_word(state
, 1542, syncFreq
);
2477 dib7000p_write_word(state
, 1554, 1);
2478 dib7000p_write_word(state
, 1536, P_Kin
);
2479 dib7000p_write_word(state
, 1537, P_Kout
);
2480 dib7000p_write_word(state
, 1539, synchroMode
);
2481 dib7000p_write_word(state
, 1540, (syncWord
>> 16) & 0xffff);
2482 dib7000p_write_word(state
, 1541, syncWord
& 0xffff);
2483 dib7000p_write_word(state
, 1543, syncSize
);
2484 dib7000p_write_word(state
, 1544, dataOutRate
);
2485 dib7000p_write_word(state
, 1554, 0);
2490 static void dib7090_enMpegMux(struct dib7000p_state
*state
, int onoff
)
2492 u16 reg_1287
= dib7000p_read_word(state
, 1287);
2496 reg_1287
&= ~(1<<7);
2503 dib7000p_write_word(state
, 1287, reg_1287
);
2506 static void dib7090_configMpegMux(struct dib7000p_state
*state
,
2507 u16 pulseWidth
, u16 enSerialMode
, u16 enSerialClkDiv2
)
2509 dprintk("Enable Mpeg mux\n");
2511 dib7090_enMpegMux(state
, 0);
2513 /* If the input mode is MPEG do not divide the serial clock */
2514 if ((enSerialMode
== 1) && (state
->input_mode_mpeg
== 1))
2515 enSerialClkDiv2
= 0;
2517 dib7000p_write_word(state
, 1287, ((pulseWidth
& 0x1f) << 2)
2518 | ((enSerialMode
& 0x1) << 1)
2519 | (enSerialClkDiv2
& 0x1));
2521 dib7090_enMpegMux(state
, 1);
2524 static void dib7090_setDibTxMux(struct dib7000p_state
*state
, int mode
)
2526 u16 reg_1288
= dib7000p_read_word(state
, 1288) & ~(0x7 << 7);
2530 dprintk("SET MPEG ON DIBSTREAM TX\n");
2531 dib7090_cfg_DibTx(state
, 8, 5, 0, 0, 0, 0);
2535 dprintk("SET DIV_OUT ON DIBSTREAM TX\n");
2536 dib7090_cfg_DibTx(state
, 5, 5, 0, 0, 0, 0);
2540 dprintk("SET ADC_OUT ON DIBSTREAM TX\n");
2541 dib7090_cfg_DibTx(state
, 20, 5, 10, 0, 0, 0);
2547 dib7000p_write_word(state
, 1288, reg_1288
);
2550 static void dib7090_setHostBusMux(struct dib7000p_state
*state
, int mode
)
2552 u16 reg_1288
= dib7000p_read_word(state
, 1288) & ~(0x7 << 4);
2555 case DEMOUT_ON_HOSTBUS
:
2556 dprintk("SET DEM OUT OLD INTERF ON HOST BUS\n");
2557 dib7090_enMpegMux(state
, 0);
2560 case DIBTX_ON_HOSTBUS
:
2561 dprintk("SET DIBSTREAM TX ON HOST BUS\n");
2562 dib7090_enMpegMux(state
, 0);
2565 case MPEG_ON_HOSTBUS
:
2566 dprintk("SET MPEG MUX ON HOST BUS\n");
2572 dib7000p_write_word(state
, 1288, reg_1288
);
2575 static int dib7090_set_diversity_in(struct dvb_frontend
*fe
, int onoff
)
2577 struct dib7000p_state
*state
= fe
->demodulator_priv
;
2581 case 0: /* only use the internal way - not the diversity input */
2582 dprintk("%s mode OFF : by default Enable Mpeg INPUT\n", __func__
);
2583 dib7090_cfg_DibRx(state
, 8, 5, 0, 0, 0, 8, 0);
2585 /* Do not divide the serial clock of MPEG MUX */
2586 /* in SERIAL MODE in case input mode MPEG is used */
2587 reg_1287
= dib7000p_read_word(state
, 1287);
2588 /* enSerialClkDiv2 == 1 ? */
2589 if ((reg_1287
& 0x1) == 1) {
2590 /* force enSerialClkDiv2 = 0 */
2592 dib7000p_write_word(state
, 1287, reg_1287
);
2594 state
->input_mode_mpeg
= 1;
2596 case 1: /* both ways */
2597 case 2: /* only the diversity input */
2598 dprintk("%s ON : Enable diversity INPUT\n", __func__
);
2599 dib7090_cfg_DibRx(state
, 5, 5, 0, 0, 0, 0, 0);
2600 state
->input_mode_mpeg
= 0;
2604 dib7000p_set_diversity_in(&state
->demod
, onoff
);
2608 static int dib7090_set_output_mode(struct dvb_frontend
*fe
, int mode
)
2610 struct dib7000p_state
*state
= fe
->demodulator_priv
;
2612 u16 outreg
, smo_mode
, fifo_threshold
;
2613 u8 prefer_mpeg_mux_use
= 1;
2616 dib7090_host_bus_drive(state
, 1);
2618 fifo_threshold
= 1792;
2619 smo_mode
= (dib7000p_read_word(state
, 235) & 0x0050) | (1 << 1);
2620 outreg
= dib7000p_read_word(state
, 1286) & ~((1 << 10) | (0x7 << 6) | (1 << 1));
2623 case OUTMODE_HIGH_Z
:
2627 case OUTMODE_MPEG2_SERIAL
:
2628 if (prefer_mpeg_mux_use
) {
2629 dprintk("setting output mode TS_SERIAL using Mpeg Mux\n");
2630 dib7090_configMpegMux(state
, 3, 1, 1);
2631 dib7090_setHostBusMux(state
, MPEG_ON_HOSTBUS
);
2632 } else {/* Use Smooth block */
2633 dprintk("setting output mode TS_SERIAL using Smooth bloc\n");
2634 dib7090_setHostBusMux(state
, DEMOUT_ON_HOSTBUS
);
2635 outreg
|= (2<<6) | (0 << 1);
2639 case OUTMODE_MPEG2_PAR_GATED_CLK
:
2640 if (prefer_mpeg_mux_use
) {
2641 dprintk("setting output mode TS_PARALLEL_GATED using Mpeg Mux\n");
2642 dib7090_configMpegMux(state
, 2, 0, 0);
2643 dib7090_setHostBusMux(state
, MPEG_ON_HOSTBUS
);
2644 } else { /* Use Smooth block */
2645 dprintk("setting output mode TS_PARALLEL_GATED using Smooth block\n");
2646 dib7090_setHostBusMux(state
, DEMOUT_ON_HOSTBUS
);
2651 case OUTMODE_MPEG2_PAR_CONT_CLK
: /* Using Smooth block only */
2652 dprintk("setting output mode TS_PARALLEL_CONT using Smooth block\n");
2653 dib7090_setHostBusMux(state
, DEMOUT_ON_HOSTBUS
);
2657 case OUTMODE_MPEG2_FIFO
: /* Using Smooth block because not supported by new Mpeg Mux bloc */
2658 dprintk("setting output mode TS_FIFO using Smooth block\n");
2659 dib7090_setHostBusMux(state
, DEMOUT_ON_HOSTBUS
);
2661 smo_mode
|= (3 << 1);
2662 fifo_threshold
= 512;
2665 case OUTMODE_DIVERSITY
:
2666 dprintk("setting output mode MODE_DIVERSITY\n");
2667 dib7090_setDibTxMux(state
, DIV_ON_DIBTX
);
2668 dib7090_setHostBusMux(state
, DIBTX_ON_HOSTBUS
);
2671 case OUTMODE_ANALOG_ADC
:
2672 dprintk("setting output mode MODE_ANALOG_ADC\n");
2673 dib7090_setDibTxMux(state
, ADC_ON_DIBTX
);
2674 dib7090_setHostBusMux(state
, DIBTX_ON_HOSTBUS
);
2677 if (mode
!= OUTMODE_HIGH_Z
)
2678 outreg
|= (1 << 10);
2680 if (state
->cfg
.output_mpeg2_in_188_bytes
)
2681 smo_mode
|= (1 << 5);
2683 ret
|= dib7000p_write_word(state
, 235, smo_mode
);
2684 ret
|= dib7000p_write_word(state
, 236, fifo_threshold
); /* synchronous fread */
2685 ret
|= dib7000p_write_word(state
, 1286, outreg
);
2690 static int dib7090_tuner_sleep(struct dvb_frontend
*fe
, int onoff
)
2692 struct dib7000p_state
*state
= fe
->demodulator_priv
;
2695 dprintk("sleep dib7090: %d\n", onoff
);
2697 en_cur_state
= dib7000p_read_word(state
, 1922);
2699 if (en_cur_state
> 0xff)
2700 state
->tuner_enable
= en_cur_state
;
2703 en_cur_state
&= 0x00ff;
2705 if (state
->tuner_enable
!= 0)
2706 en_cur_state
= state
->tuner_enable
;
2709 dib7000p_write_word(state
, 1922, en_cur_state
);
2714 static int dib7090_get_adc_power(struct dvb_frontend
*fe
)
2716 return dib7000p_get_adc_power(fe
);
2719 static int dib7090_slave_reset(struct dvb_frontend
*fe
)
2721 struct dib7000p_state
*state
= fe
->demodulator_priv
;
2724 reg
= dib7000p_read_word(state
, 1794);
2725 dib7000p_write_word(state
, 1794, reg
| (4 << 12));
2727 dib7000p_write_word(state
, 1032, 0xffff);
2731 static const struct dvb_frontend_ops dib7000p_ops
;
2732 static struct dvb_frontend
*dib7000p_init(struct i2c_adapter
*i2c_adap
, u8 i2c_addr
, struct dib7000p_config
*cfg
)
2734 struct dvb_frontend
*demod
;
2735 struct dib7000p_state
*st
;
2736 st
= kzalloc(sizeof(struct dib7000p_state
), GFP_KERNEL
);
2740 memcpy(&st
->cfg
, cfg
, sizeof(struct dib7000p_config
));
2741 st
->i2c_adap
= i2c_adap
;
2742 st
->i2c_addr
= i2c_addr
;
2743 st
->gpio_val
= cfg
->gpio_val
;
2744 st
->gpio_dir
= cfg
->gpio_dir
;
2746 /* Ensure the output mode remains at the previous default if it's
2747 * not specifically set by the caller.
2749 if ((st
->cfg
.output_mode
!= OUTMODE_MPEG2_SERIAL
) && (st
->cfg
.output_mode
!= OUTMODE_MPEG2_PAR_GATED_CLK
))
2750 st
->cfg
.output_mode
= OUTMODE_MPEG2_FIFO
;
2753 demod
->demodulator_priv
= st
;
2754 memcpy(&st
->demod
.ops
, &dib7000p_ops
, sizeof(struct dvb_frontend_ops
));
2755 mutex_init(&st
->i2c_buffer_lock
);
2757 dib7000p_write_word(st
, 1287, 0x0003); /* sram lead in, rdy */
2759 if (dib7000p_identify(st
) != 0)
2762 st
->version
= dib7000p_read_word(st
, 897);
2764 /* FIXME: make sure the dev.parent field is initialized, or else
2765 request_firmware() will hit an OOPS (this should be moved somewhere
2767 st
->i2c_master
.gated_tuner_i2c_adap
.dev
.parent
= i2c_adap
->dev
.parent
;
2769 dibx000_init_i2c_master(&st
->i2c_master
, DIB7000P
, st
->i2c_adap
, st
->i2c_addr
);
2771 /* init 7090 tuner adapter */
2772 strscpy(st
->dib7090_tuner_adap
.name
, "DiB7090 tuner interface",
2773 sizeof(st
->dib7090_tuner_adap
.name
));
2774 st
->dib7090_tuner_adap
.algo
= &dib7090_tuner_xfer_algo
;
2775 st
->dib7090_tuner_adap
.algo_data
= NULL
;
2776 st
->dib7090_tuner_adap
.dev
.parent
= st
->i2c_adap
->dev
.parent
;
2777 i2c_set_adapdata(&st
->dib7090_tuner_adap
, st
);
2778 i2c_add_adapter(&st
->dib7090_tuner_adap
);
2780 dib7000p_demod_reset(st
);
2782 dib7000p_reset_stats(demod
);
2784 if (st
->version
== SOC7090
) {
2785 dib7090_set_output_mode(demod
, st
->cfg
.output_mode
);
2786 dib7090_set_diversity_in(demod
, 0);
2796 void *dib7000p_attach(struct dib7000p_ops
*ops
)
2801 ops
->slave_reset
= dib7090_slave_reset
;
2802 ops
->get_adc_power
= dib7090_get_adc_power
;
2803 ops
->dib7000pc_detection
= dib7000pc_detection
;
2804 ops
->get_i2c_tuner
= dib7090_get_i2c_tuner
;
2805 ops
->tuner_sleep
= dib7090_tuner_sleep
;
2806 ops
->init
= dib7000p_init
;
2807 ops
->set_agc1_min
= dib7000p_set_agc1_min
;
2808 ops
->set_gpio
= dib7000p_set_gpio
;
2809 ops
->i2c_enumeration
= dib7000p_i2c_enumeration
;
2810 ops
->pid_filter
= dib7000p_pid_filter
;
2811 ops
->pid_filter_ctrl
= dib7000p_pid_filter_ctrl
;
2812 ops
->get_i2c_master
= dib7000p_get_i2c_master
;
2813 ops
->update_pll
= dib7000p_update_pll
;
2814 ops
->ctrl_timf
= dib7000p_ctrl_timf
;
2815 ops
->get_agc_values
= dib7000p_get_agc_values
;
2816 ops
->set_wbd_ref
= dib7000p_set_wbd_ref
;
2820 EXPORT_SYMBOL_GPL(dib7000p_attach
);
2822 static const struct dvb_frontend_ops dib7000p_ops
= {
2823 .delsys
= { SYS_DVBT
},
2825 .name
= "DiBcom 7000PC",
2826 .frequency_min_hz
= 44250 * kHz
,
2827 .frequency_max_hz
= 867250 * kHz
,
2828 .frequency_stepsize_hz
= 62500,
2829 .caps
= FE_CAN_INVERSION_AUTO
|
2830 FE_CAN_FEC_1_2
| FE_CAN_FEC_2_3
| FE_CAN_FEC_3_4
|
2831 FE_CAN_FEC_5_6
| FE_CAN_FEC_7_8
| FE_CAN_FEC_AUTO
|
2832 FE_CAN_QPSK
| FE_CAN_QAM_16
| FE_CAN_QAM_64
| FE_CAN_QAM_AUTO
|
2833 FE_CAN_TRANSMISSION_MODE_AUTO
| FE_CAN_GUARD_INTERVAL_AUTO
| FE_CAN_RECOVER
| FE_CAN_HIERARCHY_AUTO
,
2836 .release
= dib7000p_release
,
2838 .init
= dib7000p_wakeup
,
2839 .sleep
= dib7000p_sleep
,
2841 .set_frontend
= dib7000p_set_frontend
,
2842 .get_tune_settings
= dib7000p_fe_get_tune_settings
,
2843 .get_frontend
= dib7000p_get_frontend
,
2845 .read_status
= dib7000p_read_status
,
2846 .read_ber
= dib7000p_read_ber
,
2847 .read_signal_strength
= dib7000p_read_signal_strength
,
2848 .read_snr
= dib7000p_read_snr
,
2849 .read_ucblocks
= dib7000p_read_unc_blocks
,
2852 MODULE_AUTHOR("Olivier Grenie <olivie.grenie@parrot.com>");
2853 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
2854 MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
2855 MODULE_LICENSE("GPL");