2 * Linux-DVB Driver for DiBcom's second generation DiB7000P (PC).
4 * Copyright (C) 2005-6 DiBcom (http://www.dibcom.fr/)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
10 #include <linux/kernel.h>
11 #include <linux/i2c.h>
13 #include "dvb_frontend.h"
18 module_param(debug
, int, 0644);
19 MODULE_PARM_DESC(debug
, "turn on debugging (default: 0)");
21 #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P:"); printk(args); } } while (0)
23 struct dib7000p_state
{
24 struct dvb_frontend demod
;
25 struct dib7000p_config cfg
;
28 struct i2c_adapter
*i2c_adap
;
30 struct dibx000_i2c_master i2c_master
;
35 fe_bandwidth_t current_bandwidth
;
36 struct dibx000_agc_config
*current_agc
;
43 enum dib7000p_power_mode
{
44 DIB7000P_POWER_ALL
= 0,
45 DIB7000P_POWER_INTERFACE_ONLY
,
48 static u16
dib7000p_read_word(struct dib7000p_state
*state
, u16 reg
)
50 u8 wb
[2] = { reg
>> 8, reg
& 0xff };
52 struct i2c_msg msg
[2] = {
53 { .addr
= state
->i2c_addr
>> 1, .flags
= 0, .buf
= wb
, .len
= 2 },
54 { .addr
= state
->i2c_addr
>> 1, .flags
= I2C_M_RD
, .buf
= rb
, .len
= 2 },
57 if (i2c_transfer(state
->i2c_adap
, msg
, 2) != 2)
58 dprintk("i2c read error on %d\n",reg
);
60 return (rb
[0] << 8) | rb
[1];
63 static int dib7000p_write_word(struct dib7000p_state
*state
, u16 reg
, u16 val
)
66 (reg
>> 8) & 0xff, reg
& 0xff,
67 (val
>> 8) & 0xff, val
& 0xff,
69 struct i2c_msg msg
= {
70 .addr
= state
->i2c_addr
>> 1, .flags
= 0, .buf
= b
, .len
= 4
72 return i2c_transfer(state
->i2c_adap
, &msg
, 1) != 1 ? -EREMOTEIO
: 0;
74 static int dib7000p_set_output_mode(struct dib7000p_state
*state
, int mode
)
77 u16 outreg
, fifo_threshold
, smo_mode
;
80 fifo_threshold
= 1792;
81 smo_mode
= (dib7000p_read_word(state
, 235) & 0x0010) | (1 << 1);
83 dprintk("-I- Setting output mode for demod %p to %d\n",
87 case OUTMODE_MPEG2_PAR_GATED_CLK
: // STBs with parallel gated clock
88 outreg
= (1 << 10); /* 0x0400 */
90 case OUTMODE_MPEG2_PAR_CONT_CLK
: // STBs with parallel continues clock
91 outreg
= (1 << 10) | (1 << 6); /* 0x0440 */
93 case OUTMODE_MPEG2_SERIAL
: // STBs with serial input
94 outreg
= (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */
96 case OUTMODE_DIVERSITY
:
97 if (state
->cfg
.hostbus_diversity
)
98 outreg
= (1 << 10) | (4 << 6); /* 0x0500 */
102 case OUTMODE_MPEG2_FIFO
: // e.g. USB feeding
103 smo_mode
|= (3 << 1);
104 fifo_threshold
= 512;
105 outreg
= (1 << 10) | (5 << 6);
107 case OUTMODE_HIGH_Z
: // disable
111 dprintk("Unhandled output_mode passed to be set for demod %p\n",&state
->demod
);
115 if (state
->cfg
.output_mpeg2_in_188_bytes
)
116 smo_mode
|= (1 << 5) ;
118 ret
|= dib7000p_write_word(state
, 235, smo_mode
);
119 ret
|= dib7000p_write_word(state
, 236, fifo_threshold
); /* synchronous fread */
120 ret
|= dib7000p_write_word(state
, 1286, outreg
); /* P_Div_active */
125 static int dib7000p_set_power_mode(struct dib7000p_state
*state
, enum dib7000p_power_mode mode
)
127 /* by default everything is powered off */
128 u16 reg_774
= 0xffff, reg_775
= 0xffff, reg_776
= 0x0007, reg_899
= 0x0003,
129 reg_1280
= (0xfe00) | (dib7000p_read_word(state
, 1280) & 0x01ff);
131 /* now, depending on the requested mode, we power on */
133 /* power up everything in the demod */
134 case DIB7000P_POWER_ALL
:
135 reg_774
= 0x0000; reg_775
= 0x0000; reg_776
= 0x0; reg_899
= 0x0; reg_1280
&= 0x01ff;
137 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
138 case DIB7000P_POWER_INTERFACE_ONLY
: /* TODO power up either SDIO or I2C */
139 reg_1280
&= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
141 /* TODO following stuff is just converted from the dib7000-driver - check when is used what */
144 dib7000p_write_word(state
, 774, reg_774
);
145 dib7000p_write_word(state
, 775, reg_775
);
146 dib7000p_write_word(state
, 776, reg_776
);
147 dib7000p_write_word(state
, 899, reg_899
);
148 dib7000p_write_word(state
, 1280, reg_1280
);
153 static void dib7000p_set_adc_state(struct dib7000p_state
*state
, enum dibx000_adc_states no
)
155 u16 reg_908
= dib7000p_read_word(state
, 908),
156 reg_909
= dib7000p_read_word(state
, 909);
159 case DIBX000_SLOW_ADC_ON
:
160 reg_909
|= (1 << 1) | (1 << 0);
161 dib7000p_write_word(state
, 909, reg_909
);
162 reg_909
&= ~(1 << 1);
165 case DIBX000_SLOW_ADC_OFF
:
166 reg_909
|= (1 << 1) | (1 << 0);
174 case DIBX000_ADC_OFF
: // leave the VBG voltage on
175 reg_908
|= (1 << 14) | (1 << 13) | (1 << 12);
176 reg_909
|= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
179 case DIBX000_VBG_ENABLE
:
180 reg_908
&= ~(1 << 15);
183 case DIBX000_VBG_DISABLE
:
184 reg_908
|= (1 << 15);
191 // dprintk("908: %x, 909: %x\n", reg_908, reg_909);
193 dib7000p_write_word(state
, 908, reg_908
);
194 dib7000p_write_word(state
, 909, reg_909
);
197 static int dib7000p_set_bandwidth(struct dvb_frontend
*demod
, u8 BW_Idx
)
199 struct dib7000p_state
*state
= demod
->demodulator_priv
;
202 // store the current bandwidth for later use
203 state
->current_bandwidth
= BW_Idx
;
205 if (state
->timf
== 0) {
206 dprintk("-D- Using default timf\n");
207 timf
= state
->cfg
.bw
->timf
;
209 dprintk("-D- Using updated timf\n");
213 timf
= timf
* (BW_INDEX_TO_KHZ(BW_Idx
) / 100) / 80;
215 dprintk("timf: %d\n",timf
);
217 dib7000p_write_word(state
, 23, (timf
>> 16) & 0xffff);
218 dib7000p_write_word(state
, 24, (timf
) & 0xffff);
223 static int dib7000p_sad_calib(struct dib7000p_state
*state
)
226 // dib7000p_write_word(state, 72, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth
227 dib7000p_write_word(state
, 73, (0 << 1) | (0 << 0));
228 dib7000p_write_word(state
, 74, 776); // 0.625*3.3 / 4096
230 /* do the calibration */
231 dib7000p_write_word(state
, 73, (1 << 0));
232 dib7000p_write_word(state
, 73, (0 << 0));
239 static void dib7000p_reset_pll(struct dib7000p_state
*state
)
241 struct dibx000_bandwidth_config
*bw
= &state
->cfg
.bw
[0];
243 dib7000p_write_word(state
, 903, (bw
->pll_prediv
<< 5) | (((bw
->pll_ratio
>> 6) & 0x3) << 3) | (bw
->pll_range
<< 1) | bw
->pll_reset
);
244 dib7000p_write_word(state
, 900, ((bw
->pll_ratio
& 0x3f) << 9) | (bw
->pll_bypass
<< 15) | (bw
->modulo
<< 7) | (bw
->ADClkSrc
<< 6) |
245 (bw
->IO_CLK_en_core
<< 5) | (bw
->bypclk_div
<< 2) | (bw
->enable_refdiv
<< 1) | (0 << 0));
247 dib7000p_write_word(state
, 18, ((bw
->internal
*1000) >> 16) & 0xffff);
248 dib7000p_write_word(state
, 19, (bw
->internal
*1000 ) & 0xffff);
249 dib7000p_write_word(state
, 21, (bw
->ifreq
>> 16) & 0xffff);
250 dib7000p_write_word(state
, 22, (bw
->ifreq
) & 0xffff);
252 dib7000p_write_word(state
, 72, bw
->sad_cfg
);
255 static int dib7000p_reset_gpio(struct dib7000p_state
*st
)
257 /* reset the GPIOs */
258 dprintk("-D- gpio dir: %x: gpio val: %x, gpio pwm pos: %x\n",st
->gpio_dir
, st
->gpio_val
,st
->cfg
.gpio_pwm_pos
);
260 dib7000p_write_word(st
, 1029, st
->gpio_dir
);
261 dib7000p_write_word(st
, 1030, st
->gpio_val
);
263 /* TODO 1031 is P_gpio_od */
265 dib7000p_write_word(st
, 1032, st
->cfg
.gpio_pwm_pos
);
267 dib7000p_write_word(st
, 1037, st
->cfg
.pwm_freq_div
);
271 static int dib7000p_demod_reset(struct dib7000p_state
*state
)
273 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
275 dib7000p_set_adc_state(state
, DIBX000_VBG_ENABLE
);
277 /* restart all parts */
278 dib7000p_write_word(state
, 770, 0xffff);
279 dib7000p_write_word(state
, 771, 0xffff);
280 dib7000p_write_word(state
, 772, 0x001f);
281 dib7000p_write_word(state
, 898, 0x0003);
282 /* except i2c, sdio, gpio - control interfaces */
283 dib7000p_write_word(state
, 1280, 0x01fc - ((1 << 7) | (1 << 6) | (1 << 5)) );
285 dib7000p_write_word(state
, 770, 0);
286 dib7000p_write_word(state
, 771, 0);
287 dib7000p_write_word(state
, 772, 0);
288 dib7000p_write_word(state
, 898, 0);
289 dib7000p_write_word(state
, 1280, 0);
292 dib7000p_reset_pll(state
);
294 if (dib7000p_reset_gpio(state
) != 0)
295 dprintk("-E- GPIO reset was not successful.\n");
297 if (dib7000p_set_output_mode(state
, OUTMODE_HIGH_Z
) != 0)
298 dprintk("-E- OUTPUT_MODE could not be resetted.\n");
300 /* unforce divstr regardless whether i2c enumeration was done or not */
301 dib7000p_write_word(state
, 1285, dib7000p_read_word(state
, 1285) & ~(1 << 1) );
303 dib7000p_set_power_mode(state
, DIB7000P_POWER_INTERFACE_ONLY
);
308 static void dib7000p_restart_agc(struct dib7000p_state
*state
)
310 // P_restart_iqc & P_restart_agc
311 dib7000p_write_word(state
, 770, 0x0c00);
312 dib7000p_write_word(state
, 770, 0x0000);
315 static void dib7000p_update_lna(struct dib7000p_state
*state
)
320 // when there is no LNA to program return immediatly
321 if (state
->cfg
.update_lna
== NULL
)
324 for (i
= 0; i
< 5; i
++) {
325 // read dyn_gain here (because it is demod-dependent and not tuner)
326 dyn_gain
= dib7000p_read_word(state
, 394);
328 if (state
->cfg
.update_lna(&state
->demod
,dyn_gain
)) { // LNA has changed
329 dib7000p_restart_agc(state
);
336 static void dib7000p_pll_clk_cfg(struct dib7000p_state
*state
)
339 tmp
= dib7000p_read_word(state
, 903);
340 dib7000p_write_word(state
, 903, (tmp
| 0x1)); //pwr-up pll
341 tmp
= dib7000p_read_word(state
, 900);
342 dib7000p_write_word(state
, 900, (tmp
& 0x7fff) | (1 << 6)); //use High freq clock
345 static void dib7000p_update_timf_freq(struct dib7000p_state
*state
)
347 u32 timf
= (dib7000p_read_word(state
, 427) << 16) | dib7000p_read_word(state
, 428);
348 state
->timf
= timf
* 80 / (BW_INDEX_TO_KHZ(state
->current_bandwidth
) / 100);
349 dib7000p_write_word(state
, 23, (u16
) (timf
>> 16));
350 dib7000p_write_word(state
, 24, (u16
) (timf
& 0xffff));
351 dprintk("-D- Updated timf_frequency: %d (default: %d)\n",state
->timf
, state
->cfg
.bw
->timf
);
354 static void dib7000p_set_channel(struct dib7000p_state
*state
, struct dibx000_ofdm_channel
*ch
, u8 seq
)
356 u16 tmp
, est
[4]; // reg_26, reg_32, reg_33, reg_187, reg_188, reg_189, reg_190, reg_207, reg_208;
358 /* nfft, guard, qam, alpha */
359 dib7000p_write_word(state
, 0, (ch
->nfft
<< 7) | (ch
->guard
<< 5) | (ch
->nqam
<< 3) | (ch
->vit_alpha
));
360 dib7000p_write_word(state
, 5, (seq
<< 4) | 1); /* do not force tps, search list 0 */
362 /* P_dintl_native, P_dintlv_inv, P_vit_hrch, P_vit_code_rate, P_vit_select_hp */
363 tmp
= (ch
->intlv_native
<< 6) | (ch
->vit_hrch
<< 4) | (ch
->vit_select_hp
& 0x1);
364 if (ch
->vit_hrch
== 0 || ch
->vit_select_hp
== 1)
365 tmp
|= (ch
->vit_code_rate_hp
<< 1);
367 tmp
|= (ch
->vit_code_rate_lp
<< 1);
368 dib7000p_write_word(state
, 208, tmp
);
370 /* P_dvsy_sync_wait */
372 case 1: tmp
= 256; break;
373 case 2: tmp
= 128; break;
375 default: tmp
= 64; break;
377 tmp
*= ((1 << (ch
->guard
)) * 3 / 2); // add 50% SFN margin
380 /* deactive the possibility of diversity reception if extended interleave */
381 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
382 if (ch
->intlv_native
|| ch
->nfft
== 1)
383 tmp
|= (1 << 2) | (2 << 0);
384 dib7000p_write_word(state
, 207, tmp
);
386 dib7000p_write_word(state
, 26, 0x6680); // timf(6xxx)
387 dib7000p_write_word(state
, 29, 0x1273); // isi inh1273 on1073
388 dib7000p_write_word(state
, 32, 0x0003); // pha_off_max(xxx3)
389 dib7000p_write_word(state
, 33, 0x0005); // sfreq(xxx5)
391 /* channel estimation fine configuration */
394 est
[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
395 est
[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
396 est
[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
397 est
[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
400 est
[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
401 est
[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
402 est
[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
403 est
[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
406 est
[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
407 est
[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
408 est
[2] = 0x0333; /* P_adp_regul_ext 0.1 */
409 est
[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
412 for (tmp
= 0; tmp
< 4; tmp
++)
413 dib7000p_write_word(state
, 187 + tmp
, est
[tmp
]);
415 // set power-up level: interf+analog+AGC
416 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
417 dib7000p_set_adc_state(state
, DIBX000_ADC_ON
);
418 dib7000p_pll_clk_cfg(state
);
421 // AGC initialization
422 if (state
->cfg
.agc_control
)
423 state
->cfg
.agc_control(&state
->demod
, 1);
425 dib7000p_restart_agc(state
);
427 // wait AGC rough lock time
430 dib7000p_update_lna(state
);
432 // wait AGC accurate lock time
434 if (state
->cfg
.agc_control
)
435 state
->cfg
.agc_control(&state
->demod
, 0);
438 static int dib7000p_autosearch_start(struct dvb_frontend
*demod
, struct dibx000_ofdm_channel
*ch
)
440 struct dib7000p_state
*state
= demod
->demodulator_priv
;
441 struct dibx000_ofdm_channel auto_ch
;
444 INIT_OFDM_CHANNEL(&auto_ch
);
445 auto_ch
.RF_kHz
= ch
->RF_kHz
;
450 auto_ch
.vit_alpha
= 1;
451 auto_ch
.vit_select_hp
= 1;
452 auto_ch
.vit_code_rate_hp
= 2;
453 auto_ch
.vit_code_rate_lp
= 3;
454 auto_ch
.vit_hrch
= 0;
455 auto_ch
.intlv_native
= 1;
457 dib7000p_set_channel(state
, &auto_ch
, 7);
459 // always use the setting for 8MHz here lock_time for 7,6 MHz are longer
460 value
= 30 * state
->cfg
.bw
->internal
;
461 dib7000p_write_word(state
, 6, (u16
) ((value
>> 16) & 0xffff)); // lock0 wait time
462 dib7000p_write_word(state
, 7, (u16
) (value
& 0xffff)); // lock0 wait time
463 value
= 100 * state
->cfg
.bw
->internal
;
464 dib7000p_write_word(state
, 8, (u16
) ((value
>> 16) & 0xffff)); // lock1 wait time
465 dib7000p_write_word(state
, 9, (u16
) (value
& 0xffff)); // lock1 wait time
466 value
= 500 * state
->cfg
.bw
->internal
;
467 dib7000p_write_word(state
, 10, (u16
) ((value
>> 16) & 0xffff)); // lock2 wait time
468 dib7000p_write_word(state
, 11, (u16
) (value
& 0xffff)); // lock2 wait time
470 value
= dib7000p_read_word(state
, 0);
471 dib7000p_write_word(state
, 0, (1 << 9) | value
);
472 dib7000p_read_word(state
, 1284);
473 dib7000p_write_word(state
, 0, (u16
) value
);
478 static int dib7000p_autosearch_is_irq(struct dvb_frontend
*demod
)
480 struct dib7000p_state
*state
= demod
->demodulator_priv
;
481 u16 irq_pending
= dib7000p_read_word(state
, 1284);
483 if (irq_pending
& 0x1) // failed
486 if (irq_pending
& 0x2) // succeeded
489 return 0; // still pending
492 static int dib7000p_tune(struct dvb_frontend
*demod
, struct dibx000_ofdm_channel
*ch
)
494 struct dib7000p_state
*state
= demod
->demodulator_priv
;
498 dib7000p_set_channel(state
, ch
, 0);
503 dib7000p_write_word(state
, 770, 0x4000);
504 dib7000p_write_word(state
, 770, 0x0000);
507 /* 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 */
508 dib7000p_write_word(state
, 29, (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3));
510 // never achieved a lock with that bandwidth so far - wait for osc-freq to update
511 if (state
->timf
== 0)
514 /* offset loop parameters */
516 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
517 tmp
= (6 << 8) | 0x80;
519 case 0: tmp
|= (7 << 12); break;
520 case 1: tmp
|= (9 << 12); break;
521 case 2: tmp
|= (8 << 12); break;
523 dib7000p_write_word(state
, 26, tmp
); /* timf_a(6xxx) */
525 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
528 case 0: tmp
|= 0x6; break;
529 case 1: tmp
|= 0x8; break;
530 case 2: tmp
|= 0x7; break;
532 dib7000p_write_word(state
, 32, tmp
);
534 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
537 case 0: tmp
|= 0x6; break;
538 case 1: tmp
|= 0x8; break;
539 case 2: tmp
|= 0x7; break;
541 dib7000p_write_word(state
, 33, tmp
);
543 tmp
= dib7000p_read_word(state
,509);
544 if (!((tmp
>> 6) & 0x1)) {
545 /* restart the fec */
546 tmp
= dib7000p_read_word(state
,771);
547 dib7000p_write_word(state
, 771, tmp
| (1 << 1));
548 dib7000p_write_word(state
, 771, tmp
);
550 tmp
= dib7000p_read_word(state
,509);
553 // we achieved a lock - it's time to update the osc freq
554 if ((tmp
>> 6) & 0x1)
555 dib7000p_update_timf_freq(state
);
560 static int dib7000p_init(struct dvb_frontend
*demod
)
562 struct dibx000_agc_config
*agc
;
563 struct dib7000p_state
*state
= demod
->demodulator_priv
;
566 // Demodulator default configuration
567 agc
= state
->cfg
.agc
;
569 dib7000p_set_power_mode(state
, DIB7000P_POWER_ALL
);
570 dib7000p_set_adc_state(state
, DIBX000_SLOW_ADC_ON
);
573 ret
|= dib7000p_write_word(state
, 75 , agc
->setup
);
574 ret
|= dib7000p_write_word(state
, 76 , agc
->inv_gain
);
575 ret
|= dib7000p_write_word(state
, 77 , agc
->time_stabiliz
);
576 ret
|= dib7000p_write_word(state
, 100, (agc
->alpha_level
<< 12) | agc
->thlock
);
578 // Demod AGC loop configuration
579 ret
|= dib7000p_write_word(state
, 101, (agc
->alpha_mant
<< 5) | agc
->alpha_exp
);
580 ret
|= dib7000p_write_word(state
, 102, (agc
->beta_mant
<< 6) | agc
->beta_exp
);
583 dprintk("-D- WBD: ref: %d, sel: %d, active: %d, alpha: %d\n",
584 state
->wbd_ref
!= 0 ? state
->wbd_ref
: agc
->wbd_ref
, agc
->wbd_sel
, !agc
->perform_agc_softsplit
, agc
->wbd_sel
);
586 if (state
->wbd_ref
!= 0)
587 ret
|= dib7000p_write_word(state
, 105, (agc
->wbd_inv
<< 12) | state
->wbd_ref
);
589 ret
|= dib7000p_write_word(state
, 105, (agc
->wbd_inv
<< 12) | agc
->wbd_ref
);
591 ret
|= dib7000p_write_word(state
, 106, (agc
->wbd_sel
<< 13) | (agc
->wbd_alpha
<< 9) | (agc
->perform_agc_softsplit
<< 8) );
593 ret
|= dib7000p_write_word(state
, 107, agc
->agc1_max
);
594 ret
|= dib7000p_write_word(state
, 108, agc
->agc1_min
);
595 ret
|= dib7000p_write_word(state
, 109, agc
->agc2_max
);
596 ret
|= dib7000p_write_word(state
, 110, agc
->agc2_min
);
597 ret
|= dib7000p_write_word(state
, 111, (agc
->agc1_pt1
<< 8) | agc
->agc1_pt2
);
598 ret
|= dib7000p_write_word(state
, 112, agc
->agc1_pt3
);
599 ret
|= dib7000p_write_word(state
, 113, (agc
->agc1_slope1
<< 8) | agc
->agc1_slope2
);
600 ret
|= dib7000p_write_word(state
, 114, (agc
->agc2_pt1
<< 8) | agc
->agc2_pt2
);
601 ret
|= dib7000p_write_word(state
, 115, (agc
->agc2_slope1
<< 8) | agc
->agc2_slope2
);
603 /* disable power smoothing */
604 ret
|= dib7000p_write_word(state
, 145, 0);
605 ret
|= dib7000p_write_word(state
, 146, 0);
606 ret
|= dib7000p_write_word(state
, 147, 0);
607 ret
|= dib7000p_write_word(state
, 148, 0);
608 ret
|= dib7000p_write_word(state
, 149, 0);
609 ret
|= dib7000p_write_word(state
, 150, 0);
610 ret
|= dib7000p_write_word(state
, 151, 0);
611 ret
|= dib7000p_write_word(state
, 152, 0);
613 // P_timf_alpha=6, P_corm_alpha=6, P_corm_thres=128 default: 6,4,26
614 ret
|= dib7000p_write_word(state
, 26 ,0x6680);
616 // P_palf_filter_on=1, P_palf_filter_freeze=0, P_palf_alpha_regul=16
617 ret
|= dib7000p_write_word(state
, 142,0x0410);
618 // P_fft_freq_dir=1, P_fft_nb_to_cut=0
619 ret
|= dib7000p_write_word(state
, 154,1 << 13);
620 // P_pha3_thres, default 0x3000
621 ret
|= dib7000p_write_word(state
, 168,0x0ccd);
622 // P_cti_use_cpe=0, P_cti_use_prog=0, P_cti_win_len=16, default: 0x0010
623 //ret |= dib7000p_write_word(state, 169,0x0010);
624 // P_cspu_regul=512, P_cspu_win_cut=15, default: 0x2005
625 ret
|= dib7000p_write_word(state
, 183,0x200f);
626 // P_adp_regul_cnt=573, default: 410
627 ret
|= dib7000p_write_word(state
, 187,0x023d);
629 ret
|= dib7000p_write_word(state
, 188,0x00a4);
631 ret
|= dib7000p_write_word(state
, 189,0x00a4);
633 ret
|= dib7000p_write_word(state
, 190,0x7ff0);
635 ret
|= dib7000p_write_word(state
, 191,0x3ccc);
637 ret
|= dib7000p_write_word(state
, 222,0x0010);
638 // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
639 ret
|= dib7000p_write_word(state
, 235,0x0062);
641 // P_iqc_alpha_pha, P_iqc_alpha_amp_dcc_alpha, ...
642 if(state
->cfg
.tuner_is_baseband
)
643 ret
|= dib7000p_write_word(state
, 36,0x0755);
645 ret
|= dib7000p_write_word(state
, 36,0x1f55);
647 // auto search configuration
648 ret
|= dib7000p_write_word(state
, 2 ,0x0004);
649 ret
|= dib7000p_write_word(state
, 3 ,0x1000);
652 ret
|= dib7000p_write_word(state
, 4 ,0x0814);
654 ret
|= dib7000p_write_word(state
, 6 ,0x001b);
655 ret
|= dib7000p_write_word(state
, 7 ,0x7740);
656 ret
|= dib7000p_write_word(state
, 8 ,0x005b);
657 ret
|= dib7000p_write_word(state
, 9 ,0x8d80);
658 ret
|= dib7000p_write_word(state
, 10 ,0x01c9);
659 ret
|= dib7000p_write_word(state
, 11 ,0xc380);
660 ret
|= dib7000p_write_word(state
, 12 ,0x0000);
661 ret
|= dib7000p_write_word(state
, 13 ,0x0080);
662 ret
|= dib7000p_write_word(state
, 14 ,0x0000);
663 ret
|= dib7000p_write_word(state
, 15 ,0x0090);
664 ret
|= dib7000p_write_word(state
, 16 ,0x0001);
665 ret
|= dib7000p_write_word(state
, 17 ,0xd4c0);
668 ret
|= dib7000p_write_word(state
, 901, 0x0006);
670 // P_divclksel=3 P_divbitsel=1
671 ret
|= dib7000p_write_word(state
, 902, (3 << 10) | (1 << 6));
673 // Tuner IO bank: max drive (14mA) + divout pads max drive
674 ret
|= dib7000p_write_word(state
, 905, 0x2c8e);
676 ret
|= dib7000p_set_bandwidth(&state
->demod
, BANDWIDTH_8_MHZ
);
677 dib7000p_sad_calib(state
);
682 static int dib7000p_sleep(struct dvb_frontend
*demod
)
684 struct dib7000p_state
*state
= demod
->demodulator_priv
;
685 return dib7000p_set_output_mode(state
, OUTMODE_HIGH_Z
) | dib7000p_set_power_mode(state
, DIB7000P_POWER_INTERFACE_ONLY
);
688 static int dib7000p_identify(struct dib7000p_state
*st
)
691 dprintk("-I- DiB7000PC: checking demod on I2C address: %d (%x)\n",
692 st
->i2c_addr
, st
->i2c_addr
);
694 if ((value
= dib7000p_read_word(st
, 768)) != 0x01b3) {
695 dprintk("-E- DiB7000PC: wrong Vendor ID (read=0x%x)\n",value
);
699 if ((value
= dib7000p_read_word(st
, 769)) != 0x4000) {
700 dprintk("-E- DiB7000PC: wrong Device ID (%x)\n",value
);
708 static int dib7000p_get_frontend(struct dvb_frontend
* fe
,
709 struct dvb_frontend_parameters
*fep
)
711 struct dib7000p_state
*state
= fe
->demodulator_priv
;
712 u16 tps
= dib7000p_read_word(state
,463);
714 fep
->inversion
= INVERSION_AUTO
;
716 fep
->u
.ofdm
.bandwidth
= state
->current_bandwidth
;
718 switch ((tps
>> 8) & 0x3) {
719 case 0: fep
->u
.ofdm
.transmission_mode
= TRANSMISSION_MODE_2K
; break;
720 case 1: fep
->u
.ofdm
.transmission_mode
= TRANSMISSION_MODE_8K
; break;
721 /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */
725 case 0: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_32
; break;
726 case 1: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_16
; break;
727 case 2: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_8
; break;
728 case 3: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_4
; break;
731 switch ((tps
>> 14) & 0x3) {
732 case 0: fep
->u
.ofdm
.constellation
= QPSK
; break;
733 case 1: fep
->u
.ofdm
.constellation
= QAM_16
; break;
735 default: fep
->u
.ofdm
.constellation
= QAM_64
; break;
738 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
739 /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
741 fep
->u
.ofdm
.hierarchy_information
= HIERARCHY_NONE
;
742 switch ((tps
>> 5) & 0x7) {
743 case 1: fep
->u
.ofdm
.code_rate_HP
= FEC_1_2
; break;
744 case 2: fep
->u
.ofdm
.code_rate_HP
= FEC_2_3
; break;
745 case 3: fep
->u
.ofdm
.code_rate_HP
= FEC_3_4
; break;
746 case 5: fep
->u
.ofdm
.code_rate_HP
= FEC_5_6
; break;
748 default: fep
->u
.ofdm
.code_rate_HP
= FEC_7_8
; break;
752 switch ((tps
>> 2) & 0x7) {
753 case 1: fep
->u
.ofdm
.code_rate_LP
= FEC_1_2
; break;
754 case 2: fep
->u
.ofdm
.code_rate_LP
= FEC_2_3
; break;
755 case 3: fep
->u
.ofdm
.code_rate_LP
= FEC_3_4
; break;
756 case 5: fep
->u
.ofdm
.code_rate_LP
= FEC_5_6
; break;
758 default: fep
->u
.ofdm
.code_rate_LP
= FEC_7_8
; break;
761 /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */
766 static int dib7000p_set_frontend(struct dvb_frontend
* fe
,
767 struct dvb_frontend_parameters
*fep
)
769 struct dib7000p_state
*state
= fe
->demodulator_priv
;
770 struct dibx000_ofdm_channel ch
;
772 INIT_OFDM_CHANNEL(&ch
);
775 state
->current_bandwidth
= fep
->u
.ofdm
.bandwidth
;
776 dib7000p_set_bandwidth(fe
, fep
->u
.ofdm
.bandwidth
);
778 if (fe
->ops
.tuner_ops
.set_params
)
779 fe
->ops
.tuner_ops
.set_params(fe
, fep
);
781 if (fep
->u
.ofdm
.transmission_mode
== TRANSMISSION_MODE_AUTO
||
782 fep
->u
.ofdm
.guard_interval
== GUARD_INTERVAL_AUTO
||
783 fep
->u
.ofdm
.constellation
== QAM_AUTO
||
784 fep
->u
.ofdm
.code_rate_HP
== FEC_AUTO
) {
787 dib7000p_autosearch_start(fe
, &ch
);
790 found
= dib7000p_autosearch_is_irq(fe
);
791 } while (found
== 0 && i
--);
793 dprintk("autosearch returns: %d\n",found
);
794 if (found
== 0 || found
== 1)
795 return 0; // no channel found
797 dib7000p_get_frontend(fe
, fep
);
801 /* make this a config parameter */
802 dib7000p_set_output_mode(state
, OUTMODE_MPEG2_FIFO
);
804 return dib7000p_tune(fe
, &ch
);
807 static int dib7000p_read_status(struct dvb_frontend
*fe
, fe_status_t
*stat
)
809 struct dib7000p_state
*state
= fe
->demodulator_priv
;
810 u16 lock
= dib7000p_read_word(state
, 509);
815 *stat
|= FE_HAS_SIGNAL
;
817 *stat
|= FE_HAS_CARRIER
;
819 *stat
|= FE_HAS_VITERBI
;
821 *stat
|= FE_HAS_SYNC
;
823 *stat
|= FE_HAS_LOCK
;
828 static int dib7000p_read_ber(struct dvb_frontend
*fe
, u32
*ber
)
830 struct dib7000p_state
*state
= fe
->demodulator_priv
;
831 *ber
= (dib7000p_read_word(state
, 500) << 16) | dib7000p_read_word(state
, 501);
835 static int dib7000p_read_unc_blocks(struct dvb_frontend
*fe
, u32
*unc
)
837 struct dib7000p_state
*state
= fe
->demodulator_priv
;
838 *unc
= dib7000p_read_word(state
, 506);
842 static int dib7000p_read_signal_strength(struct dvb_frontend
*fe
, u16
*strength
)
844 struct dib7000p_state
*state
= fe
->demodulator_priv
;
845 u16 val
= dib7000p_read_word(state
, 394);
846 *strength
= 65535 - val
;
850 static int dib7000p_read_snr(struct dvb_frontend
* fe
, u16
*snr
)
856 static int dib7000p_fe_get_tune_settings(struct dvb_frontend
* fe
, struct dvb_frontend_tune_settings
*tune
)
858 tune
->min_delay_ms
= 1000;
862 static void dib7000p_release(struct dvb_frontend
*demod
)
864 struct dib7000p_state
*st
= demod
->demodulator_priv
;
865 dibx000_exit_i2c_master(&st
->i2c_master
);
869 int dib7000pc_detection(struct i2c_adapter
*i2c_adap
)
872 struct i2c_msg msg
[2] = {
873 { .addr
= 18 >> 1, .flags
= 0, .buf
= tx
, .len
= 2 },
874 { .addr
= 18 >> 1, .flags
= I2C_M_RD
, .buf
= rx
, .len
= 2 },
880 if (i2c_transfer(i2c_adap
, msg
, 2) == 2)
881 if (rx
[0] == 0x01 && rx
[1] == 0xb3) {
882 dprintk("-D- DiB7000PC detected\n");
886 msg
[0].addr
= msg
[1].addr
= 0x40;
888 if (i2c_transfer(i2c_adap
, msg
, 2) == 2)
889 if (rx
[0] == 0x01 && rx
[1] == 0xb3) {
890 dprintk("-D- DiB7000PC detected\n");
894 dprintk("-D- DiB7000PC not detected\n");
897 EXPORT_SYMBOL(dib7000pc_detection
);
899 struct i2c_adapter
* dib7000p_get_i2c_master(struct dvb_frontend
*demod
, enum dibx000_i2c_interface intf
, int gating
)
901 struct dib7000p_state
*st
= demod
->demodulator_priv
;
902 return dibx000_get_i2c_adapter(&st
->i2c_master
, intf
, gating
);
904 EXPORT_SYMBOL(dib7000p_get_i2c_master
);
906 int dib7000p_i2c_enumeration(struct i2c_adapter
*i2c
, int no_of_demods
, u8 default_addr
, struct dib7000p_config cfg
[])
908 struct dib7000p_state st
= { .i2c_adap
= i2c
};
912 for (k
= no_of_demods
-1; k
>= 0; k
--) {
915 /* designated i2c address */
916 new_addr
= (0x40 + k
) << 1;
917 st
.i2c_addr
= new_addr
;
918 if (dib7000p_identify(&st
) != 0) {
919 st
.i2c_addr
= default_addr
;
920 if (dib7000p_identify(&st
) != 0) {
921 dprintk("DiB7000P #%d: not identified\n", k
);
926 /* start diversity to pull_down div_str - just for i2c-enumeration */
927 dib7000p_set_output_mode(&st
, OUTMODE_DIVERSITY
);
929 /* set new i2c address and force divstart */
930 dib7000p_write_word(&st
, 1285, (new_addr
<< 2) | 0x2);
932 dprintk("IC %d initialized (to i2c_address 0x%x)\n", k
, new_addr
);
935 for (k
= 0; k
< no_of_demods
; k
++) {
937 st
.i2c_addr
= (0x40 + k
) << 1;
940 dib7000p_write_word(&st
, 1285, st
.i2c_addr
<< 2);
942 /* deactivate div - it was just for i2c-enumeration */
943 dib7000p_set_output_mode(&st
, OUTMODE_HIGH_Z
);
948 EXPORT_SYMBOL(dib7000p_i2c_enumeration
);
950 static struct dvb_frontend_ops dib7000p_ops
;
951 struct dvb_frontend
* dib7000p_attach(struct i2c_adapter
*i2c_adap
, u8 i2c_addr
, struct dib7000p_config
*cfg
)
953 struct dvb_frontend
*demod
;
954 struct dib7000p_state
*st
;
955 st
= kzalloc(sizeof(struct dib7000p_state
), GFP_KERNEL
);
959 memcpy(&st
->cfg
, cfg
, sizeof(struct dib7000p_config
));
960 st
->i2c_adap
= i2c_adap
;
961 st
->i2c_addr
= i2c_addr
;
962 st
->gpio_val
= cfg
->gpio_val
;
963 st
->gpio_dir
= cfg
->gpio_dir
;
966 demod
->demodulator_priv
= st
;
967 memcpy(&st
->demod
.ops
, &dib7000p_ops
, sizeof(struct dvb_frontend_ops
));
969 if (dib7000p_identify(st
) != 0)
972 dibx000_init_i2c_master(&st
->i2c_master
, DIB7000P
, st
->i2c_adap
, st
->i2c_addr
);
974 dib7000p_demod_reset(st
);
982 EXPORT_SYMBOL(dib7000p_attach
);
984 static struct dvb_frontend_ops dib7000p_ops
= {
986 .name
= "DiBcom 7000PC",
988 .frequency_min
= 44250000,
989 .frequency_max
= 867250000,
990 .frequency_stepsize
= 62500,
991 .caps
= FE_CAN_INVERSION_AUTO
|
992 FE_CAN_FEC_1_2
| FE_CAN_FEC_2_3
| FE_CAN_FEC_3_4
|
993 FE_CAN_FEC_5_6
| FE_CAN_FEC_7_8
| FE_CAN_FEC_AUTO
|
994 FE_CAN_QPSK
| FE_CAN_QAM_16
| FE_CAN_QAM_64
| FE_CAN_QAM_AUTO
|
995 FE_CAN_TRANSMISSION_MODE_AUTO
|
996 FE_CAN_GUARD_INTERVAL_AUTO
|
998 FE_CAN_HIERARCHY_AUTO
,
1001 .release
= dib7000p_release
,
1003 .init
= dib7000p_init
,
1004 .sleep
= dib7000p_sleep
,
1006 .set_frontend
= dib7000p_set_frontend
,
1007 .get_tune_settings
= dib7000p_fe_get_tune_settings
,
1008 .get_frontend
= dib7000p_get_frontend
,
1010 .read_status
= dib7000p_read_status
,
1011 .read_ber
= dib7000p_read_ber
,
1012 .read_signal_strength
= dib7000p_read_signal_strength
,
1013 .read_snr
= dib7000p_read_snr
,
1014 .read_ucblocks
= dib7000p_read_unc_blocks
,
1017 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
1018 MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
1019 MODULE_LICENSE("GPL");