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>
15 #include "dvb_frontend.h"
20 module_param(debug
, int, 0644);
21 MODULE_PARM_DESC(debug
, "turn on debugging (default: 0)");
23 static int buggy_sfn_workaround
;
24 module_param(buggy_sfn_workaround
, int, 0644);
25 MODULE_PARM_DESC(buggy_sfn_workaround
, "Enable work-around for buggy SFNs (default: 0)");
27 #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0)
30 struct i2c_adapter
*i2c_adap
;
34 struct dib7000p_state
{
35 struct dvb_frontend demod
;
36 struct dib7000p_config cfg
;
39 struct i2c_adapter
*i2c_adap
;
41 struct dibx000_i2c_master i2c_master
;
46 u32 current_bandwidth
;
47 struct dibx000_agc_config
*current_agc
;
59 u8 sfn_workaround_active
:1;
61 #define SOC7090 0x7090
65 struct i2c_adapter dib7090_tuner_adap
;
68 enum dib7000p_power_mode
{
69 DIB7000P_POWER_ALL
= 0,
70 DIB7000P_POWER_ANALOG_ADC
,
71 DIB7000P_POWER_INTERFACE_ONLY
,
74 static int dib7090_set_output_mode(struct dvb_frontend
*fe
, int mode
);
75 static int dib7090_set_diversity_in(struct dvb_frontend
*fe
, int onoff
);
77 static u16
dib7000p_read_word(struct dib7000p_state
*state
, u16 reg
)
79 u8 wb
[2] = { reg
>> 8, reg
& 0xff };
81 struct i2c_msg msg
[2] = {
82 {.addr
= state
->i2c_addr
>> 1,.flags
= 0,.buf
= wb
,.len
= 2},
83 {.addr
= state
->i2c_addr
>> 1,.flags
= I2C_M_RD
,.buf
= rb
,.len
= 2},
86 if (i2c_transfer(state
->i2c_adap
, msg
, 2) != 2)
87 dprintk("i2c read error on %d", reg
);
89 return (rb
[0] << 8) | rb
[1];
92 static int dib7000p_write_word(struct dib7000p_state
*state
, u16 reg
, u16 val
)
95 (reg
>> 8) & 0xff, reg
& 0xff,
96 (val
>> 8) & 0xff, val
& 0xff,
98 struct i2c_msg msg
= {
99 .addr
= state
->i2c_addr
>> 1,.flags
= 0,.buf
= b
,.len
= 4
101 return i2c_transfer(state
->i2c_adap
, &msg
, 1) != 1 ? -EREMOTEIO
: 0;
104 static void dib7000p_write_tab(struct dib7000p_state
*state
, u16
* buf
)
113 dib7000p_write_word(state
, r
, *n
++);
120 static int dib7000p_set_output_mode(struct dib7000p_state
*state
, int mode
)
123 u16 outreg
, fifo_threshold
, smo_mode
;
126 fifo_threshold
= 1792;
127 smo_mode
= (dib7000p_read_word(state
, 235) & 0x0050) | (1 << 1);
129 dprintk("setting output mode for demod %p to %d", &state
->demod
, mode
);
132 case OUTMODE_MPEG2_PAR_GATED_CLK
: // STBs with parallel gated clock
133 outreg
= (1 << 10); /* 0x0400 */
135 case OUTMODE_MPEG2_PAR_CONT_CLK
: // STBs with parallel continues clock
136 outreg
= (1 << 10) | (1 << 6); /* 0x0440 */
138 case OUTMODE_MPEG2_SERIAL
: // STBs with serial input
139 outreg
= (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */
141 case OUTMODE_DIVERSITY
:
142 if (state
->cfg
.hostbus_diversity
)
143 outreg
= (1 << 10) | (4 << 6); /* 0x0500 */
147 case OUTMODE_MPEG2_FIFO
: // e.g. USB feeding
148 smo_mode
|= (3 << 1);
149 fifo_threshold
= 512;
150 outreg
= (1 << 10) | (5 << 6);
152 case OUTMODE_ANALOG_ADC
:
153 outreg
= (1 << 10) | (3 << 6);
155 case OUTMODE_HIGH_Z
: // disable
159 dprintk("Unhandled output_mode passed to be set for demod %p", &state
->demod
);
163 if (state
->cfg
.output_mpeg2_in_188_bytes
)
164 smo_mode
|= (1 << 5);
166 ret
|= dib7000p_write_word(state
, 235, smo_mode
);
167 ret
|= dib7000p_write_word(state
, 236, fifo_threshold
); /* synchronous fread */
168 if (state
->version
!= SOC7090
)
169 ret
|= dib7000p_write_word(state
, 1286, outreg
); /* P_Div_active */
174 static int dib7000p_set_diversity_in(struct dvb_frontend
*demod
, int onoff
)
176 struct dib7000p_state
*state
= demod
->demodulator_priv
;
178 if (state
->div_force_off
) {
179 dprintk("diversity combination deactivated - forced by COFDM parameters");
181 dib7000p_write_word(state
, 207, 0);
183 dib7000p_write_word(state
, 207, (state
->div_sync_wait
<< 4) | (1 << 2) | (2 << 0));
185 state
->div_state
= (u8
) onoff
;
188 dib7000p_write_word(state
, 204, 6);
189 dib7000p_write_word(state
, 205, 16);
190 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
192 dib7000p_write_word(state
, 204, 1);
193 dib7000p_write_word(state
, 205, 0);
199 static int dib7000p_set_power_mode(struct dib7000p_state
*state
, enum dib7000p_power_mode mode
)
201 /* by default everything is powered off */
202 u16 reg_774
= 0x3fff, reg_775
= 0xffff, reg_776
= 0x0007, reg_899
= 0x0003, reg_1280
= (0xfe00) | (dib7000p_read_word(state
, 1280) & 0x01ff);
204 /* now, depending on the requested mode, we power on */
206 /* power up everything in the demod */
207 case DIB7000P_POWER_ALL
:
212 if (state
->version
== SOC7090
)
218 case DIB7000P_POWER_ANALOG_ADC
:
219 /* dem, cfg, iqc, sad, agc */
220 reg_774
&= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
222 reg_776
&= ~((1 << 0));
224 if (state
->version
!= SOC7090
)
225 reg_1280
&= ~((1 << 11));
226 reg_1280
&= ~(1 << 6);
227 /* fall through wanted to enable the interfaces */
229 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
230 case DIB7000P_POWER_INTERFACE_ONLY
: /* TODO power up either SDIO or I2C */
231 if (state
->version
== SOC7090
)
232 reg_1280
&= ~((1 << 7) | (1 << 5));
234 reg_1280
&= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
237 /* TODO following stuff is just converted from the dib7000-driver - check when is used what */
240 dib7000p_write_word(state
, 774, reg_774
);
241 dib7000p_write_word(state
, 775, reg_775
);
242 dib7000p_write_word(state
, 776, reg_776
);
243 dib7000p_write_word(state
, 899, reg_899
);
244 dib7000p_write_word(state
, 1280, reg_1280
);
249 static void dib7000p_set_adc_state(struct dib7000p_state
*state
, enum dibx000_adc_states no
)
251 u16 reg_908
= dib7000p_read_word(state
, 908), reg_909
= dib7000p_read_word(state
, 909);
255 case DIBX000_SLOW_ADC_ON
:
256 if (state
->version
== SOC7090
) {
257 reg
= dib7000p_read_word(state
, 1925);
259 dib7000p_write_word(state
, 1925, reg
| (1 << 4) | (1 << 2)); /* en_slowAdc = 1 & reset_sladc = 1 */
261 reg
= dib7000p_read_word(state
, 1925); /* read acces to make it works... strange ... */
263 dib7000p_write_word(state
, 1925, reg
& ~(1 << 4)); /* en_slowAdc = 1 & reset_sladc = 0 */
265 reg
= dib7000p_read_word(state
, 72) & ~((0x3 << 14) | (0x3 << 12));
266 dib7000p_write_word(state
, 72, reg
| (1 << 14) | (3 << 12) | 524); /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ; (Vin2 = Vcm) */
268 reg_909
|= (1 << 1) | (1 << 0);
269 dib7000p_write_word(state
, 909, reg_909
);
270 reg_909
&= ~(1 << 1);
274 case DIBX000_SLOW_ADC_OFF
:
275 if (state
->version
== SOC7090
) {
276 reg
= dib7000p_read_word(state
, 1925);
277 dib7000p_write_word(state
, 1925, (reg
& ~(1 << 2)) | (1 << 4)); /* reset_sladc = 1 en_slowAdc = 0 */
279 reg_909
|= (1 << 1) | (1 << 0);
287 case DIBX000_ADC_OFF
: // leave the VBG voltage on
288 reg_908
|= (1 << 14) | (1 << 13) | (1 << 12);
289 reg_909
|= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
292 case DIBX000_VBG_ENABLE
:
293 reg_908
&= ~(1 << 15);
296 case DIBX000_VBG_DISABLE
:
297 reg_908
|= (1 << 15);
304 // dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
306 reg_909
|= (state
->cfg
.disable_sample_and_hold
& 1) << 4;
307 reg_908
|= (state
->cfg
.enable_current_mirror
& 1) << 7;
309 dib7000p_write_word(state
, 908, reg_908
);
310 dib7000p_write_word(state
, 909, reg_909
);
313 static int dib7000p_set_bandwidth(struct dib7000p_state
*state
, u32 bw
)
317 // store the current bandwidth for later use
318 state
->current_bandwidth
= bw
;
320 if (state
->timf
== 0) {
321 dprintk("using default timf");
322 timf
= state
->cfg
.bw
->timf
;
324 dprintk("using updated timf");
328 timf
= timf
* (bw
/ 50) / 160;
330 dib7000p_write_word(state
, 23, (u16
) ((timf
>> 16) & 0xffff));
331 dib7000p_write_word(state
, 24, (u16
) ((timf
) & 0xffff));
336 static int dib7000p_sad_calib(struct dib7000p_state
*state
)
339 // dib7000p_write_word(state, 72, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth
340 dib7000p_write_word(state
, 73, (0 << 1) | (0 << 0));
342 if (state
->version
== SOC7090
)
343 dib7000p_write_word(state
, 74, 2048); // P_sad_calib_value = (0.9/1.8)*4096
345 dib7000p_write_word(state
, 74, 776); // P_sad_calib_value = 0.625*3.3 / 4096
347 /* do the calibration */
348 dib7000p_write_word(state
, 73, (1 << 0));
349 dib7000p_write_word(state
, 73, (0 << 0));
356 int dib7000p_set_wbd_ref(struct dvb_frontend
*demod
, u16 value
)
358 struct dib7000p_state
*state
= demod
->demodulator_priv
;
361 state
->wbd_ref
= value
;
362 return dib7000p_write_word(state
, 105, (dib7000p_read_word(state
, 105) & 0xf000) | value
);
364 EXPORT_SYMBOL(dib7000p_set_wbd_ref
);
366 static void dib7000p_reset_pll(struct dib7000p_state
*state
)
368 struct dibx000_bandwidth_config
*bw
= &state
->cfg
.bw
[0];
371 if (state
->version
== SOC7090
) {
372 dib7000p_write_word(state
, 1856, (!bw
->pll_reset
<< 13) | (bw
->pll_range
<< 12) | (bw
->pll_ratio
<< 6) | (bw
->pll_prediv
));
374 while (((dib7000p_read_word(state
, 1856) >> 15) & 0x1) != 1) {
377 dib7000p_write_word(state
, 1857, dib7000p_read_word(state
, 1857) | (!bw
->pll_bypass
<< 15));
379 /* force PLL bypass */
380 clk_cfg0
= (1 << 15) | ((bw
->pll_ratio
& 0x3f) << 9) |
381 (bw
->modulo
<< 7) | (bw
->ADClkSrc
<< 6) | (bw
->IO_CLK_en_core
<< 5) | (bw
->bypclk_div
<< 2) | (bw
->enable_refdiv
<< 1) | (0 << 0);
383 dib7000p_write_word(state
, 900, clk_cfg0
);
386 dib7000p_write_word(state
, 903, (bw
->pll_prediv
<< 5) | (((bw
->pll_ratio
>> 6) & 0x3) << 3) | (bw
->pll_range
<< 1) | bw
->pll_reset
);
387 clk_cfg0
= (bw
->pll_bypass
<< 15) | (clk_cfg0
& 0x7fff);
388 dib7000p_write_word(state
, 900, clk_cfg0
);
391 dib7000p_write_word(state
, 18, (u16
) (((bw
->internal
* 1000) >> 16) & 0xffff));
392 dib7000p_write_word(state
, 19, (u16
) ((bw
->internal
* 1000) & 0xffff));
393 dib7000p_write_word(state
, 21, (u16
) ((bw
->ifreq
>> 16) & 0xffff));
394 dib7000p_write_word(state
, 22, (u16
) ((bw
->ifreq
) & 0xffff));
396 dib7000p_write_word(state
, 72, bw
->sad_cfg
);
399 static u32
dib7000p_get_internal_freq(struct dib7000p_state
*state
)
401 u32 internal
= (u32
) dib7000p_read_word(state
, 18) << 16;
402 internal
|= (u32
) dib7000p_read_word(state
, 19);
408 int dib7000p_update_pll(struct dvb_frontend
*fe
, struct dibx000_bandwidth_config
*bw
)
410 struct dib7000p_state
*state
= fe
->demodulator_priv
;
411 u16 reg_1857
, reg_1856
= dib7000p_read_word(state
, 1856);
415 /* get back old values */
416 prediv
= reg_1856
& 0x3f;
417 loopdiv
= (reg_1856
>> 6) & 0x3f;
419 if ((bw
!= NULL
) && (bw
->pll_prediv
!= prediv
|| bw
->pll_ratio
!= loopdiv
)) {
420 dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv
, bw
->pll_prediv
, loopdiv
, bw
->pll_ratio
);
422 reg_1857
= dib7000p_read_word(state
, 1857);
423 dib7000p_write_word(state
, 1857, reg_1857
& ~(1 << 15)); // desable pll
425 dib7000p_write_word(state
, 1856, reg_1856
| ((bw
->pll_ratio
& 0x3f) << 6) | (bw
->pll_prediv
& 0x3f));
427 /* write new system clk into P_sec_len */
428 internal
= dib7000p_get_internal_freq(state
);
429 xtal
= (internal
/ loopdiv
) * prediv
;
430 internal
= 1000 * (xtal
/ bw
->pll_prediv
) * bw
->pll_ratio
; /* new internal */
431 dib7000p_write_word(state
, 18, (u16
) ((internal
>> 16) & 0xffff));
432 dib7000p_write_word(state
, 19, (u16
) (internal
& 0xffff));
434 dib7000p_write_word(state
, 1857, reg_1857
| (1 << 15)); // enable pll
436 while (((dib7000p_read_word(state
, 1856) >> 15) & 0x1) != 1) {
437 dprintk("Waiting for PLL to lock");
444 EXPORT_SYMBOL(dib7000p_update_pll
);
446 static int dib7000p_reset_gpio(struct dib7000p_state
*st
)
448 /* reset the GPIOs */
449 dprintk("gpio dir: %x: val: %x, pwm_pos: %x", st
->gpio_dir
, st
->gpio_val
, st
->cfg
.gpio_pwm_pos
);
451 dib7000p_write_word(st
, 1029, st
->gpio_dir
);
452 dib7000p_write_word(st
, 1030, st
->gpio_val
);
454 /* TODO 1031 is P_gpio_od */
456 dib7000p_write_word(st
, 1032, st
->cfg
.gpio_pwm_pos
);
458 dib7000p_write_word(st
, 1037, st
->cfg
.pwm_freq_div
);
462 static int dib7000p_cfg_gpio(struct dib7000p_state
*st
, u8 num
, u8 dir
, u8 val
)
464 st
->gpio_dir
= dib7000p_read_word(st
, 1029);
465 st
->gpio_dir
&= ~(1 << num
); /* reset the direction bit */
466 st
->gpio_dir
|= (dir
& 0x1) << num
; /* set the new direction */
467 dib7000p_write_word(st
, 1029, st
->gpio_dir
);
469 st
->gpio_val
= dib7000p_read_word(st
, 1030);
470 st
->gpio_val
&= ~(1 << num
); /* reset the direction bit */
471 st
->gpio_val
|= (val
& 0x01) << num
; /* set the new value */
472 dib7000p_write_word(st
, 1030, st
->gpio_val
);
477 int dib7000p_set_gpio(struct dvb_frontend
*demod
, u8 num
, u8 dir
, u8 val
)
479 struct dib7000p_state
*state
= demod
->demodulator_priv
;
480 return dib7000p_cfg_gpio(state
, num
, dir
, val
);
482 EXPORT_SYMBOL(dib7000p_set_gpio
);
484 static u16 dib7000p_defaults
[] = {
485 // auto search configuration
489 0x0814, /* Equal Lock */
506 0x6680, // P_timf_alpha=6, P_corm_alpha=6, P_corm_thres=128 default: 6,4,26
508 /* set ADC level to -16 */
510 (1 << 13) - 825 - 117,
511 (1 << 13) - 837 - 117,
512 (1 << 13) - 811 - 117,
513 (1 << 13) - 766 - 117,
514 (1 << 13) - 737 - 117,
515 (1 << 13) - 693 - 117,
516 (1 << 13) - 648 - 117,
517 (1 << 13) - 619 - 117,
518 (1 << 13) - 575 - 117,
519 (1 << 13) - 531 - 117,
520 (1 << 13) - 501 - 117,
523 0x0410, // P_palf_filter_on=1, P_palf_filter_freeze=0, P_palf_alpha_regul=16
525 /* disable power smoothing */
537 1 << 13, // P_fft_freq_dir=1, P_fft_nb_to_cut=0
540 0x0ccd, // P_pha3_thres, default 0x3000
543 // 0x0010, // P_cti_use_cpe=0, P_cti_use_prog=0, P_cti_win_len=16, default: 0x0010
546 0x200f, // P_cspu_regul=512, P_cspu_win_cut=15, default: 0x2005
549 0x169, // P_vit_ksi_dwn = 5 P_vit_ksi_up = 5 0x1e1, // P_vit_ksi_dwn = 4 P_vit_ksi_up = 7
552 0x023d, // P_adp_regul_cnt=573, default: 410
553 0x00a4, // P_adp_noise_cnt=
554 0x00a4, // P_adp_regul_ext
555 0x7ff0, // P_adp_noise_ext
559 0x800, // P_equal_thres_wgn
562 0x0010, // P_fec_ber_rs_len=2
565 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
568 0x0006, // P_clk_cfg1
569 (3 << 10) | (1 << 6), // P_divclksel=3 P_divbitsel=1
572 0x2c8e, // Tuner IO bank: max drive (14mA) + divout pads max drive
577 static int dib7000p_demod_reset(struct dib7000p_state
*state
)
579 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
581 if (state
->version
== SOC7090
)
582 dibx000_reset_i2c_master(&state
->i2c_master
);
584 dib7000p_set_adc_state(state
, DIBX000_VBG_ENABLE
);
586 /* restart all parts */
587 dib7000p_write_word(state
, 770, 0xffff);
588 dib7000p_write_word(state
, 771, 0xffff);
589 dib7000p_write_word(state
, 772, 0x001f);
590 dib7000p_write_word(state
, 898, 0x0003);
591 dib7000p_write_word(state
, 1280, 0x001f - ((1 << 4) | (1 << 3)));
593 dib7000p_write_word(state
, 770, 0);
594 dib7000p_write_word(state
, 771, 0);
595 dib7000p_write_word(state
, 772, 0);
596 dib7000p_write_word(state
, 898, 0);
597 dib7000p_write_word(state
, 1280, 0);
600 dib7000p_reset_pll(state
);
602 if (dib7000p_reset_gpio(state
) != 0)
603 dprintk("GPIO reset was not successful.");
605 if (state
->version
== SOC7090
) {
606 dib7000p_write_word(state
, 899, 0);
609 dib7000p_write_word(state
, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */
610 dib7000p_write_word(state
, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */
611 dib7000p_write_word(state
, 44, 300); /* 300 fag P_iqc_dect_min = +280 */
612 //dib7000p_write_word(state, 273, (1<<6) | 10); /* P_vit_inoise_sel = 1, P_vit_inoise_gain = 10*/
613 dib7000p_write_word(state
, 273, (1<<6) | 30); //26/* P_vit_inoise_sel = 1, P_vit_inoise_gain = 26*/// FAG
615 if (dib7000p_set_output_mode(state
, OUTMODE_HIGH_Z
) != 0)
616 dprintk("OUTPUT_MODE could not be reset.");
618 dib7000p_set_adc_state(state
, DIBX000_SLOW_ADC_ON
);
619 dib7000p_sad_calib(state
);
620 dib7000p_set_adc_state(state
, DIBX000_SLOW_ADC_OFF
);
622 /* unforce divstr regardless whether i2c enumeration was done or not */
623 dib7000p_write_word(state
, 1285, dib7000p_read_word(state
, 1285) & ~(1 << 1));
625 dib7000p_set_bandwidth(state
, 8000);
627 if(state
->version
== SOC7090
) {
628 dib7000p_write_word(state
, 36, 0x5755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */
629 } else { // P_iqc_alpha_pha, P_iqc_alpha_amp_dcc_alpha, ...
630 if (state
->cfg
.tuner_is_baseband
)
631 dib7000p_write_word(state
, 36, 0x0755);
633 dib7000p_write_word(state
, 36, 0x1f55);
636 dib7000p_write_tab(state
, dib7000p_defaults
);
638 dib7000p_set_power_mode(state
, DIB7000P_POWER_INTERFACE_ONLY
);
643 static void dib7000p_pll_clk_cfg(struct dib7000p_state
*state
)
646 tmp
= dib7000p_read_word(state
, 903);
647 dib7000p_write_word(state
, 903, (tmp
| 0x1)); //pwr-up pll
648 tmp
= dib7000p_read_word(state
, 900);
649 dib7000p_write_word(state
, 900, (tmp
& 0x7fff) | (1 << 6)); //use High freq clock
652 static void dib7000p_restart_agc(struct dib7000p_state
*state
)
654 // P_restart_iqc & P_restart_agc
655 dib7000p_write_word(state
, 770, (1 << 11) | (1 << 9));
656 dib7000p_write_word(state
, 770, 0x0000);
659 static int dib7000p_update_lna(struct dib7000p_state
*state
)
663 // when there is no LNA to program return immediatly
664 if (state
->cfg
.update_lna
) {
665 // read dyn_gain here (because it is demod-dependent and not fe)
666 dyn_gain
= dib7000p_read_word(state
, 394);
667 if (state
->cfg
.update_lna(&state
->demod
, dyn_gain
)) { // LNA has changed
668 dib7000p_restart_agc(state
);
676 static int dib7000p_set_agc_config(struct dib7000p_state
*state
, u8 band
)
678 struct dibx000_agc_config
*agc
= NULL
;
680 if (state
->current_band
== band
&& state
->current_agc
!= NULL
)
682 state
->current_band
= band
;
684 for (i
= 0; i
< state
->cfg
.agc_config_count
; i
++)
685 if (state
->cfg
.agc
[i
].band_caps
& band
) {
686 agc
= &state
->cfg
.agc
[i
];
691 dprintk("no valid AGC configuration found for band 0x%02x", band
);
695 state
->current_agc
= agc
;
698 dib7000p_write_word(state
, 75, agc
->setup
);
699 dib7000p_write_word(state
, 76, agc
->inv_gain
);
700 dib7000p_write_word(state
, 77, agc
->time_stabiliz
);
701 dib7000p_write_word(state
, 100, (agc
->alpha_level
<< 12) | agc
->thlock
);
703 // Demod AGC loop configuration
704 dib7000p_write_word(state
, 101, (agc
->alpha_mant
<< 5) | agc
->alpha_exp
);
705 dib7000p_write_word(state
, 102, (agc
->beta_mant
<< 6) | agc
->beta_exp
);
708 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
709 state
->wbd_ref
!= 0 ? state
->wbd_ref
: agc
->wbd_ref
, agc
->wbd_sel
, !agc
->perform_agc_softsplit
, agc
->wbd_sel
);
711 if (state
->wbd_ref
!= 0)
712 dib7000p_write_word(state
, 105, (agc
->wbd_inv
<< 12) | state
->wbd_ref
);
714 dib7000p_write_word(state
, 105, (agc
->wbd_inv
<< 12) | agc
->wbd_ref
);
716 dib7000p_write_word(state
, 106, (agc
->wbd_sel
<< 13) | (agc
->wbd_alpha
<< 9) | (agc
->perform_agc_softsplit
<< 8));
718 dib7000p_write_word(state
, 107, agc
->agc1_max
);
719 dib7000p_write_word(state
, 108, agc
->agc1_min
);
720 dib7000p_write_word(state
, 109, agc
->agc2_max
);
721 dib7000p_write_word(state
, 110, agc
->agc2_min
);
722 dib7000p_write_word(state
, 111, (agc
->agc1_pt1
<< 8) | agc
->agc1_pt2
);
723 dib7000p_write_word(state
, 112, agc
->agc1_pt3
);
724 dib7000p_write_word(state
, 113, (agc
->agc1_slope1
<< 8) | agc
->agc1_slope2
);
725 dib7000p_write_word(state
, 114, (agc
->agc2_pt1
<< 8) | agc
->agc2_pt2
);
726 dib7000p_write_word(state
, 115, (agc
->agc2_slope1
<< 8) | agc
->agc2_slope2
);
730 static void dib7000p_set_dds(struct dib7000p_state
*state
, s32 offset_khz
)
732 u32 internal
= dib7000p_get_internal_freq(state
);
733 s32 unit_khz_dds_val
= 67108864 / (internal
); /* 2**26 / Fsampling is the unit 1KHz offset */
734 u32 abs_offset_khz
= ABS(offset_khz
);
735 u32 dds
= state
->cfg
.bw
->ifreq
& 0x1ffffff;
736 u8 invert
= !!(state
->cfg
.bw
->ifreq
& (1 << 25));
738 dprintk("setting a frequency offset of %dkHz internal freq = %d invert = %d", offset_khz
, internal
, invert
);
741 unit_khz_dds_val
*= -1;
745 dds
-= (abs_offset_khz
* unit_khz_dds_val
); /* /100 because of /100 on the unit_khz_dds_val line calc for better accuracy */
747 dds
+= (abs_offset_khz
* unit_khz_dds_val
);
749 if (abs_offset_khz
<= (internal
/ 2)) { /* Max dds offset is the half of the demod freq */
750 dib7000p_write_word(state
, 21, (u16
) (((dds
>> 16) & 0x1ff) | (0 << 10) | (invert
<< 9)));
751 dib7000p_write_word(state
, 22, (u16
) (dds
& 0xffff));
755 static int dib7000p_agc_startup(struct dvb_frontend
*demod
, struct dvb_frontend_parameters
*ch
)
757 struct dib7000p_state
*state
= demod
->demodulator_priv
;
759 u8
*agc_state
= &state
->agc_state
;
762 u32 upd_demod_gain_period
= 0x1000;
764 switch (state
->agc_state
) {
766 // set power-up level: interf+analog+AGC
767 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
768 if (state
->version
== SOC7090
) {
769 reg
= dib7000p_read_word(state
, 0x79b) & 0xff00;
770 dib7000p_write_word(state
, 0x79a, upd_demod_gain_period
& 0xFFFF); /* lsb */
771 dib7000p_write_word(state
, 0x79b, reg
| (1 << 14) | ((upd_demod_gain_period
>> 16) & 0xFF)); // bit 14 = enDemodGain
773 /* enable adc i & q */
774 reg
= dib7000p_read_word(state
, 0x780);
775 dib7000p_write_word(state
, 0x780, (reg
| (0x3)) & (~(1 << 7)));
777 dib7000p_set_adc_state(state
, DIBX000_ADC_ON
);
778 dib7000p_pll_clk_cfg(state
);
781 if (dib7000p_set_agc_config(state
, BAND_OF_FREQUENCY(ch
->frequency
/ 1000)) != 0)
784 dib7000p_set_dds(state
, 0);
790 // AGC initialization
791 if (state
->cfg
.agc_control
)
792 state
->cfg
.agc_control(&state
->demod
, 1);
794 dib7000p_write_word(state
, 78, 32768);
795 if (!state
->current_agc
->perform_agc_softsplit
) {
796 /* we are using the wbd - so slow AGC startup */
797 /* force 0 split on WBD and restart AGC */
798 dib7000p_write_word(state
, 106, (state
->current_agc
->wbd_sel
<< 13) | (state
->current_agc
->wbd_alpha
<< 9) | (1 << 8));
802 /* default AGC startup */
804 /* wait AGC rough lock time */
808 dib7000p_restart_agc(state
);
811 case 2: /* fast split search path after 5sec */
812 dib7000p_write_word(state
, 75, state
->current_agc
->setup
| (1 << 4)); /* freeze AGC loop */
813 dib7000p_write_word(state
, 106, (state
->current_agc
->wbd_sel
<< 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */
818 case 3: /* split search ended */
819 agc_split
= (u8
) dib7000p_read_word(state
, 396); /* store the split value for the next time */
820 dib7000p_write_word(state
, 78, dib7000p_read_word(state
, 394)); /* set AGC gain start value */
822 dib7000p_write_word(state
, 75, state
->current_agc
->setup
); /* std AGC loop */
823 dib7000p_write_word(state
, 106, (state
->current_agc
->wbd_sel
<< 13) | (state
->current_agc
->wbd_alpha
<< 9) | agc_split
); /* standard split search */
825 dib7000p_restart_agc(state
);
827 dprintk("SPLIT %p: %hd", demod
, agc_split
);
833 case 4: /* LNA startup */
834 // wait AGC accurate lock time
837 if (dib7000p_update_lna(state
))
838 // wait only AGC rough lock time
840 else // nothing was done, go to the next state
845 if (state
->cfg
.agc_control
)
846 state
->cfg
.agc_control(&state
->demod
, 0);
855 static void dib7000p_update_timf(struct dib7000p_state
*state
)
857 u32 timf
= (dib7000p_read_word(state
, 427) << 16) | dib7000p_read_word(state
, 428);
858 state
->timf
= timf
* 160 / (state
->current_bandwidth
/ 50);
859 dib7000p_write_word(state
, 23, (u16
) (timf
>> 16));
860 dib7000p_write_word(state
, 24, (u16
) (timf
& 0xffff));
861 dprintk("updated timf_frequency: %d (default: %d)", state
->timf
, state
->cfg
.bw
->timf
);
865 u32
dib7000p_ctrl_timf(struct dvb_frontend
*fe
, u8 op
, u32 timf
)
867 struct dib7000p_state
*state
= fe
->demodulator_priv
;
872 case DEMOD_TIMF_UPDATE
:
873 dib7000p_update_timf(state
);
878 dib7000p_set_bandwidth(state
, state
->current_bandwidth
);
881 EXPORT_SYMBOL(dib7000p_ctrl_timf
);
883 static void dib7000p_set_channel(struct dib7000p_state
*state
, struct dvb_frontend_parameters
*ch
, u8 seq
)
887 dib7000p_set_bandwidth(state
, BANDWIDTH_TO_KHZ(ch
->u
.ofdm
.bandwidth
));
889 /* nfft, guard, qam, alpha */
891 switch (ch
->u
.ofdm
.transmission_mode
) {
892 case TRANSMISSION_MODE_2K
:
895 case TRANSMISSION_MODE_4K
:
899 case TRANSMISSION_MODE_8K
:
903 switch (ch
->u
.ofdm
.guard_interval
) {
904 case GUARD_INTERVAL_1_32
:
907 case GUARD_INTERVAL_1_16
:
910 case GUARD_INTERVAL_1_4
:
914 case GUARD_INTERVAL_1_8
:
918 switch (ch
->u
.ofdm
.constellation
) {
930 switch (HIERARCHY_1
) {
942 dib7000p_write_word(state
, 0, value
);
943 dib7000p_write_word(state
, 5, (seq
<< 4) | 1); /* do not force tps, search list 0 */
945 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
949 if (ch
->u
.ofdm
.hierarchy_information
== 1)
953 switch ((ch
->u
.ofdm
.hierarchy_information
== 0 || 1 == 1) ? ch
->u
.ofdm
.code_rate_HP
: ch
->u
.ofdm
.code_rate_LP
) {
971 dib7000p_write_word(state
, 208, value
);
973 /* offset loop parameters */
974 dib7000p_write_word(state
, 26, 0x6680); // timf(6xxx)
975 dib7000p_write_word(state
, 32, 0x0003); // pha_off_max(xxx3)
976 dib7000p_write_word(state
, 29, 0x1273); // isi
977 dib7000p_write_word(state
, 33, 0x0005); // sfreq(xxx5)
979 /* P_dvsy_sync_wait */
980 switch (ch
->u
.ofdm
.transmission_mode
) {
981 case TRANSMISSION_MODE_8K
:
984 case TRANSMISSION_MODE_4K
:
987 case TRANSMISSION_MODE_2K
:
992 switch (ch
->u
.ofdm
.guard_interval
) {
993 case GUARD_INTERVAL_1_16
:
996 case GUARD_INTERVAL_1_8
:
999 case GUARD_INTERVAL_1_4
:
1003 case GUARD_INTERVAL_1_32
:
1007 if (state
->cfg
.diversity_delay
== 0)
1008 state
->div_sync_wait
= (value
* 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo
1010 state
->div_sync_wait
= (value
* 3) / 2 + state
->cfg
.diversity_delay
; // add 50% SFN margin + compensate for one DVSY-fifo
1012 /* deactive the possibility of diversity reception if extended interleaver */
1013 state
->div_force_off
= !1 && ch
->u
.ofdm
.transmission_mode
!= TRANSMISSION_MODE_8K
;
1014 dib7000p_set_diversity_in(&state
->demod
, state
->div_state
);
1016 /* channel estimation fine configuration */
1017 switch (ch
->u
.ofdm
.constellation
) {
1019 est
[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
1020 est
[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
1021 est
[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1022 est
[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
1025 est
[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
1026 est
[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
1027 est
[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1028 est
[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
1031 est
[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
1032 est
[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
1033 est
[2] = 0x0333; /* P_adp_regul_ext 0.1 */
1034 est
[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
1037 for (value
= 0; value
< 4; value
++)
1038 dib7000p_write_word(state
, 187 + value
, est
[value
]);
1041 static int dib7000p_autosearch_start(struct dvb_frontend
*demod
, struct dvb_frontend_parameters
*ch
)
1043 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1044 struct dvb_frontend_parameters schan
;
1046 u32 internal
= dib7000p_get_internal_freq(state
);
1049 schan
.u
.ofdm
.constellation
= QAM_64
;
1050 schan
.u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_32
;
1051 schan
.u
.ofdm
.transmission_mode
= TRANSMISSION_MODE_8K
;
1052 schan
.u
.ofdm
.code_rate_HP
= FEC_2_3
;
1053 schan
.u
.ofdm
.code_rate_LP
= FEC_3_4
;
1054 schan
.u
.ofdm
.hierarchy_information
= 0;
1056 dib7000p_set_channel(state
, &schan
, 7);
1058 factor
= BANDWIDTH_TO_KHZ(ch
->u
.ofdm
.bandwidth
);
1064 // always use the setting for 8MHz here lock_time for 7,6 MHz are longer
1065 value
= 30 * internal
* factor
;
1066 dib7000p_write_word(state
, 6, (u16
) ((value
>> 16) & 0xffff)); // lock0 wait time
1067 dib7000p_write_word(state
, 7, (u16
) (value
& 0xffff)); // lock0 wait time
1068 value
= 100 * internal
* factor
;
1069 dib7000p_write_word(state
, 8, (u16
) ((value
>> 16) & 0xffff)); // lock1 wait time
1070 dib7000p_write_word(state
, 9, (u16
) (value
& 0xffff)); // lock1 wait time
1071 value
= 500 * internal
* factor
;
1072 dib7000p_write_word(state
, 10, (u16
) ((value
>> 16) & 0xffff)); // lock2 wait time
1073 dib7000p_write_word(state
, 11, (u16
) (value
& 0xffff)); // lock2 wait time
1075 value
= dib7000p_read_word(state
, 0);
1076 dib7000p_write_word(state
, 0, (u16
) ((1 << 9) | value
));
1077 dib7000p_read_word(state
, 1284);
1078 dib7000p_write_word(state
, 0, (u16
) value
);
1083 static int dib7000p_autosearch_is_irq(struct dvb_frontend
*demod
)
1085 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1086 u16 irq_pending
= dib7000p_read_word(state
, 1284);
1088 if (irq_pending
& 0x1) // failed
1091 if (irq_pending
& 0x2) // succeeded
1094 return 0; // still pending
1097 static void dib7000p_spur_protect(struct dib7000p_state
*state
, u32 rf_khz
, u32 bw
)
1099 static s16 notch
[] = { 16143, 14402, 12238, 9713, 6902, 3888, 759, -2392 };
1100 static u8 sine
[] = { 0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
1101 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
1102 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
1103 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
1104 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
1105 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
1106 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
1107 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
1108 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
1109 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
1110 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
1111 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
1112 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
1113 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
1114 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
1115 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1116 255, 255, 255, 255, 255, 255
1119 u32 xtal
= state
->cfg
.bw
->xtal_hz
/ 1000;
1120 int f_rel
= DIV_ROUND_CLOSEST(rf_khz
, xtal
) * xtal
- rf_khz
;
1122 int coef_re
[8], coef_im
[8];
1126 dprintk("relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel
, rf_khz
, xtal
);
1128 if (f_rel
< -bw_khz
/ 2 || f_rel
> bw_khz
/ 2)
1133 dib7000p_write_word(state
, 142, 0x0610);
1135 for (k
= 0; k
< 8; k
++) {
1136 pha
= ((f_rel
* (k
+ 1) * 112 * 80 / bw_khz
) / 1000) & 0x3ff;
1141 } else if (pha
< 256) {
1142 coef_re
[k
] = sine
[256 - (pha
& 0xff)];
1143 coef_im
[k
] = sine
[pha
& 0xff];
1144 } else if (pha
== 256) {
1147 } else if (pha
< 512) {
1148 coef_re
[k
] = -sine
[pha
& 0xff];
1149 coef_im
[k
] = sine
[256 - (pha
& 0xff)];
1150 } else if (pha
== 512) {
1153 } else if (pha
< 768) {
1154 coef_re
[k
] = -sine
[256 - (pha
& 0xff)];
1155 coef_im
[k
] = -sine
[pha
& 0xff];
1156 } else if (pha
== 768) {
1160 coef_re
[k
] = sine
[pha
& 0xff];
1161 coef_im
[k
] = -sine
[256 - (pha
& 0xff)];
1164 coef_re
[k
] *= notch
[k
];
1165 coef_re
[k
] += (1 << 14);
1166 if (coef_re
[k
] >= (1 << 24))
1167 coef_re
[k
] = (1 << 24) - 1;
1168 coef_re
[k
] /= (1 << 15);
1170 coef_im
[k
] *= notch
[k
];
1171 coef_im
[k
] += (1 << 14);
1172 if (coef_im
[k
] >= (1 << 24))
1173 coef_im
[k
] = (1 << 24) - 1;
1174 coef_im
[k
] /= (1 << 15);
1176 dprintk("PALF COEF: %d re: %d im: %d", k
, coef_re
[k
], coef_im
[k
]);
1178 dib7000p_write_word(state
, 143, (0 << 14) | (k
<< 10) | (coef_re
[k
] & 0x3ff));
1179 dib7000p_write_word(state
, 144, coef_im
[k
] & 0x3ff);
1180 dib7000p_write_word(state
, 143, (1 << 14) | (k
<< 10) | (coef_re
[k
] & 0x3ff));
1182 dib7000p_write_word(state
, 143, 0);
1185 static int dib7000p_tune(struct dvb_frontend
*demod
, struct dvb_frontend_parameters
*ch
)
1187 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1191 dib7000p_set_channel(state
, ch
, 0);
1196 dib7000p_write_word(state
, 770, 0x4000);
1197 dib7000p_write_word(state
, 770, 0x0000);
1200 /* 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 */
1201 tmp
= (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
1202 if (state
->sfn_workaround_active
) {
1203 dprintk("SFN workaround is active");
1205 dib7000p_write_word(state
, 166, 0x4000); // P_pha3_force_pha_shift
1207 dib7000p_write_word(state
, 166, 0x0000); // P_pha3_force_pha_shift
1209 dib7000p_write_word(state
, 29, tmp
);
1211 // never achieved a lock with that bandwidth so far - wait for osc-freq to update
1212 if (state
->timf
== 0)
1215 /* offset loop parameters */
1217 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
1218 tmp
= (6 << 8) | 0x80;
1219 switch (ch
->u
.ofdm
.transmission_mode
) {
1220 case TRANSMISSION_MODE_2K
:
1223 case TRANSMISSION_MODE_4K
:
1227 case TRANSMISSION_MODE_8K
:
1231 dib7000p_write_word(state
, 26, tmp
); /* timf_a(6xxx) */
1233 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1235 switch (ch
->u
.ofdm
.transmission_mode
) {
1236 case TRANSMISSION_MODE_2K
:
1239 case TRANSMISSION_MODE_4K
:
1243 case TRANSMISSION_MODE_8K
:
1247 dib7000p_write_word(state
, 32, tmp
);
1249 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1251 switch (ch
->u
.ofdm
.transmission_mode
) {
1252 case TRANSMISSION_MODE_2K
:
1255 case TRANSMISSION_MODE_4K
:
1259 case TRANSMISSION_MODE_8K
:
1263 dib7000p_write_word(state
, 33, tmp
);
1265 tmp
= dib7000p_read_word(state
, 509);
1266 if (!((tmp
>> 6) & 0x1)) {
1267 /* restart the fec */
1268 tmp
= dib7000p_read_word(state
, 771);
1269 dib7000p_write_word(state
, 771, tmp
| (1 << 1));
1270 dib7000p_write_word(state
, 771, tmp
);
1272 tmp
= dib7000p_read_word(state
, 509);
1274 // we achieved a lock - it's time to update the osc freq
1275 if ((tmp
>> 6) & 0x1) {
1276 dib7000p_update_timf(state
);
1277 /* P_timf_alpha += 2 */
1278 tmp
= dib7000p_read_word(state
, 26);
1279 dib7000p_write_word(state
, 26, (tmp
& ~(0xf << 12)) | ((((tmp
>> 12) & 0xf) + 5) << 12));
1282 if (state
->cfg
.spur_protect
)
1283 dib7000p_spur_protect(state
, ch
->frequency
/ 1000, BANDWIDTH_TO_KHZ(ch
->u
.ofdm
.bandwidth
));
1285 dib7000p_set_bandwidth(state
, BANDWIDTH_TO_KHZ(ch
->u
.ofdm
.bandwidth
));
1289 static int dib7000p_wakeup(struct dvb_frontend
*demod
)
1291 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1292 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
1293 dib7000p_set_adc_state(state
, DIBX000_SLOW_ADC_ON
);
1294 if (state
->version
== SOC7090
)
1295 dib7000p_sad_calib(state
);
1299 static int dib7000p_sleep(struct dvb_frontend
*demod
)
1301 struct dib7000p_state
*state
= demod
->demodulator_priv
;
1302 if (state
->version
== SOC7090
)
1303 return dib7090_set_output_mode(demod
, OUTMODE_HIGH_Z
) | dib7000p_set_power_mode(state
, DIB7000P_POWER_INTERFACE_ONLY
);
1304 return dib7000p_set_output_mode(state
, OUTMODE_HIGH_Z
) | dib7000p_set_power_mode(state
, DIB7000P_POWER_INTERFACE_ONLY
);
1307 static int dib7000p_identify(struct dib7000p_state
*st
)
1310 dprintk("checking demod on I2C address: %d (%x)", st
->i2c_addr
, st
->i2c_addr
);
1312 if ((value
= dib7000p_read_word(st
, 768)) != 0x01b3) {
1313 dprintk("wrong Vendor ID (read=0x%x)", value
);
1317 if ((value
= dib7000p_read_word(st
, 769)) != 0x4000) {
1318 dprintk("wrong Device ID (%x)", value
);
1325 static int dib7000p_get_frontend(struct dvb_frontend
*fe
, struct dvb_frontend_parameters
*fep
)
1327 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1328 u16 tps
= dib7000p_read_word(state
, 463);
1330 fep
->inversion
= INVERSION_AUTO
;
1332 fep
->u
.ofdm
.bandwidth
= BANDWIDTH_TO_INDEX(state
->current_bandwidth
);
1334 switch ((tps
>> 8) & 0x3) {
1336 fep
->u
.ofdm
.transmission_mode
= TRANSMISSION_MODE_2K
;
1339 fep
->u
.ofdm
.transmission_mode
= TRANSMISSION_MODE_8K
;
1341 /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */
1344 switch (tps
& 0x3) {
1346 fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_32
;
1349 fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_16
;
1352 fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_8
;
1355 fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_4
;
1359 switch ((tps
>> 14) & 0x3) {
1361 fep
->u
.ofdm
.constellation
= QPSK
;
1364 fep
->u
.ofdm
.constellation
= QAM_16
;
1368 fep
->u
.ofdm
.constellation
= QAM_64
;
1372 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1373 /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1375 fep
->u
.ofdm
.hierarchy_information
= HIERARCHY_NONE
;
1376 switch ((tps
>> 5) & 0x7) {
1378 fep
->u
.ofdm
.code_rate_HP
= FEC_1_2
;
1381 fep
->u
.ofdm
.code_rate_HP
= FEC_2_3
;
1384 fep
->u
.ofdm
.code_rate_HP
= FEC_3_4
;
1387 fep
->u
.ofdm
.code_rate_HP
= FEC_5_6
;
1391 fep
->u
.ofdm
.code_rate_HP
= FEC_7_8
;
1396 switch ((tps
>> 2) & 0x7) {
1398 fep
->u
.ofdm
.code_rate_LP
= FEC_1_2
;
1401 fep
->u
.ofdm
.code_rate_LP
= FEC_2_3
;
1404 fep
->u
.ofdm
.code_rate_LP
= FEC_3_4
;
1407 fep
->u
.ofdm
.code_rate_LP
= FEC_5_6
;
1411 fep
->u
.ofdm
.code_rate_LP
= FEC_7_8
;
1415 /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */
1420 static int dib7000p_set_frontend(struct dvb_frontend
*fe
, struct dvb_frontend_parameters
*fep
)
1422 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1425 if (state
->version
== SOC7090
) {
1426 dib7090_set_diversity_in(fe
, 0);
1427 dib7090_set_output_mode(fe
, OUTMODE_HIGH_Z
);
1430 dib7000p_set_output_mode(state
, OUTMODE_HIGH_Z
);
1432 /* maybe the parameter has been changed */
1433 state
->sfn_workaround_active
= buggy_sfn_workaround
;
1435 if (fe
->ops
.tuner_ops
.set_params
)
1436 fe
->ops
.tuner_ops
.set_params(fe
, fep
);
1438 /* start up the AGC */
1439 state
->agc_state
= 0;
1441 time
= dib7000p_agc_startup(fe
, fep
);
1444 } while (time
!= -1);
1446 if (fep
->u
.ofdm
.transmission_mode
== TRANSMISSION_MODE_AUTO
||
1447 fep
->u
.ofdm
.guard_interval
== GUARD_INTERVAL_AUTO
|| fep
->u
.ofdm
.constellation
== QAM_AUTO
|| fep
->u
.ofdm
.code_rate_HP
== FEC_AUTO
) {
1450 dib7000p_autosearch_start(fe
, fep
);
1453 found
= dib7000p_autosearch_is_irq(fe
);
1454 } while (found
== 0 && i
--);
1456 dprintk("autosearch returns: %d", found
);
1457 if (found
== 0 || found
== 1)
1458 return 0; // no channel found
1460 dib7000p_get_frontend(fe
, fep
);
1463 ret
= dib7000p_tune(fe
, fep
);
1465 /* make this a config parameter */
1466 if (state
->version
== SOC7090
)
1467 dib7090_set_output_mode(fe
, state
->cfg
.output_mode
);
1469 dib7000p_set_output_mode(state
, state
->cfg
.output_mode
);
1474 static int dib7000p_read_status(struct dvb_frontend
*fe
, fe_status_t
* stat
)
1476 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1477 u16 lock
= dib7000p_read_word(state
, 509);
1482 *stat
|= FE_HAS_SIGNAL
;
1484 *stat
|= FE_HAS_CARRIER
;
1486 *stat
|= FE_HAS_VITERBI
;
1488 *stat
|= FE_HAS_SYNC
;
1489 if ((lock
& 0x0038) == 0x38)
1490 *stat
|= FE_HAS_LOCK
;
1495 static int dib7000p_read_ber(struct dvb_frontend
*fe
, u32
* ber
)
1497 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1498 *ber
= (dib7000p_read_word(state
, 500) << 16) | dib7000p_read_word(state
, 501);
1502 static int dib7000p_read_unc_blocks(struct dvb_frontend
*fe
, u32
* unc
)
1504 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1505 *unc
= dib7000p_read_word(state
, 506);
1509 static int dib7000p_read_signal_strength(struct dvb_frontend
*fe
, u16
* strength
)
1511 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1512 u16 val
= dib7000p_read_word(state
, 394);
1513 *strength
= 65535 - val
;
1517 static int dib7000p_read_snr(struct dvb_frontend
*fe
, u16
* snr
)
1519 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1521 s32 signal_mant
, signal_exp
, noise_mant
, noise_exp
;
1524 val
= dib7000p_read_word(state
, 479);
1525 noise_mant
= (val
>> 4) & 0xff;
1526 noise_exp
= ((val
& 0xf) << 2);
1527 val
= dib7000p_read_word(state
, 480);
1528 noise_exp
+= ((val
>> 14) & 0x3);
1529 if ((noise_exp
& 0x20) != 0)
1532 signal_mant
= (val
>> 6) & 0xFF;
1533 signal_exp
= (val
& 0x3F);
1534 if ((signal_exp
& 0x20) != 0)
1537 if (signal_mant
!= 0)
1538 result
= intlog10(2) * 10 * signal_exp
+ 10 * intlog10(signal_mant
);
1540 result
= intlog10(2) * 10 * signal_exp
- 100;
1542 if (noise_mant
!= 0)
1543 result
-= intlog10(2) * 10 * noise_exp
+ 10 * intlog10(noise_mant
);
1545 result
-= intlog10(2) * 10 * noise_exp
- 100;
1547 *snr
= result
/ ((1 << 24) / 10);
1551 static int dib7000p_fe_get_tune_settings(struct dvb_frontend
*fe
, struct dvb_frontend_tune_settings
*tune
)
1553 tune
->min_delay_ms
= 1000;
1557 static void dib7000p_release(struct dvb_frontend
*demod
)
1559 struct dib7000p_state
*st
= demod
->demodulator_priv
;
1560 dibx000_exit_i2c_master(&st
->i2c_master
);
1561 i2c_del_adapter(&st
->dib7090_tuner_adap
);
1565 int dib7000pc_detection(struct i2c_adapter
*i2c_adap
)
1568 struct i2c_msg msg
[2] = {
1569 {.addr
= 18 >> 1,.flags
= 0,.buf
= tx
,.len
= 2},
1570 {.addr
= 18 >> 1,.flags
= I2C_M_RD
,.buf
= rx
,.len
= 2},
1576 if (i2c_transfer(i2c_adap
, msg
, 2) == 2)
1577 if (rx
[0] == 0x01 && rx
[1] == 0xb3) {
1578 dprintk("-D- DiB7000PC detected");
1582 msg
[0].addr
= msg
[1].addr
= 0x40;
1584 if (i2c_transfer(i2c_adap
, msg
, 2) == 2)
1585 if (rx
[0] == 0x01 && rx
[1] == 0xb3) {
1586 dprintk("-D- DiB7000PC detected");
1590 dprintk("-D- DiB7000PC not detected");
1593 EXPORT_SYMBOL(dib7000pc_detection
);
1595 struct i2c_adapter
*dib7000p_get_i2c_master(struct dvb_frontend
*demod
, enum dibx000_i2c_interface intf
, int gating
)
1597 struct dib7000p_state
*st
= demod
->demodulator_priv
;
1598 return dibx000_get_i2c_adapter(&st
->i2c_master
, intf
, gating
);
1600 EXPORT_SYMBOL(dib7000p_get_i2c_master
);
1602 int dib7000p_pid_filter_ctrl(struct dvb_frontend
*fe
, u8 onoff
)
1604 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1605 u16 val
= dib7000p_read_word(state
, 235) & 0xffef;
1606 val
|= (onoff
& 0x1) << 4;
1607 dprintk("PID filter enabled %d", onoff
);
1608 return dib7000p_write_word(state
, 235, val
);
1610 EXPORT_SYMBOL(dib7000p_pid_filter_ctrl
);
1612 int dib7000p_pid_filter(struct dvb_frontend
*fe
, u8 id
, u16 pid
, u8 onoff
)
1614 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1615 dprintk("PID filter: index %x, PID %d, OnOff %d", id
, pid
, onoff
);
1616 return dib7000p_write_word(state
, 241 + id
, onoff
? (1 << 13) | pid
: 0);
1618 EXPORT_SYMBOL(dib7000p_pid_filter
);
1620 int dib7000p_i2c_enumeration(struct i2c_adapter
*i2c
, int no_of_demods
, u8 default_addr
, struct dib7000p_config cfg
[])
1622 struct dib7000p_state
*dpst
;
1626 dpst
= kzalloc(sizeof(struct dib7000p_state
), GFP_KERNEL
);
1630 dpst
->i2c_adap
= i2c
;
1632 for (k
= no_of_demods
- 1; k
>= 0; k
--) {
1635 /* designated i2c address */
1636 if (cfg
[k
].default_i2c_addr
!= 0)
1637 new_addr
= cfg
[k
].default_i2c_addr
+ (k
<< 1);
1639 new_addr
= (0x40 + k
) << 1;
1640 dpst
->i2c_addr
= new_addr
;
1641 dib7000p_write_word(dpst
, 1287, 0x0003); /* sram lead in, rdy */
1642 if (dib7000p_identify(dpst
) != 0) {
1643 dpst
->i2c_addr
= default_addr
;
1644 dib7000p_write_word(dpst
, 1287, 0x0003); /* sram lead in, rdy */
1645 if (dib7000p_identify(dpst
) != 0) {
1646 dprintk("DiB7000P #%d: not identified\n", k
);
1652 /* start diversity to pull_down div_str - just for i2c-enumeration */
1653 dib7000p_set_output_mode(dpst
, OUTMODE_DIVERSITY
);
1655 /* set new i2c address and force divstart */
1656 dib7000p_write_word(dpst
, 1285, (new_addr
<< 2) | 0x2);
1658 dprintk("IC %d initialized (to i2c_address 0x%x)", k
, new_addr
);
1661 for (k
= 0; k
< no_of_demods
; k
++) {
1663 if (cfg
[k
].default_i2c_addr
!= 0)
1664 dpst
->i2c_addr
= (cfg
[k
].default_i2c_addr
+ k
) << 1;
1666 dpst
->i2c_addr
= (0x40 + k
) << 1;
1669 dib7000p_write_word(dpst
, 1285, dpst
->i2c_addr
<< 2);
1671 /* deactivate div - it was just for i2c-enumeration */
1672 dib7000p_set_output_mode(dpst
, OUTMODE_HIGH_Z
);
1678 EXPORT_SYMBOL(dib7000p_i2c_enumeration
);
1680 static const s32 lut_1000ln_mant
[] = {
1681 6908, 6956, 7003, 7047, 7090, 7131, 7170, 7208, 7244, 7279, 7313, 7346, 7377, 7408, 7438, 7467, 7495, 7523, 7549, 7575, 7600
1684 static s32
dib7000p_get_adc_power(struct dvb_frontend
*fe
)
1686 struct dib7000p_state
*state
= fe
->demodulator_priv
;
1687 u32 tmp_val
= 0, exp
= 0, mant
= 0;
1692 buf
[0] = dib7000p_read_word(state
, 0x184);
1693 buf
[1] = dib7000p_read_word(state
, 0x185);
1694 pow_i
= (buf
[0] << 16) | buf
[1];
1695 dprintk("raw pow_i = %d", pow_i
);
1698 while (tmp_val
>>= 1)
1701 mant
= (pow_i
* 1000 / (1 << exp
));
1702 dprintk(" mant = %d exp = %d", mant
/ 1000, exp
);
1704 ix
= (u8
) ((mant
- 1000) / 100); /* index of the LUT */
1705 dprintk(" ix = %d", ix
);
1707 pow_i
= (lut_1000ln_mant
[ix
] + 693 * (exp
- 20) - 6908);
1708 pow_i
= (pow_i
<< 8) / 1000;
1709 dprintk(" pow_i = %d", pow_i
);
1714 static int map_addr_to_serpar_number(struct i2c_msg
*msg
)
1716 if ((msg
->buf
[0] <= 15))
1718 else if (msg
->buf
[0] == 17)
1720 else if (msg
->buf
[0] == 16)
1722 else if (msg
->buf
[0] == 19)
1724 else if (msg
->buf
[0] >= 21 && msg
->buf
[0] <= 25)
1726 else if (msg
->buf
[0] == 28)
1734 static int w7090p_tuner_write_serpar(struct i2c_adapter
*i2c_adap
, struct i2c_msg msg
[], int num
)
1736 struct dib7000p_state
*state
= i2c_get_adapdata(i2c_adap
);
1739 u16 serpar_num
= msg
[0].buf
[0];
1741 while (n_overflow
== 1 && i
) {
1742 n_overflow
= (dib7000p_read_word(state
, 1984) >> 1) & 0x1;
1745 dprintk("Tuner ITF: write busy (overflow)");
1747 dib7000p_write_word(state
, 1985, (1 << 6) | (serpar_num
& 0x3f));
1748 dib7000p_write_word(state
, 1986, (msg
[0].buf
[1] << 8) | msg
[0].buf
[2]);
1753 static int w7090p_tuner_read_serpar(struct i2c_adapter
*i2c_adap
, struct i2c_msg msg
[], int num
)
1755 struct dib7000p_state
*state
= i2c_get_adapdata(i2c_adap
);
1756 u8 n_overflow
= 1, n_empty
= 1;
1758 u16 serpar_num
= msg
[0].buf
[0];
1761 while (n_overflow
== 1 && i
) {
1762 n_overflow
= (dib7000p_read_word(state
, 1984) >> 1) & 0x1;
1765 dprintk("TunerITF: read busy (overflow)");
1767 dib7000p_write_word(state
, 1985, (0 << 6) | (serpar_num
& 0x3f));
1770 while (n_empty
== 1 && i
) {
1771 n_empty
= dib7000p_read_word(state
, 1984) & 0x1;
1774 dprintk("TunerITF: read busy (empty)");
1776 read_word
= dib7000p_read_word(state
, 1987);
1777 msg
[1].buf
[0] = (read_word
>> 8) & 0xff;
1778 msg
[1].buf
[1] = (read_word
) & 0xff;
1783 static int w7090p_tuner_rw_serpar(struct i2c_adapter
*i2c_adap
, struct i2c_msg msg
[], int num
)
1785 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... */
1786 if (num
== 1) { /* write */
1787 return w7090p_tuner_write_serpar(i2c_adap
, msg
, 1);
1789 return w7090p_tuner_read_serpar(i2c_adap
, msg
, 2);
1795 int dib7090p_rw_on_apb(struct i2c_adapter
*i2c_adap
, struct i2c_msg msg
[], int num
, u16 apb_address
)
1797 struct dib7000p_state
*state
= i2c_get_adapdata(i2c_adap
);
1800 if (num
== 1) { /* write */
1801 dib7000p_write_word(state
, apb_address
, ((msg
[0].buf
[1] << 8) | (msg
[0].buf
[2])));
1803 word
= dib7000p_read_word(state
, apb_address
);
1804 msg
[1].buf
[0] = (word
>> 8) & 0xff;
1805 msg
[1].buf
[1] = (word
) & 0xff;
1811 static int dib7090_tuner_xfer(struct i2c_adapter
*i2c_adap
, struct i2c_msg msg
[], int num
)
1813 struct dib7000p_state
*state
= i2c_get_adapdata(i2c_adap
);
1815 u16 apb_address
= 0, word
;
1817 switch (msg
[0].buf
[0]) {
1903 i
= ((dib7000p_read_word(state
, 72) >> 12) & 0x3);
1904 word
= dib7000p_read_word(state
, 384 + i
);
1905 msg
[1].buf
[0] = (word
>> 8) & 0xff;
1906 msg
[1].buf
[1] = (word
) & 0xff;
1909 if (num
== 1) { /* write */
1910 word
= (u16
) ((msg
[0].buf
[1] << 8) | msg
[0].buf
[2]);
1912 word
= (dib7000p_read_word(state
, 72) & ~(3 << 12)) | (word
<< 12); //Mask bit 12,13
1913 dib7000p_write_word(state
, 72, word
); /* Set the proper input */
1918 if (apb_address
!= 0) /* R/W acces via APB */
1919 return dib7090p_rw_on_apb(i2c_adap
, msg
, num
, apb_address
);
1920 else /* R/W access via SERPAR */
1921 return w7090p_tuner_rw_serpar(i2c_adap
, msg
, num
);
1926 static u32
dib7000p_i2c_func(struct i2c_adapter
*adapter
)
1928 return I2C_FUNC_I2C
;
1931 static struct i2c_algorithm dib7090_tuner_xfer_algo
= {
1932 .master_xfer
= dib7090_tuner_xfer
,
1933 .functionality
= dib7000p_i2c_func
,
1936 struct i2c_adapter
*dib7090_get_i2c_tuner(struct dvb_frontend
*fe
)
1938 struct dib7000p_state
*st
= fe
->demodulator_priv
;
1939 return &st
->dib7090_tuner_adap
;
1941 EXPORT_SYMBOL(dib7090_get_i2c_tuner
);
1943 static int dib7090_host_bus_drive(struct dib7000p_state
*state
, u8 drive
)
1947 /* drive host bus 2, 3, 4 */
1948 reg
= dib7000p_read_word(state
, 1798) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1949 reg
|= (drive
<< 12) | (drive
<< 6) | drive
;
1950 dib7000p_write_word(state
, 1798, reg
);
1952 /* drive host bus 5,6 */
1953 reg
= dib7000p_read_word(state
, 1799) & ~((0x7 << 2) | (0x7 << 8));
1954 reg
|= (drive
<< 8) | (drive
<< 2);
1955 dib7000p_write_word(state
, 1799, reg
);
1957 /* drive host bus 7, 8, 9 */
1958 reg
= dib7000p_read_word(state
, 1800) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1959 reg
|= (drive
<< 12) | (drive
<< 6) | drive
;
1960 dib7000p_write_word(state
, 1800, reg
);
1962 /* drive host bus 10, 11 */
1963 reg
= dib7000p_read_word(state
, 1801) & ~((0x7 << 2) | (0x7 << 8));
1964 reg
|= (drive
<< 8) | (drive
<< 2);
1965 dib7000p_write_word(state
, 1801, reg
);
1967 /* drive host bus 12, 13, 14 */
1968 reg
= dib7000p_read_word(state
, 1802) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1969 reg
|= (drive
<< 12) | (drive
<< 6) | drive
;
1970 dib7000p_write_word(state
, 1802, reg
);
1975 static u32
dib7090_calcSyncFreq(u32 P_Kin
, u32 P_Kout
, u32 insertExtSynchro
, u32 syncSize
)
1978 u32 nom
= (insertExtSynchro
* P_Kin
+ syncSize
);
1980 u32 syncFreq
= ((nom
<< quantif
) / denom
);
1982 if ((syncFreq
& ((1 << quantif
) - 1)) != 0)
1983 syncFreq
= (syncFreq
>> quantif
) + 1;
1985 syncFreq
= (syncFreq
>> quantif
);
1988 syncFreq
= syncFreq
- 1;
1993 static int dib7090_cfg_DibTx(struct dib7000p_state
*state
, u32 P_Kin
, u32 P_Kout
, u32 insertExtSynchro
, u32 synchroMode
, u32 syncWord
, u32 syncSize
)
1996 u16 rx_copy_buf
[22];
1998 dprintk("Configure DibStream Tx");
1999 for (index_buf
= 0; index_buf
<22; index_buf
++)
2000 rx_copy_buf
[index_buf
] = dib7000p_read_word(state
, 1536+index_buf
);
2002 dib7000p_write_word(state
, 1615, 1);
2003 dib7000p_write_word(state
, 1603, P_Kin
);
2004 dib7000p_write_word(state
, 1605, P_Kout
);
2005 dib7000p_write_word(state
, 1606, insertExtSynchro
);
2006 dib7000p_write_word(state
, 1608, synchroMode
);
2007 dib7000p_write_word(state
, 1609, (syncWord
>> 16) & 0xffff);
2008 dib7000p_write_word(state
, 1610, syncWord
& 0xffff);
2009 dib7000p_write_word(state
, 1612, syncSize
);
2010 dib7000p_write_word(state
, 1615, 0);
2012 for (index_buf
= 0; index_buf
<22; index_buf
++)
2013 dib7000p_write_word(state
, 1536+index_buf
, rx_copy_buf
[index_buf
]);
2018 static int dib7090_cfg_DibRx(struct dib7000p_state
*state
, u32 P_Kin
, u32 P_Kout
, u32 synchroMode
, u32 insertExtSynchro
, u32 syncWord
, u32 syncSize
,
2023 dprintk("Configure DibStream Rx");
2024 if ((P_Kin
!= 0) && (P_Kout
!= 0))
2026 syncFreq
= dib7090_calcSyncFreq(P_Kin
, P_Kout
, insertExtSynchro
, syncSize
);
2027 dib7000p_write_word(state
, 1542, syncFreq
);
2029 dib7000p_write_word(state
, 1554, 1);
2030 dib7000p_write_word(state
, 1536, P_Kin
);
2031 dib7000p_write_word(state
, 1537, P_Kout
);
2032 dib7000p_write_word(state
, 1539, synchroMode
);
2033 dib7000p_write_word(state
, 1540, (syncWord
>> 16) & 0xffff);
2034 dib7000p_write_word(state
, 1541, syncWord
& 0xffff);
2035 dib7000p_write_word(state
, 1543, syncSize
);
2036 dib7000p_write_word(state
, 1544, dataOutRate
);
2037 dib7000p_write_word(state
, 1554, 0);
2042 static int dib7090_enDivOnHostBus(struct dib7000p_state
*state
)
2046 dprintk("Enable Diversity on host bus");
2047 reg
= (1 << 8) | (1 << 5); // P_enDivOutOnDibTx = 1 ; P_enDibTxOnHostBus = 1
2048 dib7000p_write_word(state
, 1288, reg
);
2050 return dib7090_cfg_DibTx(state
, 5, 5, 0, 0, 0, 0);
2053 static int dib7090_enAdcOnHostBus(struct dib7000p_state
*state
)
2057 dprintk("Enable ADC on host bus");
2058 reg
= (1 << 7) | (1 << 5); //P_enAdcOnDibTx = 1 ; P_enDibTxOnHostBus = 1
2059 dib7000p_write_word(state
, 1288, reg
);
2061 return dib7090_cfg_DibTx(state
, 20, 5, 10, 0, 0, 0);
2064 static int dib7090_enMpegOnHostBus(struct dib7000p_state
*state
)
2068 dprintk("Enable Mpeg on host bus");
2069 reg
= (1 << 9) | (1 << 5); //P_enMpegOnDibTx = 1 ; P_enDibTxOnHostBus = 1
2070 dib7000p_write_word(state
, 1288, reg
);
2072 return dib7090_cfg_DibTx(state
, 8, 5, 0, 0, 0, 0);
2075 static int dib7090_enMpegInput(struct dib7000p_state
*state
)
2077 dprintk("Enable Mpeg input");
2078 return dib7090_cfg_DibRx(state
, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */
2081 static int dib7090_enMpegMux(struct dib7000p_state
*state
, u16 pulseWidth
, u16 enSerialMode
, u16 enSerialClkDiv2
)
2083 u16 reg
= (1 << 7) | ((pulseWidth
& 0x1f) << 2) | ((enSerialMode
& 0x1) << 1) | (enSerialClkDiv2
& 0x1);
2085 dprintk("Enable Mpeg mux");
2086 dib7000p_write_word(state
, 1287, reg
);
2088 reg
&= ~(1 << 7); // P_restart_mpegMux = 0
2089 dib7000p_write_word(state
, 1287, reg
);
2091 reg
= (1 << 4); //P_enMpegMuxOnHostBus = 1
2092 dib7000p_write_word(state
, 1288, reg
);
2097 static int dib7090_disableMpegMux(struct dib7000p_state
*state
)
2101 dprintk("Disable Mpeg mux");
2102 dib7000p_write_word(state
, 1288, 0); //P_enMpegMuxOnHostBus = 0
2104 reg
= dib7000p_read_word(state
, 1287);
2105 reg
&= ~(1 << 7); // P_restart_mpegMux = 0
2106 dib7000p_write_word(state
, 1287, reg
);
2111 static int dib7090_set_input_mode(struct dvb_frontend
*fe
, int mode
)
2113 struct dib7000p_state
*state
= fe
->demodulator_priv
;
2116 case INPUT_MODE_DIVERSITY
:
2117 dprintk("Enable diversity INPUT");
2118 dib7090_cfg_DibRx(state
, 5,5,0,0,0,0,0);
2120 case INPUT_MODE_MPEG
:
2121 dprintk("Enable Mpeg INPUT");
2122 dib7090_cfg_DibRx(state
, 8,5,0,0,0,8,0); /*outputRate = 8 */
2124 case INPUT_MODE_OFF
:
2126 dprintk("Disable INPUT");
2127 dib7090_cfg_DibRx(state
, 0,0,0,0,0,0,0);
2133 static int dib7090_set_diversity_in(struct dvb_frontend
*fe
, int onoff
)
2136 case 0: /* only use the internal way - not the diversity input */
2137 dib7090_set_input_mode(fe
, INPUT_MODE_MPEG
);
2139 case 1: /* both ways */
2140 case 2: /* only the diversity input */
2141 dib7090_set_input_mode(fe
, INPUT_MODE_DIVERSITY
);
2148 static int dib7090_set_output_mode(struct dvb_frontend
*fe
, int mode
)
2150 struct dib7000p_state
*state
= fe
->demodulator_priv
;
2152 u16 outreg
, smo_mode
, fifo_threshold
;
2153 u8 prefer_mpeg_mux_use
= 1;
2156 dib7090_host_bus_drive(state
, 1);
2158 fifo_threshold
= 1792;
2159 smo_mode
= (dib7000p_read_word(state
, 235) & 0x0050) | (1 << 1);
2160 outreg
= dib7000p_read_word(state
, 1286) & ~((1 << 10) | (0x7 << 6) | (1 << 1));
2163 case OUTMODE_HIGH_Z
:
2167 case OUTMODE_MPEG2_SERIAL
:
2168 if (prefer_mpeg_mux_use
) {
2169 dprintk("Sip 7090P setting output mode TS_SERIAL using Mpeg Mux");
2170 dib7090_enMpegOnHostBus(state
);
2171 dib7090_enMpegInput(state
);
2172 if (state
->cfg
.enMpegOutput
== 1)
2173 dib7090_enMpegMux(state
, 3, 1, 1);
2175 } else { /* Use Smooth block */
2176 dprintk("Sip 7090P setting output mode TS_SERIAL using Smooth bloc");
2177 dib7090_disableMpegMux(state
);
2178 dib7000p_write_word(state
, 1288, (1 << 6)); //P_enDemOutInterfOnHostBus = 1
2179 outreg
|= (2 << 6) | (0 << 1);
2183 case OUTMODE_MPEG2_PAR_GATED_CLK
:
2184 if (prefer_mpeg_mux_use
) {
2185 dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Mpeg Mux");
2186 dib7090_enMpegOnHostBus(state
);
2187 dib7090_enMpegInput(state
);
2188 if (state
->cfg
.enMpegOutput
== 1)
2189 dib7090_enMpegMux(state
, 2, 0, 0);
2190 } else { /* Use Smooth block */
2191 dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Smooth block");
2192 dib7090_disableMpegMux(state
);
2193 dib7000p_write_word(state
, 1288, (1 << 6)); //P_enDemOutInterfOnHostBus = 1
2198 case OUTMODE_MPEG2_PAR_CONT_CLK
: /* Using Smooth block only */
2199 dprintk("Sip 7090P setting output mode TS_PARALLEL_CONT using Smooth block");
2200 dib7090_disableMpegMux(state
);
2201 dib7000p_write_word(state
, 1288, (1 << 6)); //P_enDemOutInterfOnHostBus = 1
2205 case OUTMODE_MPEG2_FIFO
: /* Using Smooth block because not supported by new Mpeg Mux bloc */
2206 dprintk("Sip 7090P setting output mode TS_FIFO using Smooth block");
2207 dib7090_disableMpegMux(state
);
2208 dib7000p_write_word(state
, 1288, (1 << 6)); //P_enDemOutInterfOnHostBus = 1
2210 smo_mode
|= (3 << 1);
2211 fifo_threshold
= 512;
2214 case OUTMODE_DIVERSITY
:
2215 dprintk("Sip 7090P setting output mode MODE_DIVERSITY");
2216 dib7090_disableMpegMux(state
);
2217 dib7090_enDivOnHostBus(state
);
2220 case OUTMODE_ANALOG_ADC
:
2221 dprintk("Sip 7090P setting output mode MODE_ANALOG_ADC");
2222 dib7090_enAdcOnHostBus(state
);
2226 if (state
->cfg
.output_mpeg2_in_188_bytes
)
2227 smo_mode
|= (1 << 5);
2229 ret
|= dib7000p_write_word(state
, 235, smo_mode
);
2230 ret
|= dib7000p_write_word(state
, 236, fifo_threshold
); /* synchronous fread */
2231 ret
|= dib7000p_write_word(state
, 1286, outreg
| (1 << 10)); /* allways set Dout active = 1 !!! */
2236 int dib7090_tuner_sleep(struct dvb_frontend
*fe
, int onoff
)
2238 struct dib7000p_state
*state
= fe
->demodulator_priv
;
2241 dprintk("sleep dib7090: %d", onoff
);
2243 en_cur_state
= dib7000p_read_word(state
, 1922);
2245 if (en_cur_state
> 0xff) { //LNAs and MIX are ON and therefore it is a valid configuration
2246 state
->tuner_enable
= en_cur_state
;
2250 en_cur_state
&= 0x00ff; //Mask to be applied
2252 if (state
->tuner_enable
!= 0)
2253 en_cur_state
= state
->tuner_enable
;
2256 dib7000p_write_word(state
, 1922, en_cur_state
);
2260 EXPORT_SYMBOL(dib7090_tuner_sleep
);
2262 int dib7090_agc_restart(struct dvb_frontend
*fe
, u8 restart
)
2264 dprintk("AGC restart callback: %d", restart
);
2267 EXPORT_SYMBOL(dib7090_agc_restart
);
2269 int dib7090_get_adc_power(struct dvb_frontend
*fe
)
2271 return dib7000p_get_adc_power(fe
);
2273 EXPORT_SYMBOL(dib7090_get_adc_power
);
2275 int dib7090_slave_reset(struct dvb_frontend
*fe
)
2277 struct dib7000p_state
*state
= fe
->demodulator_priv
;
2280 reg
= dib7000p_read_word(state
, 1794);
2281 dib7000p_write_word(state
, 1794, reg
| (4 << 12));
2283 dib7000p_write_word(state
, 1032, 0xffff);
2286 EXPORT_SYMBOL(dib7090_slave_reset
);
2288 static struct dvb_frontend_ops dib7000p_ops
;
2289 struct dvb_frontend
*dib7000p_attach(struct i2c_adapter
*i2c_adap
, u8 i2c_addr
, struct dib7000p_config
*cfg
)
2291 struct dvb_frontend
*demod
;
2292 struct dib7000p_state
*st
;
2293 st
= kzalloc(sizeof(struct dib7000p_state
), GFP_KERNEL
);
2297 memcpy(&st
->cfg
, cfg
, sizeof(struct dib7000p_config
));
2298 st
->i2c_adap
= i2c_adap
;
2299 st
->i2c_addr
= i2c_addr
;
2300 st
->gpio_val
= cfg
->gpio_val
;
2301 st
->gpio_dir
= cfg
->gpio_dir
;
2303 /* Ensure the output mode remains at the previous default if it's
2304 * not specifically set by the caller.
2306 if ((st
->cfg
.output_mode
!= OUTMODE_MPEG2_SERIAL
) && (st
->cfg
.output_mode
!= OUTMODE_MPEG2_PAR_GATED_CLK
))
2307 st
->cfg
.output_mode
= OUTMODE_MPEG2_FIFO
;
2310 demod
->demodulator_priv
= st
;
2311 memcpy(&st
->demod
.ops
, &dib7000p_ops
, sizeof(struct dvb_frontend_ops
));
2313 dib7000p_write_word(st
, 1287, 0x0003); /* sram lead in, rdy */
2315 if (dib7000p_identify(st
) != 0)
2318 st
->version
= dib7000p_read_word(st
, 897);
2320 /* FIXME: make sure the dev.parent field is initialized, or else
2321 request_firmware() will hit an OOPS (this should be moved somewhere
2324 dibx000_init_i2c_master(&st
->i2c_master
, DIB7000P
, st
->i2c_adap
, st
->i2c_addr
);
2326 /* init 7090 tuner adapter */
2327 strncpy(st
->dib7090_tuner_adap
.name
, "DiB7090 tuner interface", sizeof(st
->dib7090_tuner_adap
.name
));
2328 st
->dib7090_tuner_adap
.algo
= &dib7090_tuner_xfer_algo
;
2329 st
->dib7090_tuner_adap
.algo_data
= NULL
;
2330 st
->dib7090_tuner_adap
.dev
.parent
= st
->i2c_adap
->dev
.parent
;
2331 i2c_set_adapdata(&st
->dib7090_tuner_adap
, st
);
2332 i2c_add_adapter(&st
->dib7090_tuner_adap
);
2334 dib7000p_demod_reset(st
);
2336 if (st
->version
== SOC7090
) {
2337 dib7090_set_output_mode(demod
, st
->cfg
.output_mode
);
2338 dib7090_set_diversity_in(demod
, 0);
2347 EXPORT_SYMBOL(dib7000p_attach
);
2349 static struct dvb_frontend_ops dib7000p_ops
= {
2351 .name
= "DiBcom 7000PC",
2353 .frequency_min
= 44250000,
2354 .frequency_max
= 867250000,
2355 .frequency_stepsize
= 62500,
2356 .caps
= FE_CAN_INVERSION_AUTO
|
2357 FE_CAN_FEC_1_2
| FE_CAN_FEC_2_3
| FE_CAN_FEC_3_4
|
2358 FE_CAN_FEC_5_6
| FE_CAN_FEC_7_8
| FE_CAN_FEC_AUTO
|
2359 FE_CAN_QPSK
| FE_CAN_QAM_16
| FE_CAN_QAM_64
| FE_CAN_QAM_AUTO
|
2360 FE_CAN_TRANSMISSION_MODE_AUTO
| FE_CAN_GUARD_INTERVAL_AUTO
| FE_CAN_RECOVER
| FE_CAN_HIERARCHY_AUTO
,
2363 .release
= dib7000p_release
,
2365 .init
= dib7000p_wakeup
,
2366 .sleep
= dib7000p_sleep
,
2368 .set_frontend
= dib7000p_set_frontend
,
2369 .get_tune_settings
= dib7000p_fe_get_tune_settings
,
2370 .get_frontend
= dib7000p_get_frontend
,
2372 .read_status
= dib7000p_read_status
,
2373 .read_ber
= dib7000p_read_ber
,
2374 .read_signal_strength
= dib7000p_read_signal_strength
,
2375 .read_snr
= dib7000p_read_snr
,
2376 .read_ucblocks
= dib7000p_read_unc_blocks
,
2379 MODULE_AUTHOR("Olivier Grenie <ogrenie@dibcom.fr>");
2380 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
2381 MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
2382 MODULE_LICENSE("GPL");