aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/dib7000p.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-11 22:09:32 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-11 22:09:32 -0400
commitc634920abaf9c0a93266a57beff6fce9d3852cb2 (patch)
tree5ac85f54905a8cd3b12b262c66189084cbff54fc /drivers/media/dvb/frontends/dib7000p.c
parent6abd2c860e34add677de50e8b134f5af6f4b0893 (diff)
parenta991f44b79fa49b281eb078eed4a76a42101012a (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (310 commits) V4L/DVB (6316): Change list_for_each+list_entry to list_for_each_entry V4L/DVB (6315): pvrusb2: Change list_for_each+list_entry to list_for_each_entry V4L/DVB (6314): saa7134: Replace list_for_each+list_entry with list_for_each_entry V4L/DVB (6313): ivtv: Replace list_for_each+list_entry with list_for_each_entry V4L/DVB (6312): cx88: Replace list_for_each+list_entry with list_for_each_entry V4L/DVB (6311): dvb: Replace list_for_each+list_entry with list_for_each_entry V4L/DVB (6308): V4L: zc0301, remove bad usage of ERESTARTSYS V4L/DVB (6307): V4L: w9968cf, remove bad usage of ERESTARTSYS V4L/DVB (6306): Few clenups for saa7134 resume code V4L/DVB (6305): V4L: videobuf-core.c avoid NULL dereferences in videobuf-core V4L/DVB (6301): pvrusb: Update DEBUGIFC sysfs to kernel 2.6.13+ V4L/DVB (6300): CodingStyle cleanup V4L/DVB (6299): dvb: Add dependencies for VIDEOBUF_DVB V4L/DVB (6297): cx23885: remove wrong Kconfig selection of VIDEOBUF V4L/DVB (6296): dib0700: add support for AverMedia DVB-T Express card V4L/DVB (6295): saa7134: add autodetection for KWorld ATSC-115 V4L/DVB (6293): V4L: convert struct class_device to struct device V4L/DVB (6292): videobuf_core init always require callback implementation V4L/DVB (6291): Fix: avoid oops on some SMP machines V4L/DVB (6290): remove videobuf_set_pci_ops ...
Diffstat (limited to 'drivers/media/dvb/frontends/dib7000p.c')
-rw-r--r--drivers/media/dvb/frontends/dib7000p.c908
1 files changed, 638 insertions, 270 deletions
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
index aece458cfe12..f45bcfc51cf8 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,11 @@ 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) 21static int buggy_sfn_workaround;
22module_param(buggy_sfn_workaround, int, 0644);
23MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
24
25#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0)
22 26
23struct dib7000p_state { 27struct dib7000p_state {
24 struct dvb_frontend demod; 28 struct dvb_frontend demod;
@@ -36,12 +40,21 @@ struct dib7000p_state {
36 struct dibx000_agc_config *current_agc; 40 struct dibx000_agc_config *current_agc;
37 u32 timf; 41 u32 timf;
38 42
43 u8 div_force_off : 1;
44 u8 div_state : 1;
45 u16 div_sync_wait;
46
47 u8 agc_state;
48
39 u16 gpio_dir; 49 u16 gpio_dir;
40 u16 gpio_val; 50 u16 gpio_val;
51
52 u8 sfn_workaround_active :1;
41}; 53};
42 54
43enum dib7000p_power_mode { 55enum dib7000p_power_mode {
44 DIB7000P_POWER_ALL = 0, 56 DIB7000P_POWER_ALL = 0,
57 DIB7000P_POWER_ANALOG_ADC,
45 DIB7000P_POWER_INTERFACE_ONLY, 58 DIB7000P_POWER_INTERFACE_ONLY,
46}; 59};
47 60
@@ -55,7 +68,7 @@ static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
55 }; 68 };
56 69
57 if (i2c_transfer(state->i2c_adap, msg, 2) != 2) 70 if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
58 dprintk("i2c read error on %d\n",reg); 71 dprintk("i2c read error on %d",reg);
59 72
60 return (rb[0] << 8) | rb[1]; 73 return (rb[0] << 8) | rb[1];
61} 74}
@@ -71,6 +84,22 @@ static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
71 }; 84 };
72 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; 85 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
73} 86}
87static void dib7000p_write_tab(struct dib7000p_state *state, u16 *buf)
88{
89 u16 l = 0, r, *n;
90 n = buf;
91 l = *n++;
92 while (l) {
93 r = *n++;
94
95 do {
96 dib7000p_write_word(state, r, *n++);
97 r++;
98 } while (--l);
99 l = *n++;
100 }
101}
102
74static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode) 103static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
75{ 104{
76 int ret = 0; 105 int ret = 0;
@@ -80,7 +109,7 @@ static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
80 fifo_threshold = 1792; 109 fifo_threshold = 1792;
81 smo_mode = (dib7000p_read_word(state, 235) & 0x0010) | (1 << 1); 110 smo_mode = (dib7000p_read_word(state, 235) & 0x0010) | (1 << 1);
82 111
83 dprintk("-I- Setting output mode for demod %p to %d\n", 112 dprintk( "setting output mode for demod %p to %d",
84 &state->demod, mode); 113 &state->demod, mode);
85 114
86 switch (mode) { 115 switch (mode) {
@@ -104,11 +133,14 @@ static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
104 fifo_threshold = 512; 133 fifo_threshold = 512;
105 outreg = (1 << 10) | (5 << 6); 134 outreg = (1 << 10) | (5 << 6);
106 break; 135 break;
136 case OUTMODE_ANALOG_ADC:
137 outreg = (1 << 10) | (3 << 6);
138 break;
107 case OUTMODE_HIGH_Z: // disable 139 case OUTMODE_HIGH_Z: // disable
108 outreg = 0; 140 outreg = 0;
109 break; 141 break;
110 default: 142 default:
111 dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod); 143 dprintk( "Unhandled output_mode passed to be set for demod %p",&state->demod);
112 break; 144 break;
113 } 145 }
114 146
@@ -122,6 +154,30 @@ static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
122 return ret; 154 return ret;
123} 155}
124 156
157static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
158{
159 struct dib7000p_state *state = demod->demodulator_priv;
160
161 if (state->div_force_off) {
162 dprintk( "diversity combination deactivated - forced by COFDM parameters");
163 onoff = 0;
164 }
165 state->div_state = (u8)onoff;
166
167 if (onoff) {
168 dib7000p_write_word(state, 204, 6);
169 dib7000p_write_word(state, 205, 16);
170 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
171 dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
172 } else {
173 dib7000p_write_word(state, 204, 1);
174 dib7000p_write_word(state, 205, 0);
175 dib7000p_write_word(state, 207, 0);
176 }
177
178 return 0;
179}
180
125static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode) 181static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode)
126{ 182{
127 /* by default everything is powered off */ 183 /* by default everything is powered off */
@@ -134,10 +190,21 @@ static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_p
134 case DIB7000P_POWER_ALL: 190 case DIB7000P_POWER_ALL:
135 reg_774 = 0x0000; reg_775 = 0x0000; reg_776 = 0x0; reg_899 = 0x0; reg_1280 &= 0x01ff; 191 reg_774 = 0x0000; reg_775 = 0x0000; reg_776 = 0x0; reg_899 = 0x0; reg_1280 &= 0x01ff;
136 break; 192 break;
193
194 case DIB7000P_POWER_ANALOG_ADC:
195 /* dem, cfg, iqc, sad, agc */
196 reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
197 /* nud */
198 reg_776 &= ~((1 << 0));
199 /* Dout */
200 reg_1280 &= ~((1 << 11));
201 /* fall through wanted to enable the interfaces */
202
137 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */ 203 /* 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 */ 204 case DIB7000P_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C */
139 reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10)); 205 reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
140 break; 206 break;
207
141/* TODO following stuff is just converted from the dib7000-driver - check when is used what */ 208/* TODO following stuff is just converted from the dib7000-driver - check when is used what */
142 } 209 }
143 210
@@ -188,34 +255,31 @@ static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_ad
188 break; 255 break;
189 } 256 }
190 257
191// dprintk("908: %x, 909: %x\n", reg_908, reg_909); 258// dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
192 259
193 dib7000p_write_word(state, 908, reg_908); 260 dib7000p_write_word(state, 908, reg_908);
194 dib7000p_write_word(state, 909, reg_909); 261 dib7000p_write_word(state, 909, reg_909);
195} 262}
196 263
197static int dib7000p_set_bandwidth(struct dvb_frontend *demod, u8 BW_Idx) 264static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
198{ 265{
199 struct dib7000p_state *state = demod->demodulator_priv;
200 u32 timf; 266 u32 timf;
201 267
202 // store the current bandwidth for later use 268 // store the current bandwidth for later use
203 state->current_bandwidth = BW_Idx; 269 state->current_bandwidth = bw;
204 270
205 if (state->timf == 0) { 271 if (state->timf == 0) {
206 dprintk("-D- Using default timf\n"); 272 dprintk( "using default timf");
207 timf = state->cfg.bw->timf; 273 timf = state->cfg.bw->timf;
208 } else { 274 } else {
209 dprintk("-D- Using updated timf\n"); 275 dprintk( "using updated timf");
210 timf = state->timf; 276 timf = state->timf;
211 } 277 }
212 278
213 timf = timf * (BW_INDEX_TO_KHZ(BW_Idx) / 100) / 80; 279 timf = timf * (bw / 50) / 160;
214
215 dprintk("timf: %d\n",timf);
216 280
217 dib7000p_write_word(state, 23, (timf >> 16) & 0xffff); 281 dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
218 dib7000p_write_word(state, 24, (timf ) & 0xffff); 282 dib7000p_write_word(state, 24, (u16) ((timf ) & 0xffff));
219 283
220 return 0; 284 return 0;
221} 285}
@@ -223,7 +287,7 @@ static int dib7000p_set_bandwidth(struct dvb_frontend *demod, u8 BW_Idx)
223static int dib7000p_sad_calib(struct dib7000p_state *state) 287static int dib7000p_sad_calib(struct dib7000p_state *state)
224{ 288{
225/* internal */ 289/* internal */
226// dib7000p_write_word(state, 72, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is written in set_bandwidth 290// 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)); 291 dib7000p_write_word(state, 73, (0 << 1) | (0 << 0));
228 dib7000p_write_word(state, 74, 776); // 0.625*3.3 / 4096 292 dib7000p_write_word(state, 74, 776); // 0.625*3.3 / 4096
229 293
@@ -236,18 +300,37 @@ static int dib7000p_sad_calib(struct dib7000p_state *state)
236 return 0; 300 return 0;
237} 301}
238 302
303int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
304{
305 struct dib7000p_state *state = demod->demodulator_priv;
306 if (value > 4095)
307 value = 4095;
308 state->wbd_ref = value;
309 return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value);
310}
311
312EXPORT_SYMBOL(dib7000p_set_wbd_ref);
239static void dib7000p_reset_pll(struct dib7000p_state *state) 313static void dib7000p_reset_pll(struct dib7000p_state *state)
240{ 314{
241 struct dibx000_bandwidth_config *bw = &state->cfg.bw[0]; 315 struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
316 u16 clk_cfg0;
317
318 /* force PLL bypass */
319 clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) |
320 (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) |
321 (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0);
242 322
323 dib7000p_write_word(state, 900, clk_cfg0);
324
325 /* P_pll_cfg */
243 dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset); 326 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) | 327 clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff);
245 (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0)); 328 dib7000p_write_word(state, 900, clk_cfg0);
246 329
247 dib7000p_write_word(state, 18, ((bw->internal*1000) >> 16) & 0xffff); 330 dib7000p_write_word(state, 18, (u16) (((bw->internal*1000) >> 16) & 0xffff));
248 dib7000p_write_word(state, 19, (bw->internal*1000 ) & 0xffff); 331 dib7000p_write_word(state, 19, (u16) ( (bw->internal*1000 ) & 0xffff));
249 dib7000p_write_word(state, 21, (bw->ifreq >> 16) & 0xffff); 332 dib7000p_write_word(state, 21, (u16) ( (bw->ifreq >> 16) & 0xffff));
250 dib7000p_write_word(state, 22, (bw->ifreq ) & 0xffff); 333 dib7000p_write_word(state, 22, (u16) ( (bw->ifreq ) & 0xffff));
251 334
252 dib7000p_write_word(state, 72, bw->sad_cfg); 335 dib7000p_write_word(state, 72, bw->sad_cfg);
253} 336}
@@ -255,7 +338,7 @@ static void dib7000p_reset_pll(struct dib7000p_state *state)
255static int dib7000p_reset_gpio(struct dib7000p_state *st) 338static int dib7000p_reset_gpio(struct dib7000p_state *st)
256{ 339{
257 /* reset the GPIOs */ 340 /* 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); 341 dprintk( "gpio dir: %x: val: %x, pwm_pos: %x",st->gpio_dir, st->gpio_val,st->cfg.gpio_pwm_pos);
259 342
260 dib7000p_write_word(st, 1029, st->gpio_dir); 343 dib7000p_write_word(st, 1029, st->gpio_dir);
261 dib7000p_write_word(st, 1030, st->gpio_val); 344 dib7000p_write_word(st, 1030, st->gpio_val);
@@ -268,6 +351,120 @@ static int dib7000p_reset_gpio(struct dib7000p_state *st)
268 return 0; 351 return 0;
269} 352}
270 353
354static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val)
355{
356 st->gpio_dir = dib7000p_read_word(st, 1029);
357 st->gpio_dir &= ~(1 << num); /* reset the direction bit */
358 st->gpio_dir |= (dir & 0x1) << num; /* set the new direction */
359 dib7000p_write_word(st, 1029, st->gpio_dir);
360
361 st->gpio_val = dib7000p_read_word(st, 1030);
362 st->gpio_val &= ~(1 << num); /* reset the direction bit */
363 st->gpio_val |= (val & 0x01) << num; /* set the new value */
364 dib7000p_write_word(st, 1030, st->gpio_val);
365
366 return 0;
367}
368
369int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val)
370{
371 struct dib7000p_state *state = demod->demodulator_priv;
372 return dib7000p_cfg_gpio(state, num, dir, val);
373}
374
375EXPORT_SYMBOL(dib7000p_set_gpio);
376static u16 dib7000p_defaults[] =
377
378{
379 // auto search configuration
380 3, 2,
381 0x0004,
382 0x1000,
383 0x0814, /* Equal Lock */
384
385 12, 6,
386 0x001b,
387 0x7740,
388 0x005b,
389 0x8d80,
390 0x01c9,
391 0xc380,
392 0x0000,
393 0x0080,
394 0x0000,
395 0x0090,
396 0x0001,
397 0xd4c0,
398
399 1, 26,
400 0x6680, // P_timf_alpha=6, P_corm_alpha=6, P_corm_thres=128 default: 6,4,26
401
402 /* set ADC level to -16 */
403 11, 79,
404 (1 << 13) - 825 - 117,
405 (1 << 13) - 837 - 117,
406 (1 << 13) - 811 - 117,
407 (1 << 13) - 766 - 117,
408 (1 << 13) - 737 - 117,
409 (1 << 13) - 693 - 117,
410 (1 << 13) - 648 - 117,
411 (1 << 13) - 619 - 117,
412 (1 << 13) - 575 - 117,
413 (1 << 13) - 531 - 117,
414 (1 << 13) - 501 - 117,
415
416 1, 142,
417 0x0410, // P_palf_filter_on=1, P_palf_filter_freeze=0, P_palf_alpha_regul=16
418
419 /* disable power smoothing */
420 8, 145,
421 0,
422 0,
423 0,
424 0,
425 0,
426 0,
427 0,
428 0,
429
430 1, 154,
431 1 << 13, // P_fft_freq_dir=1, P_fft_nb_to_cut=0
432
433 1, 168,
434 0x0ccd, // P_pha3_thres, default 0x3000
435
436// 1, 169,
437// 0x0010, // P_cti_use_cpe=0, P_cti_use_prog=0, P_cti_win_len=16, default: 0x0010
438
439 1, 183,
440 0x200f, // P_cspu_regul=512, P_cspu_win_cut=15, default: 0x2005
441
442 5, 187,
443 0x023d, // P_adp_regul_cnt=573, default: 410
444 0x00a4, // P_adp_noise_cnt=
445 0x00a4, // P_adp_regul_ext
446 0x7ff0, // P_adp_noise_ext
447 0x3ccc, // P_adp_fil
448
449 1, 198,
450 0x800, // P_equal_thres_wgn
451
452 1, 222,
453 0x0010, // P_fec_ber_rs_len=2
454
455 1, 235,
456 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
457
458 2, 901,
459 0x0006, // P_clk_cfg1
460 (3 << 10) | (1 << 6), // P_divclksel=3 P_divbitsel=1
461
462 1, 905,
463 0x2c8e, // Tuner IO bank: max drive (14mA) + divout pads max drive
464
465 0,
466};
467
271static int dib7000p_demod_reset(struct dib7000p_state *state) 468static int dib7000p_demod_reset(struct dib7000p_state *state)
272{ 469{
273 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL); 470 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
@@ -292,111 +489,307 @@ static int dib7000p_demod_reset(struct dib7000p_state *state)
292 dib7000p_reset_pll(state); 489 dib7000p_reset_pll(state);
293 490
294 if (dib7000p_reset_gpio(state) != 0) 491 if (dib7000p_reset_gpio(state) != 0)
295 dprintk("-E- GPIO reset was not successful.\n"); 492 dprintk( "GPIO reset was not successful.");
296 493
297 if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0) 494 if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
298 dprintk("-E- OUTPUT_MODE could not be resetted.\n"); 495 dprintk( "OUTPUT_MODE could not be reset.");
299 496
300 /* unforce divstr regardless whether i2c enumeration was done or not */ 497 /* unforce divstr regardless whether i2c enumeration was done or not */
301 dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1) ); 498 dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1) );
302 499
500 dib7000p_set_bandwidth(state, 8000);
501
502 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
503 dib7000p_sad_calib(state);
504 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
505
506 // P_iqc_alpha_pha, P_iqc_alpha_amp_dcc_alpha, ...
507 if(state->cfg.tuner_is_baseband)
508 dib7000p_write_word(state, 36,0x0755);
509 else
510 dib7000p_write_word(state, 36,0x1f55);
511
512 dib7000p_write_tab(state, dib7000p_defaults);
513
303 dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); 514 dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
304 515
516
305 return 0; 517 return 0;
306} 518}
307 519
520static void dib7000p_pll_clk_cfg(struct dib7000p_state *state)
521{
522 u16 tmp = 0;
523 tmp = dib7000p_read_word(state, 903);
524 dib7000p_write_word(state, 903, (tmp | 0x1)); //pwr-up pll
525 tmp = dib7000p_read_word(state, 900);
526 dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6)); //use High freq clock
527}
528
308static void dib7000p_restart_agc(struct dib7000p_state *state) 529static void dib7000p_restart_agc(struct dib7000p_state *state)
309{ 530{
310 // P_restart_iqc & P_restart_agc 531 // P_restart_iqc & P_restart_agc
311 dib7000p_write_word(state, 770, 0x0c00); 532 dib7000p_write_word(state, 770, (1 << 11) | (1 << 9));
312 dib7000p_write_word(state, 770, 0x0000); 533 dib7000p_write_word(state, 770, 0x0000);
313} 534}
314 535
315static void dib7000p_update_lna(struct dib7000p_state *state) 536static int dib7000p_update_lna(struct dib7000p_state *state)
316{ 537{
317 int i;
318 u16 dyn_gain; 538 u16 dyn_gain;
319 539
320 // when there is no LNA to program return immediatly 540 // when there is no LNA to program return immediatly
321 if (state->cfg.update_lna == NULL) 541 if (state->cfg.update_lna) {
322 return; 542 // read dyn_gain here (because it is demod-dependent and not fe)
323
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); 543 dyn_gain = dib7000p_read_word(state, 394);
327
328 if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed 544 if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed
329 dib7000p_restart_agc(state); 545 dib7000p_restart_agc(state);
330 msleep(5); 546 return 1;
331 } else 547 }
548 }
549
550 return 0;
551}
552
553static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
554{
555 struct dibx000_agc_config *agc = NULL;
556 int i;
557 if (state->current_band == band && state->current_agc != NULL)
558 return 0;
559 state->current_band = band;
560
561 for (i = 0; i < state->cfg.agc_config_count; i++)
562 if (state->cfg.agc[i].band_caps & band) {
563 agc = &state->cfg.agc[i];
332 break; 564 break;
565 }
566
567 if (agc == NULL) {
568 dprintk( "no valid AGC configuration found for band 0x%02x",band);
569 return -EINVAL;
333 } 570 }
571
572 state->current_agc = agc;
573
574 /* AGC */
575 dib7000p_write_word(state, 75 , agc->setup );
576 dib7000p_write_word(state, 76 , agc->inv_gain );
577 dib7000p_write_word(state, 77 , agc->time_stabiliz );
578 dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);
579
580 // Demod AGC loop configuration
581 dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);
582 dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp);
583
584 /* AGC continued */
585 dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d",
586 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
587
588 if (state->wbd_ref != 0)
589 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref);
590 else
591 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref);
592
593 dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
594
595 dib7000p_write_word(state, 107, agc->agc1_max);
596 dib7000p_write_word(state, 108, agc->agc1_min);
597 dib7000p_write_word(state, 109, agc->agc2_max);
598 dib7000p_write_word(state, 110, agc->agc2_min);
599 dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
600 dib7000p_write_word(state, 112, agc->agc1_pt3);
601 dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
602 dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
603 dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
604 return 0;
334} 605}
335 606
336static void dib7000p_pll_clk_cfg(struct dib7000p_state *state) 607static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
337{ 608{
338 u16 tmp = 0; 609 struct dib7000p_state *state = demod->demodulator_priv;
339 tmp = dib7000p_read_word(state, 903); 610 int ret = -1;
340 dib7000p_write_word(state, 903, (tmp | 0x1)); //pwr-up pll 611 u8 *agc_state = &state->agc_state;
341 tmp = dib7000p_read_word(state, 900); 612 u8 agc_split;
342 dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6)); //use High freq clock 613
614 switch (state->agc_state) {
615 case 0:
616 // set power-up level: interf+analog+AGC
617 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
618 dib7000p_set_adc_state(state, DIBX000_ADC_ON);
619 dib7000p_pll_clk_cfg(state);
620
621 if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0)
622 return -1;
623
624 ret = 7;
625 (*agc_state)++;
626 break;
627
628 case 1:
629 // AGC initialization
630 if (state->cfg.agc_control)
631 state->cfg.agc_control(&state->demod, 1);
632
633 dib7000p_write_word(state, 78, 32768);
634 if (!state->current_agc->perform_agc_softsplit) {
635 /* we are using the wbd - so slow AGC startup */
636 /* force 0 split on WBD and restart AGC */
637 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));
638 (*agc_state)++;
639 ret = 5;
640 } else {
641 /* default AGC startup */
642 (*agc_state) = 4;
643 /* wait AGC rough lock time */
644 ret = 7;
645 }
646
647 dib7000p_restart_agc(state);
648 break;
649
650 case 2: /* fast split search path after 5sec */
651 dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4)); /* freeze AGC loop */
652 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */
653 (*agc_state)++;
654 ret = 14;
655 break;
656
657 case 3: /* split search ended */
658 agc_split = (u8)dib7000p_read_word(state, 396); /* store the split value for the next time */
659 dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */
660
661 dib7000p_write_word(state, 75, state->current_agc->setup); /* std AGC loop */
662 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
663
664 dib7000p_restart_agc(state);
665
666 dprintk( "SPLIT %p: %hd", demod, agc_split);
667
668 (*agc_state)++;
669 ret = 5;
670 break;
671
672 case 4: /* LNA startup */
673 // wait AGC accurate lock time
674 ret = 7;
675
676 if (dib7000p_update_lna(state))
677 // wait only AGC rough lock time
678 ret = 5;
679 else // nothing was done, go to the next state
680 (*agc_state)++;
681 break;
682
683 case 5:
684 if (state->cfg.agc_control)
685 state->cfg.agc_control(&state->demod, 0);
686 (*agc_state)++;
687 break;
688 default:
689 break;
690 }
691 return ret;
343} 692}
344 693
345static void dib7000p_update_timf_freq(struct dib7000p_state *state) 694static void dib7000p_update_timf(struct dib7000p_state *state)
346{ 695{
347 u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428); 696 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); 697 state->timf = timf * 160 / (state->current_bandwidth / 50);
349 dib7000p_write_word(state, 23, (u16) (timf >> 16)); 698 dib7000p_write_word(state, 23, (u16) (timf >> 16));
350 dib7000p_write_word(state, 24, (u16) (timf & 0xffff)); 699 dib7000p_write_word(state, 24, (u16) (timf & 0xffff));
351 dprintk("-D- Updated timf_frequency: %d (default: %d)\n",state->timf, state->cfg.bw->timf); 700 dprintk( "updated timf_frequency: %d (default: %d)",state->timf, state->cfg.bw->timf);
701
352} 702}
353 703
354static void dib7000p_set_channel(struct dib7000p_state *state, struct dibx000_ofdm_channel *ch, u8 seq) 704static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq)
355{ 705{
356 u16 tmp, est[4]; // reg_26, reg_32, reg_33, reg_187, reg_188, reg_189, reg_190, reg_207, reg_208; 706 u16 value, est[4];
707
708 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
357 709
358 /* nfft, guard, qam, alpha */ 710 /* nfft, guard, qam, alpha */
359 dib7000p_write_word(state, 0, (ch->nfft << 7) | (ch->guard << 5) | (ch->nqam << 3) | (ch->vit_alpha)); 711 value = 0;
712 switch (ch->u.ofdm.transmission_mode) {
713 case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
714 case /* 4K MODE */ 255: value |= (2 << 7); break;
715 default:
716 case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
717 }
718 switch (ch->u.ofdm.guard_interval) {
719 case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
720 case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
721 case GUARD_INTERVAL_1_4: value |= (3 << 5); break;
722 default:
723 case GUARD_INTERVAL_1_8: value |= (2 << 5); break;
724 }
725 switch (ch->u.ofdm.constellation) {
726 case QPSK: value |= (0 << 3); break;
727 case QAM_16: value |= (1 << 3); break;
728 default:
729 case QAM_64: value |= (2 << 3); break;
730 }
731 switch (HIERARCHY_1) {
732 case HIERARCHY_2: value |= 2; break;
733 case HIERARCHY_4: value |= 4; break;
734 default:
735 case HIERARCHY_1: value |= 1; break;
736 }
737 dib7000p_write_word(state, 0, value);
360 dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */ 738 dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */
361 739
362 /* P_dintl_native, P_dintlv_inv, P_vit_hrch, P_vit_code_rate, P_vit_select_hp */ 740 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
363 tmp = (ch->intlv_native << 6) | (ch->vit_hrch << 4) | (ch->vit_select_hp & 0x1); 741 value = 0;
364 if (ch->vit_hrch == 0 || ch->vit_select_hp == 1) 742 if (1 != 0)
365 tmp |= (ch->vit_code_rate_hp << 1); 743 value |= (1 << 6);
366 else 744 if (ch->u.ofdm.hierarchy_information == 1)
367 tmp |= (ch->vit_code_rate_lp << 1); 745 value |= (1 << 4);
368 dib7000p_write_word(state, 208, tmp); 746 if (1 == 1)
747 value |= 1;
748 switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
749 case FEC_2_3: value |= (2 << 1); break;
750 case FEC_3_4: value |= (3 << 1); break;
751 case FEC_5_6: value |= (5 << 1); break;
752 case FEC_7_8: value |= (7 << 1); break;
753 default:
754 case FEC_1_2: value |= (1 << 1); break;
755 }
756 dib7000p_write_word(state, 208, value);
757
758 /* offset loop parameters */
759 dib7000p_write_word(state, 26, 0x6680); // timf(6xxx)
760 dib7000p_write_word(state, 32, 0x0003); // pha_off_max(xxx3)
761 dib7000p_write_word(state, 29, 0x1273); // isi
762 dib7000p_write_word(state, 33, 0x0005); // sfreq(xxx5)
369 763
370 /* P_dvsy_sync_wait */ 764 /* P_dvsy_sync_wait */
371 switch (ch->nfft) { 765 switch (ch->u.ofdm.transmission_mode) {
372 case 1: tmp = 256; break; 766 case TRANSMISSION_MODE_8K: value = 256; break;
373 case 2: tmp = 128; break; 767 case /* 4K MODE */ 255: value = 128; break;
374 case 0: 768 case TRANSMISSION_MODE_2K:
375 default: tmp = 64; break; 769 default: value = 64; break;
376 } 770 }
377 tmp *= ((1 << (ch->guard)) * 3 / 2); // add 50% SFN margin 771 switch (ch->u.ofdm.guard_interval) {
378 tmp <<= 4; 772 case GUARD_INTERVAL_1_16: value *= 2; break;
379 773 case GUARD_INTERVAL_1_8: value *= 4; break;
380 /* deactive the possibility of diversity reception if extended interleave */ 774 case GUARD_INTERVAL_1_4: value *= 8; break;
381 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */ 775 default:
382 if (ch->intlv_native || ch->nfft == 1) 776 case GUARD_INTERVAL_1_32: value *= 1; break;
383 tmp |= (1 << 2) | (2 << 0); 777 }
384 dib7000p_write_word(state, 207, tmp); 778 state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO
385 779
386 dib7000p_write_word(state, 26, 0x6680); // timf(6xxx) 780 /* deactive the possibility of diversity reception if extended interleaver */
387 dib7000p_write_word(state, 29, 0x1273); // isi inh1273 on1073 781 state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K;
388 dib7000p_write_word(state, 32, 0x0003); // pha_off_max(xxx3) 782 dib7000p_set_diversity_in(&state->demod, state->div_state);
389 dib7000p_write_word(state, 33, 0x0005); // sfreq(xxx5)
390 783
391 /* channel estimation fine configuration */ 784 /* channel estimation fine configuration */
392 switch (ch->nqam) { 785 switch (ch->u.ofdm.constellation) {
393 case 2: 786 case QAM_64:
394 est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */ 787 est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
395 est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */ 788 est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
396 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */ 789 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
397 est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */ 790 est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
398 break; 791 break;
399 case 1: 792 case QAM_16:
400 est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */ 793 est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
401 est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */ 794 est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
402 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */ 795 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
@@ -409,66 +802,45 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dibx000_of
409 est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */ 802 est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
410 break; 803 break;
411 } 804 }
412 for (tmp = 0; tmp < 4; tmp++) 805 for (value = 0; value < 4; value++)
413 dib7000p_write_word(state, 187 + tmp, est[tmp]); 806 dib7000p_write_word(state, 187 + value, est[value]);
414
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);
419 msleep(7);
420
421 // AGC initialization
422 if (state->cfg.agc_control)
423 state->cfg.agc_control(&state->demod, 1);
424
425 dib7000p_restart_agc(state);
426
427 // wait AGC rough lock time
428 msleep(5);
429
430 dib7000p_update_lna(state);
431
432 // wait AGC accurate lock time
433 msleep(7);
434 if (state->cfg.agc_control)
435 state->cfg.agc_control(&state->demod, 0);
436} 807}
437 808
438static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dibx000_ofdm_channel *ch) 809static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
439{ 810{
440 struct dib7000p_state *state = demod->demodulator_priv; 811 struct dib7000p_state *state = demod->demodulator_priv;
441 struct dibx000_ofdm_channel auto_ch; 812 struct dvb_frontend_parameters schan;
442 u32 value; 813 u32 value, factor;
443 814
444 INIT_OFDM_CHANNEL(&auto_ch); 815 schan = *ch;
445 auto_ch.RF_kHz = ch->RF_kHz; 816 schan.u.ofdm.constellation = QAM_64;
446 auto_ch.Bw = ch->Bw; 817 schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
447 auto_ch.nqam = 2; 818 schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
448 auto_ch.guard = 0; 819 schan.u.ofdm.code_rate_HP = FEC_2_3;
449 auto_ch.nfft = 1; 820 schan.u.ofdm.code_rate_LP = FEC_3_4;
450 auto_ch.vit_alpha = 1; 821 schan.u.ofdm.hierarchy_information = 0;
451 auto_ch.vit_select_hp = 1; 822
452 auto_ch.vit_code_rate_hp = 2; 823 dib7000p_set_channel(state, &schan, 7);
453 auto_ch.vit_code_rate_lp = 3; 824
454 auto_ch.vit_hrch = 0; 825 factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth);
455 auto_ch.intlv_native = 1; 826 if (factor >= 5000)
456 827 factor = 1;
457 dib7000p_set_channel(state, &auto_ch, 7); 828 else
829 factor = 6;
458 830
459 // always use the setting for 8MHz here lock_time for 7,6 MHz are longer 831 // always use the setting for 8MHz here lock_time for 7,6 MHz are longer
460 value = 30 * state->cfg.bw->internal; 832 value = 30 * state->cfg.bw->internal * factor;
461 dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff)); // lock0 wait time 833 dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff)); // lock0 wait time
462 dib7000p_write_word(state, 7, (u16) (value & 0xffff)); // lock0 wait time 834 dib7000p_write_word(state, 7, (u16) (value & 0xffff)); // lock0 wait time
463 value = 100 * state->cfg.bw->internal; 835 value = 100 * state->cfg.bw->internal * factor;
464 dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff)); // lock1 wait time 836 dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff)); // lock1 wait time
465 dib7000p_write_word(state, 9, (u16) (value & 0xffff)); // lock1 wait time 837 dib7000p_write_word(state, 9, (u16) (value & 0xffff)); // lock1 wait time
466 value = 500 * state->cfg.bw->internal; 838 value = 500 * state->cfg.bw->internal * factor;
467 dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time 839 dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
468 dib7000p_write_word(state, 11, (u16) (value & 0xffff)); // lock2 wait time 840 dib7000p_write_word(state, 11, (u16) (value & 0xffff)); // lock2 wait time
469 841
470 value = dib7000p_read_word(state, 0); 842 value = dib7000p_read_word(state, 0);
471 dib7000p_write_word(state, 0, (1 << 9) | value); 843 dib7000p_write_word(state, 0, (u16) ((1 << 9) | value));
472 dib7000p_read_word(state, 1284); 844 dib7000p_read_word(state, 1284);
473 dib7000p_write_word(state, 0, (u16) value); 845 dib7000p_write_word(state, 0, (u16) value);
474 846
@@ -489,7 +861,95 @@ static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod)
489 return 0; // still pending 861 return 0; // still pending
490} 862}
491 863
492static int dib7000p_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel *ch) 864static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw)
865{
866 static s16 notch[]={16143, 14402, 12238, 9713, 6902, 3888, 759, -2392};
867 static u8 sine [] ={0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
868 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
869 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
870 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
871 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
872 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
873 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
874 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
875 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
876 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
877 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
878 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
879 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
880 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
881 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
882 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
883 255, 255, 255, 255, 255, 255};
884
885 u32 xtal = state->cfg.bw->xtal_hz / 1000;
886 int f_rel = ( (rf_khz + xtal/2) / xtal) * xtal - rf_khz;
887 int k;
888 int coef_re[8],coef_im[8];
889 int bw_khz = bw;
890 u32 pha;
891
892 dprintk( "relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal);
893
894
895 if (f_rel < -bw_khz/2 || f_rel > bw_khz/2)
896 return;
897
898 bw_khz /= 100;
899
900 dib7000p_write_word(state, 142 ,0x0610);
901
902 for (k = 0; k < 8; k++) {
903 pha = ((f_rel * (k+1) * 112 * 80/bw_khz) /1000) & 0x3ff;
904
905 if (pha==0) {
906 coef_re[k] = 256;
907 coef_im[k] = 0;
908 } else if(pha < 256) {
909 coef_re[k] = sine[256-(pha&0xff)];
910 coef_im[k] = sine[pha&0xff];
911 } else if (pha == 256) {
912 coef_re[k] = 0;
913 coef_im[k] = 256;
914 } else if (pha < 512) {
915 coef_re[k] = -sine[pha&0xff];
916 coef_im[k] = sine[256 - (pha&0xff)];
917 } else if (pha == 512) {
918 coef_re[k] = -256;
919 coef_im[k] = 0;
920 } else if (pha < 768) {
921 coef_re[k] = -sine[256-(pha&0xff)];
922 coef_im[k] = -sine[pha&0xff];
923 } else if (pha == 768) {
924 coef_re[k] = 0;
925 coef_im[k] = -256;
926 } else {
927 coef_re[k] = sine[pha&0xff];
928 coef_im[k] = -sine[256 - (pha&0xff)];
929 }
930
931 coef_re[k] *= notch[k];
932 coef_re[k] += (1<<14);
933 if (coef_re[k] >= (1<<24))
934 coef_re[k] = (1<<24) - 1;
935 coef_re[k] /= (1<<15);
936
937 coef_im[k] *= notch[k];
938 coef_im[k] += (1<<14);
939 if (coef_im[k] >= (1<<24))
940 coef_im[k] = (1<<24)-1;
941 coef_im[k] /= (1<<15);
942
943 dprintk( "PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]);
944
945 dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
946 dib7000p_write_word(state, 144, coef_im[k] & 0x3ff);
947 dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
948 }
949 dib7000p_write_word(state,143 ,0);
950}
951
952static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
493{ 953{
494 struct dib7000p_state *state = demod->demodulator_priv; 954 struct dib7000p_state *state = demod->demodulator_priv;
495 u16 tmp = 0; 955 u16 tmp = 0;
@@ -505,7 +965,15 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel
505 msleep(45); 965 msleep(45);
506 966
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 */ 967 /* 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)); 968 tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
969 if (state->sfn_workaround_active) {
970 dprintk( "SFN workaround is active");
971 tmp |= (1 << 9);
972 dib7000p_write_word(state, 166, 0x4000); // P_pha3_force_pha_shift
973 } else {
974 dib7000p_write_word(state, 166, 0x0000); // P_pha3_force_pha_shift
975 }
976 dib7000p_write_word(state, 29, tmp);
509 977
510 // never achieved a lock with that bandwidth so far - wait for osc-freq to update 978 // never achieved a lock with that bandwidth so far - wait for osc-freq to update
511 if (state->timf == 0) 979 if (state->timf == 0)
@@ -515,28 +983,31 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel
515 983
516 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */ 984 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
517 tmp = (6 << 8) | 0x80; 985 tmp = (6 << 8) | 0x80;
518 switch (ch->nfft) { 986 switch (ch->u.ofdm.transmission_mode) {
519 case 0: tmp |= (7 << 12); break; 987 case TRANSMISSION_MODE_2K: tmp |= (7 << 12); break;
520 case 1: tmp |= (9 << 12); break; 988 case /* 4K MODE */ 255: tmp |= (8 << 12); break;
521 case 2: tmp |= (8 << 12); break; 989 default:
990 case TRANSMISSION_MODE_8K: tmp |= (9 << 12); break;
522 } 991 }
523 dib7000p_write_word(state, 26, tmp); /* timf_a(6xxx) */ 992 dib7000p_write_word(state, 26, tmp); /* timf_a(6xxx) */
524 993
525 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */ 994 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
526 tmp = (0 << 4); 995 tmp = (0 << 4);
527 switch (ch->nfft) { 996 switch (ch->u.ofdm.transmission_mode) {
528 case 0: tmp |= 0x6; break; 997 case TRANSMISSION_MODE_2K: tmp |= 0x6; break;
529 case 1: tmp |= 0x8; break; 998 case /* 4K MODE */ 255: tmp |= 0x7; break;
530 case 2: tmp |= 0x7; break; 999 default:
1000 case TRANSMISSION_MODE_8K: tmp |= 0x8; break;
531 } 1001 }
532 dib7000p_write_word(state, 32, tmp); 1002 dib7000p_write_word(state, 32, tmp);
533 1003
534 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */ 1004 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
535 tmp = (0 << 4); 1005 tmp = (0 << 4);
536 switch (ch->nfft) { 1006 switch (ch->u.ofdm.transmission_mode) {
537 case 0: tmp |= 0x6; break; 1007 case TRANSMISSION_MODE_2K: tmp |= 0x6; break;
538 case 1: tmp |= 0x8; break; 1008 case /* 4K MODE */ 255: tmp |= 0x7; break;
539 case 2: tmp |= 0x7; break; 1009 default:
1010 case TRANSMISSION_MODE_8K: tmp |= 0x8; break;
540 } 1011 }
541 dib7000p_write_word(state, 33, tmp); 1012 dib7000p_write_word(state, 33, tmp);
542 1013
@@ -552,131 +1023,21 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel
552 1023
553 // we achieved a lock - it's time to update the osc freq 1024 // we achieved a lock - it's time to update the osc freq
554 if ((tmp >> 6) & 0x1) 1025 if ((tmp >> 6) & 0x1)
555 dib7000p_update_timf_freq(state); 1026 dib7000p_update_timf(state);
556 1027
1028 if (state->cfg.spur_protect)
1029 dib7000p_spur_protect(state, ch->frequency/1000, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1030
1031 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
557 return 0; 1032 return 0;
558} 1033}
559 1034
560static int dib7000p_init(struct dvb_frontend *demod) 1035static int dib7000p_wakeup(struct dvb_frontend *demod)
561{ 1036{
562 struct dibx000_agc_config *agc;
563 struct dib7000p_state *state = demod->demodulator_priv; 1037 struct dib7000p_state *state = demod->demodulator_priv;
564 int ret = 0;
565
566 // Demodulator default configuration
567 agc = state->cfg.agc;
568
569 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL); 1038 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
570 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON); 1039 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
571 1040 return 0;
572 /* AGC */
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);
577
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);
581
582 /* AGC continued */
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);
585
586 if (state->wbd_ref != 0)
587 ret |= dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref);
588 else
589 ret |= dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref);
590
591 ret |= dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8) );
592
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);
602
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);
612
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);
615
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);
628 // P_adp_noise_cnt=
629 ret |= dib7000p_write_word(state, 188,0x00a4);
630 // P_adp_regul_ext
631 ret |= dib7000p_write_word(state, 189,0x00a4);
632 // P_adp_noise_ext
633 ret |= dib7000p_write_word(state, 190,0x7ff0);
634 // P_adp_fil
635 ret |= dib7000p_write_word(state, 191,0x3ccc);
636
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);
640
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);
644 else
645 ret |= dib7000p_write_word(state, 36,0x1f55);
646
647 // auto search configuration
648 ret |= dib7000p_write_word(state, 2 ,0x0004);
649 ret |= dib7000p_write_word(state, 3 ,0x1000);
650
651 /* Equal Lock */
652 ret |= dib7000p_write_word(state, 4 ,0x0814);
653
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);
666
667 // P_clk_cfg1
668 ret |= dib7000p_write_word(state, 901, 0x0006);
669
670 // P_divclksel=3 P_divbitsel=1
671 ret |= dib7000p_write_word(state, 902, (3 << 10) | (1 << 6));
672
673 // Tuner IO bank: max drive (14mA) + divout pads max drive
674 ret |= dib7000p_write_word(state, 905, 0x2c8e);
675
676 ret |= dib7000p_set_bandwidth(&state->demod, BANDWIDTH_8_MHZ);
677 dib7000p_sad_calib(state);
678
679 return ret;
680} 1041}
681 1042
682static int dib7000p_sleep(struct dvb_frontend *demod) 1043static int dib7000p_sleep(struct dvb_frontend *demod)
@@ -688,16 +1049,16 @@ static int dib7000p_sleep(struct dvb_frontend *demod)
688static int dib7000p_identify(struct dib7000p_state *st) 1049static int dib7000p_identify(struct dib7000p_state *st)
689{ 1050{
690 u16 value; 1051 u16 value;
691 dprintk("-I- DiB7000PC: checking demod on I2C address: %d (%x)\n", 1052 dprintk( "checking demod on I2C address: %d (%x)",
692 st->i2c_addr, st->i2c_addr); 1053 st->i2c_addr, st->i2c_addr);
693 1054
694 if ((value = dib7000p_read_word(st, 768)) != 0x01b3) { 1055 if ((value = dib7000p_read_word(st, 768)) != 0x01b3) {
695 dprintk("-E- DiB7000PC: wrong Vendor ID (read=0x%x)\n",value); 1056 dprintk( "wrong Vendor ID (read=0x%x)",value);
696 return -EREMOTEIO; 1057 return -EREMOTEIO;
697 } 1058 }
698 1059
699 if ((value = dib7000p_read_word(st, 769)) != 0x4000) { 1060 if ((value = dib7000p_read_word(st, 769)) != 0x4000) {
700 dprintk("-E- DiB7000PC: wrong Device ID (%x)\n",value); 1061 dprintk( "wrong Device ID (%x)",value);
701 return -EREMOTEIO; 1062 return -EREMOTEIO;
702 } 1063 }
703 1064
@@ -767,41 +1128,48 @@ static int dib7000p_set_frontend(struct dvb_frontend* fe,
767 struct dvb_frontend_parameters *fep) 1128 struct dvb_frontend_parameters *fep)
768{ 1129{
769 struct dib7000p_state *state = fe->demodulator_priv; 1130 struct dib7000p_state *state = fe->demodulator_priv;
770 struct dibx000_ofdm_channel ch; 1131 int time;
771
772 INIT_OFDM_CHANNEL(&ch);
773 FEP2DIB(fep,&ch);
774 1132
775 state->current_bandwidth = fep->u.ofdm.bandwidth; 1133 state->current_bandwidth = fep->u.ofdm.bandwidth;
776 dib7000p_set_bandwidth(fe, fep->u.ofdm.bandwidth); 1134 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth));
1135
1136 /* maybe the parameter has been changed */
1137 state->sfn_workaround_active = buggy_sfn_workaround;
777 1138
778 if (fe->ops.tuner_ops.set_params) 1139 if (fe->ops.tuner_ops.set_params)
779 fe->ops.tuner_ops.set_params(fe, fep); 1140 fe->ops.tuner_ops.set_params(fe, fep);
780 1141
1142 /* start up the AGC */
1143 state->agc_state = 0;
1144 do {
1145 time = dib7000p_agc_startup(fe, fep);
1146 if (time != -1)
1147 msleep(time);
1148 } while (time != -1);
1149
781 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO || 1150 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
782 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || 1151 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ||
783 fep->u.ofdm.constellation == QAM_AUTO || 1152 fep->u.ofdm.constellation == QAM_AUTO ||
784 fep->u.ofdm.code_rate_HP == FEC_AUTO) { 1153 fep->u.ofdm.code_rate_HP == FEC_AUTO) {
785 int i = 800, found; 1154 int i = 800, found;
786 1155
787 dib7000p_autosearch_start(fe, &ch); 1156 dib7000p_autosearch_start(fe, fep);
788 do { 1157 do {
789 msleep(1); 1158 msleep(1);
790 found = dib7000p_autosearch_is_irq(fe); 1159 found = dib7000p_autosearch_is_irq(fe);
791 } while (found == 0 && i--); 1160 } while (found == 0 && i--);
792 1161
793 dprintk("autosearch returns: %d\n",found); 1162 dprintk("autosearch returns: %d",found);
794 if (found == 0 || found == 1) 1163 if (found == 0 || found == 1)
795 return 0; // no channel found 1164 return 0; // no channel found
796 1165
797 dib7000p_get_frontend(fe, fep); 1166 dib7000p_get_frontend(fe, fep);
798 FEP2DIB(fep, &ch);
799 } 1167 }
800 1168
801 /* make this a config parameter */ 1169 /* make this a config parameter */
802 dib7000p_set_output_mode(state, OUTMODE_MPEG2_FIFO); 1170 dib7000p_set_output_mode(state, OUTMODE_MPEG2_FIFO);
803 1171
804 return dib7000p_tune(fe, &ch); 1172 return dib7000p_tune(fe, fep);
805} 1173}
806 1174
807static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t *stat) 1175static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t *stat)
@@ -879,7 +1247,7 @@ int dib7000pc_detection(struct i2c_adapter *i2c_adap)
879 1247
880 if (i2c_transfer(i2c_adap, msg, 2) == 2) 1248 if (i2c_transfer(i2c_adap, msg, 2) == 2)
881 if (rx[0] == 0x01 && rx[1] == 0xb3) { 1249 if (rx[0] == 0x01 && rx[1] == 0xb3) {
882 dprintk("-D- DiB7000PC detected\n"); 1250 dprintk("-D- DiB7000PC detected");
883 return 1; 1251 return 1;
884 } 1252 }
885 1253
@@ -887,11 +1255,11 @@ int dib7000pc_detection(struct i2c_adapter *i2c_adap)
887 1255
888 if (i2c_transfer(i2c_adap, msg, 2) == 2) 1256 if (i2c_transfer(i2c_adap, msg, 2) == 2)
889 if (rx[0] == 0x01 && rx[1] == 0xb3) { 1257 if (rx[0] == 0x01 && rx[1] == 0xb3) {
890 dprintk("-D- DiB7000PC detected\n"); 1258 dprintk("-D- DiB7000PC detected");
891 return 1; 1259 return 1;
892 } 1260 }
893 1261
894 dprintk("-D- DiB7000PC not detected\n"); 1262 dprintk("-D- DiB7000PC not detected");
895 return 0; 1263 return 0;
896} 1264}
897EXPORT_SYMBOL(dib7000pc_detection); 1265EXPORT_SYMBOL(dib7000pc_detection);
@@ -929,7 +1297,7 @@ int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defau
929 /* set new i2c address and force divstart */ 1297 /* set new i2c address and force divstart */
930 dib7000p_write_word(&st, 1285, (new_addr << 2) | 0x2); 1298 dib7000p_write_word(&st, 1285, (new_addr << 2) | 0x2);
931 1299
932 dprintk("IC %d initialized (to i2c_address 0x%x)\n", k, new_addr); 1300 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
933 } 1301 }
934 1302
935 for (k = 0; k < no_of_demods; k++) { 1303 for (k = 0; k < no_of_demods; k++) {
@@ -1000,7 +1368,7 @@ static struct dvb_frontend_ops dib7000p_ops = {
1000 1368
1001 .release = dib7000p_release, 1369 .release = dib7000p_release,
1002 1370
1003 .init = dib7000p_init, 1371 .init = dib7000p_wakeup,
1004 .sleep = dib7000p_sleep, 1372 .sleep = dib7000p_sleep,
1005 1373
1006 .set_frontend = dib7000p_set_frontend, 1374 .set_frontend = dib7000p_set_frontend,