2 * Linux-DVB Driver for DiBcom's second generation DiB7000P (PC).
4 * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
10 #include <linux/kernel.h>
11 #include <linux/slab.h>
12 #include <linux/i2c.h>
13 #include <linux/mutex.h>
16 #include "dvb_frontend.h"
21 module_param(debug
, int, 0644);
22 MODULE_PARM_DESC(debug
, "turn on debugging (default: 0)");
24 static int buggy_sfn_workaround
;
25 module_param(buggy_sfn_workaround
, int, 0644);
26 MODULE_PARM_DESC(buggy_sfn_workaround
, "Enable work-around for buggy SFNs (default: 0)");
28 #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0)
31 struct i2c_adapter
*i2c_adap
;
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
;
77 enum dib7000p_power_mode
{
78 DIB7000P_POWER_ALL
= 0,
79 DIB7000P_POWER_ANALOG_ADC
,
80 DIB7000P_POWER_INTERFACE_ONLY
,
83 /* dib7090 specific fonctions */
84 static int dib7090_set_output_mode(struct dvb_frontend
*fe
, int mode
);
85 static int dib7090_set_diversity_in(struct dvb_frontend
*fe
, int onoff
);
86 static void dib7090_setDibTxMux(struct dib7000p_state
*state
, int mode
);
87 static void dib7090_setHostBusMux(struct dib7000p_state
*state
, int mode
);
89 static u16
dib7000p_read_word(struct dib7000p_state
*state
, u16 reg
)
93 if (mutex_lock_interruptible(&state
->i2c_buffer_lock
) < 0) {
94 dprintk("could not acquire lock");
98 state
->i2c_write_buffer
[0] = reg
>> 8;
99 state
->i2c_write_buffer
[1] = reg
& 0xff;
101 memset(state
->msg
, 0, 2 * sizeof(struct i2c_msg
));
102 state
->msg
[0].addr
= state
->i2c_addr
>> 1;
103 state
->msg
[0].flags
= 0;
104 state
->msg
[0].buf
= state
->i2c_write_buffer
;
105 state
->msg
[0].len
= 2;
106 state
->msg
[1].addr
= state
->i2c_addr
>> 1;
107 state
->msg
[1].flags
= I2C_M_RD
;
108 state
->msg
[1].buf
= state
->i2c_read_buffer
;
109 state
->msg
[1].len
= 2;
111 if (i2c_transfer(state
->i2c_adap
, state
->msg
, 2) != 2)
112 dprintk("i2c read error on %d", reg
);
114 ret
= (state
->i2c_read_buffer
[0] << 8) | state
->i2c_read_buffer
[1];
115 mutex_unlock(&state
->i2c_buffer_lock
);
119 static int dib7000p_write_word(struct dib7000p_state
*state
, u16 reg
, u16 val
)
123 if (mutex_lock_interruptible(&state
->i2c_buffer_lock
) < 0) {
124 dprintk("could not acquire lock");
128 state
->i2c_write_buffer
[0] = (reg
>> 8) & 0xff;
129 state
->i2c_write_buffer
[1] = reg
& 0xff;
130 state
->i2c_write_buffer
[2] = (val
>> 8) & 0xff;
131 state
->i2c_write_buffer
[3] = val
& 0xff;
133 memset(&state
->msg
[0], 0, sizeof(struct i2c_msg
));
134 state
->msg
[0].addr
= state
->i2c_addr
>> 1;
135 state
->msg
[0].flags
= 0;
136 state
->msg
[0].buf
= state
->i2c_write_buffer
;
137 state
->msg
[0].len
= 4;
139 ret
= (i2c_transfer(state
->i2c_adap
, state
->msg
, 1) != 1 ?
141 mutex_unlock(&state
->i2c_buffer_lock
);
145 static void dib7000p_write_tab(struct dib7000p_state
*state
, u16
* buf
)
154 dib7000p_write_word(state
, r
, *n
++);
161 static int dib7000p_set_output_mode(struct dib7000p_state
*state
, int mode
)
164 u16 outreg
, fifo_threshold
, smo_mode
;
167 fifo_threshold
= 1792;
168 smo_mode
= (dib7000p_read_word(state
, 235) & 0x0050) | (1 << 1);
170 dprintk("setting output mode for demod %p to %d", &state
->demod
, mode
);
173 case OUTMODE_MPEG2_PAR_GATED_CLK
:
174 outreg
= (1 << 10); /* 0x0400 */
176 case OUTMODE_MPEG2_PAR_CONT_CLK
:
177 outreg
= (1 << 10) | (1 << 6); /* 0x0440 */
179 case OUTMODE_MPEG2_SERIAL
:
180 outreg
= (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */
182 case OUTMODE_DIVERSITY
:
183 if (state
->cfg
.hostbus_diversity
)
184 outreg
= (1 << 10) | (4 << 6); /* 0x0500 */
188 case OUTMODE_MPEG2_FIFO
:
189 smo_mode
|= (3 << 1);
190 fifo_threshold
= 512;
191 outreg
= (1 << 10) | (5 << 6);
193 case OUTMODE_ANALOG_ADC
:
194 outreg
= (1 << 10) | (3 << 6);
200 dprintk("Unhandled output_mode passed to be set for demod %p", &state
->demod
);
204 if (state
->cfg
.output_mpeg2_in_188_bytes
)
205 smo_mode
|= (1 << 5);
207 ret
|= dib7000p_write_word(state
, 235, smo_mode
);
208 ret
|= dib7000p_write_word(state
, 236, fifo_threshold
); /* synchronous fread */
209 if (state
->version
!= SOC7090
)
210 ret
|= dib7000p_write_word(state
, 1286, outreg
); /* P_Div_active */
215 static int dib7000p_set_diversity_in(struct dvb_frontend
*demod
, int onoff
)
217 struct dib7000p_state
*state
= demod
->demodulator_priv
;
219 if (state
->div_force_off
) {
220 dprintk("diversity combination deactivated - forced by COFDM parameters");
222 dib7000p_write_word(state
, 207, 0);
224 dib7000p_write_word(state
, 207, (state
->div_sync_wait
<< 4) | (1 << 2) | (2 << 0));
226 state
->div_state
= (u8
) onoff
;
229 dib7000p_write_word(state
, 204, 6);
230 dib7000p_write_word(state
, 205, 16);
231 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
233 dib7000p_write_word(state
, 204, 1);
234 dib7000p_write_word(state
, 205, 0);
240 static int dib7000p_set_power_mode(struct dib7000p_state
*state
, enum dib7000p_power_mode mode
)
242 /* by default everything is powered off */
243 u16 reg_774
= 0x3fff, reg_775
= 0xffff, reg_776
= 0x0007, reg_899
= 0x0003, reg_1280
= (0xfe00) | (dib7000p_read_word(state
, 1280) & 0x01ff);
245 /* now, depending on the requested mode, we power on */
247 /* power up everything in the demod */
248 case DIB7000P_POWER_ALL
:
253 if (state
->version
== SOC7090
)
259 case DIB7000P_POWER_ANALOG_ADC
:
260 /* dem, cfg, iqc, sad, agc */
261 reg_774
&= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
263 reg_776
&= ~((1 << 0));
265 if (state
->version
!= SOC7090
)
266 reg_1280
&= ~((1 << 11));
267 reg_1280
&= ~(1 << 6);
268 /* fall through wanted to enable the interfaces */
270 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
271 case DIB7000P_POWER_INTERFACE_ONLY
: /* TODO power up either SDIO or I2C */
272 if (state
->version
== SOC7090
)
273 reg_1280
&= ~((1 << 7) | (1 << 5));
275 reg_1280
&= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
278 /* TODO following stuff is just converted from the dib7000-driver - check when is used what */
281 dib7000p_write_word(state
, 774, reg_774
);
282 dib7000p_write_word(state
, 775, reg_775
);
283 dib7000p_write_word(state
, 776, reg_776
);
284 dib7000p_write_word(state
, 1280, reg_1280
);
285 if (state
->version
!= SOC7090
)
286 dib7000p_write_word(state
, 899, reg_899
);
291 static void dib7000p_set_adc_state(struct dib7000p_state
*state
, enum dibx000_adc_states no
)
293 u16 reg_908
= 0, reg_909
= 0;
296 if (state
->version
!= SOC7090
) {
297 reg_908
= dib7000p_read_word(state
, 908);
298 reg_909
= dib7000p_read_word(state
, 909);
302 case DIBX000_SLOW_ADC_ON
:
303 if (state
->version
== SOC7090
) {
304 reg
= dib7000p_read_word(state
, 1925);
306 dib7000p_write_word(state
, 1925, reg
| (1 << 4) | (1 << 2)); /* en_slowAdc = 1 & reset_sladc = 1 */
308 reg
= dib7000p_read_word(state
, 1925); /* read acces to make it works... strange ... */
310 dib7000p_write_word(state
, 1925, reg
& ~(1 << 4)); /* en_slowAdc = 1 & reset_sladc = 0 */
312 reg
= dib7000p_read_word(state
, 72) & ~((0x3 << 14) | (0x3 << 12));
313 dib7000p_write_word(state
, 72, reg
| (1 << 14) | (3 << 12) | 524); /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ; (Vin2 = Vcm) */
315 reg_909
|= (1 << 1) | (1 << 0);
316 dib7000p_write_word(state
, 909, reg_909
);
317 reg_909
&= ~(1 << 1);
321 case DIBX000_SLOW_ADC_OFF
:
322 if (state
->version
== SOC7090
) {
323 reg
= dib7000p_read_word(state
, 1925);
324 dib7000p_write_word(state
, 1925, (reg
& ~(1 << 2)) | (1 << 4)); /* reset_sladc = 1 en_slowAdc = 0 */
326 reg_909
|= (1 << 1) | (1 << 0);
334 case DIBX000_ADC_OFF
:
335 reg_908
|= (1 << 14) | (1 << 13) | (1 << 12);
336 reg_909
|= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
339 case DIBX000_VBG_ENABLE
:
340 reg_908
&= ~(1 << 15);
343 case DIBX000_VBG_DISABLE
:
344 reg_908
|= (1 << 15);
351 // dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
353 reg_909
|= (state
->cfg
.disable_sample_and_hold
& 1) << 4;
354 reg_908
|= (state
->cfg
.enable_current_mirror
& 1) << 7;
356 if (state
->version
!= SOC7090
) {
357 dib7000p_write_word(state
, 908, reg_908
);
358 dib7000p_write_word(state
, 909, reg_909
);
362 static int dib7000p_set_bandwidth(struct dib7000p_state
*state
, u32 bw
)
366 // store the current bandwidth for later use
367 state
->current_bandwidth
= bw
;
369 if (state
->timf
== 0) {
370 dprintk("using default timf");
371 timf
= state
->cfg
.bw
->timf
;
373 dprintk("using updated timf");
377 timf
= timf
* (bw
/ 50) / 160;
379 dib7000p_write_word(state
, 23, (u16
) ((timf
>> 16) & 0xffff));
380 dib7000p_write_word(state
, 24, (u16
) ((timf
) & 0xffff));
385 static int dib7000p_sad_calib(struct dib7000p_state
*state
)
388 dib7000p_write_word(state
, 73, (0 << 1) | (0 << 0));
390 if (state
->version
== SOC7090
)
391 dib7000p_write_word(state
, 74, 2048);
393 dib7000p_write_word(state
, 74, 776);
395 /* do the calibration */
396 dib7000p_write_word(state
, 73, (1 << 0));
397 dib7000p_write_word(state
, 73, (0 << 0));
404 int dib7000p_set_wbd_ref(struct dvb_frontend
*demod
, u16 value
)
406 struct dib7000p_state
*state
= demod
->demodulator_priv
;
409 state
->wbd_ref
= value
;
410 return dib7000p_write_word(state
, 105, (dib7000p_read_word(state
, 105) & 0xf000) | value
);
412 EXPORT_SYMBOL(dib7000p_set_wbd_ref
);
414 int dib7000p_get_agc_values(struct dvb_frontend
*fe
,
415 u16
*agc_global
, u16
*agc1
, u16
*agc2
, u16
*wbd
)
417 struct dib7000p_state
*state
= fe
->demodulator_priv
;
419 if (agc_global
!= NULL
)
420 *agc_global
= dib7000p_read_word(state
, 394);
422 *agc1
= dib7000p_read_word(state
, 392);
424 *agc2
= dib7000p_read_word(state
, 393);
426 *wbd
= dib7000p_read_word(state
, 397);
430 EXPORT_SYMBOL(dib7000p_get_agc_values
);
432 int dib7000p_set_agc1_min(struct dvb_frontend
*fe
, u16 v
)
434 struct dib7000p_state
*state
= fe
->demodulator_priv
;
435 return dib7000p_write_word(state
, 108, v
);
437 EXPORT_SYMBOL(dib7000p_set_agc1_min
);
439 static void dib7000p_reset_pll(struct dib7000p_state
*state
)
441 struct dibx000_bandwidth_config
*bw
= &state
->cfg
.bw
[0];
444 if (state
->version
== SOC7090
) {
445 dib7000p_write_word(state
, 1856, (!bw
->pll_reset
<< 13) | (bw
->pll_range
<< 12) | (bw
->pll_ratio
<< 6) | (bw
->pll_prediv
));
447 while (((dib7000p_read_word(state
, 1856) >> 15) & 0x1) != 1)
450 dib7000p_write_word(state
, 1857, dib7000p_read_word(state
, 1857) | (!bw
->pll_bypass
<< 15));
452 /* force PLL bypass */
453 clk_cfg0
= (1 << 15) | ((bw
->pll_ratio
& 0x3f) << 9) |
454 (bw
->modulo
<< 7) | (bw
->ADClkSrc
<< 6) | (bw
->IO_CLK_en_core
<< 5) | (bw
->bypclk_div
<< 2) | (bw
->enable_refdiv
<< 1) | (0 << 0);
456 dib7000p_write_word(state
, 900, clk_cfg0
);
459 dib7000p_write_word(state
, 903, (bw
->pll_prediv
<< 5) | (((bw
->pll_ratio
>> 6) & 0x3) << 3) | (bw
->pll_range
<< 1) | bw
->pll_reset
);
460 clk_cfg0
= (bw
->pll_bypass
<< 15) | (clk_cfg0
& 0x7fff);
461 dib7000p_write_word(state
, 900, clk_cfg0
);
464 dib7000p_write_word(state
, 18, (u16
) (((bw
->internal
* 1000) >> 16) & 0xffff));
465 dib7000p_write_word(state
, 19, (u16
) ((bw
->internal
* 1000) & 0xffff));
466 dib7000p_write_word(state
, 21, (u16
) ((bw
->ifreq
>> 16) & 0xffff));
467 dib7000p_write_word(state
, 22, (u16
) ((bw
->ifreq
) & 0xffff));
469 dib7000p_write_word(state
, 72, bw
->sad_cfg
);
472 static u32
dib7000p_get_internal_freq(struct dib7000p_state
*state
)
474 u32 internal
= (u32
) dib7000p_read_word(state
, 18) << 16;
475 internal
|= (u32
) dib7000p_read_word(state
, 19);
481 int dib7000p_update_pll(struct dvb_frontend
*fe
, struct dibx000_bandwidth_config
*bw
)
483 struct dib7000p_state
*state
= fe
->demodulator_priv
;
484 u16 reg_1857
, reg_1856
= dib7000p_read_word(state
, 1856);
488 /* get back old values */
489 prediv
= reg_1856
& 0x3f;
490 loopdiv
= (reg_1856
>> 6) & 0x3f;
492 if ((bw
!= NULL
) && (bw
->pll_prediv
!= prediv
|| bw
->pll_ratio
!= loopdiv
)) {
493 dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv
, bw
->pll_prediv
, loopdiv
, bw
->pll_ratio
);
495 reg_1857
= dib7000p_read_word(state
, 1857);
496 dib7000p_write_word(state
, 1857, reg_1857
& ~(1 << 15));
498 dib7000p_write_word(state
, 1856, reg_1856
| ((bw
->pll_ratio
& 0x3f) << 6) | (bw
->pll_prediv
& 0x3f));
500 /* write new system clk into P_sec_len */
501 internal
= dib7000p_get_internal_freq(state
);
502 xtal
= (internal
/ loopdiv
) * prediv
;
503 internal
= 1000 * (xtal
/ bw
->pll_prediv
) * bw
->pll_ratio
; /* new internal */
504 dib7000p_write_word(state
, 18, (u16
) ((internal
>> 16) & 0xffff));
505 dib7000p_write_word(state
, 19, (u16
) (internal
& 0xffff));
507 dib7000p_write_word(state
, 1857, reg_1857
| (1 << 15));
509 while (((dib7000p_read_word(state
, 1856) >> 15) & 0x1) != 1)
510 dprintk("Waiting for PLL to lock");
516 EXPORT_SYMBOL(dib7000p_update_pll
);
518 static int dib7000p_reset_gpio(struct dib7000p_state
*st
)
520 /* reset the GPIOs */
521 dprintk("gpio dir: %x: val: %x, pwm_pos: %x", st
->gpio_dir
, st
->gpio_val
, st
->cfg
.gpio_pwm_pos
);
523 dib7000p_write_word(st
, 1029, st
->gpio_dir
);
524 dib7000p_write_word(st
, 1030, st
->gpio_val
);
526 /* TODO 1031 is P_gpio_od */
528 dib7000p_write_word(st
, 1032, st
->cfg
.gpio_pwm_pos
);
530 dib7000p_write_word(st
, 1037, st
->cfg
.pwm_freq_div
);
534 static int dib7000p_cfg_gpio(struct dib7000p_state
*st
, u8 num
, u8 dir
, u8 val
)
536 st
->gpio_dir
= dib7000p_read_word(st
, 1029);
537 st
->gpio_dir
&= ~(1 << num
); /* reset the direction bit */
538 st
->gpio_dir
|= (dir
& 0x1) << num
; /* set the new direction */
539 dib7000p_write_word(st
, 1029, st
->gpio_dir
);
541 st
->gpio_val
= dib7000p_read_word(st
, 1030);
542 st
->gpio_val
&= ~(1 << num
); /* reset the direction bit */
543 st
->gpio_val
|= (val
& 0x01) << num
; /* set the new value */
544 dib7000p_write_word(st
, 1030, st
->gpio_val
);
549 int dib7000p_set_gpio(struct dvb_frontend
*demod
, u8 num
, u8 dir
, u8 val
)
551 struct dib7000p_state
*state
= demod
->demodulator_priv
;
552 return dib7000p_cfg_gpio(state
, num
, dir
, val
);
554 EXPORT_SYMBOL(dib7000p_set_gpio
);
556 static u16 dib7000p_defaults
[] = {
557 // auto search configuration
560 (1<<3)|(1<<11)|(1<<12)|(1<<13),
561 0x0814, /* Equal Lock */
580 /* set ADC level to -16 */
582 (1 << 13) - 825 - 117,
583 (1 << 13) - 837 - 117,
584 (1 << 13) - 811 - 117,
585 (1 << 13) - 766 - 117,
586 (1 << 13) - 737 - 117,
587 (1 << 13) - 693 - 117,
588 (1 << 13) - 648 - 117,
589 (1 << 13) - 619 - 117,
590 (1 << 13) - 575 - 117,
591 (1 << 13) - 531 - 117,
592 (1 << 13) - 501 - 117,
597 /* disable power smoothing */
639 static int dib7000p_demod_reset(struct dib7000p_state
*state
)
641 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
643 if (state
->version
== SOC7090
)
644 dibx000_reset_i2c_master(&state
->i2c_master
);
646 dib7000p_set_adc_state(state
, DIBX000_VBG_ENABLE
);
648 /* restart all parts */
649 dib7000p_write_word(state
, 770, 0xffff);
650 dib7000p_write_word(state
, 771, 0xffff);
651 dib7000p_write_word(state
, 772, 0x001f);
652 dib7000p_write_word(state
, 1280, 0x001f - ((1 << 4) | (1 << 3)));
654 dib7000p_write_word(state
, 770, 0);
655 dib7000p_write_word(state
, 771, 0);
656 dib7000p_write_word(state
, 772, 0);
657 dib7000p_write_word(state
, 1280, 0);
659 if (state
->version
!= SOC7090
) {
660 dib7000p_write_word(state
, 898, 0x0003);
661 dib7000p_write_word(state
, 898, 0);
665 dib7000p_reset_pll(state
);
667 if (dib7000p_reset_gpio(state
) != 0)
668 dprintk("GPIO reset was not successful.");
670 if (state
->version
== SOC7090
) {
671 dib7000p_write_word(state
, 899, 0);
674 dib7000p_write_word(state
, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */
675 dib7000p_write_word(state
, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */
676 dib7000p_write_word(state
, 44, 300); /* 300 fag P_iqc_dect_min = +280 */
677 dib7000p_write_word(state
, 273, (0<<6) | 30);
679 if (dib7000p_set_output_mode(state
, OUTMODE_HIGH_Z
) != 0)
680 dprintk("OUTPUT_MODE could not be reset.");
682 dib7000p_set_adc_state(state
, DIBX000_SLOW_ADC_ON
);
683 dib7000p_sad_calib(state
);
684 dib7000p_set_adc_state(state
, DIBX000_SLOW_ADC_OFF
);
686 /* unforce divstr regardless whether i2c enumeration was done or not */
687 dib7000p_write_word(state
, 1285, dib7000p_read_word(state
, 1285) & ~(1 << 1));
689 dib7000p_set_bandwidth(state
, 8000);
691 if (state
->version
== SOC7090
) {
692 dib7000p_write_word(state
, 36, 0x0755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */
694 if (state
->cfg
.tuner_is_baseband
)
695 dib7000p_write_word(state
, 36, 0x0755);
697 dib7000p_write_word(state
, 36, 0x1f55);
700 dib7000p_write_tab(state
, dib7000p_defaults
);
701 if (state
->version
!= SOC7090
) {
702 dib7000p_write_word(state
, 901, 0x0006);
703 dib7000p_write_word(state
, 902, (3 << 10) | (1 << 6));
704 dib7000p_write_word(state
, 905, 0x2c8e);
707 dib7000p_set_power_mode(state
, DIB7000P_POWER_INTERFACE_ONLY
);
712 static void dib7000p_pll_clk_cfg(struct dib7000p_state
*state
)
715 tmp
= dib7000p_read_word(state
, 903);
716 dib7000p_write_word(state
, 903, (tmp
| 0x1));
717 tmp
= dib7000p_read_word(state
, 900);
718 dib7000p_write_word(state
, 900, (tmp
& 0x7fff) | (1 << 6));
721 static void dib7000p_restart_agc(struct dib7000p_state
*state
)
723 // P_restart_iqc & P_restart_agc
724 dib7000p_write_word(state
, 770, (1 << 11) | (1 << 9));
725 dib7000p_write_word(state
, 770, 0x0000);
728 static int dib7000p_update_lna(struct dib7000p_state
*state
)
732 if (state
->cfg
.update_lna
) {
733 dyn_gain
= dib7000p_read_word(state
, 394);
734 if (state
->cfg
.update_lna(&state
->demod
, dyn_gain
)) {
735 dib7000p_restart_agc(state
);
743 static int dib7000p_set_agc_config(struct dib7000p_state
*state
, u8 band
)
745 struct dibx000_agc_config
*agc
= NULL
;
747 if (state
->current_band
== band
&& state
->current_agc
!= NULL
)
749 state
->current_band
= band
;
751 for (i
= 0; i
< state
->cfg
.agc_config_count
; i
++)
752 if (state
->cfg
.agc
[i
].band_caps
& band
) {
753 agc
= &state
->cfg
.agc
[i
];
758 dprintk("no valid AGC configuration found for band 0x%02x", band
);
762 state
->current_agc
= agc
;
765 dib7000p_write_word(state
, 75, agc
->setup
);
766 dib7000p_write_word(state
, 76, agc
->inv_gain
);
767 dib7000p_write_word(state
, 77, agc
->time_stabiliz
);
768 dib7000p_write_word(state
, 100, (agc
->alpha_level
<< 12) | agc
->thlock
);
770 // Demod AGC loop configuration
771 dib7000p_write_word(state
, 101, (agc
->alpha_mant
<< 5) | agc
->alpha_exp
);
772 dib7000p_write_word(state
, 102, (agc
->beta_mant
<< 6) | agc
->beta_exp
);
775 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
776 state
->wbd_ref
!= 0 ? state
->wbd_ref
: agc
->wbd_ref
, agc
->wbd_sel
, !agc
->perform_agc_softsplit
, agc
->wbd_sel
);
778 if (state
->wbd_ref
!= 0)
779 dib7000p_write_word(state
, 105, (agc
->wbd_inv
<< 12) | state
->wbd_ref
);
781 dib7000p_write_word(state
, 105, (agc
->wbd_inv
<< 12) | agc
->wbd_ref
);
783 dib7000p_write_word(state
, 106, (agc
->wbd_sel
<< 13) | (agc
->wbd_alpha
<< 9) | (agc
->perform_agc_softsplit
<< 8));
785 dib7000p_write_word(state
, 107, agc
->agc1_max
);
786 dib7000p_write_word(state
, 108, agc
->agc1_min
);
787 dib7000p_write_word(state
, 109, agc
->agc2_max
);
788 dib7000p_write_word(state
, 110, agc
->agc2_min
);
789 dib7000p_write_word(state
, 111, (agc
->agc1_pt1
<< 8) | agc
->agc1_pt2
);
790 dib7000p_write_word(state
, 112, agc
->agc1_pt3
);
791 dib7000p_write_word(state
, 113, (agc
->agc1_slope1
<< 8) | agc
->agc1_slope2
);
792 dib7000p_write_word(state
, 114, (agc
->agc2_pt1
<< 8) | agc
->agc2_pt2
);
793 dib7000p_write_word(state
, 115, (agc
->agc2_slope1
<< 8) | agc
->agc2_slope2
);
797 static void dib7000p_set_dds(struct dib7000p_state
*state
, s32 offset_khz
)
799 u32 internal
= dib7000p_get_internal_freq(state
);
800 s32 unit_khz_dds_val
= 67108864 / (internal
); /* 2**26 / Fsampling is the unit 1KHz offset */
801 u32 abs_offset_khz
= ABS(offset_khz
);
802 u32 dds
= state
->cfg
.bw
->ifreq
& 0x1ffffff;
803 u8 invert
= !!(state
->cfg
.bw
->ifreq
& (1 << 25));
805 dprintk("setting a frequency offset of %dkHz internal freq = %d invert = %d", offset_khz
, internal
, invert
);
808 unit_khz_dds_val
*= -1;
812 dds
-= (abs_offset_khz
* unit_khz_dds_val
); /* /100 because of /100 on the unit_khz_dds_val line calc for better accuracy */
814 dds
+= (abs_offset_khz
* unit_khz_dds_val
);
816 if (abs_offset_khz
<= (internal
/ 2)) { /* Max dds offset is the half of the demod freq */
817 dib7000p_write_word(state
, 21, (u16
) (((dds
>> 16) & 0x1ff) | (0 << 10) | (invert
<< 9)));
818 dib7000p_write_word(state
, 22, (u16
) (dds
& 0xffff));
822 static int dib7000p_agc_startup(struct dvb_frontend
*demod
)
824 struct dtv_frontend_properties
*ch
= &demod
->dtv_property_cache
;
825 struct dib7000p_state
*state
= demod
->demodulator_priv
;
827 u8
*agc_state
= &state
->agc_state
;
830 u32 upd_demod_gain_period
= 0x1000;
831 s32 frequency_offset
= 0;
833 switch (state
->agc_state
) {
835 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
836 if (state
->version
== SOC7090
) {
837 reg
= dib7000p_read_word(state
, 0x79b) & 0xff00;
838 dib7000p_write_word(state
, 0x79a, upd_demod_gain_period
& 0xFFFF); /* lsb */
839 dib7000p_write_word(state
, 0x79b, reg
| (1 << 14) | ((upd_demod_gain_period
>> 16) & 0xFF));
841 /* enable adc i & q */
842 reg
= dib7000p_read_word(state
, 0x780);
843 dib7000p_write_word(state
, 0x780, (reg
| (0x3)) & (~(1 << 7)));
845 dib7000p_set_adc_state(state
, DIBX000_ADC_ON
);
846 dib7000p_pll_clk_cfg(state
);
849 if (dib7000p_set_agc_config(state
, BAND_OF_FREQUENCY(ch
->frequency
/ 1000)) != 0)
852 if (demod
->ops
.tuner_ops
.get_frequency
) {
855 demod
->ops
.tuner_ops
.get_frequency(demod
, &frequency_tuner
);
856 frequency_offset
= (s32
)frequency_tuner
/ 1000 - ch
->frequency
/ 1000;
859 dib7000p_set_dds(state
, frequency_offset
);
865 if (state
->cfg
.agc_control
)
866 state
->cfg
.agc_control(&state
->demod
, 1);
868 dib7000p_write_word(state
, 78, 32768);
869 if (!state
->current_agc
->perform_agc_softsplit
) {
870 /* we are using the wbd - so slow AGC startup */
871 /* force 0 split on WBD and restart AGC */
872 dib7000p_write_word(state
, 106, (state
->current_agc
->wbd_sel
<< 13) | (state
->current_agc
->wbd_alpha
<< 9) | (1 << 8));
876 /* default AGC startup */
878 /* wait AGC rough lock time */
882 dib7000p_restart_agc(state
);
885 case 2: /* fast split search path after 5sec */
886 dib7000p_write_word(state
, 75, state
->current_agc
->setup
| (1 << 4)); /* freeze AGC loop */
887 dib7000p_write_word(state
, 106, (state
->current_agc
->wbd_sel
<< 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */
892 case 3: /* split search ended */
893 agc_split
= (u8
) dib7000p_read_word(state
, 396); /* store the split value for the next time */
894 dib7000p_write_word(state
, 78, dib7000p_read_word(state
, 394)); /* set AGC gain start value */
896 dib7000p_write_word(state
, 75, state
->current_agc
->setup
); /* std AGC loop */
897 dib7000p_write_word(state
, 106, (state
->current_agc
->wbd_sel
<< 13) | (state
->current_agc
->wbd_alpha
<< 9) | agc_split
); /* standard split search */
899 dib7000p_restart_agc(state
);
901 dprintk("SPLIT %p: %hd", demod
, agc_split
);
907 case 4: /* LNA startup */
910 if (dib7000p_update_lna(state
))
917 if (state
->cfg
.agc_control
)
918 state
->cfg
.agc_control(&state
->demod
, 0);
927 static void dib7000p_update_timf(struct dib7000p_state
*state
)
929 u32 timf
= (dib7000p_read_word(state
, 427) << 16) | dib7000p_read_word(state
, 428);
930 state
->timf
= timf
* 160 / (state
->current_bandwidth
/ 50);
931 dib7000p_write_word(state
, 23, (u16
) (timf
>> 16));
932 dib7000p_write_word(state
, 24, (u16
) (timf
& 0xffff));
933 dprintk("updated timf_frequency: %d (default: %d)", state
->timf
, state
->cfg
.bw
->timf
);
937 u32
dib7000p_ctrl_timf(struct dvb_frontend
*fe
, u8 op
, u32 timf
)
939 struct dib7000p_state
*state
= fe
->demodulator_priv
;
944 case DEMOD_TIMF_UPDATE
:
945 dib7000p_update_timf(state
);
950 dib7000p_set_bandwidth(state
, state
->current_bandwidth
);
953 EXPORT_SYMBOL(dib7000p_ctrl_timf
);
955 static void dib7000p_set_channel(struct dib7000p_state
*state
,
956 struct dtv_frontend_properties
*ch
, u8 seq
)
960 dib7000p_set_bandwidth(state
, BANDWIDTH_TO_KHZ(ch
->bandwidth_hz
));
962 /* nfft, guard, qam, alpha */
964 switch (ch
->transmission_mode
) {
965 case TRANSMISSION_MODE_2K
:
968 case TRANSMISSION_MODE_4K
:
972 case TRANSMISSION_MODE_8K
:
976 switch (ch
->guard_interval
) {
977 case GUARD_INTERVAL_1_32
:
980 case GUARD_INTERVAL_1_16
:
983 case GUARD_INTERVAL_1_4
:
987 case GUARD_INTERVAL_1_8
:
991 switch (ch
->modulation
) {
1003 switch (HIERARCHY_1
) {
1015 dib7000p_write_word(state
, 0, value
);
1016 dib7000p_write_word(state
, 5, (seq
<< 4) | 1); /* do not force tps, search list 0 */
1018 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
1022 if (ch
->hierarchy
== 1)
1026 switch ((ch
->hierarchy
== 0 || 1 == 1) ? ch
->code_rate_HP
: ch
->code_rate_LP
) {
1044 dib7000p_write_word(state
, 208, value
);
1046 /* offset loop parameters */
1047 dib7000p_write_word(state
, 26, 0x6680);
1048 dib7000p_write_word(state
, 32, 0x0003);
1049 dib7000p_write_word(state
, 29, 0x1273);
1050 dib7000p_write_word(state
, 33, 0x0005);
1052 /* P_dvsy_sync_wait */
1053 switch (ch
->transmission_mode
) {
1054 case TRANSMISSION_MODE_8K
:
1057 case TRANSMISSION_MODE_4K
:
1060 case TRANSMISSION_MODE_2K
:
1065 switch (ch
->guard_interval
) {
1066 case GUARD_INTERVAL_1_16
:
1069 case GUARD_INTERVAL_1_8
:
1072 case GUARD_INTERVAL_1_4
:
1076 case GUARD_INTERVAL_1_32
:
1080 if (state
->cfg
.diversity_delay
== 0)
1081 state
->div_sync_wait
= (value
* 3) / 2 + 48;
1083 state
->div_sync_wait
= (value
* 3) / 2 + state
->cfg
.diversity_delay
;
1085 /* deactive the possibility of diversity reception if extended interleaver */
1086 state
->div_force_off
= !1 && ch
->transmission_mode
!= TRANSMISSION_MODE_8K
;
1087 dib7000p_set_diversity_in(&state
->demod
, state
->div_state
);
1089 /* channel estimation fine configuration */
1090 switch (ch
->modulation
) {
1092 est
[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
1093 est
[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
1094 est
[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1095 est
[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
1098 est
[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
1099 est
[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
1100 est
[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1101 est
[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
1104 est
[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
1105 est
[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
1106 est
[2] = 0x0333; /* P_adp_regul_ext 0.1 */
1107 est
[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
1110 for (value
= 0; value
< 4; value
++)
1111 dib7000p_write_word(state
, 187 + value
, est
[value
]);
1114 static int dib7000p_autosearch_start(struct dvb_frontend
*demod
)
1116 struct dtv_frontend_properties
*ch
= &demod
->dtv_property_cache
;
1117 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1118 struct dtv_frontend_properties schan
;
1120 u32 internal
= dib7000p_get_internal_freq(state
);
1123 schan
.modulation
= QAM_64
;
1124 schan
.guard_interval
= GUARD_INTERVAL_1_32
;
1125 schan
.transmission_mode
= TRANSMISSION_MODE_8K
;
1126 schan
.code_rate_HP
= FEC_2_3
;
1127 schan
.code_rate_LP
= FEC_3_4
;
1128 schan
.hierarchy
= 0;
1130 dib7000p_set_channel(state
, &schan
, 7);
1132 factor
= BANDWIDTH_TO_KHZ(ch
->bandwidth_hz
);
1133 if (factor
>= 5000) {
1134 if (state
->version
== SOC7090
)
1141 value
= 30 * internal
* factor
;
1142 dib7000p_write_word(state
, 6, (u16
) ((value
>> 16) & 0xffff));
1143 dib7000p_write_word(state
, 7, (u16
) (value
& 0xffff));
1144 value
= 100 * internal
* factor
;
1145 dib7000p_write_word(state
, 8, (u16
) ((value
>> 16) & 0xffff));
1146 dib7000p_write_word(state
, 9, (u16
) (value
& 0xffff));
1147 value
= 500 * internal
* factor
;
1148 dib7000p_write_word(state
, 10, (u16
) ((value
>> 16) & 0xffff));
1149 dib7000p_write_word(state
, 11, (u16
) (value
& 0xffff));
1151 value
= dib7000p_read_word(state
, 0);
1152 dib7000p_write_word(state
, 0, (u16
) ((1 << 9) | value
));
1153 dib7000p_read_word(state
, 1284);
1154 dib7000p_write_word(state
, 0, (u16
) value
);
1159 static int dib7000p_autosearch_is_irq(struct dvb_frontend
*demod
)
1161 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1162 u16 irq_pending
= dib7000p_read_word(state
, 1284);
1164 if (irq_pending
& 0x1)
1167 if (irq_pending
& 0x2)
1173 static void dib7000p_spur_protect(struct dib7000p_state
*state
, u32 rf_khz
, u32 bw
)
1175 static s16 notch
[] = { 16143, 14402, 12238, 9713, 6902, 3888, 759, -2392 };
1176 static u8 sine
[] = { 0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
1177 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
1178 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
1179 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
1180 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
1181 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
1182 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
1183 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
1184 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
1185 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
1186 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
1187 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
1188 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
1189 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
1190 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
1191 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1192 255, 255, 255, 255, 255, 255
1195 u32 xtal
= state
->cfg
.bw
->xtal_hz
/ 1000;
1196 int f_rel
= DIV_ROUND_CLOSEST(rf_khz
, xtal
) * xtal
- rf_khz
;
1198 int coef_re
[8], coef_im
[8];
1202 dprintk("relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel
, rf_khz
, xtal
);
1204 if (f_rel
< -bw_khz
/ 2 || f_rel
> bw_khz
/ 2)
1209 dib7000p_write_word(state
, 142, 0x0610);
1211 for (k
= 0; k
< 8; k
++) {
1212 pha
= ((f_rel
* (k
+ 1) * 112 * 80 / bw_khz
) / 1000) & 0x3ff;
1217 } else if (pha
< 256) {
1218 coef_re
[k
] = sine
[256 - (pha
& 0xff)];
1219 coef_im
[k
] = sine
[pha
& 0xff];
1220 } else if (pha
== 256) {
1223 } else if (pha
< 512) {
1224 coef_re
[k
] = -sine
[pha
& 0xff];
1225 coef_im
[k
] = sine
[256 - (pha
& 0xff)];
1226 } else if (pha
== 512) {
1229 } else if (pha
< 768) {
1230 coef_re
[k
] = -sine
[256 - (pha
& 0xff)];
1231 coef_im
[k
] = -sine
[pha
& 0xff];
1232 } else if (pha
== 768) {
1236 coef_re
[k
] = sine
[pha
& 0xff];
1237 coef_im
[k
] = -sine
[256 - (pha
& 0xff)];
1240 coef_re
[k
] *= notch
[k
];
1241 coef_re
[k
] += (1 << 14);
1242 if (coef_re
[k
] >= (1 << 24))
1243 coef_re
[k
] = (1 << 24) - 1;
1244 coef_re
[k
] /= (1 << 15);
1246 coef_im
[k
] *= notch
[k
];
1247 coef_im
[k
] += (1 << 14);
1248 if (coef_im
[k
] >= (1 << 24))
1249 coef_im
[k
] = (1 << 24) - 1;
1250 coef_im
[k
] /= (1 << 15);
1252 dprintk("PALF COEF: %d re: %d im: %d", k
, coef_re
[k
], coef_im
[k
]);
1254 dib7000p_write_word(state
, 143, (0 << 14) | (k
<< 10) | (coef_re
[k
] & 0x3ff));
1255 dib7000p_write_word(state
, 144, coef_im
[k
] & 0x3ff);
1256 dib7000p_write_word(state
, 143, (1 << 14) | (k
<< 10) | (coef_re
[k
] & 0x3ff));
1258 dib7000p_write_word(state
, 143, 0);
1261 static int dib7000p_tune(struct dvb_frontend
*demod
)
1263 struct dtv_frontend_properties
*ch
= &demod
->dtv_property_cache
;
1264 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1268 dib7000p_set_channel(state
, ch
, 0);
1273 dib7000p_write_word(state
, 770, 0x4000);
1274 dib7000p_write_word(state
, 770, 0x0000);
1277 /* 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 */
1278 tmp
= (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
1279 if (state
->sfn_workaround_active
) {
1280 dprintk("SFN workaround is active");
1282 dib7000p_write_word(state
, 166, 0x4000);
1284 dib7000p_write_word(state
, 166, 0x0000);
1286 dib7000p_write_word(state
, 29, tmp
);
1288 // never achieved a lock with that bandwidth so far - wait for osc-freq to update
1289 if (state
->timf
== 0)
1292 /* offset loop parameters */
1294 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
1295 tmp
= (6 << 8) | 0x80;
1296 switch (ch
->transmission_mode
) {
1297 case TRANSMISSION_MODE_2K
:
1300 case TRANSMISSION_MODE_4K
:
1304 case TRANSMISSION_MODE_8K
:
1308 dib7000p_write_word(state
, 26, tmp
); /* timf_a(6xxx) */
1310 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1312 switch (ch
->transmission_mode
) {
1313 case TRANSMISSION_MODE_2K
:
1316 case TRANSMISSION_MODE_4K
:
1320 case TRANSMISSION_MODE_8K
:
1324 dib7000p_write_word(state
, 32, tmp
);
1326 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1328 switch (ch
->transmission_mode
) {
1329 case TRANSMISSION_MODE_2K
:
1332 case TRANSMISSION_MODE_4K
:
1336 case TRANSMISSION_MODE_8K
:
1340 dib7000p_write_word(state
, 33, tmp
);
1342 tmp
= dib7000p_read_word(state
, 509);
1343 if (!((tmp
>> 6) & 0x1)) {
1344 /* restart the fec */
1345 tmp
= dib7000p_read_word(state
, 771);
1346 dib7000p_write_word(state
, 771, tmp
| (1 << 1));
1347 dib7000p_write_word(state
, 771, tmp
);
1349 tmp
= dib7000p_read_word(state
, 509);
1351 // we achieved a lock - it's time to update the osc freq
1352 if ((tmp
>> 6) & 0x1) {
1353 dib7000p_update_timf(state
);
1354 /* P_timf_alpha += 2 */
1355 tmp
= dib7000p_read_word(state
, 26);
1356 dib7000p_write_word(state
, 26, (tmp
& ~(0xf << 12)) | ((((tmp
>> 12) & 0xf) + 5) << 12));
1359 if (state
->cfg
.spur_protect
)
1360 dib7000p_spur_protect(state
, ch
->frequency
/ 1000, BANDWIDTH_TO_KHZ(ch
->bandwidth_hz
));
1362 dib7000p_set_bandwidth(state
, BANDWIDTH_TO_KHZ(ch
->bandwidth_hz
));
1366 static int dib7000p_wakeup(struct dvb_frontend
*demod
)
1368 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1369 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
1370 dib7000p_set_adc_state(state
, DIBX000_SLOW_ADC_ON
);
1371 if (state
->version
== SOC7090
)
1372 dib7000p_sad_calib(state
);
1376 static int dib7000p_sleep(struct dvb_frontend
*demod
)
1378 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1379 if (state
->version
== SOC7090
)
1380 return dib7000p_set_power_mode(state
, DIB7000P_POWER_INTERFACE_ONLY
);
1381 return dib7000p_set_output_mode(state
, OUTMODE_HIGH_Z
) | dib7000p_set_power_mode(state
, DIB7000P_POWER_INTERFACE_ONLY
);
1384 static int dib7000p_identify(struct dib7000p_state
*st
)
1387 dprintk("checking demod on I2C address: %d (%x)", st
->i2c_addr
, st
->i2c_addr
);
1389 if ((value
= dib7000p_read_word(st
, 768)) != 0x01b3) {
1390 dprintk("wrong Vendor ID (read=0x%x)", value
);
1394 if ((value
= dib7000p_read_word(st
, 769)) != 0x4000) {
1395 dprintk("wrong Device ID (%x)", value
);
1402 static int dib7000p_get_frontend(struct dvb_frontend
*fe
)
1404 struct dtv_frontend_properties
*fep
= &fe
->dtv_property_cache
;
1405 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1406 u16 tps
= dib7000p_read_word(state
, 463);
1408 fep
->inversion
= INVERSION_AUTO
;
1410 fep
->bandwidth_hz
= BANDWIDTH_TO_HZ(state
->current_bandwidth
);
1412 switch ((tps
>> 8) & 0x3) {
1414 fep
->transmission_mode
= TRANSMISSION_MODE_2K
;
1417 fep
->transmission_mode
= TRANSMISSION_MODE_8K
;
1419 /* case 2: fep->transmission_mode = TRANSMISSION_MODE_4K; break; */
1422 switch (tps
& 0x3) {
1424 fep
->guard_interval
= GUARD_INTERVAL_1_32
;
1427 fep
->guard_interval
= GUARD_INTERVAL_1_16
;
1430 fep
->guard_interval
= GUARD_INTERVAL_1_8
;
1433 fep
->guard_interval
= GUARD_INTERVAL_1_4
;
1437 switch ((tps
>> 14) & 0x3) {
1439 fep
->modulation
= QPSK
;
1442 fep
->modulation
= QAM_16
;
1446 fep
->modulation
= QAM_64
;
1450 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1451 /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1453 fep
->hierarchy
= HIERARCHY_NONE
;
1454 switch ((tps
>> 5) & 0x7) {
1456 fep
->code_rate_HP
= FEC_1_2
;
1459 fep
->code_rate_HP
= FEC_2_3
;
1462 fep
->code_rate_HP
= FEC_3_4
;
1465 fep
->code_rate_HP
= FEC_5_6
;
1469 fep
->code_rate_HP
= FEC_7_8
;
1474 switch ((tps
>> 2) & 0x7) {
1476 fep
->code_rate_LP
= FEC_1_2
;
1479 fep
->code_rate_LP
= FEC_2_3
;
1482 fep
->code_rate_LP
= FEC_3_4
;
1485 fep
->code_rate_LP
= FEC_5_6
;
1489 fep
->code_rate_LP
= FEC_7_8
;
1493 /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */
1498 static int dib7000p_set_frontend(struct dvb_frontend
*fe
)
1500 struct dtv_frontend_properties
*fep
= &fe
->dtv_property_cache
;
1501 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1504 if (state
->version
== SOC7090
)
1505 dib7090_set_diversity_in(fe
, 0);
1507 dib7000p_set_output_mode(state
, OUTMODE_HIGH_Z
);
1509 /* maybe the parameter has been changed */
1510 state
->sfn_workaround_active
= buggy_sfn_workaround
;
1512 if (fe
->ops
.tuner_ops
.set_params
)
1513 fe
->ops
.tuner_ops
.set_params(fe
);
1515 /* start up the AGC */
1516 state
->agc_state
= 0;
1518 time
= dib7000p_agc_startup(fe
);
1521 } while (time
!= -1);
1523 if (fep
->transmission_mode
== TRANSMISSION_MODE_AUTO
||
1524 fep
->guard_interval
== GUARD_INTERVAL_AUTO
|| fep
->modulation
== QAM_AUTO
|| fep
->code_rate_HP
== FEC_AUTO
) {
1527 dib7000p_autosearch_start(fe
);
1530 found
= dib7000p_autosearch_is_irq(fe
);
1531 } while (found
== 0 && i
--);
1533 dprintk("autosearch returns: %d", found
);
1534 if (found
== 0 || found
== 1)
1537 dib7000p_get_frontend(fe
);
1540 ret
= dib7000p_tune(fe
);
1542 /* make this a config parameter */
1543 if (state
->version
== SOC7090
) {
1544 dib7090_set_output_mode(fe
, state
->cfg
.output_mode
);
1545 if (state
->cfg
.enMpegOutput
== 0) {
1546 dib7090_setDibTxMux(state
, MPEG_ON_DIBTX
);
1547 dib7090_setHostBusMux(state
, DIBTX_ON_HOSTBUS
);
1550 dib7000p_set_output_mode(state
, state
->cfg
.output_mode
);
1555 static int dib7000p_read_status(struct dvb_frontend
*fe
, fe_status_t
* stat
)
1557 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1558 u16 lock
= dib7000p_read_word(state
, 509);
1563 *stat
|= FE_HAS_SIGNAL
;
1565 *stat
|= FE_HAS_CARRIER
;
1567 *stat
|= FE_HAS_VITERBI
;
1569 *stat
|= FE_HAS_SYNC
;
1570 if ((lock
& 0x0038) == 0x38)
1571 *stat
|= FE_HAS_LOCK
;
1576 static int dib7000p_read_ber(struct dvb_frontend
*fe
, u32
* ber
)
1578 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1579 *ber
= (dib7000p_read_word(state
, 500) << 16) | dib7000p_read_word(state
, 501);
1583 static int dib7000p_read_unc_blocks(struct dvb_frontend
*fe
, u32
* unc
)
1585 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1586 *unc
= dib7000p_read_word(state
, 506);
1590 static int dib7000p_read_signal_strength(struct dvb_frontend
*fe
, u16
* strength
)
1592 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1593 u16 val
= dib7000p_read_word(state
, 394);
1594 *strength
= 65535 - val
;
1598 static int dib7000p_read_snr(struct dvb_frontend
*fe
, u16
* snr
)
1600 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1602 s32 signal_mant
, signal_exp
, noise_mant
, noise_exp
;
1605 val
= dib7000p_read_word(state
, 479);
1606 noise_mant
= (val
>> 4) & 0xff;
1607 noise_exp
= ((val
& 0xf) << 2);
1608 val
= dib7000p_read_word(state
, 480);
1609 noise_exp
+= ((val
>> 14) & 0x3);
1610 if ((noise_exp
& 0x20) != 0)
1613 signal_mant
= (val
>> 6) & 0xFF;
1614 signal_exp
= (val
& 0x3F);
1615 if ((signal_exp
& 0x20) != 0)
1618 if (signal_mant
!= 0)
1619 result
= intlog10(2) * 10 * signal_exp
+ 10 * intlog10(signal_mant
);
1621 result
= intlog10(2) * 10 * signal_exp
- 100;
1623 if (noise_mant
!= 0)
1624 result
-= intlog10(2) * 10 * noise_exp
+ 10 * intlog10(noise_mant
);
1626 result
-= intlog10(2) * 10 * noise_exp
- 100;
1628 *snr
= result
/ ((1 << 24) / 10);
1632 static int dib7000p_fe_get_tune_settings(struct dvb_frontend
*fe
, struct dvb_frontend_tune_settings
*tune
)
1634 tune
->min_delay_ms
= 1000;
1638 static void dib7000p_release(struct dvb_frontend
*demod
)
1640 struct dib7000p_state
*st
= demod
->demodulator_priv
;
1641 dibx000_exit_i2c_master(&st
->i2c_master
);
1642 i2c_del_adapter(&st
->dib7090_tuner_adap
);
1646 int dib7000pc_detection(struct i2c_adapter
*i2c_adap
)
1649 struct i2c_msg msg
[2] = {
1650 {.addr
= 18 >> 1, .flags
= 0, .len
= 2},
1651 {.addr
= 18 >> 1, .flags
= I2C_M_RD
, .len
= 2},
1655 tx
= kzalloc(2*sizeof(u8
), GFP_KERNEL
);
1658 rx
= kzalloc(2*sizeof(u8
), GFP_KERNEL
);
1661 goto rx_memory_error
;
1670 if (i2c_transfer(i2c_adap
, msg
, 2) == 2)
1671 if (rx
[0] == 0x01 && rx
[1] == 0xb3) {
1672 dprintk("-D- DiB7000PC detected");
1676 msg
[0].addr
= msg
[1].addr
= 0x40;
1678 if (i2c_transfer(i2c_adap
, msg
, 2) == 2)
1679 if (rx
[0] == 0x01 && rx
[1] == 0xb3) {
1680 dprintk("-D- DiB7000PC detected");
1684 dprintk("-D- DiB7000PC not detected");
1691 EXPORT_SYMBOL(dib7000pc_detection
);
1693 struct i2c_adapter
*dib7000p_get_i2c_master(struct dvb_frontend
*demod
, enum dibx000_i2c_interface intf
, int gating
)
1695 struct dib7000p_state
*st
= demod
->demodulator_priv
;
1696 return dibx000_get_i2c_adapter(&st
->i2c_master
, intf
, gating
);
1698 EXPORT_SYMBOL(dib7000p_get_i2c_master
);
1700 int dib7000p_pid_filter_ctrl(struct dvb_frontend
*fe
, u8 onoff
)
1702 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1703 u16 val
= dib7000p_read_word(state
, 235) & 0xffef;
1704 val
|= (onoff
& 0x1) << 4;
1705 dprintk("PID filter enabled %d", onoff
);
1706 return dib7000p_write_word(state
, 235, val
);
1708 EXPORT_SYMBOL(dib7000p_pid_filter_ctrl
);
1710 int dib7000p_pid_filter(struct dvb_frontend
*fe
, u8 id
, u16 pid
, u8 onoff
)
1712 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1713 dprintk("PID filter: index %x, PID %d, OnOff %d", id
, pid
, onoff
);
1714 return dib7000p_write_word(state
, 241 + id
, onoff
? (1 << 13) | pid
: 0);
1716 EXPORT_SYMBOL(dib7000p_pid_filter
);
1718 int dib7000p_i2c_enumeration(struct i2c_adapter
*i2c
, int no_of_demods
, u8 default_addr
, struct dib7000p_config cfg
[])
1720 struct dib7000p_state
*dpst
;
1724 dpst
= kzalloc(sizeof(struct dib7000p_state
), GFP_KERNEL
);
1728 dpst
->i2c_adap
= i2c
;
1729 mutex_init(&dpst
->i2c_buffer_lock
);
1731 for (k
= no_of_demods
- 1; k
>= 0; k
--) {
1734 /* designated i2c address */
1735 if (cfg
[k
].default_i2c_addr
!= 0)
1736 new_addr
= cfg
[k
].default_i2c_addr
+ (k
<< 1);
1738 new_addr
= (0x40 + k
) << 1;
1739 dpst
->i2c_addr
= new_addr
;
1740 dib7000p_write_word(dpst
, 1287, 0x0003); /* sram lead in, rdy */
1741 if (dib7000p_identify(dpst
) != 0) {
1742 dpst
->i2c_addr
= default_addr
;
1743 dib7000p_write_word(dpst
, 1287, 0x0003); /* sram lead in, rdy */
1744 if (dib7000p_identify(dpst
) != 0) {
1745 dprintk("DiB7000P #%d: not identified\n", k
);
1751 /* start diversity to pull_down div_str - just for i2c-enumeration */
1752 dib7000p_set_output_mode(dpst
, OUTMODE_DIVERSITY
);
1754 /* set new i2c address and force divstart */
1755 dib7000p_write_word(dpst
, 1285, (new_addr
<< 2) | 0x2);
1757 dprintk("IC %d initialized (to i2c_address 0x%x)", k
, new_addr
);
1760 for (k
= 0; k
< no_of_demods
; k
++) {
1762 if (cfg
[k
].default_i2c_addr
!= 0)
1763 dpst
->i2c_addr
= (cfg
[k
].default_i2c_addr
+ k
) << 1;
1765 dpst
->i2c_addr
= (0x40 + k
) << 1;
1768 dib7000p_write_word(dpst
, 1285, dpst
->i2c_addr
<< 2);
1770 /* deactivate div - it was just for i2c-enumeration */
1771 dib7000p_set_output_mode(dpst
, OUTMODE_HIGH_Z
);
1777 EXPORT_SYMBOL(dib7000p_i2c_enumeration
);
1779 static const s32 lut_1000ln_mant
[] = {
1780 6908, 6956, 7003, 7047, 7090, 7131, 7170, 7208, 7244, 7279, 7313, 7346, 7377, 7408, 7438, 7467, 7495, 7523, 7549, 7575, 7600
1783 static s32
dib7000p_get_adc_power(struct dvb_frontend
*fe
)
1785 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1786 u32 tmp_val
= 0, exp
= 0, mant
= 0;
1791 buf
[0] = dib7000p_read_word(state
, 0x184);
1792 buf
[1] = dib7000p_read_word(state
, 0x185);
1793 pow_i
= (buf
[0] << 16) | buf
[1];
1794 dprintk("raw pow_i = %d", pow_i
);
1797 while (tmp_val
>>= 1)
1800 mant
= (pow_i
* 1000 / (1 << exp
));
1801 dprintk(" mant = %d exp = %d", mant
/ 1000, exp
);
1803 ix
= (u8
) ((mant
- 1000) / 100); /* index of the LUT */
1804 dprintk(" ix = %d", ix
);
1806 pow_i
= (lut_1000ln_mant
[ix
] + 693 * (exp
- 20) - 6908);
1807 pow_i
= (pow_i
<< 8) / 1000;
1808 dprintk(" pow_i = %d", pow_i
);
1813 static int map_addr_to_serpar_number(struct i2c_msg
*msg
)
1815 if ((msg
->buf
[0] <= 15))
1817 else if (msg
->buf
[0] == 17)
1819 else if (msg
->buf
[0] == 16)
1821 else if (msg
->buf
[0] == 19)
1823 else if (msg
->buf
[0] >= 21 && msg
->buf
[0] <= 25)
1825 else if (msg
->buf
[0] == 28)
1832 static int w7090p_tuner_write_serpar(struct i2c_adapter
*i2c_adap
, struct i2c_msg msg
[], int num
)
1834 struct dib7000p_state
*state
= i2c_get_adapdata(i2c_adap
);
1837 u16 serpar_num
= msg
[0].buf
[0];
1839 while (n_overflow
== 1 && i
) {
1840 n_overflow
= (dib7000p_read_word(state
, 1984) >> 1) & 0x1;
1843 dprintk("Tuner ITF: write busy (overflow)");
1845 dib7000p_write_word(state
, 1985, (1 << 6) | (serpar_num
& 0x3f));
1846 dib7000p_write_word(state
, 1986, (msg
[0].buf
[1] << 8) | msg
[0].buf
[2]);
1851 static int w7090p_tuner_read_serpar(struct i2c_adapter
*i2c_adap
, struct i2c_msg msg
[], int num
)
1853 struct dib7000p_state
*state
= i2c_get_adapdata(i2c_adap
);
1854 u8 n_overflow
= 1, n_empty
= 1;
1856 u16 serpar_num
= msg
[0].buf
[0];
1859 while (n_overflow
== 1 && i
) {
1860 n_overflow
= (dib7000p_read_word(state
, 1984) >> 1) & 0x1;
1863 dprintk("TunerITF: read busy (overflow)");
1865 dib7000p_write_word(state
, 1985, (0 << 6) | (serpar_num
& 0x3f));
1868 while (n_empty
== 1 && i
) {
1869 n_empty
= dib7000p_read_word(state
, 1984) & 0x1;
1872 dprintk("TunerITF: read busy (empty)");
1874 read_word
= dib7000p_read_word(state
, 1987);
1875 msg
[1].buf
[0] = (read_word
>> 8) & 0xff;
1876 msg
[1].buf
[1] = (read_word
) & 0xff;
1881 static int w7090p_tuner_rw_serpar(struct i2c_adapter
*i2c_adap
, struct i2c_msg msg
[], int num
)
1883 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... */
1884 if (num
== 1) { /* write */
1885 return w7090p_tuner_write_serpar(i2c_adap
, msg
, 1);
1887 return w7090p_tuner_read_serpar(i2c_adap
, msg
, 2);
1893 static int dib7090p_rw_on_apb(struct i2c_adapter
*i2c_adap
,
1894 struct i2c_msg msg
[], int num
, u16 apb_address
)
1896 struct dib7000p_state
*state
= i2c_get_adapdata(i2c_adap
);
1899 if (num
== 1) { /* write */
1900 dib7000p_write_word(state
, apb_address
, ((msg
[0].buf
[1] << 8) | (msg
[0].buf
[2])));
1902 word
= dib7000p_read_word(state
, apb_address
);
1903 msg
[1].buf
[0] = (word
>> 8) & 0xff;
1904 msg
[1].buf
[1] = (word
) & 0xff;
1910 static int dib7090_tuner_xfer(struct i2c_adapter
*i2c_adap
, struct i2c_msg msg
[], int num
)
1912 struct dib7000p_state
*state
= i2c_get_adapdata(i2c_adap
);
1914 u16 apb_address
= 0, word
;
1916 switch (msg
[0].buf
[0]) {
2002 i
= ((dib7000p_read_word(state
, 72) >> 12) & 0x3);
2003 word
= dib7000p_read_word(state
, 384 + i
);
2004 msg
[1].buf
[0] = (word
>> 8) & 0xff;
2005 msg
[1].buf
[1] = (word
) & 0xff;
2008 if (num
== 1) { /* write */
2009 word
= (u16
) ((msg
[0].buf
[1] << 8) | msg
[0].buf
[2]);
2011 word
= (dib7000p_read_word(state
, 72) & ~(3 << 12)) | (word
<< 12);
2012 dib7000p_write_word(state
, 72, word
); /* Set the proper input */
2017 if (apb_address
!= 0) /* R/W acces via APB */
2018 return dib7090p_rw_on_apb(i2c_adap
, msg
, num
, apb_address
);
2019 else /* R/W access via SERPAR */
2020 return w7090p_tuner_rw_serpar(i2c_adap
, msg
, num
);
2025 static u32
dib7000p_i2c_func(struct i2c_adapter
*adapter
)
2027 return I2C_FUNC_I2C
;
2030 static struct i2c_algorithm dib7090_tuner_xfer_algo
= {
2031 .master_xfer
= dib7090_tuner_xfer
,
2032 .functionality
= dib7000p_i2c_func
,
2035 struct i2c_adapter
*dib7090_get_i2c_tuner(struct dvb_frontend
*fe
)
2037 struct dib7000p_state
*st
= fe
->demodulator_priv
;
2038 return &st
->dib7090_tuner_adap
;
2040 EXPORT_SYMBOL(dib7090_get_i2c_tuner
);
2042 static int dib7090_host_bus_drive(struct dib7000p_state
*state
, u8 drive
)
2046 /* drive host bus 2, 3, 4 */
2047 reg
= dib7000p_read_word(state
, 1798) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
2048 reg
|= (drive
<< 12) | (drive
<< 6) | drive
;
2049 dib7000p_write_word(state
, 1798, reg
);
2051 /* drive host bus 5,6 */
2052 reg
= dib7000p_read_word(state
, 1799) & ~((0x7 << 2) | (0x7 << 8));
2053 reg
|= (drive
<< 8) | (drive
<< 2);
2054 dib7000p_write_word(state
, 1799, reg
);
2056 /* drive host bus 7, 8, 9 */
2057 reg
= dib7000p_read_word(state
, 1800) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
2058 reg
|= (drive
<< 12) | (drive
<< 6) | drive
;
2059 dib7000p_write_word(state
, 1800, reg
);
2061 /* drive host bus 10, 11 */
2062 reg
= dib7000p_read_word(state
, 1801) & ~((0x7 << 2) | (0x7 << 8));
2063 reg
|= (drive
<< 8) | (drive
<< 2);
2064 dib7000p_write_word(state
, 1801, reg
);
2066 /* drive host bus 12, 13, 14 */
2067 reg
= dib7000p_read_word(state
, 1802) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
2068 reg
|= (drive
<< 12) | (drive
<< 6) | drive
;
2069 dib7000p_write_word(state
, 1802, reg
);
2074 static u32
dib7090_calcSyncFreq(u32 P_Kin
, u32 P_Kout
, u32 insertExtSynchro
, u32 syncSize
)
2077 u32 nom
= (insertExtSynchro
* P_Kin
+ syncSize
);
2079 u32 syncFreq
= ((nom
<< quantif
) / denom
);
2081 if ((syncFreq
& ((1 << quantif
) - 1)) != 0)
2082 syncFreq
= (syncFreq
>> quantif
) + 1;
2084 syncFreq
= (syncFreq
>> quantif
);
2087 syncFreq
= syncFreq
- 1;
2092 static int dib7090_cfg_DibTx(struct dib7000p_state
*state
, u32 P_Kin
, u32 P_Kout
, u32 insertExtSynchro
, u32 synchroMode
, u32 syncWord
, u32 syncSize
)
2094 dprintk("Configure DibStream Tx");
2096 dib7000p_write_word(state
, 1615, 1);
2097 dib7000p_write_word(state
, 1603, P_Kin
);
2098 dib7000p_write_word(state
, 1605, P_Kout
);
2099 dib7000p_write_word(state
, 1606, insertExtSynchro
);
2100 dib7000p_write_word(state
, 1608, synchroMode
);
2101 dib7000p_write_word(state
, 1609, (syncWord
>> 16) & 0xffff);
2102 dib7000p_write_word(state
, 1610, syncWord
& 0xffff);
2103 dib7000p_write_word(state
, 1612, syncSize
);
2104 dib7000p_write_word(state
, 1615, 0);
2109 static int dib7090_cfg_DibRx(struct dib7000p_state
*state
, u32 P_Kin
, u32 P_Kout
, u32 synchroMode
, u32 insertExtSynchro
, u32 syncWord
, u32 syncSize
,
2114 dprintk("Configure DibStream Rx");
2115 if ((P_Kin
!= 0) && (P_Kout
!= 0)) {
2116 syncFreq
= dib7090_calcSyncFreq(P_Kin
, P_Kout
, insertExtSynchro
, syncSize
);
2117 dib7000p_write_word(state
, 1542, syncFreq
);
2119 dib7000p_write_word(state
, 1554, 1);
2120 dib7000p_write_word(state
, 1536, P_Kin
);
2121 dib7000p_write_word(state
, 1537, P_Kout
);
2122 dib7000p_write_word(state
, 1539, synchroMode
);
2123 dib7000p_write_word(state
, 1540, (syncWord
>> 16) & 0xffff);
2124 dib7000p_write_word(state
, 1541, syncWord
& 0xffff);
2125 dib7000p_write_word(state
, 1543, syncSize
);
2126 dib7000p_write_word(state
, 1544, dataOutRate
);
2127 dib7000p_write_word(state
, 1554, 0);
2132 static void dib7090_enMpegMux(struct dib7000p_state
*state
, int onoff
)
2134 u16 reg_1287
= dib7000p_read_word(state
, 1287);
2138 reg_1287
&= ~(1<<7);
2145 dib7000p_write_word(state
, 1287, reg_1287
);
2148 static void dib7090_configMpegMux(struct dib7000p_state
*state
,
2149 u16 pulseWidth
, u16 enSerialMode
, u16 enSerialClkDiv2
)
2151 dprintk("Enable Mpeg mux");
2153 dib7090_enMpegMux(state
, 0);
2155 /* If the input mode is MPEG do not divide the serial clock */
2156 if ((enSerialMode
== 1) && (state
->input_mode_mpeg
== 1))
2157 enSerialClkDiv2
= 0;
2159 dib7000p_write_word(state
, 1287, ((pulseWidth
& 0x1f) << 2)
2160 | ((enSerialMode
& 0x1) << 1)
2161 | (enSerialClkDiv2
& 0x1));
2163 dib7090_enMpegMux(state
, 1);
2166 static void dib7090_setDibTxMux(struct dib7000p_state
*state
, int mode
)
2168 u16 reg_1288
= dib7000p_read_word(state
, 1288) & ~(0x7 << 7);
2172 dprintk("SET MPEG ON DIBSTREAM TX");
2173 dib7090_cfg_DibTx(state
, 8, 5, 0, 0, 0, 0);
2177 dprintk("SET DIV_OUT ON DIBSTREAM TX");
2178 dib7090_cfg_DibTx(state
, 5, 5, 0, 0, 0, 0);
2182 dprintk("SET ADC_OUT ON DIBSTREAM TX");
2183 dib7090_cfg_DibTx(state
, 20, 5, 10, 0, 0, 0);
2189 dib7000p_write_word(state
, 1288, reg_1288
);
2192 static void dib7090_setHostBusMux(struct dib7000p_state
*state
, int mode
)
2194 u16 reg_1288
= dib7000p_read_word(state
, 1288) & ~(0x7 << 4);
2197 case DEMOUT_ON_HOSTBUS
:
2198 dprintk("SET DEM OUT OLD INTERF ON HOST BUS");
2199 dib7090_enMpegMux(state
, 0);
2202 case DIBTX_ON_HOSTBUS
:
2203 dprintk("SET DIBSTREAM TX ON HOST BUS");
2204 dib7090_enMpegMux(state
, 0);
2207 case MPEG_ON_HOSTBUS
:
2208 dprintk("SET MPEG MUX ON HOST BUS");
2214 dib7000p_write_word(state
, 1288, reg_1288
);
2217 int dib7090_set_diversity_in(struct dvb_frontend
*fe
, int onoff
)
2219 struct dib7000p_state
*state
= fe
->demodulator_priv
;
2223 case 0: /* only use the internal way - not the diversity input */
2224 dprintk("%s mode OFF : by default Enable Mpeg INPUT", __func__
);
2225 dib7090_cfg_DibRx(state
, 8, 5, 0, 0, 0, 8, 0);
2227 /* Do not divide the serial clock of MPEG MUX */
2228 /* in SERIAL MODE in case input mode MPEG is used */
2229 reg_1287
= dib7000p_read_word(state
, 1287);
2230 /* enSerialClkDiv2 == 1 ? */
2231 if ((reg_1287
& 0x1) == 1) {
2232 /* force enSerialClkDiv2 = 0 */
2234 dib7000p_write_word(state
, 1287, reg_1287
);
2236 state
->input_mode_mpeg
= 1;
2238 case 1: /* both ways */
2239 case 2: /* only the diversity input */
2240 dprintk("%s ON : Enable diversity INPUT", __func__
);
2241 dib7090_cfg_DibRx(state
, 5, 5, 0, 0, 0, 0, 0);
2242 state
->input_mode_mpeg
= 0;
2246 dib7000p_set_diversity_in(&state
->demod
, onoff
);
2250 static int dib7090_set_output_mode(struct dvb_frontend
*fe
, int mode
)
2252 struct dib7000p_state
*state
= fe
->demodulator_priv
;
2254 u16 outreg
, smo_mode
, fifo_threshold
;
2255 u8 prefer_mpeg_mux_use
= 1;
2258 dib7090_host_bus_drive(state
, 1);
2260 fifo_threshold
= 1792;
2261 smo_mode
= (dib7000p_read_word(state
, 235) & 0x0050) | (1 << 1);
2262 outreg
= dib7000p_read_word(state
, 1286) & ~((1 << 10) | (0x7 << 6) | (1 << 1));
2265 case OUTMODE_HIGH_Z
:
2269 case OUTMODE_MPEG2_SERIAL
:
2270 if (prefer_mpeg_mux_use
) {
2271 dprintk("setting output mode TS_SERIAL using Mpeg Mux");
2272 dib7090_configMpegMux(state
, 3, 1, 1);
2273 dib7090_setHostBusMux(state
, MPEG_ON_HOSTBUS
);
2274 } else {/* Use Smooth block */
2275 dprintk("setting output mode TS_SERIAL using Smooth bloc");
2276 dib7090_setHostBusMux(state
, DEMOUT_ON_HOSTBUS
);
2277 outreg
|= (2<<6) | (0 << 1);
2281 case OUTMODE_MPEG2_PAR_GATED_CLK
:
2282 if (prefer_mpeg_mux_use
) {
2283 dprintk("setting output mode TS_PARALLEL_GATED using Mpeg Mux");
2284 dib7090_configMpegMux(state
, 2, 0, 0);
2285 dib7090_setHostBusMux(state
, MPEG_ON_HOSTBUS
);
2286 } else { /* Use Smooth block */
2287 dprintk("setting output mode TS_PARALLEL_GATED using Smooth block");
2288 dib7090_setHostBusMux(state
, DEMOUT_ON_HOSTBUS
);
2293 case OUTMODE_MPEG2_PAR_CONT_CLK
: /* Using Smooth block only */
2294 dprintk("setting output mode TS_PARALLEL_CONT using Smooth block");
2295 dib7090_setHostBusMux(state
, DEMOUT_ON_HOSTBUS
);
2299 case OUTMODE_MPEG2_FIFO
: /* Using Smooth block because not supported by new Mpeg Mux bloc */
2300 dprintk("setting output mode TS_FIFO using Smooth block");
2301 dib7090_setHostBusMux(state
, DEMOUT_ON_HOSTBUS
);
2303 smo_mode
|= (3 << 1);
2304 fifo_threshold
= 512;
2307 case OUTMODE_DIVERSITY
:
2308 dprintk("setting output mode MODE_DIVERSITY");
2309 dib7090_setDibTxMux(state
, DIV_ON_DIBTX
);
2310 dib7090_setHostBusMux(state
, DIBTX_ON_HOSTBUS
);
2313 case OUTMODE_ANALOG_ADC
:
2314 dprintk("setting output mode MODE_ANALOG_ADC");
2315 dib7090_setDibTxMux(state
, ADC_ON_DIBTX
);
2316 dib7090_setHostBusMux(state
, DIBTX_ON_HOSTBUS
);
2319 if (mode
!= OUTMODE_HIGH_Z
)
2320 outreg
|= (1 << 10);
2322 if (state
->cfg
.output_mpeg2_in_188_bytes
)
2323 smo_mode
|= (1 << 5);
2325 ret
|= dib7000p_write_word(state
, 235, smo_mode
);
2326 ret
|= dib7000p_write_word(state
, 236, fifo_threshold
); /* synchronous fread */
2327 ret
|= dib7000p_write_word(state
, 1286, outreg
);
2332 int dib7090_tuner_sleep(struct dvb_frontend
*fe
, int onoff
)
2334 struct dib7000p_state
*state
= fe
->demodulator_priv
;
2337 dprintk("sleep dib7090: %d", onoff
);
2339 en_cur_state
= dib7000p_read_word(state
, 1922);
2341 if (en_cur_state
> 0xff)
2342 state
->tuner_enable
= en_cur_state
;
2345 en_cur_state
&= 0x00ff;
2347 if (state
->tuner_enable
!= 0)
2348 en_cur_state
= state
->tuner_enable
;
2351 dib7000p_write_word(state
, 1922, en_cur_state
);
2355 EXPORT_SYMBOL(dib7090_tuner_sleep
);
2357 int dib7090_get_adc_power(struct dvb_frontend
*fe
)
2359 return dib7000p_get_adc_power(fe
);
2361 EXPORT_SYMBOL(dib7090_get_adc_power
);
2363 int dib7090_slave_reset(struct dvb_frontend
*fe
)
2365 struct dib7000p_state
*state
= fe
->demodulator_priv
;
2368 reg
= dib7000p_read_word(state
, 1794);
2369 dib7000p_write_word(state
, 1794, reg
| (4 << 12));
2371 dib7000p_write_word(state
, 1032, 0xffff);
2374 EXPORT_SYMBOL(dib7090_slave_reset
);
2376 static struct dvb_frontend_ops dib7000p_ops
;
2377 struct dvb_frontend
*dib7000p_attach(struct i2c_adapter
*i2c_adap
, u8 i2c_addr
, struct dib7000p_config
*cfg
)
2379 struct dvb_frontend
*demod
;
2380 struct dib7000p_state
*st
;
2381 st
= kzalloc(sizeof(struct dib7000p_state
), GFP_KERNEL
);
2385 memcpy(&st
->cfg
, cfg
, sizeof(struct dib7000p_config
));
2386 st
->i2c_adap
= i2c_adap
;
2387 st
->i2c_addr
= i2c_addr
;
2388 st
->gpio_val
= cfg
->gpio_val
;
2389 st
->gpio_dir
= cfg
->gpio_dir
;
2391 /* Ensure the output mode remains at the previous default if it's
2392 * not specifically set by the caller.
2394 if ((st
->cfg
.output_mode
!= OUTMODE_MPEG2_SERIAL
) && (st
->cfg
.output_mode
!= OUTMODE_MPEG2_PAR_GATED_CLK
))
2395 st
->cfg
.output_mode
= OUTMODE_MPEG2_FIFO
;
2398 demod
->demodulator_priv
= st
;
2399 memcpy(&st
->demod
.ops
, &dib7000p_ops
, sizeof(struct dvb_frontend_ops
));
2400 mutex_init(&st
->i2c_buffer_lock
);
2402 dib7000p_write_word(st
, 1287, 0x0003); /* sram lead in, rdy */
2404 if (dib7000p_identify(st
) != 0)
2407 st
->version
= dib7000p_read_word(st
, 897);
2409 /* FIXME: make sure the dev.parent field is initialized, or else
2410 request_firmware() will hit an OOPS (this should be moved somewhere
2412 st
->i2c_master
.gated_tuner_i2c_adap
.dev
.parent
= i2c_adap
->dev
.parent
;
2414 dibx000_init_i2c_master(&st
->i2c_master
, DIB7000P
, st
->i2c_adap
, st
->i2c_addr
);
2416 /* init 7090 tuner adapter */
2417 strncpy(st
->dib7090_tuner_adap
.name
, "DiB7090 tuner interface", sizeof(st
->dib7090_tuner_adap
.name
));
2418 st
->dib7090_tuner_adap
.algo
= &dib7090_tuner_xfer_algo
;
2419 st
->dib7090_tuner_adap
.algo_data
= NULL
;
2420 st
->dib7090_tuner_adap
.dev
.parent
= st
->i2c_adap
->dev
.parent
;
2421 i2c_set_adapdata(&st
->dib7090_tuner_adap
, st
);
2422 i2c_add_adapter(&st
->dib7090_tuner_adap
);
2424 dib7000p_demod_reset(st
);
2426 if (st
->version
== SOC7090
) {
2427 dib7090_set_output_mode(demod
, st
->cfg
.output_mode
);
2428 dib7090_set_diversity_in(demod
, 0);
2437 EXPORT_SYMBOL(dib7000p_attach
);
2439 static struct dvb_frontend_ops dib7000p_ops
= {
2440 .delsys
= { SYS_DVBT
},
2442 .name
= "DiBcom 7000PC",
2443 .frequency_min
= 44250000,
2444 .frequency_max
= 867250000,
2445 .frequency_stepsize
= 62500,
2446 .caps
= FE_CAN_INVERSION_AUTO
|
2447 FE_CAN_FEC_1_2
| FE_CAN_FEC_2_3
| FE_CAN_FEC_3_4
|
2448 FE_CAN_FEC_5_6
| FE_CAN_FEC_7_8
| FE_CAN_FEC_AUTO
|
2449 FE_CAN_QPSK
| FE_CAN_QAM_16
| FE_CAN_QAM_64
| FE_CAN_QAM_AUTO
|
2450 FE_CAN_TRANSMISSION_MODE_AUTO
| FE_CAN_GUARD_INTERVAL_AUTO
| FE_CAN_RECOVER
| FE_CAN_HIERARCHY_AUTO
,
2453 .release
= dib7000p_release
,
2455 .init
= dib7000p_wakeup
,
2456 .sleep
= dib7000p_sleep
,
2458 .set_frontend
= dib7000p_set_frontend
,
2459 .get_tune_settings
= dib7000p_fe_get_tune_settings
,
2460 .get_frontend
= dib7000p_get_frontend
,
2462 .read_status
= dib7000p_read_status
,
2463 .read_ber
= dib7000p_read_ber
,
2464 .read_signal_strength
= dib7000p_read_signal_strength
,
2465 .read_snr
= dib7000p_read_snr
,
2466 .read_ucblocks
= dib7000p_read_unc_blocks
,
2469 MODULE_AUTHOR("Olivier Grenie <ogrenie@dibcom.fr>");
2470 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
2471 MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
2472 MODULE_LICENSE("GPL");