aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/dib7000m.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/dib7000m.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/dib7000m.c')
-rw-r--r--drivers/media/dvb/frontends/dib7000m.c723
1 files changed, 466 insertions, 257 deletions
diff --git a/drivers/media/dvb/frontends/dib7000m.c b/drivers/media/dvb/frontends/dib7000m.c
index f64546c6aeb5..608156a691de 100644
--- a/drivers/media/dvb/frontends/dib7000m.c
+++ b/drivers/media/dvb/frontends/dib7000m.c
@@ -2,7 +2,7 @@
2 * Linux-DVB Driver for DiBcom's DiB7000M and 2 * Linux-DVB Driver for DiBcom's DiB7000M and
3 * first generation DiB7000P-demodulator-family. 3 * first generation DiB7000P-demodulator-family.
4 * 4 *
5 * Copyright (C) 2005-6 DiBcom (http://www.dibcom.fr/) 5 * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as 8 * modify it under the terms of the GNU General Public License as
@@ -19,7 +19,7 @@ static int debug;
19module_param(debug, int, 0644); 19module_param(debug, int, 0644);
20MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); 20MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
21 21
22#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000M:"); printk(args); } } while (0) 22#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000M: "); printk(args); printk("\n"); } } while (0)
23 23
24struct dib7000m_state { 24struct dib7000m_state {
25 struct dvb_frontend demod; 25 struct dvb_frontend demod;
@@ -39,8 +39,16 @@ struct dib7000m_state {
39 fe_bandwidth_t current_bandwidth; 39 fe_bandwidth_t current_bandwidth;
40 struct dibx000_agc_config *current_agc; 40 struct dibx000_agc_config *current_agc;
41 u32 timf; 41 u32 timf;
42 u32 timf_default;
43 u32 internal_clk;
44
45 uint8_t div_force_off : 1;
46 uint8_t div_state : 1;
47 uint16_t div_sync_wait;
42 48
43 u16 revision; 49 u16 revision;
50
51 u8 agc_state;
44}; 52};
45 53
46enum dib7000m_power_mode { 54enum dib7000m_power_mode {
@@ -63,7 +71,7 @@ static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg)
63 }; 71 };
64 72
65 if (i2c_transfer(state->i2c_adap, msg, 2) != 2) 73 if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
66 dprintk("i2c read error on %d\n",reg); 74 dprintk("i2c read error on %d",reg);
67 75
68 return (rb[0] << 8) | rb[1]; 76 return (rb[0] << 8) | rb[1];
69} 77}
@@ -79,6 +87,25 @@ static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val)
79 }; 87 };
80 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; 88 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
81} 89}
90static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf)
91{
92 u16 l = 0, r, *n;
93 n = buf;
94 l = *n++;
95 while (l) {
96 r = *n++;
97
98 if (state->reg_offs && (r >= 112 && r <= 331)) // compensate for 7000MC
99 r++;
100
101 do {
102 dib7000m_write_word(state, r, *n++);
103 r++;
104 } while (--l);
105 l = *n++;
106 }
107}
108
82static int dib7000m_set_output_mode(struct dib7000m_state *state, int mode) 109static int dib7000m_set_output_mode(struct dib7000m_state *state, int mode)
83{ 110{
84 int ret = 0; 111 int ret = 0;
@@ -89,8 +116,7 @@ static int dib7000m_set_output_mode(struct dib7000m_state *state, int mode)
89 fifo_threshold = 1792; 116 fifo_threshold = 1792;
90 smo_mode = (dib7000m_read_word(state, 294 + state->reg_offs) & 0x0010) | (1 << 1); 117 smo_mode = (dib7000m_read_word(state, 294 + state->reg_offs) & 0x0010) | (1 << 1);
91 118
92 dprintk("-I- Setting output mode for demod %p to %d\n", 119 dprintk( "setting output mode for demod %p to %d", &state->demod, mode);
93 &state->demod, mode);
94 120
95 switch (mode) { 121 switch (mode) {
96 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock 122 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
@@ -117,7 +143,7 @@ static int dib7000m_set_output_mode(struct dib7000m_state *state, int mode)
117 outreg = 0; 143 outreg = 0;
118 break; 144 break;
119 default: 145 default:
120 dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod); 146 dprintk( "Unhandled output_mode passed to be set for demod %p",&state->demod);
121 break; 147 break;
122 } 148 }
123 149
@@ -129,13 +155,20 @@ static int dib7000m_set_output_mode(struct dib7000m_state *state, int mode)
129 ret |= dib7000m_write_word(state, 1795, outreg); 155 ret |= dib7000m_write_word(state, 1795, outreg);
130 ret |= dib7000m_write_word(state, 1805, sram); 156 ret |= dib7000m_write_word(state, 1805, sram);
131 157
158 if (state->revision == 0x4003) {
159 u16 clk_cfg1 = dib7000m_read_word(state, 909) & 0xfffd;
160 if (mode == OUTMODE_DIVERSITY)
161 clk_cfg1 |= (1 << 1); // P_O_CLK_en
162 dib7000m_write_word(state, 909, clk_cfg1);
163 }
132 return ret; 164 return ret;
133} 165}
134 166
135static int dib7000m_set_power_mode(struct dib7000m_state *state, enum dib7000m_power_mode mode) 167static void dib7000m_set_power_mode(struct dib7000m_state *state, enum dib7000m_power_mode mode)
136{ 168{
137 /* by default everything is going to be powered off */ 169 /* by default everything is going to be powered off */
138 u16 reg_903 = 0xffff, reg_904 = 0xffff, reg_905 = 0xffff, reg_906 = 0x3fff; 170 u16 reg_903 = 0xffff, reg_904 = 0xffff, reg_905 = 0xffff, reg_906 = 0x3fff;
171 u8 offset = 0;
139 172
140 /* now, depending on the requested mode, we power on */ 173 /* now, depending on the requested mode, we power on */
141 switch (mode) { 174 switch (mode) {
@@ -170,16 +203,17 @@ static int dib7000m_set_power_mode(struct dib7000m_state *state, enum dib7000m_p
170 if (!state->cfg.mobile_mode) 203 if (!state->cfg.mobile_mode)
171 reg_904 |= (1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) | (1 << 1); 204 reg_904 |= (1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) | (1 << 1);
172 205
173 /* P_sdio_select_clk = 0 on MC */ 206 /* P_sdio_select_clk = 0 on MC and after*/
174 if (state->revision != 0x4000) 207 if (state->revision != 0x4000)
175 reg_906 <<= 1; 208 reg_906 <<= 1;
176 209
177 dib7000m_write_word(state, 903, reg_903); 210 if (state->revision == 0x4003)
178 dib7000m_write_word(state, 904, reg_904); 211 offset = 1;
179 dib7000m_write_word(state, 905, reg_905);
180 dib7000m_write_word(state, 906, reg_906);
181 212
182 return 0; 213 dib7000m_write_word(state, 903 + offset, reg_903);
214 dib7000m_write_word(state, 904 + offset, reg_904);
215 dib7000m_write_word(state, 905 + offset, reg_905);
216 dib7000m_write_word(state, 906 + offset, reg_906);
183} 217}
184 218
185static int dib7000m_set_adc_state(struct dib7000m_state *state, enum dibx000_adc_states no) 219static int dib7000m_set_adc_state(struct dib7000m_state *state, enum dibx000_adc_states no)
@@ -230,34 +264,55 @@ static int dib7000m_set_adc_state(struct dib7000m_state *state, enum dibx000_adc
230 break; 264 break;
231 } 265 }
232 266
233// dprintk("-D- 913: %x, 914: %x\n", reg_913, reg_914); 267// dprintk( "913: %x, 914: %x", reg_913, reg_914);
234
235 ret |= dib7000m_write_word(state, 913, reg_913); 268 ret |= dib7000m_write_word(state, 913, reg_913);
236 ret |= dib7000m_write_word(state, 914, reg_914); 269 ret |= dib7000m_write_word(state, 914, reg_914);
237 270
238 return ret; 271 return ret;
239} 272}
240 273
241static int dib7000m_set_bandwidth(struct dvb_frontend *demod, u8 bw_idx) 274static int dib7000m_set_bandwidth(struct dib7000m_state *state, u32 bw)
242{ 275{
243 struct dib7000m_state *state = demod->demodulator_priv;
244 u32 timf; 276 u32 timf;
245 277
246 // store the current bandwidth for later use 278 // store the current bandwidth for later use
247 state->current_bandwidth = bw_idx; 279 state->current_bandwidth = bw;
248 280
249 if (state->timf == 0) { 281 if (state->timf == 0) {
250 dprintk("-D- Using default timf\n"); 282 dprintk( "using default timf");
251 timf = state->cfg.bw->timf; 283 timf = state->timf_default;
252 } else { 284 } else {
253 dprintk("-D- Using updated timf\n"); 285 dprintk( "using updated timf");
254 timf = state->timf; 286 timf = state->timf;
255 } 287 }
256 288
257 timf = timf * (BW_INDEX_TO_KHZ(bw_idx) / 100) / 80; 289 timf = timf * (bw / 50) / 160;
258 290
259 dib7000m_write_word(state, 23, (timf >> 16) & 0xffff); 291 dib7000m_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
260 dib7000m_write_word(state, 24, (timf ) & 0xffff); 292 dib7000m_write_word(state, 24, (u16) ((timf ) & 0xffff));
293
294 return 0;
295}
296
297static int dib7000m_set_diversity_in(struct dvb_frontend *demod, int onoff)
298{
299 struct dib7000m_state *state = demod->demodulator_priv;
300
301 if (state->div_force_off) {
302 dprintk( "diversity combination deactivated - forced by COFDM parameters");
303 onoff = 0;
304 }
305 state->div_state = (uint8_t)onoff;
306
307 if (onoff) {
308 dib7000m_write_word(state, 263 + state->reg_offs, 6);
309 dib7000m_write_word(state, 264 + state->reg_offs, 6);
310 dib7000m_write_word(state, 266 + state->reg_offs, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
311 } else {
312 dib7000m_write_word(state, 263 + state->reg_offs, 1);
313 dib7000m_write_word(state, 264 + state->reg_offs, 0);
314 dib7000m_write_word(state, 266 + state->reg_offs, 0);
315 }
261 316
262 return 0; 317 return 0;
263} 318}
@@ -266,7 +321,7 @@ static int dib7000m_sad_calib(struct dib7000m_state *state)
266{ 321{
267 322
268/* internal */ 323/* internal */
269// dib7000m_write_word(state, 928, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is written in set_bandwidth 324// dib7000m_write_word(state, 928, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth
270 dib7000m_write_word(state, 929, (0 << 1) | (0 << 0)); 325 dib7000m_write_word(state, 929, (0 << 1) | (0 << 0));
271 dib7000m_write_word(state, 930, 776); // 0.625*3.3 / 4096 326 dib7000m_write_word(state, 930, 776); // 0.625*3.3 / 4096
272 327
@@ -281,10 +336,10 @@ static int dib7000m_sad_calib(struct dib7000m_state *state)
281 336
282static void dib7000m_reset_pll_common(struct dib7000m_state *state, const struct dibx000_bandwidth_config *bw) 337static void dib7000m_reset_pll_common(struct dib7000m_state *state, const struct dibx000_bandwidth_config *bw)
283{ 338{
284 dib7000m_write_word(state, 18, ((bw->internal*1000) >> 16) & 0xffff); 339 dib7000m_write_word(state, 18, (u16) (((bw->internal*1000) >> 16) & 0xffff));
285 dib7000m_write_word(state, 19, (bw->internal*1000) & 0xffff); 340 dib7000m_write_word(state, 19, (u16) ( (bw->internal*1000) & 0xffff));
286 dib7000m_write_word(state, 21, (bw->ifreq >> 16) & 0xffff); 341 dib7000m_write_word(state, 21, (u16) ( (bw->ifreq >> 16) & 0xffff));
287 dib7000m_write_word(state, 22, bw->ifreq & 0xffff); 342 dib7000m_write_word(state, 22, (u16) ( bw->ifreq & 0xffff));
288 343
289 dib7000m_write_word(state, 928, bw->sad_cfg); 344 dib7000m_write_word(state, 928, bw->sad_cfg);
290} 345}
@@ -325,15 +380,19 @@ static void dib7000m_reset_pll(struct dib7000m_state *state)
325static void dib7000mc_reset_pll(struct dib7000m_state *state) 380static void dib7000mc_reset_pll(struct dib7000m_state *state)
326{ 381{
327 const struct dibx000_bandwidth_config *bw = state->cfg.bw; 382 const struct dibx000_bandwidth_config *bw = state->cfg.bw;
383 u16 clk_cfg1;
328 384
329 // clk_cfg0 385 // clk_cfg0
330 dib7000m_write_word(state, 907, (bw->pll_prediv << 8) | (bw->pll_ratio << 0)); 386 dib7000m_write_word(state, 907, (bw->pll_prediv << 8) | (bw->pll_ratio << 0));
331 387
332 // clk_cfg1 388 // clk_cfg1
333 //dib7000m_write_word(state, 908, (1 << 14) | (3 << 12) |(0 << 11) | 389 //dib7000m_write_word(state, 908, (1 << 14) | (3 << 12) |(0 << 11) |
334 dib7000m_write_word(state, 908, (0 << 14) | (3 << 12) |(0 << 11) | 390 clk_cfg1 = (0 << 14) | (3 << 12) |(0 << 11) |
335 (bw->IO_CLK_en_core << 10) | (bw->bypclk_div << 5) | (bw->enable_refdiv << 4) | 391 (bw->IO_CLK_en_core << 10) | (bw->bypclk_div << 5) | (bw->enable_refdiv << 4) |
336 (bw->pll_bypass << 3) | (bw->pll_range << 1) | (bw->pll_reset << 0)); 392 (1 << 3) | (bw->pll_range << 1) | (bw->pll_reset << 0);
393 dib7000m_write_word(state, 908, clk_cfg1);
394 clk_cfg1 = (clk_cfg1 & 0xfff7) | (bw->pll_bypass << 3);
395 dib7000m_write_word(state, 908, clk_cfg1);
337 396
338 // smpl_cfg 397 // smpl_cfg
339 dib7000m_write_word(state, 910, (1 << 12) | (2 << 10) | (bw->modulo << 8) | (bw->ADClkSrc << 7)); 398 dib7000m_write_word(state, 910, (1 << 12) | (2 << 10) | (bw->modulo << 8) | (bw->ADClkSrc << 7));
@@ -344,9 +403,6 @@ static void dib7000mc_reset_pll(struct dib7000m_state *state)
344static int dib7000m_reset_gpio(struct dib7000m_state *st) 403static int dib7000m_reset_gpio(struct dib7000m_state *st)
345{ 404{
346 /* reset the GPIOs */ 405 /* reset the GPIOs */
347 dprintk("-D- gpio dir: %x: gpio val: %x, gpio pwm pos: %x\n",
348 st->cfg.gpio_dir, st->cfg.gpio_val,st->cfg.gpio_pwm_pos);
349
350 dib7000m_write_word(st, 773, st->cfg.gpio_dir); 406 dib7000m_write_word(st, 773, st->cfg.gpio_dir);
351 dib7000m_write_word(st, 774, st->cfg.gpio_val); 407 dib7000m_write_word(st, 774, st->cfg.gpio_val);
352 408
@@ -358,6 +414,107 @@ static int dib7000m_reset_gpio(struct dib7000m_state *st)
358 return 0; 414 return 0;
359} 415}
360 416
417static u16 dib7000m_defaults_common[] =
418
419{
420 // auto search configuration
421 3, 2,
422 0x0004,
423 0x1000,
424 0x0814,
425
426 12, 6,
427 0x001b,
428 0x7740,
429 0x005b,
430 0x8d80,
431 0x01c9,
432 0xc380,
433 0x0000,
434 0x0080,
435 0x0000,
436 0x0090,
437 0x0001,
438 0xd4c0,
439
440 1, 26,
441 0x6680, // P_corm_thres Lock algorithms configuration
442
443 1, 170,
444 0x0410, // P_palf_alpha_regul, P_palf_filter_freeze, P_palf_filter_on
445
446 8, 173,
447 0,
448 0,
449 0,
450 0,
451 0,
452 0,
453 0,
454 0,
455
456 1, 182,
457 8192, // P_fft_nb_to_cut
458
459 2, 195,
460 0x0ccd, // P_pha3_thres
461 0, // P_cti_use_cpe, P_cti_use_prog
462
463 1, 205,
464 0x200f, // P_cspu_regul, P_cspu_win_cut
465
466 5, 214,
467 0x023d, // P_adp_regul_cnt
468 0x00a4, // P_adp_noise_cnt
469 0x00a4, // P_adp_regul_ext
470 0x7ff0, // P_adp_noise_ext
471 0x3ccc, // P_adp_fil
472
473 1, 226,
474 0, // P_2d_byp_ti_num
475
476 1, 255,
477 0x800, // P_equal_thres_wgn
478
479 1, 263,
480 0x0001,
481
482 1, 281,
483 0x0010, // P_fec_*
484
485 1, 294,
486 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
487
488 0
489};
490
491static u16 dib7000m_defaults[] =
492
493{
494 /* set ADC level to -16 */
495 11, 76,
496 (1 << 13) - 825 - 117,
497 (1 << 13) - 837 - 117,
498 (1 << 13) - 811 - 117,
499 (1 << 13) - 766 - 117,
500 (1 << 13) - 737 - 117,
501 (1 << 13) - 693 - 117,
502 (1 << 13) - 648 - 117,
503 (1 << 13) - 619 - 117,
504 (1 << 13) - 575 - 117,
505 (1 << 13) - 531 - 117,
506 (1 << 13) - 501 - 117,
507
508 // Tuner IO bank: max drive (14mA)
509 1, 912,
510 0x2c8a,
511
512 1, 1817,
513 1,
514
515 0,
516};
517
361static int dib7000m_demod_reset(struct dib7000m_state *state) 518static int dib7000m_demod_reset(struct dib7000m_state *state)
362{ 519{
363 dib7000m_set_power_mode(state, DIB7000M_POWER_ALL); 520 dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
@@ -382,22 +539,47 @@ static int dib7000m_demod_reset(struct dib7000m_state *state)
382 dib7000mc_reset_pll(state); 539 dib7000mc_reset_pll(state);
383 540
384 if (dib7000m_reset_gpio(state) != 0) 541 if (dib7000m_reset_gpio(state) != 0)
385 dprintk("-E- GPIO reset was not successful.\n"); 542 dprintk( "GPIO reset was not successful.");
386 543
387 if (dib7000m_set_output_mode(state, OUTMODE_HIGH_Z) != 0) 544 if (dib7000m_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
388 dprintk("-E- OUTPUT_MODE could not be resetted.\n"); 545 dprintk( "OUTPUT_MODE could not be reset.");
389 546
390 /* unforce divstr regardless whether i2c enumeration was done or not */ 547 /* unforce divstr regardless whether i2c enumeration was done or not */
391 dib7000m_write_word(state, 1794, dib7000m_read_word(state, 1794) & ~(1 << 1) ); 548 dib7000m_write_word(state, 1794, dib7000m_read_word(state, 1794) & ~(1 << 1) );
392 549
393 dib7000m_set_bandwidth(&state->demod, BANDWIDTH_8_MHZ); 550 dib7000m_set_bandwidth(state, 8000);
394 551
395 dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON); 552 dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON);
396 dib7000m_sad_calib(state); 553 dib7000m_sad_calib(state);
397 dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_OFF); 554 dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
398 555
556 if (state->cfg.dvbt_mode)
557 dib7000m_write_word(state, 1796, 0x0); // select DVB-T output
558
559 if (state->cfg.mobile_mode)
560 dib7000m_write_word(state, 261 + state->reg_offs, 2);
561 else
562 dib7000m_write_word(state, 224 + state->reg_offs, 1);
563
564 // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
565 if(state->cfg.tuner_is_baseband)
566 dib7000m_write_word(state, 36, 0x0755);
567 else
568 dib7000m_write_word(state, 36, 0x1f55);
569
570 // P_divclksel=3 P_divbitsel=1
571 if (state->revision == 0x4000)
572 dib7000m_write_word(state, 909, (3 << 10) | (1 << 6));
573 else
574 dib7000m_write_word(state, 909, (3 << 4) | 1);
575
576 dib7000m_write_tab(state, dib7000m_defaults_common);
577 dib7000m_write_tab(state, dib7000m_defaults);
578
399 dib7000m_set_power_mode(state, DIB7000M_POWER_INTERFACE_ONLY); 579 dib7000m_set_power_mode(state, DIB7000M_POWER_INTERFACE_ONLY);
400 580
581 state->internal_clk = state->cfg.bw->internal;
582
401 return 0; 583 return 0;
402} 584}
403 585
@@ -427,7 +609,7 @@ static int dib7000m_agc_soft_split(struct dib7000m_state *state)
427 (agc - state->current_agc->split.min_thres) / 609 (agc - state->current_agc->split.min_thres) /
428 (state->current_agc->split.max_thres - state->current_agc->split.min_thres); 610 (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
429 611
430 dprintk("AGC split_offset: %d\n",split_offset); 612 dprintk( "AGC split_offset: %d",split_offset);
431 613
432 // P_agc_force_split and P_agc_split_offset 614 // P_agc_force_split and P_agc_split_offset
433 return dib7000m_write_word(state, 103, (dib7000m_read_word(state, 103) & 0xff00) | split_offset); 615 return dib7000m_write_word(state, 103, (dib7000m_read_word(state, 103) & 0xff00) | split_offset);
@@ -435,35 +617,26 @@ static int dib7000m_agc_soft_split(struct dib7000m_state *state)
435 617
436static int dib7000m_update_lna(struct dib7000m_state *state) 618static int dib7000m_update_lna(struct dib7000m_state *state)
437{ 619{
438 int i;
439 u16 dyn_gain; 620 u16 dyn_gain;
440 621
441 // when there is no LNA to program return immediatly 622 if (state->cfg.update_lna) {
442 if (state->cfg.update_lna == NULL)
443 return 0;
444
445 msleep(60);
446 for (i = 0; i < 20; i++) {
447 // read dyn_gain here (because it is demod-dependent and not tuner) 623 // read dyn_gain here (because it is demod-dependent and not tuner)
448 dyn_gain = dib7000m_read_word(state, 390); 624 dyn_gain = dib7000m_read_word(state, 390);
449 625
450 dprintk("agc global: %d\n", dyn_gain);
451
452 if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed 626 if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed
453 dib7000m_restart_agc(state); 627 dib7000m_restart_agc(state);
454 msleep(60); 628 return 1;
455 } else 629 }
456 break;
457 } 630 }
458 return 0; 631 return 0;
459} 632}
460 633
461static void dib7000m_set_agc_config(struct dib7000m_state *state, u8 band) 634static int dib7000m_set_agc_config(struct dib7000m_state *state, u8 band)
462{ 635{
463 struct dibx000_agc_config *agc = NULL; 636 struct dibx000_agc_config *agc = NULL;
464 int i; 637 int i;
465 if (state->current_band == band) 638 if (state->current_band == band && state->current_agc != NULL)
466 return; 639 return 0;
467 state->current_band = band; 640 state->current_band = band;
468 641
469 for (i = 0; i < state->cfg.agc_config_count; i++) 642 for (i = 0; i < state->cfg.agc_config_count; i++)
@@ -473,8 +646,8 @@ static void dib7000m_set_agc_config(struct dib7000m_state *state, u8 band)
473 } 646 }
474 647
475 if (agc == NULL) { 648 if (agc == NULL) {
476 dprintk("-E- No valid AGC configuration found for band 0x%02x\n",band); 649 dprintk( "no valid AGC configuration found for band 0x%02x",band);
477 return; 650 return -EINVAL;
478 } 651 }
479 652
480 state->current_agc = agc; 653 state->current_agc = agc;
@@ -489,7 +662,7 @@ static void dib7000m_set_agc_config(struct dib7000m_state *state, u8 band)
489 dib7000m_write_word(state, 98, (agc->alpha_mant << 5) | agc->alpha_exp); 662 dib7000m_write_word(state, 98, (agc->alpha_mant << 5) | agc->alpha_exp);
490 dib7000m_write_word(state, 99, (agc->beta_mant << 6) | agc->beta_exp); 663 dib7000m_write_word(state, 99, (agc->beta_mant << 6) | agc->beta_exp);
491 664
492 dprintk("-D- WBD: ref: %d, sel: %d, active: %d, alpha: %d\n", 665 dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d",
493 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel); 666 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
494 667
495 /* AGC continued */ 668 /* AGC continued */
@@ -510,7 +683,7 @@ static void dib7000m_set_agc_config(struct dib7000m_state *state, u8 band)
510 683
511 if (state->revision > 0x4000) { // settings for the MC 684 if (state->revision > 0x4000) { // settings for the MC
512 dib7000m_write_word(state, 71, agc->agc1_pt3); 685 dib7000m_write_word(state, 71, agc->agc1_pt3);
513// dprintk("-D- 929: %x %d %d\n", 686// dprintk( "929: %x %d %d",
514// (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2), agc->wbd_inv, agc->wbd_sel); 687// (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2), agc->wbd_inv, agc->wbd_sel);
515 dib7000m_write_word(state, 929, (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2)); 688 dib7000m_write_word(state, 929, (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2));
516 } else { 689 } else {
@@ -519,33 +692,160 @@ static void dib7000m_set_agc_config(struct dib7000m_state *state, u8 band)
519 for (i = 0; i < 9; i++) 692 for (i = 0; i < 9; i++)
520 dib7000m_write_word(state, 88 + i, b[i]); 693 dib7000m_write_word(state, 88 + i, b[i]);
521 } 694 }
695 return 0;
522} 696}
523 697
524static void dib7000m_update_timf_freq(struct dib7000m_state *state) 698static void dib7000m_update_timf(struct dib7000m_state *state)
525{ 699{
526 u32 timf = (dib7000m_read_word(state, 436) << 16) | dib7000m_read_word(state, 437); 700 u32 timf = (dib7000m_read_word(state, 436) << 16) | dib7000m_read_word(state, 437);
527 state->timf = timf * 80 / (BW_INDEX_TO_KHZ(state->current_bandwidth) / 100); 701 state->timf = timf * 160 / (state->current_bandwidth / 50);
528 dib7000m_write_word(state, 23, (u16) (timf >> 16)); 702 dib7000m_write_word(state, 23, (u16) (timf >> 16));
529 dib7000m_write_word(state, 24, (u16) (timf & 0xffff)); 703 dib7000m_write_word(state, 24, (u16) (timf & 0xffff));
530 dprintk("-D- Updated timf_frequency: %d (default: %d)\n",state->timf, state->cfg.bw->timf); 704 dprintk( "updated timf_frequency: %d (default: %d)",state->timf, state->timf_default);
531} 705}
532 706
533static void dib7000m_set_channel(struct dib7000m_state *state, struct dibx000_ofdm_channel *ch, u8 seq) 707static int dib7000m_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
708{
709 struct dib7000m_state *state = demod->demodulator_priv;
710 u16 cfg_72 = dib7000m_read_word(state, 72);
711 int ret = -1;
712 u8 *agc_state = &state->agc_state;
713 u8 agc_split;
714
715 switch (state->agc_state) {
716 case 0:
717 // set power-up level: interf+analog+AGC
718 dib7000m_set_power_mode(state, DIB7000M_POWER_INTERF_ANALOG_AGC);
719 dib7000m_set_adc_state(state, DIBX000_ADC_ON);
720
721 if (dib7000m_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0)
722 return -1;
723
724 ret = 7; /* ADC power up */
725 (*agc_state)++;
726 break;
727
728 case 1:
729 /* AGC initialization */
730 if (state->cfg.agc_control)
731 state->cfg.agc_control(&state->demod, 1);
732
733 dib7000m_write_word(state, 75, 32768);
734 if (!state->current_agc->perform_agc_softsplit) {
735 /* we are using the wbd - so slow AGC startup */
736 dib7000m_write_word(state, 103, 1 << 8); /* force 0 split on WBD and restart AGC */
737 (*agc_state)++;
738 ret = 5;
739 } else {
740 /* default AGC startup */
741 (*agc_state) = 4;
742 /* wait AGC rough lock time */
743 ret = 7;
744 }
745
746 dib7000m_restart_agc(state);
747 break;
748
749 case 2: /* fast split search path after 5sec */
750 dib7000m_write_word(state, 72, cfg_72 | (1 << 4)); /* freeze AGC loop */
751 dib7000m_write_word(state, 103, 2 << 9); /* fast split search 0.25kHz */
752 (*agc_state)++;
753 ret = 14;
754 break;
755
756 case 3: /* split search ended */
757 agc_split = (uint8_t)dib7000m_read_word(state, 392); /* store the split value for the next time */
758 dib7000m_write_word(state, 75, dib7000m_read_word(state, 390)); /* set AGC gain start value */
759
760 dib7000m_write_word(state, 72, cfg_72 & ~(1 << 4)); /* std AGC loop */
761 dib7000m_write_word(state, 103, (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
762
763 dib7000m_restart_agc(state);
764
765 dprintk( "SPLIT %p: %hd", demod, agc_split);
766
767 (*agc_state)++;
768 ret = 5;
769 break;
770
771 case 4: /* LNA startup */
772 /* wait AGC accurate lock time */
773 ret = 7;
774
775 if (dib7000m_update_lna(state))
776 // wait only AGC rough lock time
777 ret = 5;
778 else
779 (*agc_state)++;
780 break;
781
782 case 5:
783 dib7000m_agc_soft_split(state);
784
785 if (state->cfg.agc_control)
786 state->cfg.agc_control(&state->demod, 0);
787
788 (*agc_state)++;
789 break;
790
791 default:
792 break;
793 }
794 return ret;
795}
796
797static void dib7000m_set_channel(struct dib7000m_state *state, struct dvb_frontend_parameters *ch, u8 seq)
534{ 798{
535 u16 value, est[4]; 799 u16 value, est[4];
536 800
537 dib7000m_set_agc_config(state, BAND_OF_FREQUENCY(ch->RF_kHz)); 801 dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
538 802
539 /* nfft, guard, qam, alpha */ 803 /* nfft, guard, qam, alpha */
540 dib7000m_write_word(state, 0, (ch->nfft << 7) | (ch->guard << 5) | (ch->nqam << 3) | (ch->vit_alpha)); 804 value = 0;
805 switch (ch->u.ofdm.transmission_mode) {
806 case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
807 case /* 4K MODE */ 255: value |= (2 << 7); break;
808 default:
809 case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
810 }
811 switch (ch->u.ofdm.guard_interval) {
812 case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
813 case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
814 case GUARD_INTERVAL_1_4: value |= (3 << 5); break;
815 default:
816 case GUARD_INTERVAL_1_8: value |= (2 << 5); break;
817 }
818 switch (ch->u.ofdm.constellation) {
819 case QPSK: value |= (0 << 3); break;
820 case QAM_16: value |= (1 << 3); break;
821 default:
822 case QAM_64: value |= (2 << 3); break;
823 }
824 switch (HIERARCHY_1) {
825 case HIERARCHY_2: value |= 2; break;
826 case HIERARCHY_4: value |= 4; break;
827 default:
828 case HIERARCHY_1: value |= 1; break;
829 }
830 dib7000m_write_word(state, 0, value);
541 dib7000m_write_word(state, 5, (seq << 4)); 831 dib7000m_write_word(state, 5, (seq << 4));
542 832
543 /* P_dintl_native, P_dintlv_inv, P_vit_hrch, P_vit_code_rate, P_vit_select_hp */ 833 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
544 value = (ch->intlv_native << 6) | (ch->vit_hrch << 4) | (ch->vit_select_hp & 0x1); 834 value = 0;
545 if (ch->vit_hrch == 0 || ch->vit_select_hp == 1) 835 if (1 != 0)
546 value |= (ch->vit_code_rate_hp << 1); 836 value |= (1 << 6);
547 else 837 if (ch->u.ofdm.hierarchy_information == 1)
548 value |= (ch->vit_code_rate_lp << 1); 838 value |= (1 << 4);
839 if (1 == 1)
840 value |= 1;
841 switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
842 case FEC_2_3: value |= (2 << 1); break;
843 case FEC_3_4: value |= (3 << 1); break;
844 case FEC_5_6: value |= (5 << 1); break;
845 case FEC_7_8: value |= (7 << 1); break;
846 default:
847 case FEC_1_2: value |= (1 << 1); break;
848 }
549 dib7000m_write_word(state, 267 + state->reg_offs, value); 849 dib7000m_write_word(state, 267 + state->reg_offs, value);
550 850
551 /* offset loop parameters */ 851 /* offset loop parameters */
@@ -563,32 +863,38 @@ static void dib7000m_set_channel(struct dib7000m_state *state, struct dibx000_of
563 dib7000m_write_word(state, 33, (0 << 4) | 0x5); 863 dib7000m_write_word(state, 33, (0 << 4) | 0x5);
564 864
565 /* P_dvsy_sync_wait */ 865 /* P_dvsy_sync_wait */
566 switch (ch->nfft) { 866 switch (ch->u.ofdm.transmission_mode) {
567 case 1: value = 256; break; 867 case TRANSMISSION_MODE_8K: value = 256; break;
568 case 2: value = 128; break; 868 case /* 4K MODE */ 255: value = 128; break;
569 case 0: 869 case TRANSMISSION_MODE_2K:
570 default: value = 64; break; 870 default: value = 64; break;
571 } 871 }
572 value *= ((1 << (ch->guard)) * 3 / 2); // add 50% SFN margin 872 switch (ch->u.ofdm.guard_interval) {
573 value <<= 4; 873 case GUARD_INTERVAL_1_16: value *= 2; break;
874 case GUARD_INTERVAL_1_8: value *= 4; break;
875 case GUARD_INTERVAL_1_4: value *= 8; break;
876 default:
877 case GUARD_INTERVAL_1_32: value *= 1; break;
878 }
879 state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO
574 880
575 /* deactive the possibility of diversity reception if extended interleave - not for 7000MC */ 881 /* deactive the possibility of diversity reception if extended interleave - not for 7000MC */
576 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */ 882 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
577 if (ch->intlv_native || state->revision > 0x4000) 883 if (1 == 1 || state->revision > 0x4000)
578 value |= (1 << 2) | (2 << 0); 884 state->div_force_off = 0;
579 else 885 else
580 value |= 0; 886 state->div_force_off = 1;
581 dib7000m_write_word(state, 266 + state->reg_offs, value); 887 dib7000m_set_diversity_in(&state->demod, state->div_state);
582 888
583 /* channel estimation fine configuration */ 889 /* channel estimation fine configuration */
584 switch (ch->nqam) { 890 switch (ch->u.ofdm.constellation) {
585 case 2: 891 case QAM_64:
586 est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */ 892 est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
587 est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */ 893 est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
588 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */ 894 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
589 est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */ 895 est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
590 break; 896 break;
591 case 1: 897 case QAM_16:
592 est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */ 898 est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
593 est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */ 899 est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
594 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */ 900 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
@@ -604,70 +910,48 @@ static void dib7000m_set_channel(struct dib7000m_state *state, struct dibx000_of
604 for (value = 0; value < 4; value++) 910 for (value = 0; value < 4; value++)
605 dib7000m_write_word(state, 214 + value + state->reg_offs, est[value]); 911 dib7000m_write_word(state, 214 + value + state->reg_offs, est[value]);
606 912
607 // set power-up level: interf+analog+AGC
608 dib7000m_set_power_mode(state, DIB7000M_POWER_INTERF_ANALOG_AGC);
609 dib7000m_set_adc_state(state, DIBX000_ADC_ON);
610
611 msleep(7);
612
613 //AGC initialization
614 if (state->cfg.agc_control)
615 state->cfg.agc_control(&state->demod, 1);
616
617 dib7000m_restart_agc(state);
618
619 // wait AGC rough lock time
620 msleep(5);
621
622 dib7000m_update_lna(state);
623 dib7000m_agc_soft_split(state);
624
625 // wait AGC accurate lock time
626 msleep(7);
627
628 if (state->cfg.agc_control)
629 state->cfg.agc_control(&state->demod, 0);
630
631 // set power-up level: autosearch 913 // set power-up level: autosearch
632 dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD); 914 dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD);
633} 915}
634 916
635static int dib7000m_autosearch_start(struct dvb_frontend *demod, struct dibx000_ofdm_channel *ch) 917static int dib7000m_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
636{ 918{
637 struct dib7000m_state *state = demod->demodulator_priv; 919 struct dib7000m_state *state = demod->demodulator_priv;
638 struct dibx000_ofdm_channel auto_ch; 920 struct dvb_frontend_parameters schan;
639 int ret = 0; 921 int ret = 0;
640 u32 value; 922 u32 value, factor;
641 923
642 INIT_OFDM_CHANNEL(&auto_ch); 924 schan = *ch;
643 auto_ch.RF_kHz = ch->RF_kHz; 925
644 auto_ch.Bw = ch->Bw; 926 schan.u.ofdm.constellation = QAM_64;
645 auto_ch.nqam = 2; 927 schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
646 auto_ch.guard = 0; 928 schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
647 auto_ch.nfft = 1; 929 schan.u.ofdm.code_rate_HP = FEC_2_3;
648 auto_ch.vit_alpha = 1; 930 schan.u.ofdm.code_rate_LP = FEC_3_4;
649 auto_ch.vit_select_hp = 1; 931 schan.u.ofdm.hierarchy_information = 0;
650 auto_ch.vit_code_rate_hp = 2; 932
651 auto_ch.vit_code_rate_lp = 3; 933 dib7000m_set_channel(state, &schan, 7);
652 auto_ch.vit_hrch = 0; 934
653 auto_ch.intlv_native = 1; 935 factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth);
654 936 if (factor >= 5000)
655 dib7000m_set_channel(state, &auto_ch, 7); 937 factor = 1;
938 else
939 factor = 6;
656 940
657 // always use the setting for 8MHz here lock_time for 7,6 MHz are longer 941 // always use the setting for 8MHz here lock_time for 7,6 MHz are longer
658 value = 30 * state->cfg.bw->internal; 942 value = 30 * state->internal_clk * factor;
659 ret |= dib7000m_write_word(state, 6, (u16) ((value >> 16) & 0xffff)); // lock0 wait time 943 ret |= dib7000m_write_word(state, 6, (u16) ((value >> 16) & 0xffff)); // lock0 wait time
660 ret |= dib7000m_write_word(state, 7, (u16) (value & 0xffff)); // lock0 wait time 944 ret |= dib7000m_write_word(state, 7, (u16) (value & 0xffff)); // lock0 wait time
661 value = 100 * state->cfg.bw->internal; 945 value = 100 * state->internal_clk * factor;
662 ret |= dib7000m_write_word(state, 8, (u16) ((value >> 16) & 0xffff)); // lock1 wait time 946 ret |= dib7000m_write_word(state, 8, (u16) ((value >> 16) & 0xffff)); // lock1 wait time
663 ret |= dib7000m_write_word(state, 9, (u16) (value & 0xffff)); // lock1 wait time 947 ret |= dib7000m_write_word(state, 9, (u16) (value & 0xffff)); // lock1 wait time
664 value = 500 * state->cfg.bw->internal; 948 value = 500 * state->internal_clk * factor;
665 ret |= dib7000m_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time 949 ret |= dib7000m_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
666 ret |= dib7000m_write_word(state, 11, (u16) (value & 0xffff)); // lock2 wait time 950 ret |= dib7000m_write_word(state, 11, (u16) (value & 0xffff)); // lock2 wait time
667 951
668 // start search 952 // start search
669 value = dib7000m_read_word(state, 0); 953 value = dib7000m_read_word(state, 0);
670 ret |= dib7000m_write_word(state, 0, value | (1 << 9)); 954 ret |= dib7000m_write_word(state, 0, (u16) (value | (1 << 9)));
671 955
672 /* clear n_irq_pending */ 956 /* clear n_irq_pending */
673 if (state->revision == 0x4000) 957 if (state->revision == 0x4000)
@@ -685,12 +969,12 @@ static int dib7000m_autosearch_irq(struct dib7000m_state *state, u16 reg)
685 u16 irq_pending = dib7000m_read_word(state, reg); 969 u16 irq_pending = dib7000m_read_word(state, reg);
686 970
687 if (irq_pending & 0x1) { // failed 971 if (irq_pending & 0x1) { // failed
688 dprintk("#\n"); 972 dprintk( "autosearch failed");
689 return 1; 973 return 1;
690 } 974 }
691 975
692 if (irq_pending & 0x2) { // succeeded 976 if (irq_pending & 0x2) { // succeeded
693 dprintk("!\n"); 977 dprintk( "autosearch succeeded");
694 return 2; 978 return 2;
695 } 979 }
696 return 0; // still pending 980 return 0; // still pending
@@ -705,7 +989,7 @@ static int dib7000m_autosearch_is_irq(struct dvb_frontend *demod)
705 return dib7000m_autosearch_irq(state, 537); 989 return dib7000m_autosearch_irq(state, 537);
706} 990}
707 991
708static int dib7000m_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel *ch) 992static int dib7000m_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
709{ 993{
710 struct dib7000m_state *state = demod->demodulator_priv; 994 struct dib7000m_state *state = demod->demodulator_priv;
711 int ret = 0; 995 int ret = 0;
@@ -722,182 +1006,103 @@ static int dib7000m_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel
722 ret |= dib7000m_write_word(state, 898, 0x0000); 1006 ret |= dib7000m_write_word(state, 898, 0x0000);
723 msleep(45); 1007 msleep(45);
724 1008
725 ret |= dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD); 1009 dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD);
726 /* 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 */ 1010 /* 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 */
727 ret |= dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3)); 1011 ret |= dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3));
728 1012
729 // never achieved a lock with that bandwidth so far - wait for timfreq to update 1013 // never achieved a lock before - wait for timfreq to update
730 if (state->timf == 0) 1014 if (state->timf == 0)
731 msleep(200); 1015 msleep(200);
732 1016
733 //dump_reg(state); 1017 //dump_reg(state);
734 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */ 1018 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
735 value = (6 << 8) | 0x80; 1019 value = (6 << 8) | 0x80;
736 switch (ch->nfft) { 1020 switch (ch->u.ofdm.transmission_mode) {
737 case 0: value |= (7 << 12); break; 1021 case TRANSMISSION_MODE_2K: value |= (7 << 12); break;
738 case 1: value |= (9 << 12); break; 1022 case /* 4K MODE */ 255: value |= (8 << 12); break;
739 case 2: value |= (8 << 12); break; 1023 default:
1024 case TRANSMISSION_MODE_8K: value |= (9 << 12); break;
740 } 1025 }
741 ret |= dib7000m_write_word(state, 26, value); 1026 ret |= dib7000m_write_word(state, 26, value);
742 1027
743 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */ 1028 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
744 value = (0 << 4); 1029 value = (0 << 4);
745 switch (ch->nfft) { 1030 switch (ch->u.ofdm.transmission_mode) {
746 case 0: value |= 0x6; break; 1031 case TRANSMISSION_MODE_2K: value |= 0x6; break;
747 case 1: value |= 0x8; break; 1032 case /* 4K MODE */ 255: value |= 0x7; break;
748 case 2: value |= 0x7; break; 1033 default:
1034 case TRANSMISSION_MODE_8K: value |= 0x8; break;
749 } 1035 }
750 ret |= dib7000m_write_word(state, 32, value); 1036 ret |= dib7000m_write_word(state, 32, value);
751 1037
752 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */ 1038 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
753 value = (0 << 4); 1039 value = (0 << 4);
754 switch (ch->nfft) { 1040 switch (ch->u.ofdm.transmission_mode) {
755 case 0: value |= 0x6; break; 1041 case TRANSMISSION_MODE_2K: value |= 0x6; break;
756 case 1: value |= 0x8; break; 1042 case /* 4K MODE */ 255: value |= 0x7; break;
757 case 2: value |= 0x7; break; 1043 default:
1044 case TRANSMISSION_MODE_8K: value |= 0x8; break;
758 } 1045 }
759 ret |= dib7000m_write_word(state, 33, value); 1046 ret |= dib7000m_write_word(state, 33, value);
760 1047
761 // we achieved a lock - it's time to update the osc freq 1048 // we achieved a lock - it's time to update the timf freq
762 if ((dib7000m_read_word(state, 535) >> 6) & 0x1) 1049 if ((dib7000m_read_word(state, 535) >> 6) & 0x1)
763 dib7000m_update_timf_freq(state); 1050 dib7000m_update_timf(state);
764 1051
1052 dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
765 return ret; 1053 return ret;
766} 1054}
767 1055
768static int dib7000m_init(struct dvb_frontend *demod) 1056static int dib7000m_wakeup(struct dvb_frontend *demod)
769{ 1057{
770 struct dib7000m_state *state = demod->demodulator_priv; 1058 struct dib7000m_state *state = demod->demodulator_priv;
771 int ret = 0;
772 u8 o = state->reg_offs;
773 1059
774 dib7000m_set_power_mode(state, DIB7000M_POWER_ALL); 1060 dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
775 1061
776 if (dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0) 1062 if (dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
777 dprintk("-E- could not start Slow ADC\n"); 1063 dprintk( "could not start Slow ADC");
778
779 if (state->cfg.dvbt_mode)
780 dib7000m_write_word(state, 1796, 0x0); // select DVB-T output
781
782 if (state->cfg.mobile_mode)
783 ret |= dib7000m_write_word(state, 261 + o, 2);
784 else
785 ret |= dib7000m_write_word(state, 224 + o, 1);
786
787 ret |= dib7000m_write_word(state, 173 + o, 0);
788 ret |= dib7000m_write_word(state, 174 + o, 0);
789 ret |= dib7000m_write_word(state, 175 + o, 0);
790 ret |= dib7000m_write_word(state, 176 + o, 0);
791 ret |= dib7000m_write_word(state, 177 + o, 0);
792 ret |= dib7000m_write_word(state, 178 + o, 0);
793 ret |= dib7000m_write_word(state, 179 + o, 0);
794 ret |= dib7000m_write_word(state, 180 + o, 0);
795
796 // P_corm_thres Lock algorithms configuration
797 ret |= dib7000m_write_word(state, 26, 0x6680);
798
799 // P_palf_alpha_regul, P_palf_filter_freeze, P_palf_filter_on
800 ret |= dib7000m_write_word(state, 170 + o, 0x0410);
801 // P_fft_nb_to_cut
802 ret |= dib7000m_write_word(state, 182 + o, 8192);
803 // P_pha3_thres
804 ret |= dib7000m_write_word(state, 195 + o, 0x0ccd);
805 // P_cti_use_cpe, P_cti_use_prog
806 ret |= dib7000m_write_word(state, 196 + o, 0);
807 // P_cspu_regul, P_cspu_win_cut
808 ret |= dib7000m_write_word(state, 205 + o, 0x200f);
809 // P_adp_regul_cnt
810 ret |= dib7000m_write_word(state, 214 + o, 0x023d);
811 // P_adp_noise_cnt
812 ret |= dib7000m_write_word(state, 215 + o, 0x00a4);
813 // P_adp_regul_ext
814 ret |= dib7000m_write_word(state, 216 + o, 0x00a4);
815 // P_adp_noise_ext
816 ret |= dib7000m_write_word(state, 217 + o, 0x7ff0);
817 // P_adp_fil
818 ret |= dib7000m_write_word(state, 218 + o, 0x3ccc);
819
820 // P_2d_byp_ti_num
821 ret |= dib7000m_write_word(state, 226 + o, 0);
822
823 // P_fec_*
824 ret |= dib7000m_write_word(state, 281 + o, 0x0010);
825 // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
826 ret |= dib7000m_write_word(state, 294 + o,0x0062);
827 1064
828 // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ... 1065 return 0;
829 if(state->cfg.tuner_is_baseband)
830 ret |= dib7000m_write_word(state, 36, 0x0755);
831 else
832 ret |= dib7000m_write_word(state, 36, 0x1f55);
833
834 // auto search configuration
835 ret |= dib7000m_write_word(state, 2, 0x0004);
836 ret |= dib7000m_write_word(state, 3, 0x1000);
837 ret |= dib7000m_write_word(state, 4, 0x0814);
838 ret |= dib7000m_write_word(state, 6, 0x001b);
839 ret |= dib7000m_write_word(state, 7, 0x7740);
840 ret |= dib7000m_write_word(state, 8, 0x005b);
841 ret |= dib7000m_write_word(state, 9, 0x8d80);
842 ret |= dib7000m_write_word(state, 10, 0x01c9);
843 ret |= dib7000m_write_word(state, 11, 0xc380);
844 ret |= dib7000m_write_word(state, 12, 0x0000);
845 ret |= dib7000m_write_word(state, 13, 0x0080);
846 ret |= dib7000m_write_word(state, 14, 0x0000);
847 ret |= dib7000m_write_word(state, 15, 0x0090);
848 ret |= dib7000m_write_word(state, 16, 0x0001);
849 ret |= dib7000m_write_word(state, 17, 0xd4c0);
850 ret |= dib7000m_write_word(state, 263 + o,0x0001);
851
852 // P_divclksel=3 P_divbitsel=1
853 if (state->revision == 0x4000)
854 dib7000m_write_word(state, 909, (3 << 10) | (1 << 6));
855 else
856 dib7000m_write_word(state, 909, (3 << 4) | 1);
857
858 // Tuner IO bank: max drive (14mA)
859 ret |= dib7000m_write_word(state, 912 ,0x2c8a);
860
861 ret |= dib7000m_write_word(state, 1817, 1);
862
863 return ret;
864} 1066}
865 1067
866static int dib7000m_sleep(struct dvb_frontend *demod) 1068static int dib7000m_sleep(struct dvb_frontend *demod)
867{ 1069{
868 struct dib7000m_state *st = demod->demodulator_priv; 1070 struct dib7000m_state *st = demod->demodulator_priv;
869 dib7000m_set_output_mode(st, OUTMODE_HIGH_Z); 1071 dib7000m_set_output_mode(st, OUTMODE_HIGH_Z);
870 return dib7000m_set_power_mode(st, DIB7000M_POWER_INTERFACE_ONLY) | 1072 dib7000m_set_power_mode(st, DIB7000M_POWER_INTERFACE_ONLY);
871 dib7000m_set_adc_state(st, DIBX000_SLOW_ADC_OFF) | 1073 return dib7000m_set_adc_state(st, DIBX000_SLOW_ADC_OFF) |
872 dib7000m_set_adc_state(st, DIBX000_ADC_OFF); 1074 dib7000m_set_adc_state(st, DIBX000_ADC_OFF);
873} 1075}
874 1076
875static int dib7000m_identify(struct dib7000m_state *state) 1077static int dib7000m_identify(struct dib7000m_state *state)
876{ 1078{
877 u16 value; 1079 u16 value;
1080
878 if ((value = dib7000m_read_word(state, 896)) != 0x01b3) { 1081 if ((value = dib7000m_read_word(state, 896)) != 0x01b3) {
879 dprintk("-E- DiB7000M: wrong Vendor ID (read=0x%x)\n",value); 1082 dprintk( "wrong Vendor ID (0x%x)",value);
880 return -EREMOTEIO; 1083 return -EREMOTEIO;
881 } 1084 }
882 1085
883 state->revision = dib7000m_read_word(state, 897); 1086 state->revision = dib7000m_read_word(state, 897);
884 if (state->revision != 0x4000 && 1087 if (state->revision != 0x4000 &&
885 state->revision != 0x4001 && 1088 state->revision != 0x4001 &&
886 state->revision != 0x4002) { 1089 state->revision != 0x4002 &&
887 dprintk("-E- DiB7000M: wrong Device ID (%x)\n",value); 1090 state->revision != 0x4003) {
1091 dprintk( "wrong Device ID (0x%x)",value);
888 return -EREMOTEIO; 1092 return -EREMOTEIO;
889 } 1093 }
890 1094
891 /* protect this driver to be used with 7000PC */ 1095 /* protect this driver to be used with 7000PC */
892 if (state->revision == 0x4000 && dib7000m_read_word(state, 769) == 0x4000) { 1096 if (state->revision == 0x4000 && dib7000m_read_word(state, 769) == 0x4000) {
893 dprintk("-E- DiB7000M: this driver does not work with DiB7000PC\n"); 1097 dprintk( "this driver does not work with DiB7000PC");
894 return -EREMOTEIO; 1098 return -EREMOTEIO;
895 } 1099 }
896 1100
897 switch (state->revision) { 1101 switch (state->revision) {
898 case 0x4000: dprintk("-I- found DiB7000MA/PA/MB/PB\n"); break; 1102 case 0x4000: dprintk( "found DiB7000MA/PA/MB/PB"); break;
899 case 0x4001: state->reg_offs = 1; dprintk("-I- found DiB7000HC\n"); break; 1103 case 0x4001: state->reg_offs = 1; dprintk( "found DiB7000HC"); break;
900 case 0x4002: state->reg_offs = 1; dprintk("-I- found DiB7000MC\n"); break; 1104 case 0x4002: state->reg_offs = 1; dprintk( "found DiB7000MC"); break;
1105 case 0x4003: state->reg_offs = 1; dprintk( "found DiB9000"); break;
901 } 1106 }
902 1107
903 return 0; 1108 return 0;
@@ -966,41 +1171,45 @@ static int dib7000m_set_frontend(struct dvb_frontend* fe,
966 struct dvb_frontend_parameters *fep) 1171 struct dvb_frontend_parameters *fep)
967{ 1172{
968 struct dib7000m_state *state = fe->demodulator_priv; 1173 struct dib7000m_state *state = fe->demodulator_priv;
969 struct dibx000_ofdm_channel ch; 1174 int time;
970
971 INIT_OFDM_CHANNEL(&ch);
972 FEP2DIB(fep,&ch);
973 1175
974 state->current_bandwidth = fep->u.ofdm.bandwidth; 1176 state->current_bandwidth = fep->u.ofdm.bandwidth;
975 dib7000m_set_bandwidth(fe, fep->u.ofdm.bandwidth); 1177 dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth));
976 1178
977 if (fe->ops.tuner_ops.set_params) 1179 if (fe->ops.tuner_ops.set_params)
978 fe->ops.tuner_ops.set_params(fe, fep); 1180 fe->ops.tuner_ops.set_params(fe, fep);
979 1181
1182 /* start up the AGC */
1183 state->agc_state = 0;
1184 do {
1185 time = dib7000m_agc_startup(fe, fep);
1186 if (time != -1)
1187 msleep(time);
1188 } while (time != -1);
1189
980 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO || 1190 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
981 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || 1191 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ||
982 fep->u.ofdm.constellation == QAM_AUTO || 1192 fep->u.ofdm.constellation == QAM_AUTO ||
983 fep->u.ofdm.code_rate_HP == FEC_AUTO) { 1193 fep->u.ofdm.code_rate_HP == FEC_AUTO) {
984 int i = 800, found; 1194 int i = 800, found;
985 1195
986 dib7000m_autosearch_start(fe, &ch); 1196 dib7000m_autosearch_start(fe, fep);
987 do { 1197 do {
988 msleep(1); 1198 msleep(1);
989 found = dib7000m_autosearch_is_irq(fe); 1199 found = dib7000m_autosearch_is_irq(fe);
990 } while (found == 0 && i--); 1200 } while (found == 0 && i--);
991 1201
992 dprintk("autosearch returns: %d\n",found); 1202 dprintk("autosearch returns: %d",found);
993 if (found == 0 || found == 1) 1203 if (found == 0 || found == 1)
994 return 0; // no channel found 1204 return 0; // no channel found
995 1205
996 dib7000m_get_frontend(fe, fep); 1206 dib7000m_get_frontend(fe, fep);
997 FEP2DIB(fep, &ch);
998 } 1207 }
999 1208
1000 /* make this a config parameter */ 1209 /* make this a config parameter */
1001 dib7000m_set_output_mode(state, OUTMODE_MPEG2_FIFO); 1210 dib7000m_set_output_mode(state, OUTMODE_MPEG2_FIFO);
1002 1211
1003 return dib7000m_tune(fe, &ch); 1212 return dib7000m_tune(fe, fep);
1004} 1213}
1005 1214
1006static int dib7000m_read_status(struct dvb_frontend *fe, fe_status_t *stat) 1215static int dib7000m_read_status(struct dvb_frontend *fe, fe_status_t *stat)
@@ -1087,7 +1296,7 @@ int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defau
1087 if (dib7000m_identify(&st) != 0) { 1296 if (dib7000m_identify(&st) != 0) {
1088 st.i2c_addr = default_addr; 1297 st.i2c_addr = default_addr;
1089 if (dib7000m_identify(&st) != 0) { 1298 if (dib7000m_identify(&st) != 0) {
1090 dprintk("DiB7000M #%d: not identified\n", k); 1299 dprintk("DiB7000M #%d: not identified", k);
1091 return -EIO; 1300 return -EIO;
1092 } 1301 }
1093 } 1302 }
@@ -1100,7 +1309,7 @@ int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defau
1100 /* set new i2c address and force divstart */ 1309 /* set new i2c address and force divstart */
1101 dib7000m_write_word(&st, 1794, (new_addr << 2) | 0x2); 1310 dib7000m_write_word(&st, 1794, (new_addr << 2) | 0x2);
1102 1311
1103 dprintk("IC %d initialized (to i2c_address 0x%x)\n", k, new_addr); 1312 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
1104 } 1313 }
1105 1314
1106 for (k = 0; k < no_of_demods; k++) { 1315 for (k = 0; k < no_of_demods; k++) {
@@ -1172,7 +1381,7 @@ static struct dvb_frontend_ops dib7000m_ops = {
1172 1381
1173 .release = dib7000m_release, 1382 .release = dib7000m_release,
1174 1383
1175 .init = dib7000m_init, 1384 .init = dib7000m_wakeup,
1176 .sleep = dib7000m_sleep, 1385 .sleep = dib7000m_sleep,
1177 1386
1178 .set_frontend = dib7000m_set_frontend, 1387 .set_frontend = dib7000m_set_frontend,