aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/dib7000p.c
diff options
context:
space:
mode:
authorPatrick Boettcher <pboettcher@dibcom.fr>2007-07-27 09:08:51 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-10-09 21:03:43 -0400
commitb6884a17fc70e979ef34e4b5560988b522bb50a0 (patch)
treea1be75fb986d578f810d3cd017dbaa678c068b99 /drivers/media/dvb/frontends/dib7000p.c
parentb2a657603e7285bf05b86ad198111b5403c57b41 (diff)
V4L/DVB (5954): Sync with DiBcom Driver Release 2.1.3 + some improvements
This changesets syncs the OpenSource driver for DiBcom demodulators with version 2.1.3 of DiBcom reference driver. There were some improvements since the last release for linux-dvb, e.g.: - stepped AGC startup - less space for initialization - diversity synchronization Furthermore this changeset contains the following things: - latest AGC settings for MT2266-based devices (namely Nova-TD and other) will improve the sensitivity - support for STK7700D reference design in dib0700-devices - remove some line-breaks when debugging is enabled - getting rid of layer between frontend_parameters and ofdm_channel used in dib*-drivers Signed-off-by: Patrick Boettcher <pboettcher@dibcom.fr> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/dvb/frontends/dib7000p.c')
-rw-r--r--drivers/media/dvb/frontends/dib7000p.c860
1 files changed, 587 insertions, 273 deletions
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
index c24189fcbc89..156c53ab56db 100644
--- a/drivers/media/dvb/frontends/dib7000p.c
+++ b/drivers/media/dvb/frontends/dib7000p.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Linux-DVB Driver for DiBcom's second generation DiB7000P (PC). 2 * Linux-DVB Driver for DiBcom's second generation DiB7000P (PC).
3 * 3 *
4 * Copyright (C) 2005-6 DiBcom (http://www.dibcom.fr/) 4 * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 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 7 * modify it under the terms of the GNU General Public License as
@@ -18,7 +18,7 @@ static int debug;
18module_param(debug, int, 0644); 18module_param(debug, int, 0644);
19MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); 19MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
20 20
21#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P:"); printk(args); } } while (0) 21#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0)
22 22
23struct dib7000p_state { 23struct dib7000p_state {
24 struct dvb_frontend demod; 24 struct dvb_frontend demod;
@@ -36,12 +36,19 @@ struct dib7000p_state {
36 struct dibx000_agc_config *current_agc; 36 struct dibx000_agc_config *current_agc;
37 u32 timf; 37 u32 timf;
38 38
39 uint8_t div_force_off : 1;
40 uint8_t div_state : 1;
41 uint16_t div_sync_wait;
42
43 u8 agc_state;
44
39 u16 gpio_dir; 45 u16 gpio_dir;
40 u16 gpio_val; 46 u16 gpio_val;
41}; 47};
42 48
43enum dib7000p_power_mode { 49enum dib7000p_power_mode {
44 DIB7000P_POWER_ALL = 0, 50 DIB7000P_POWER_ALL = 0,
51 DIB7000P_POWER_ANALOG_ADC,
45 DIB7000P_POWER_INTERFACE_ONLY, 52 DIB7000P_POWER_INTERFACE_ONLY,
46}; 53};
47 54
@@ -55,7 +62,7 @@ static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
55 }; 62 };
56 63
57 if (i2c_transfer(state->i2c_adap, msg, 2) != 2) 64 if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
58 dprintk("i2c read error on %d\n",reg); 65 dprintk("i2c read error on %d",reg);
59 66
60 return (rb[0] << 8) | rb[1]; 67 return (rb[0] << 8) | rb[1];
61} 68}
@@ -71,6 +78,22 @@ static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
71 }; 78 };
72 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; 79 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
73} 80}
81static void dib7000p_write_tab(struct dib7000p_state *state, u16 *buf)
82{
83 u16 l = 0, r, *n;
84 n = buf;
85 l = *n++;
86 while (l) {
87 r = *n++;
88
89 do {
90 dib7000p_write_word(state, r, *n++);
91 r++;
92 } while (--l);
93 l = *n++;
94 }
95}
96
74static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode) 97static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
75{ 98{
76 int ret = 0; 99 int ret = 0;
@@ -80,7 +103,7 @@ static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
80 fifo_threshold = 1792; 103 fifo_threshold = 1792;
81 smo_mode = (dib7000p_read_word(state, 235) & 0x0010) | (1 << 1); 104 smo_mode = (dib7000p_read_word(state, 235) & 0x0010) | (1 << 1);
82 105
83 dprintk("-I- Setting output mode for demod %p to %d\n", 106 dprintk( "setting output mode for demod %p to %d",
84 &state->demod, mode); 107 &state->demod, mode);
85 108
86 switch (mode) { 109 switch (mode) {
@@ -104,19 +127,17 @@ static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
104 fifo_threshold = 512; 127 fifo_threshold = 512;
105 outreg = (1 << 10) | (5 << 6); 128 outreg = (1 << 10) | (5 << 6);
106 break; 129 break;
130 case OUTMODE_ANALOG_ADC:
131 outreg = (1 << 10) | (3 << 6);
132 break;
107 case OUTMODE_HIGH_Z: // disable 133 case OUTMODE_HIGH_Z: // disable
108 outreg = 0; 134 outreg = 0;
109 break; 135 break;
110 default: 136 default:
111 dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod); 137 dprintk( "Unhandled output_mode passed to be set for demod %p",&state->demod);
112 break; 138 break;
113 } 139 }
114 140
115 if (state->cfg.hostbus_diversity) {
116 ret |= dib7000p_write_word(state, 204, 1); // Diversity ?
117 ret |= dib7000p_write_word(state, 205, 0); // Diversity ?
118 }
119
120 if (state->cfg.output_mpeg2_in_188_bytes) 141 if (state->cfg.output_mpeg2_in_188_bytes)
121 smo_mode |= (1 << 5) ; 142 smo_mode |= (1 << 5) ;
122 143
@@ -127,6 +148,30 @@ static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
127 return ret; 148 return ret;
128} 149}
129 150
151static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
152{
153 struct dib7000p_state *state = demod->demodulator_priv;
154
155 if (state->div_force_off) {
156 dprintk( "diversity combination deactivated - forced by COFDM parameters");
157 onoff = 0;
158 }
159 state->div_state = (uint8_t)onoff;
160
161 if (onoff) {
162 dib7000p_write_word(state, 204, 6);
163 dib7000p_write_word(state, 205, 16);
164 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
165 dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
166 } else {
167 dib7000p_write_word(state, 204, 1);
168 dib7000p_write_word(state, 205, 0);
169 dib7000p_write_word(state, 207, 0);
170 }
171
172 return 0;
173}
174
130static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode) 175static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode)
131{ 176{
132 /* by default everything is powered off */ 177 /* by default everything is powered off */
@@ -139,10 +184,21 @@ static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_p
139 case DIB7000P_POWER_ALL: 184 case DIB7000P_POWER_ALL:
140 reg_774 = 0x0000; reg_775 = 0x0000; reg_776 = 0x0; reg_899 = 0x0; reg_1280 &= 0x01ff; 185 reg_774 = 0x0000; reg_775 = 0x0000; reg_776 = 0x0; reg_899 = 0x0; reg_1280 &= 0x01ff;
141 break; 186 break;
187
188 case DIB7000P_POWER_ANALOG_ADC:
189 /* dem, cfg, iqc, sad, agc */
190 reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
191 /* nud */
192 reg_776 &= ~((1 << 0));
193 /* Dout */
194 reg_1280 &= ~((1 << 11));
195 /* fall through wanted to enable the interfaces */
196
142 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */ 197 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
143 case DIB7000P_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C */ 198 case DIB7000P_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C */
144 reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10)); 199 reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
145 break; 200 break;
201
146/* TODO following stuff is just converted from the dib7000-driver - check when is used what */ 202/* TODO following stuff is just converted from the dib7000-driver - check when is used what */
147 } 203 }
148 204
@@ -193,34 +249,31 @@ static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_ad
193 break; 249 break;
194 } 250 }
195 251
196// dprintk("908: %x, 909: %x\n", reg_908, reg_909); 252// dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
197 253
198 dib7000p_write_word(state, 908, reg_908); 254 dib7000p_write_word(state, 908, reg_908);
199 dib7000p_write_word(state, 909, reg_909); 255 dib7000p_write_word(state, 909, reg_909);
200} 256}
201 257
202static int dib7000p_set_bandwidth(struct dvb_frontend *demod, u8 BW_Idx) 258static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
203{ 259{
204 struct dib7000p_state *state = demod->demodulator_priv;
205 u32 timf; 260 u32 timf;
206 261
207 // store the current bandwidth for later use 262 // store the current bandwidth for later use
208 state->current_bandwidth = BW_Idx; 263 state->current_bandwidth = bw;
209 264
210 if (state->timf == 0) { 265 if (state->timf == 0) {
211 dprintk("-D- Using default timf\n"); 266 dprintk( "using default timf");
212 timf = state->cfg.bw->timf; 267 timf = state->cfg.bw->timf;
213 } else { 268 } else {
214 dprintk("-D- Using updated timf\n"); 269 dprintk( "using updated timf");
215 timf = state->timf; 270 timf = state->timf;
216 } 271 }
217 272
218 timf = timf * (BW_INDEX_TO_KHZ(BW_Idx) / 100) / 80; 273 timf = timf * (bw / 50) / 160;
219 274
220 dprintk("timf: %d\n",timf); 275 dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
221 276 dib7000p_write_word(state, 24, (u16) ((timf ) & 0xffff));
222 dib7000p_write_word(state, 23, (timf >> 16) & 0xffff);
223 dib7000p_write_word(state, 24, (timf ) & 0xffff);
224 277
225 return 0; 278 return 0;
226} 279}
@@ -228,7 +281,7 @@ static int dib7000p_set_bandwidth(struct dvb_frontend *demod, u8 BW_Idx)
228static int dib7000p_sad_calib(struct dib7000p_state *state) 281static int dib7000p_sad_calib(struct dib7000p_state *state)
229{ 282{
230/* internal */ 283/* internal */
231// dib7000p_write_word(state, 72, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is written in set_bandwidth 284// dib7000p_write_word(state, 72, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth
232 dib7000p_write_word(state, 73, (0 << 1) | (0 << 0)); 285 dib7000p_write_word(state, 73, (0 << 1) | (0 << 0));
233 dib7000p_write_word(state, 74, 776); // 0.625*3.3 / 4096 286 dib7000p_write_word(state, 74, 776); // 0.625*3.3 / 4096
234 287
@@ -244,15 +297,24 @@ static int dib7000p_sad_calib(struct dib7000p_state *state)
244static void dib7000p_reset_pll(struct dib7000p_state *state) 297static void dib7000p_reset_pll(struct dib7000p_state *state)
245{ 298{
246 struct dibx000_bandwidth_config *bw = &state->cfg.bw[0]; 299 struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
300 u16 clk_cfg0;
301
302 /* force PLL bypass */
303 clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) |
304 (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) |
305 (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0);
247 306
307 dib7000p_write_word(state, 900, clk_cfg0);
308
309 /* P_pll_cfg */
248 dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset); 310 dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset);
249 dib7000p_write_word(state, 900, ((bw->pll_ratio & 0x3f) << 9) | (bw->pll_bypass << 15) | (bw->modulo << 7) | (bw->ADClkSrc << 6) | 311 clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff);
250 (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0)); 312 dib7000p_write_word(state, 900, clk_cfg0);
251 313
252 dib7000p_write_word(state, 18, ((bw->internal*1000) >> 16) & 0xffff); 314 dib7000p_write_word(state, 18, (u16) (((bw->internal*1000) >> 16) & 0xffff));
253 dib7000p_write_word(state, 19, (bw->internal*1000 ) & 0xffff); 315 dib7000p_write_word(state, 19, (u16) ( (bw->internal*1000 ) & 0xffff));
254 dib7000p_write_word(state, 21, (bw->ifreq >> 16) & 0xffff); 316 dib7000p_write_word(state, 21, (u16) ( (bw->ifreq >> 16) & 0xffff));
255 dib7000p_write_word(state, 22, (bw->ifreq ) & 0xffff); 317 dib7000p_write_word(state, 22, (u16) ( (bw->ifreq ) & 0xffff));
256 318
257 dib7000p_write_word(state, 72, bw->sad_cfg); 319 dib7000p_write_word(state, 72, bw->sad_cfg);
258} 320}
@@ -260,7 +322,7 @@ static void dib7000p_reset_pll(struct dib7000p_state *state)
260static int dib7000p_reset_gpio(struct dib7000p_state *st) 322static int dib7000p_reset_gpio(struct dib7000p_state *st)
261{ 323{
262 /* reset the GPIOs */ 324 /* reset the GPIOs */
263 dprintk("-D- gpio dir: %x: gpio val: %x, gpio pwm pos: %x\n",st->gpio_dir, st->gpio_val,st->cfg.gpio_pwm_pos); 325 dprintk( "gpio dir: %x: val: %x, pwm_pos: %x",st->gpio_dir, st->gpio_val,st->cfg.gpio_pwm_pos);
264 326
265 dib7000p_write_word(st, 1029, st->gpio_dir); 327 dib7000p_write_word(st, 1029, st->gpio_dir);
266 dib7000p_write_word(st, 1030, st->gpio_val); 328 dib7000p_write_word(st, 1030, st->gpio_val);
@@ -273,6 +335,98 @@ static int dib7000p_reset_gpio(struct dib7000p_state *st)
273 return 0; 335 return 0;
274} 336}
275 337
338static u16 dib7000p_defaults[] =
339
340{
341 // auto search configuration
342 3, 2,
343 0x0004,
344 0x1000,
345 0x0814, /* Equal Lock */
346
347 12, 6,
348 0x001b,
349 0x7740,
350 0x005b,
351 0x8d80,
352 0x01c9,
353 0xc380,
354 0x0000,
355 0x0080,
356 0x0000,
357 0x0090,
358 0x0001,
359 0xd4c0,
360
361 1, 26,
362 0x6680, // P_timf_alpha=6, P_corm_alpha=6, P_corm_thres=128 default: 6,4,26
363
364 /* set ADC level to -16 */
365 11, 79,
366 (1 << 13) - 825 - 117,
367 (1 << 13) - 837 - 117,
368 (1 << 13) - 811 - 117,
369 (1 << 13) - 766 - 117,
370 (1 << 13) - 737 - 117,
371 (1 << 13) - 693 - 117,
372 (1 << 13) - 648 - 117,
373 (1 << 13) - 619 - 117,
374 (1 << 13) - 575 - 117,
375 (1 << 13) - 531 - 117,
376 (1 << 13) - 501 - 117,
377
378 1, 142,
379 0x0410, // P_palf_filter_on=1, P_palf_filter_freeze=0, P_palf_alpha_regul=16
380
381 /* disable power smoothing */
382 8, 145,
383 0,
384 0,
385 0,
386 0,
387 0,
388 0,
389 0,
390 0,
391
392 1, 154,
393 1 << 13, // P_fft_freq_dir=1, P_fft_nb_to_cut=0
394
395 1, 168,
396 0x0ccd, // P_pha3_thres, default 0x3000
397
398// 1, 169,
399// 0x0010, // P_cti_use_cpe=0, P_cti_use_prog=0, P_cti_win_len=16, default: 0x0010
400
401 1, 183,
402 0x200f, // P_cspu_regul=512, P_cspu_win_cut=15, default: 0x2005
403
404 5, 187,
405 0x023d, // P_adp_regul_cnt=573, default: 410
406 0x00a4, // P_adp_noise_cnt=
407 0x00a4, // P_adp_regul_ext
408 0x7ff0, // P_adp_noise_ext
409 0x3ccc, // P_adp_fil
410
411 1, 198,
412 0x800, // P_equal_thres_wgn
413
414 1, 222,
415 0x0010, // P_fec_ber_rs_len=2
416
417 1, 235,
418 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
419
420 2, 901,
421 0x0006, // P_clk_cfg1
422 (3 << 10) | (1 << 6), // P_divclksel=3 P_divbitsel=1
423
424 1, 905,
425 0x2c8e, // Tuner IO bank: max drive (14mA) + divout pads max drive
426
427 0,
428};
429
276static int dib7000p_demod_reset(struct dib7000p_state *state) 430static int dib7000p_demod_reset(struct dib7000p_state *state)
277{ 431{
278 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL); 432 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
@@ -297,111 +451,307 @@ static int dib7000p_demod_reset(struct dib7000p_state *state)
297 dib7000p_reset_pll(state); 451 dib7000p_reset_pll(state);
298 452
299 if (dib7000p_reset_gpio(state) != 0) 453 if (dib7000p_reset_gpio(state) != 0)
300 dprintk("-E- GPIO reset was not successful.\n"); 454 dprintk( "GPIO reset was not successful.");
301 455
302 if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0) 456 if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
303 dprintk("-E- OUTPUT_MODE could not be resetted.\n"); 457 dprintk( "OUTPUT_MODE could not be reset.");
304 458
305 /* unforce divstr regardless whether i2c enumeration was done or not */ 459 /* unforce divstr regardless whether i2c enumeration was done or not */
306 dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1) ); 460 dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1) );
307 461
462 dib7000p_set_bandwidth(state, 8000);
463
464 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
465 dib7000p_sad_calib(state);
466 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
467
468 // P_iqc_alpha_pha, P_iqc_alpha_amp_dcc_alpha, ...
469 if(state->cfg.tuner_is_baseband)
470 dib7000p_write_word(state, 36,0x0755);
471 else
472 dib7000p_write_word(state, 36,0x1f55);
473
474 dib7000p_write_tab(state, dib7000p_defaults);
475
308 dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); 476 dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
309 477
478
310 return 0; 479 return 0;
311} 480}
312 481
482static void dib7000p_pll_clk_cfg(struct dib7000p_state *state)
483{
484 u16 tmp = 0;
485 tmp = dib7000p_read_word(state, 903);
486 dib7000p_write_word(state, 903, (tmp | 0x1)); //pwr-up pll
487 tmp = dib7000p_read_word(state, 900);
488 dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6)); //use High freq clock
489}
490
313static void dib7000p_restart_agc(struct dib7000p_state *state) 491static void dib7000p_restart_agc(struct dib7000p_state *state)
314{ 492{
315 // P_restart_iqc & P_restart_agc 493 // P_restart_iqc & P_restart_agc
316 dib7000p_write_word(state, 770, 0x0c00); 494 dib7000p_write_word(state, 770, (1 << 11) | (1 << 9));
317 dib7000p_write_word(state, 770, 0x0000); 495 dib7000p_write_word(state, 770, 0x0000);
318} 496}
319 497
320static void dib7000p_update_lna(struct dib7000p_state *state) 498static int dib7000p_update_lna(struct dib7000p_state *state)
321{ 499{
322 int i;
323 u16 dyn_gain; 500 u16 dyn_gain;
324 501
325 // when there is no LNA to program return immediatly 502 // when there is no LNA to program return immediatly
326 if (state->cfg.update_lna == NULL) 503 if (state->cfg.update_lna) {
327 return;
328
329 for (i = 0; i < 5; i++) {
330 // read dyn_gain here (because it is demod-dependent and not tuner) 504 // read dyn_gain here (because it is demod-dependent and not tuner)
331 dyn_gain = dib7000p_read_word(state, 394); 505 dyn_gain = dib7000p_read_word(state, 394);
332
333 if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed 506 if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed
334 dib7000p_restart_agc(state); 507 dib7000p_restart_agc(state);
335 msleep(5); 508 return 1;
336 } else 509 }
510 }
511
512 return 0;
513}
514
515static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
516{
517 struct dibx000_agc_config *agc = NULL;
518 int i;
519 if (state->current_band == band && state->current_agc != NULL)
520 return 0;
521 state->current_band = band;
522
523 for (i = 0; i < state->cfg.agc_config_count; i++)
524 if (state->cfg.agc[i].band_caps & band) {
525 agc = &state->cfg.agc[i];
337 break; 526 break;
527 }
528
529 if (agc == NULL) {
530 dprintk( "no valid AGC configuration found for band 0x%02x",band);
531 return -EINVAL;
338 } 532 }
533
534 state->current_agc = agc;
535
536 /* AGC */
537 dib7000p_write_word(state, 75 , agc->setup );
538 dib7000p_write_word(state, 76 , agc->inv_gain );
539 dib7000p_write_word(state, 77 , agc->time_stabiliz );
540 dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);
541
542 // Demod AGC loop configuration
543 dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);
544 dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp);
545
546 /* AGC continued */
547 dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d",
548 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
549
550 if (state->wbd_ref != 0)
551 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref);
552 else
553 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref);
554
555 dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
556
557 dib7000p_write_word(state, 107, agc->agc1_max);
558 dib7000p_write_word(state, 108, agc->agc1_min);
559 dib7000p_write_word(state, 109, agc->agc2_max);
560 dib7000p_write_word(state, 110, agc->agc2_min);
561 dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
562 dib7000p_write_word(state, 112, agc->agc1_pt3);
563 dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
564 dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
565 dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
566 return 0;
339} 567}
340 568
341static void dib7000p_pll_clk_cfg(struct dib7000p_state *state) 569static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
342{ 570{
343 u16 tmp = 0; 571 struct dib7000p_state *state = demod->demodulator_priv;
344 tmp = dib7000p_read_word(state, 903); 572 int ret = -1;
345 dib7000p_write_word(state, 903, (tmp | 0x1)); //pwr-up pll 573 u8 *agc_state = &state->agc_state;
346 tmp = dib7000p_read_word(state, 900); 574 u8 agc_split;
347 dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6)); //use High freq clock 575
576 switch (state->agc_state) {
577 case 0:
578 // set power-up level: interf+analog+AGC
579 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
580 dib7000p_set_adc_state(state, DIBX000_ADC_ON);
581 dib7000p_pll_clk_cfg(state);
582
583 if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0)
584 return -1;
585
586 ret = 7;
587 (*agc_state)++;
588 break;
589
590 case 1:
591 // AGC initialization
592 if (state->cfg.agc_control)
593 state->cfg.agc_control(&state->demod, 1);
594
595 dib7000p_write_word(state, 78, 32768);
596 if (!state->current_agc->perform_agc_softsplit) {
597 /* we are using the wbd - so slow AGC startup */
598 /* force 0 split on WBD and restart AGC */
599 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));
600 (*agc_state)++;
601 ret = 5;
602 } else {
603 /* default AGC startup */
604 (*agc_state) = 4;
605 /* wait AGC rough lock time */
606 ret = 7;
607 }
608
609 dib7000p_restart_agc(state);
610 break;
611
612 case 2: /* fast split search path after 5sec */
613 dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4)); /* freeze AGC loop */
614 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */
615 (*agc_state)++;
616 ret = 14;
617 break;
618
619 case 3: /* split search ended */
620 agc_split = (uint8_t)dib7000p_read_word(state, 396); /* store the split value for the next time */
621 dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */
622
623 dib7000p_write_word(state, 75, state->current_agc->setup); /* std AGC loop */
624 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
625
626 dib7000p_restart_agc(state);
627
628 dprintk( "SPLIT %p: %hd", demod, agc_split);
629
630 (*agc_state)++;
631 ret = 5;
632 break;
633
634 case 4: /* LNA startup */
635 // wait AGC accurate lock time
636 ret = 7;
637
638 if (dib7000p_update_lna(state))
639 // wait only AGC rough lock time
640 ret = 5;
641 else // nothing was done, go to the next state
642 (*agc_state)++;
643 break;
644
645 case 5:
646 if (state->cfg.agc_control)
647 state->cfg.agc_control(&state->demod, 0);
648 (*agc_state)++;
649 break;
650 default:
651 break;
652 }
653 return ret;
348} 654}
349 655
350static void dib7000p_update_timf_freq(struct dib7000p_state *state) 656static void dib7000p_update_timf(struct dib7000p_state *state)
351{ 657{
352 u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428); 658 u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428);
353 state->timf = timf * 80 / (BW_INDEX_TO_KHZ(state->current_bandwidth) / 100); 659 state->timf = timf * 160 / (state->current_bandwidth / 50);
354 dib7000p_write_word(state, 23, (u16) (timf >> 16)); 660 dib7000p_write_word(state, 23, (u16) (timf >> 16));
355 dib7000p_write_word(state, 24, (u16) (timf & 0xffff)); 661 dib7000p_write_word(state, 24, (u16) (timf & 0xffff));
356 dprintk("-D- Updated timf_frequency: %d (default: %d)\n",state->timf, state->cfg.bw->timf); 662 dprintk( "updated timf_frequency: %d (default: %d)",state->timf, state->cfg.bw->timf);
663
357} 664}
358 665
359static void dib7000p_set_channel(struct dib7000p_state *state, struct dibx000_ofdm_channel *ch, u8 seq) 666static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq)
360{ 667{
361 u16 tmp, est[4]; // reg_26, reg_32, reg_33, reg_187, reg_188, reg_189, reg_190, reg_207, reg_208; 668 u16 value, est[4];
669
670 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
362 671
363 /* nfft, guard, qam, alpha */ 672 /* nfft, guard, qam, alpha */
364 dib7000p_write_word(state, 0, (ch->nfft << 7) | (ch->guard << 5) | (ch->nqam << 3) | (ch->vit_alpha)); 673 value = 0;
674 switch (ch->u.ofdm.transmission_mode) {
675 case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
676 case /* 4K MODE */ 255: value |= (2 << 7); break;
677 default:
678 case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
679 }
680 switch (ch->u.ofdm.guard_interval) {
681 case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
682 case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
683 case GUARD_INTERVAL_1_4: value |= (3 << 5); break;
684 default:
685 case GUARD_INTERVAL_1_8: value |= (2 << 5); break;
686 }
687 switch (ch->u.ofdm.constellation) {
688 case QPSK: value |= (0 << 3); break;
689 case QAM_16: value |= (1 << 3); break;
690 default:
691 case QAM_64: value |= (2 << 3); break;
692 }
693 switch (HIERARCHY_1) {
694 case HIERARCHY_2: value |= 2; break;
695 case HIERARCHY_4: value |= 4; break;
696 default:
697 case HIERARCHY_1: value |= 1; break;
698 }
699 dib7000p_write_word(state, 0, value);
365 dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */ 700 dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */
366 701
367 /* P_dintl_native, P_dintlv_inv, P_vit_hrch, P_vit_code_rate, P_vit_select_hp */ 702 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
368 tmp = (ch->intlv_native << 6) | (ch->vit_hrch << 4) | (ch->vit_select_hp & 0x1); 703 value = 0;
369 if (ch->vit_hrch == 0 || ch->vit_select_hp == 1) 704 if (1 != 0)
370 tmp |= (ch->vit_code_rate_hp << 1); 705 value |= (1 << 6);
371 else 706 if (ch->u.ofdm.hierarchy_information == 1)
372 tmp |= (ch->vit_code_rate_lp << 1); 707 value |= (1 << 4);
373 dib7000p_write_word(state, 208, tmp); 708 if (1 == 1)
709 value |= 1;
710 switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
711 case FEC_2_3: value |= (2 << 1); break;
712 case FEC_3_4: value |= (3 << 1); break;
713 case FEC_5_6: value |= (5 << 1); break;
714 case FEC_7_8: value |= (7 << 1); break;
715 default:
716 case FEC_1_2: value |= (1 << 1); break;
717 }
718 dib7000p_write_word(state, 208, value);
719
720 /* offset loop parameters */
721 dib7000p_write_word(state, 26, 0x6680); // timf(6xxx)
722 dib7000p_write_word(state, 29, 0x1273); // isi inh1273 on1073
723 dib7000p_write_word(state, 32, 0x0003); // pha_off_max(xxx3)
724 dib7000p_write_word(state, 33, 0x0005); // sfreq(xxx5)
374 725
375 /* P_dvsy_sync_wait */ 726 /* P_dvsy_sync_wait */
376 switch (ch->nfft) { 727 switch (ch->u.ofdm.transmission_mode) {
377 case 1: tmp = 256; break; 728 case TRANSMISSION_MODE_8K: value = 256; break;
378 case 2: tmp = 128; break; 729 case /* 4K MODE */ 255: value = 128; break;
379 case 0: 730 case TRANSMISSION_MODE_2K:
380 default: tmp = 64; break; 731 default: value = 64; break;
381 } 732 }
382 tmp *= ((1 << (ch->guard)) * 3 / 2); // add 50% SFN margin 733 switch (ch->u.ofdm.guard_interval) {
383 tmp <<= 4; 734 case GUARD_INTERVAL_1_16: value *= 2; break;
384 735 case GUARD_INTERVAL_1_8: value *= 4; break;
385 /* deactive the possibility of diversity reception if extended interleave */ 736 case GUARD_INTERVAL_1_4: value *= 8; break;
386 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */ 737 default:
387 if (ch->intlv_native || ch->nfft == 1) 738 case GUARD_INTERVAL_1_32: value *= 1; break;
388 tmp |= (1 << 2) | (2 << 0); 739 }
389 dib7000p_write_word(state, 207, tmp); 740 state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO
390 741
391 dib7000p_write_word(state, 26, 0x6680); // timf(6xxx) 742 /* deactive the possibility of diversity reception if extended interleaver */
392 dib7000p_write_word(state, 29, 0x1273); // isi inh1273 on1073 743 state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K;
393 dib7000p_write_word(state, 32, 0x0003); // pha_off_max(xxx3) 744 dib7000p_set_diversity_in(&state->demod, state->div_state);
394 dib7000p_write_word(state, 33, 0x0005); // sfreq(xxx5)
395 745
396 /* channel estimation fine configuration */ 746 /* channel estimation fine configuration */
397 switch (ch->nqam) { 747 switch (ch->u.ofdm.constellation) {
398 case 2: 748 case QAM_64:
399 est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */ 749 est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
400 est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */ 750 est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
401 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */ 751 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
402 est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */ 752 est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
403 break; 753 break;
404 case 1: 754 case QAM_16:
405 est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */ 755 est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
406 est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */ 756 est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
407 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */ 757 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
@@ -414,66 +764,45 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dibx000_of
414 est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */ 764 est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
415 break; 765 break;
416 } 766 }
417 for (tmp = 0; tmp < 4; tmp++) 767 for (value = 0; value < 4; value++)
418 dib7000p_write_word(state, 187 + tmp, est[tmp]); 768 dib7000p_write_word(state, 187 + value, est[value]);
419
420 // set power-up level: interf+analog+AGC
421 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
422 dib7000p_set_adc_state(state, DIBX000_ADC_ON);
423 dib7000p_pll_clk_cfg(state);
424 msleep(7);
425
426 // AGC initialization
427 if (state->cfg.agc_control)
428 state->cfg.agc_control(&state->demod, 1);
429
430 dib7000p_restart_agc(state);
431
432 // wait AGC rough lock time
433 msleep(5);
434
435 dib7000p_update_lna(state);
436
437 // wait AGC accurate lock time
438 msleep(7);
439 if (state->cfg.agc_control)
440 state->cfg.agc_control(&state->demod, 0);
441} 769}
442 770
443static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dibx000_ofdm_channel *ch) 771static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
444{ 772{
445 struct dib7000p_state *state = demod->demodulator_priv; 773 struct dib7000p_state *state = demod->demodulator_priv;
446 struct dibx000_ofdm_channel auto_ch; 774 struct dvb_frontend_parameters schan;
447 u32 value; 775 u32 value, factor;
448 776
449 INIT_OFDM_CHANNEL(&auto_ch); 777 schan = *ch;
450 auto_ch.RF_kHz = ch->RF_kHz; 778 schan.u.ofdm.constellation = QAM_64;
451 auto_ch.Bw = ch->Bw; 779 schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
452 auto_ch.nqam = 2; 780 schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
453 auto_ch.guard = 0; 781 schan.u.ofdm.code_rate_HP = FEC_2_3;
454 auto_ch.nfft = 1; 782 schan.u.ofdm.code_rate_LP = FEC_3_4;
455 auto_ch.vit_alpha = 1; 783 schan.u.ofdm.hierarchy_information = 0;
456 auto_ch.vit_select_hp = 1; 784
457 auto_ch.vit_code_rate_hp = 2; 785 dib7000p_set_channel(state, &schan, 7);
458 auto_ch.vit_code_rate_lp = 3; 786
459 auto_ch.vit_hrch = 0; 787 factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth);
460 auto_ch.intlv_native = 1; 788 if (factor >= 5000)
461 789 factor = 1;
462 dib7000p_set_channel(state, &auto_ch, 7); 790 else
791 factor = 6;
463 792
464 // always use the setting for 8MHz here lock_time for 7,6 MHz are longer 793 // always use the setting for 8MHz here lock_time for 7,6 MHz are longer
465 value = 30 * state->cfg.bw->internal; 794 value = 30 * state->cfg.bw->internal * factor;
466 dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff)); // lock0 wait time 795 dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff)); // lock0 wait time
467 dib7000p_write_word(state, 7, (u16) (value & 0xffff)); // lock0 wait time 796 dib7000p_write_word(state, 7, (u16) (value & 0xffff)); // lock0 wait time
468 value = 100 * state->cfg.bw->internal; 797 value = 100 * state->cfg.bw->internal * factor;
469 dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff)); // lock1 wait time 798 dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff)); // lock1 wait time
470 dib7000p_write_word(state, 9, (u16) (value & 0xffff)); // lock1 wait time 799 dib7000p_write_word(state, 9, (u16) (value & 0xffff)); // lock1 wait time
471 value = 500 * state->cfg.bw->internal; 800 value = 500 * state->cfg.bw->internal * factor;
472 dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time 801 dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
473 dib7000p_write_word(state, 11, (u16) (value & 0xffff)); // lock2 wait time 802 dib7000p_write_word(state, 11, (u16) (value & 0xffff)); // lock2 wait time
474 803
475 value = dib7000p_read_word(state, 0); 804 value = dib7000p_read_word(state, 0);
476 dib7000p_write_word(state, 0, (1 << 9) | value); 805 dib7000p_write_word(state, 0, (u16) ((1 << 9) | value));
477 dib7000p_read_word(state, 1284); 806 dib7000p_read_word(state, 1284);
478 dib7000p_write_word(state, 0, (u16) value); 807 dib7000p_write_word(state, 0, (u16) value);
479 808
@@ -494,7 +823,95 @@ static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod)
494 return 0; // still pending 823 return 0; // still pending
495} 824}
496 825
497static int dib7000p_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel *ch) 826static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw)
827{
828 static s16 notch[]={16143, 14402, 12238, 9713, 6902, 3888, 759, -2392};
829 static u8 sine [] ={0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
830 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
831 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
832 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
833 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
834 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
835 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
836 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
837 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
838 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
839 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
840 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
841 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
842 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
843 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
844 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
845 255, 255, 255, 255, 255, 255};
846
847 u32 xtal = state->cfg.bw->xtal_hz / 1000;
848 int f_rel = ( (rf_khz + xtal/2) / xtal) * xtal - rf_khz;
849 int k;
850 int coef_re[8],coef_im[8];
851 int bw_khz = bw;
852 u32 pha;
853
854 dprintk( "relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal);
855
856
857 if (f_rel < -bw_khz/2 || f_rel > bw_khz/2)
858 return;
859
860 bw_khz /= 100;
861
862 dib7000p_write_word(state, 142 ,0x0610);
863
864 for (k = 0; k < 8; k++) {
865 pha = ((f_rel * (k+1) * 112 * 80/bw_khz) /1000) & 0x3ff;
866
867 if (pha==0) {
868 coef_re[k] = 256;
869 coef_im[k] = 0;
870 } else if(pha < 256) {
871 coef_re[k] = sine[256-(pha&0xff)];
872 coef_im[k] = sine[pha&0xff];
873 } else if (pha == 256) {
874 coef_re[k] = 0;
875 coef_im[k] = 256;
876 } else if (pha < 512) {
877 coef_re[k] = -sine[pha&0xff];
878 coef_im[k] = sine[256 - (pha&0xff)];
879 } else if (pha == 512) {
880 coef_re[k] = -256;
881 coef_im[k] = 0;
882 } else if (pha < 768) {
883 coef_re[k] = -sine[256-(pha&0xff)];
884 coef_im[k] = -sine[pha&0xff];
885 } else if (pha == 768) {
886 coef_re[k] = 0;
887 coef_im[k] = -256;
888 } else {
889 coef_re[k] = sine[pha&0xff];
890 coef_im[k] = -sine[256 - (pha&0xff)];
891 }
892
893 coef_re[k] *= notch[k];
894 coef_re[k] += (1<<14);
895 if (coef_re[k] >= (1<<24))
896 coef_re[k] = (1<<24) - 1;
897 coef_re[k] /= (1<<15);
898
899 coef_im[k] *= notch[k];
900 coef_im[k] += (1<<14);
901 if (coef_im[k] >= (1<<24))
902 coef_im[k] = (1<<24)-1;
903 coef_im[k] /= (1<<15);
904
905 dprintk( "PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]);
906
907 dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
908 dib7000p_write_word(state, 144, coef_im[k] & 0x3ff);
909 dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
910 }
911 dib7000p_write_word(state,143 ,0);
912}
913
914static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
498{ 915{
499 struct dib7000p_state *state = demod->demodulator_priv; 916 struct dib7000p_state *state = demod->demodulator_priv;
500 u16 tmp = 0; 917 u16 tmp = 0;
@@ -520,28 +937,31 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel
520 937
521 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */ 938 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
522 tmp = (6 << 8) | 0x80; 939 tmp = (6 << 8) | 0x80;
523 switch (ch->nfft) { 940 switch (ch->u.ofdm.transmission_mode) {
524 case 0: tmp |= (7 << 12); break; 941 case TRANSMISSION_MODE_2K: tmp |= (7 << 12); break;
525 case 1: tmp |= (9 << 12); break; 942 case /* 4K MODE */ 255: tmp |= (8 << 12); break;
526 case 2: tmp |= (8 << 12); break; 943 default:
944 case TRANSMISSION_MODE_8K: tmp |= (9 << 12); break;
527 } 945 }
528 dib7000p_write_word(state, 26, tmp); /* timf_a(6xxx) */ 946 dib7000p_write_word(state, 26, tmp); /* timf_a(6xxx) */
529 947
530 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */ 948 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
531 tmp = (0 << 4); 949 tmp = (0 << 4);
532 switch (ch->nfft) { 950 switch (ch->u.ofdm.transmission_mode) {
533 case 0: tmp |= 0x6; break; 951 case TRANSMISSION_MODE_2K: tmp |= 0x6; break;
534 case 1: tmp |= 0x8; break; 952 case /* 4K MODE */ 255: tmp |= 0x7; break;
535 case 2: tmp |= 0x7; break; 953 default:
954 case TRANSMISSION_MODE_8K: tmp |= 0x8; break;
536 } 955 }
537 dib7000p_write_word(state, 32, tmp); 956 dib7000p_write_word(state, 32, tmp);
538 957
539 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */ 958 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
540 tmp = (0 << 4); 959 tmp = (0 << 4);
541 switch (ch->nfft) { 960 switch (ch->u.ofdm.transmission_mode) {
542 case 0: tmp |= 0x6; break; 961 case TRANSMISSION_MODE_2K: tmp |= 0x6; break;
543 case 1: tmp |= 0x8; break; 962 case /* 4K MODE */ 255: tmp |= 0x7; break;
544 case 2: tmp |= 0x7; break; 963 default:
964 case TRANSMISSION_MODE_8K: tmp |= 0x8; break;
545 } 965 }
546 dib7000p_write_word(state, 33, tmp); 966 dib7000p_write_word(state, 33, tmp);
547 967
@@ -557,131 +977,21 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel
557 977
558 // we achieved a lock - it's time to update the osc freq 978 // we achieved a lock - it's time to update the osc freq
559 if ((tmp >> 6) & 0x1) 979 if ((tmp >> 6) & 0x1)
560 dib7000p_update_timf_freq(state); 980 dib7000p_update_timf(state);
981
982 if (state->cfg.spur_protect)
983 dib7000p_spur_protect(state, ch->frequency/1000, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
561 984
985 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
562 return 0; 986 return 0;
563} 987}
564 988
565static int dib7000p_init(struct dvb_frontend *demod) 989static int dib7000p_wakeup(struct dvb_frontend *demod)
566{ 990{
567 struct dibx000_agc_config *agc;
568 struct dib7000p_state *state = demod->demodulator_priv; 991 struct dib7000p_state *state = demod->demodulator_priv;
569 int ret = 0;
570
571 // Demodulator default configuration
572 agc = state->cfg.agc;
573
574 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL); 992 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
575 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON); 993 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
576 994 return 0;
577 /* AGC */
578 ret |= dib7000p_write_word(state, 75 , agc->setup );
579 ret |= dib7000p_write_word(state, 76 , agc->inv_gain );
580 ret |= dib7000p_write_word(state, 77 , agc->time_stabiliz );
581 ret |= dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);
582
583 // Demod AGC loop configuration
584 ret |= dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);
585 ret |= dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp);
586
587 /* AGC continued */
588 dprintk("-D- WBD: ref: %d, sel: %d, active: %d, alpha: %d\n",
589 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
590
591 if (state->wbd_ref != 0)
592 ret |= dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref);
593 else
594 ret |= dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref);
595
596 ret |= dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8) );
597
598 ret |= dib7000p_write_word(state, 107, agc->agc1_max);
599 ret |= dib7000p_write_word(state, 108, agc->agc1_min);
600 ret |= dib7000p_write_word(state, 109, agc->agc2_max);
601 ret |= dib7000p_write_word(state, 110, agc->agc2_min);
602 ret |= dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2 );
603 ret |= dib7000p_write_word(state, 112, agc->agc1_pt3);
604 ret |= dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
605 ret |= dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
606 ret |= dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
607
608 /* disable power smoothing */
609 ret |= dib7000p_write_word(state, 145, 0);
610 ret |= dib7000p_write_word(state, 146, 0);
611 ret |= dib7000p_write_word(state, 147, 0);
612 ret |= dib7000p_write_word(state, 148, 0);
613 ret |= dib7000p_write_word(state, 149, 0);
614 ret |= dib7000p_write_word(state, 150, 0);
615 ret |= dib7000p_write_word(state, 151, 0);
616 ret |= dib7000p_write_word(state, 152, 0);
617
618 // P_timf_alpha=6, P_corm_alpha=6, P_corm_thres=128 default: 6,4,26
619 ret |= dib7000p_write_word(state, 26 ,0x6680);
620
621 // P_palf_filter_on=1, P_palf_filter_freeze=0, P_palf_alpha_regul=16
622 ret |= dib7000p_write_word(state, 142,0x0410);
623 // P_fft_freq_dir=1, P_fft_nb_to_cut=0
624 ret |= dib7000p_write_word(state, 154,1 << 13);
625 // P_pha3_thres, default 0x3000
626 ret |= dib7000p_write_word(state, 168,0x0ccd);
627 // P_cti_use_cpe=0, P_cti_use_prog=0, P_cti_win_len=16, default: 0x0010
628 //ret |= dib7000p_write_word(state, 169,0x0010);
629 // P_cspu_regul=512, P_cspu_win_cut=15, default: 0x2005
630 ret |= dib7000p_write_word(state, 183,0x200f);
631 // P_adp_regul_cnt=573, default: 410
632 ret |= dib7000p_write_word(state, 187,0x023d);
633 // P_adp_noise_cnt=
634 ret |= dib7000p_write_word(state, 188,0x00a4);
635 // P_adp_regul_ext
636 ret |= dib7000p_write_word(state, 189,0x00a4);
637 // P_adp_noise_ext
638 ret |= dib7000p_write_word(state, 190,0x7ff0);
639 // P_adp_fil
640 ret |= dib7000p_write_word(state, 191,0x3ccc);
641
642 ret |= dib7000p_write_word(state, 222,0x0010);
643 // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
644 ret |= dib7000p_write_word(state, 235,0x0062);
645
646 // P_iqc_alpha_pha, P_iqc_alpha_amp_dcc_alpha, ...
647 if(state->cfg.tuner_is_baseband)
648 ret |= dib7000p_write_word(state, 36,0x0755);
649 else
650 ret |= dib7000p_write_word(state, 36,0x1f55);
651
652 // auto search configuration
653 ret |= dib7000p_write_word(state, 2 ,0x0004);
654 ret |= dib7000p_write_word(state, 3 ,0x1000);
655
656 /* Equal Lock */
657 ret |= dib7000p_write_word(state, 4 ,0x0814);
658
659 ret |= dib7000p_write_word(state, 6 ,0x001b);
660 ret |= dib7000p_write_word(state, 7 ,0x7740);
661 ret |= dib7000p_write_word(state, 8 ,0x005b);
662 ret |= dib7000p_write_word(state, 9 ,0x8d80);
663 ret |= dib7000p_write_word(state, 10 ,0x01c9);
664 ret |= dib7000p_write_word(state, 11 ,0xc380);
665 ret |= dib7000p_write_word(state, 12 ,0x0000);
666 ret |= dib7000p_write_word(state, 13 ,0x0080);
667 ret |= dib7000p_write_word(state, 14 ,0x0000);
668 ret |= dib7000p_write_word(state, 15 ,0x0090);
669 ret |= dib7000p_write_word(state, 16 ,0x0001);
670 ret |= dib7000p_write_word(state, 17 ,0xd4c0);
671
672 // P_clk_cfg1
673 ret |= dib7000p_write_word(state, 901, 0x0006);
674
675 // P_divclksel=3 P_divbitsel=1
676 ret |= dib7000p_write_word(state, 902, (3 << 10) | (1 << 6));
677
678 // Tuner IO bank: max drive (14mA) + divout pads max drive
679 ret |= dib7000p_write_word(state, 905, 0x2c8e);
680
681 ret |= dib7000p_set_bandwidth(&state->demod, BANDWIDTH_8_MHZ);
682 dib7000p_sad_calib(state);
683
684 return ret;
685} 995}
686 996
687static int dib7000p_sleep(struct dvb_frontend *demod) 997static int dib7000p_sleep(struct dvb_frontend *demod)
@@ -693,16 +1003,16 @@ static int dib7000p_sleep(struct dvb_frontend *demod)
693static int dib7000p_identify(struct dib7000p_state *st) 1003static int dib7000p_identify(struct dib7000p_state *st)
694{ 1004{
695 u16 value; 1005 u16 value;
696 dprintk("-I- DiB7000PC: checking demod on I2C address: %d (%x)\n", 1006 dprintk( "checking demod on I2C address: %d (%x)",
697 st->i2c_addr, st->i2c_addr); 1007 st->i2c_addr, st->i2c_addr);
698 1008
699 if ((value = dib7000p_read_word(st, 768)) != 0x01b3) { 1009 if ((value = dib7000p_read_word(st, 768)) != 0x01b3) {
700 dprintk("-E- DiB7000PC: wrong Vendor ID (read=0x%x)\n",value); 1010 dprintk( "wrong Vendor ID (read=0x%x)",value);
701 return -EREMOTEIO; 1011 return -EREMOTEIO;
702 } 1012 }
703 1013
704 if ((value = dib7000p_read_word(st, 769)) != 0x4000) { 1014 if ((value = dib7000p_read_word(st, 769)) != 0x4000) {
705 dprintk("-E- DiB7000PC: wrong Device ID (%x)\n",value); 1015 dprintk( "wrong Device ID (%x)",value);
706 return -EREMOTEIO; 1016 return -EREMOTEIO;
707 } 1017 }
708 1018
@@ -772,41 +1082,45 @@ static int dib7000p_set_frontend(struct dvb_frontend* fe,
772 struct dvb_frontend_parameters *fep) 1082 struct dvb_frontend_parameters *fep)
773{ 1083{
774 struct dib7000p_state *state = fe->demodulator_priv; 1084 struct dib7000p_state *state = fe->demodulator_priv;
775 struct dibx000_ofdm_channel ch; 1085 int time;
776
777 INIT_OFDM_CHANNEL(&ch);
778 FEP2DIB(fep,&ch);
779 1086
780 state->current_bandwidth = fep->u.ofdm.bandwidth; 1087 state->current_bandwidth = fep->u.ofdm.bandwidth;
781 dib7000p_set_bandwidth(fe, fep->u.ofdm.bandwidth); 1088 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth));
782 1089
783 if (fe->ops.tuner_ops.set_params) 1090 if (fe->ops.tuner_ops.set_params)
784 fe->ops.tuner_ops.set_params(fe, fep); 1091 fe->ops.tuner_ops.set_params(fe, fep);
785 1092
1093 /* start up the AGC */
1094 state->agc_state = 0;
1095 do {
1096 time = dib7000p_agc_startup(fe, fep);
1097 if (time != -1)
1098 msleep(time);
1099 } while (time != -1);
1100
786 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO || 1101 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
787 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || 1102 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ||
788 fep->u.ofdm.constellation == QAM_AUTO || 1103 fep->u.ofdm.constellation == QAM_AUTO ||
789 fep->u.ofdm.code_rate_HP == FEC_AUTO) { 1104 fep->u.ofdm.code_rate_HP == FEC_AUTO) {
790 int i = 800, found; 1105 int i = 800, found;
791 1106
792 dib7000p_autosearch_start(fe, &ch); 1107 dib7000p_autosearch_start(fe, fep);
793 do { 1108 do {
794 msleep(1); 1109 msleep(1);
795 found = dib7000p_autosearch_is_irq(fe); 1110 found = dib7000p_autosearch_is_irq(fe);
796 } while (found == 0 && i--); 1111 } while (found == 0 && i--);
797 1112
798 dprintk("autosearch returns: %d\n",found); 1113 dprintk("autosearch returns: %d",found);
799 if (found == 0 || found == 1) 1114 if (found == 0 || found == 1)
800 return 0; // no channel found 1115 return 0; // no channel found
801 1116
802 dib7000p_get_frontend(fe, fep); 1117 dib7000p_get_frontend(fe, fep);
803 FEP2DIB(fep, &ch);
804 } 1118 }
805 1119
806 /* make this a config parameter */ 1120 /* make this a config parameter */
807 dib7000p_set_output_mode(state, OUTMODE_MPEG2_FIFO); 1121 dib7000p_set_output_mode(state, OUTMODE_MPEG2_FIFO);
808 1122
809 return dib7000p_tune(fe, &ch); 1123 return dib7000p_tune(fe, fep);
810} 1124}
811 1125
812static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t *stat) 1126static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t *stat)
@@ -884,7 +1198,7 @@ int dib7000pc_detection(struct i2c_adapter *i2c_adap)
884 1198
885 if (i2c_transfer(i2c_adap, msg, 2) == 2) 1199 if (i2c_transfer(i2c_adap, msg, 2) == 2)
886 if (rx[0] == 0x01 && rx[1] == 0xb3) { 1200 if (rx[0] == 0x01 && rx[1] == 0xb3) {
887 dprintk("-D- DiB7000PC detected\n"); 1201 dprintk("-D- DiB7000PC detected");
888 return 1; 1202 return 1;
889 } 1203 }
890 1204
@@ -892,11 +1206,11 @@ int dib7000pc_detection(struct i2c_adapter *i2c_adap)
892 1206
893 if (i2c_transfer(i2c_adap, msg, 2) == 2) 1207 if (i2c_transfer(i2c_adap, msg, 2) == 2)
894 if (rx[0] == 0x01 && rx[1] == 0xb3) { 1208 if (rx[0] == 0x01 && rx[1] == 0xb3) {
895 dprintk("-D- DiB7000PC detected\n"); 1209 dprintk("-D- DiB7000PC detected");
896 return 1; 1210 return 1;
897 } 1211 }
898 1212
899 dprintk("-D- DiB7000PC not detected\n"); 1213 dprintk("-D- DiB7000PC not detected");
900 return 0; 1214 return 0;
901} 1215}
902EXPORT_SYMBOL(dib7000pc_detection); 1216EXPORT_SYMBOL(dib7000pc_detection);
@@ -934,7 +1248,7 @@ int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defau
934 /* set new i2c address and force divstart */ 1248 /* set new i2c address and force divstart */
935 dib7000p_write_word(&st, 1285, (new_addr << 2) | 0x2); 1249 dib7000p_write_word(&st, 1285, (new_addr << 2) | 0x2);
936 1250
937 dprintk("IC %d initialized (to i2c_address 0x%x)\n", k, new_addr); 1251 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
938 } 1252 }
939 1253
940 for (k = 0; k < no_of_demods; k++) { 1254 for (k = 0; k < no_of_demods; k++) {
@@ -1005,7 +1319,7 @@ static struct dvb_frontend_ops dib7000p_ops = {
1005 1319
1006 .release = dib7000p_release, 1320 .release = dib7000p_release,
1007 1321
1008 .init = dib7000p_init, 1322 .init = dib7000p_wakeup,
1009 .sleep = dib7000p_sleep, 1323 .sleep = dib7000p_sleep,
1010 1324
1011 .set_frontend = dib7000p_set_frontend, 1325 .set_frontend = dib7000p_set_frontend,