]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/media/dvb/frontends/dib7000p.c
V4L/DVB (5954): Sync with DiBcom Driver Release 2.1.3 + some improvements
[net-next-2.6.git] / drivers / media / dvb / frontends / dib7000p.c
CommitLineData
a75763ff
PB
1/*
2 * Linux-DVB Driver for DiBcom's second generation DiB7000P (PC).
3 *
b6884a17 4 * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
a75763ff
PB
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 */
10#include <linux/kernel.h>
11#include <linux/i2c.h>
12
13#include "dvb_frontend.h"
14
15#include "dib7000p.h"
16
17static int debug;
18module_param(debug, int, 0644);
19MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
20
b6884a17 21#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0)
a75763ff
PB
22
23struct dib7000p_state {
24 struct dvb_frontend demod;
25 struct dib7000p_config cfg;
26
27 u8 i2c_addr;
28 struct i2c_adapter *i2c_adap;
29
30 struct dibx000_i2c_master i2c_master;
31
32 u16 wbd_ref;
33
34 u8 current_band;
35 fe_bandwidth_t current_bandwidth;
36 struct dibx000_agc_config *current_agc;
37 u32 timf;
38
b6884a17
PB
39 uint8_t div_force_off : 1;
40 uint8_t div_state : 1;
41 uint16_t div_sync_wait;
42
43 u8 agc_state;
44
a75763ff
PB
45 u16 gpio_dir;
46 u16 gpio_val;
47};
48
49enum dib7000p_power_mode {
50 DIB7000P_POWER_ALL = 0,
b6884a17 51 DIB7000P_POWER_ANALOG_ADC,
a75763ff
PB
52 DIB7000P_POWER_INTERFACE_ONLY,
53};
54
55static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
56{
57 u8 wb[2] = { reg >> 8, reg & 0xff };
58 u8 rb[2];
59 struct i2c_msg msg[2] = {
60 { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 },
61 { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
62 };
63
64 if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
b6884a17 65 dprintk("i2c read error on %d",reg);
a75763ff
PB
66
67 return (rb[0] << 8) | rb[1];
68}
69
70static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
71{
72 u8 b[4] = {
73 (reg >> 8) & 0xff, reg & 0xff,
74 (val >> 8) & 0xff, val & 0xff,
75 };
76 struct i2c_msg msg = {
77 .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
78 };
79 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
80}
b6884a17
PB
81static void dib7000p_write_tab(struct dib7000p_state *state, u16 *buf)
82{
83 u16 l = 0, r, *n;
84 n = buf;
85 l = *n++;
86 while (l) {
87 r = *n++;
88
89 do {
90 dib7000p_write_word(state, r, *n++);
91 r++;
92 } while (--l);
93 l = *n++;
94 }
95}
96
a75763ff
PB
97static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
98{
99 int ret = 0;
100 u16 outreg, fifo_threshold, smo_mode;
101
102 outreg = 0;
103 fifo_threshold = 1792;
104 smo_mode = (dib7000p_read_word(state, 235) & 0x0010) | (1 << 1);
105
b6884a17 106 dprintk( "setting output mode for demod %p to %d",
a75763ff
PB
107 &state->demod, mode);
108
109 switch (mode) {
110 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
111 outreg = (1 << 10); /* 0x0400 */
112 break;
113 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
114 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
115 break;
116 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
117 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */
118 break;
119 case OUTMODE_DIVERSITY:
120 if (state->cfg.hostbus_diversity)
121 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
122 else
123 outreg = (1 << 11);
124 break;
125 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
126 smo_mode |= (3 << 1);
127 fifo_threshold = 512;
128 outreg = (1 << 10) | (5 << 6);
129 break;
b6884a17
PB
130 case OUTMODE_ANALOG_ADC:
131 outreg = (1 << 10) | (3 << 6);
132 break;
a75763ff
PB
133 case OUTMODE_HIGH_Z: // disable
134 outreg = 0;
135 break;
136 default:
b6884a17 137 dprintk( "Unhandled output_mode passed to be set for demod %p",&state->demod);
a75763ff
PB
138 break;
139 }
140
141 if (state->cfg.output_mpeg2_in_188_bytes)
142 smo_mode |= (1 << 5) ;
143
144 ret |= dib7000p_write_word(state, 235, smo_mode);
145 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
146 ret |= dib7000p_write_word(state, 1286, outreg); /* P_Div_active */
147
148 return ret;
149}
150
b6884a17
PB
151static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
152{
153 struct dib7000p_state *state = demod->demodulator_priv;
154
155 if (state->div_force_off) {
156 dprintk( "diversity combination deactivated - forced by COFDM parameters");
157 onoff = 0;
158 }
159 state->div_state = (uint8_t)onoff;
160
161 if (onoff) {
162 dib7000p_write_word(state, 204, 6);
163 dib7000p_write_word(state, 205, 16);
164 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
165 dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
166 } else {
167 dib7000p_write_word(state, 204, 1);
168 dib7000p_write_word(state, 205, 0);
169 dib7000p_write_word(state, 207, 0);
170 }
171
172 return 0;
173}
174
a75763ff
PB
175static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode)
176{
177 /* by default everything is powered off */
178 u16 reg_774 = 0xffff, reg_775 = 0xffff, reg_776 = 0x0007, reg_899 = 0x0003,
179 reg_1280 = (0xfe00) | (dib7000p_read_word(state, 1280) & 0x01ff);
180
181 /* now, depending on the requested mode, we power on */
182 switch (mode) {
183 /* power up everything in the demod */
184 case DIB7000P_POWER_ALL:
185 reg_774 = 0x0000; reg_775 = 0x0000; reg_776 = 0x0; reg_899 = 0x0; reg_1280 &= 0x01ff;
186 break;
b6884a17
PB
187
188 case DIB7000P_POWER_ANALOG_ADC:
189 /* dem, cfg, iqc, sad, agc */
190 reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
191 /* nud */
192 reg_776 &= ~((1 << 0));
193 /* Dout */
194 reg_1280 &= ~((1 << 11));
195 /* fall through wanted to enable the interfaces */
196
a75763ff
PB
197 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
198 case DIB7000P_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C */
199 reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
200 break;
b6884a17 201
a75763ff
PB
202/* TODO following stuff is just converted from the dib7000-driver - check when is used what */
203 }
204
205 dib7000p_write_word(state, 774, reg_774);
206 dib7000p_write_word(state, 775, reg_775);
207 dib7000p_write_word(state, 776, reg_776);
208 dib7000p_write_word(state, 899, reg_899);
209 dib7000p_write_word(state, 1280, reg_1280);
210
211 return 0;
212}
213
214static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no)
215{
216 u16 reg_908 = dib7000p_read_word(state, 908),
217 reg_909 = dib7000p_read_word(state, 909);
218
219 switch (no) {
220 case DIBX000_SLOW_ADC_ON:
221 reg_909 |= (1 << 1) | (1 << 0);
222 dib7000p_write_word(state, 909, reg_909);
223 reg_909 &= ~(1 << 1);
224 break;
225
226 case DIBX000_SLOW_ADC_OFF:
227 reg_909 |= (1 << 1) | (1 << 0);
228 break;
229
230 case DIBX000_ADC_ON:
231 reg_908 &= 0x0fff;
232 reg_909 &= 0x0003;
233 break;
234
235 case DIBX000_ADC_OFF: // leave the VBG voltage on
236 reg_908 |= (1 << 14) | (1 << 13) | (1 << 12);
237 reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
238 break;
239
240 case DIBX000_VBG_ENABLE:
241 reg_908 &= ~(1 << 15);
242 break;
243
244 case DIBX000_VBG_DISABLE:
245 reg_908 |= (1 << 15);
246 break;
247
248 default:
249 break;
250 }
251
b6884a17 252// dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
a75763ff
PB
253
254 dib7000p_write_word(state, 908, reg_908);
255 dib7000p_write_word(state, 909, reg_909);
256}
257
b6884a17 258static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
a75763ff 259{
a75763ff
PB
260 u32 timf;
261
262 // store the current bandwidth for later use
b6884a17 263 state->current_bandwidth = bw;
a75763ff
PB
264
265 if (state->timf == 0) {
b6884a17 266 dprintk( "using default timf");
a75763ff
PB
267 timf = state->cfg.bw->timf;
268 } else {
b6884a17 269 dprintk( "using updated timf");
a75763ff
PB
270 timf = state->timf;
271 }
272
b6884a17 273 timf = timf * (bw / 50) / 160;
a75763ff 274
b6884a17
PB
275 dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
276 dib7000p_write_word(state, 24, (u16) ((timf ) & 0xffff));
a75763ff
PB
277
278 return 0;
279}
280
281static int dib7000p_sad_calib(struct dib7000p_state *state)
282{
283/* internal */
b6884a17 284// dib7000p_write_word(state, 72, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth
a75763ff
PB
285 dib7000p_write_word(state, 73, (0 << 1) | (0 << 0));
286 dib7000p_write_word(state, 74, 776); // 0.625*3.3 / 4096
287
288 /* do the calibration */
289 dib7000p_write_word(state, 73, (1 << 0));
290 dib7000p_write_word(state, 73, (0 << 0));
291
292 msleep(1);
293
294 return 0;
295}
296
297static void dib7000p_reset_pll(struct dib7000p_state *state)
298{
299 struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
b6884a17
PB
300 u16 clk_cfg0;
301
302 /* force PLL bypass */
303 clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) |
304 (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) |
305 (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0);
a75763ff 306
b6884a17
PB
307 dib7000p_write_word(state, 900, clk_cfg0);
308
309 /* P_pll_cfg */
a75763ff 310 dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset);
b6884a17
PB
311 clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff);
312 dib7000p_write_word(state, 900, clk_cfg0);
a75763ff 313
b6884a17
PB
314 dib7000p_write_word(state, 18, (u16) (((bw->internal*1000) >> 16) & 0xffff));
315 dib7000p_write_word(state, 19, (u16) ( (bw->internal*1000 ) & 0xffff));
316 dib7000p_write_word(state, 21, (u16) ( (bw->ifreq >> 16) & 0xffff));
317 dib7000p_write_word(state, 22, (u16) ( (bw->ifreq ) & 0xffff));
a75763ff
PB
318
319 dib7000p_write_word(state, 72, bw->sad_cfg);
320}
321
322static int dib7000p_reset_gpio(struct dib7000p_state *st)
323{
324 /* reset the GPIOs */
b6884a17 325 dprintk( "gpio dir: %x: val: %x, pwm_pos: %x",st->gpio_dir, st->gpio_val,st->cfg.gpio_pwm_pos);
a75763ff
PB
326
327 dib7000p_write_word(st, 1029, st->gpio_dir);
328 dib7000p_write_word(st, 1030, st->gpio_val);
329
330 /* TODO 1031 is P_gpio_od */
331
332 dib7000p_write_word(st, 1032, st->cfg.gpio_pwm_pos);
333
334 dib7000p_write_word(st, 1037, st->cfg.pwm_freq_div);
335 return 0;
336}
337
b6884a17
PB
338static u16 dib7000p_defaults[] =
339
340{
341 // auto search configuration
342 3, 2,
343 0x0004,
344 0x1000,
345 0x0814, /* Equal Lock */
346
347 12, 6,
348 0x001b,
349 0x7740,
350 0x005b,
351 0x8d80,
352 0x01c9,
353 0xc380,
354 0x0000,
355 0x0080,
356 0x0000,
357 0x0090,
358 0x0001,
359 0xd4c0,
360
361 1, 26,
362 0x6680, // P_timf_alpha=6, P_corm_alpha=6, P_corm_thres=128 default: 6,4,26
363
364 /* set ADC level to -16 */
365 11, 79,
366 (1 << 13) - 825 - 117,
367 (1 << 13) - 837 - 117,
368 (1 << 13) - 811 - 117,
369 (1 << 13) - 766 - 117,
370 (1 << 13) - 737 - 117,
371 (1 << 13) - 693 - 117,
372 (1 << 13) - 648 - 117,
373 (1 << 13) - 619 - 117,
374 (1 << 13) - 575 - 117,
375 (1 << 13) - 531 - 117,
376 (1 << 13) - 501 - 117,
377
378 1, 142,
379 0x0410, // P_palf_filter_on=1, P_palf_filter_freeze=0, P_palf_alpha_regul=16
380
381 /* disable power smoothing */
382 8, 145,
383 0,
384 0,
385 0,
386 0,
387 0,
388 0,
389 0,
390 0,
391
392 1, 154,
393 1 << 13, // P_fft_freq_dir=1, P_fft_nb_to_cut=0
394
395 1, 168,
396 0x0ccd, // P_pha3_thres, default 0x3000
397
398// 1, 169,
399// 0x0010, // P_cti_use_cpe=0, P_cti_use_prog=0, P_cti_win_len=16, default: 0x0010
400
401 1, 183,
402 0x200f, // P_cspu_regul=512, P_cspu_win_cut=15, default: 0x2005
403
404 5, 187,
405 0x023d, // P_adp_regul_cnt=573, default: 410
406 0x00a4, // P_adp_noise_cnt=
407 0x00a4, // P_adp_regul_ext
408 0x7ff0, // P_adp_noise_ext
409 0x3ccc, // P_adp_fil
410
411 1, 198,
412 0x800, // P_equal_thres_wgn
413
414 1, 222,
415 0x0010, // P_fec_ber_rs_len=2
416
417 1, 235,
418 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
419
420 2, 901,
421 0x0006, // P_clk_cfg1
422 (3 << 10) | (1 << 6), // P_divclksel=3 P_divbitsel=1
423
424 1, 905,
425 0x2c8e, // Tuner IO bank: max drive (14mA) + divout pads max drive
426
427 0,
428};
429
a75763ff
PB
430static int dib7000p_demod_reset(struct dib7000p_state *state)
431{
432 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
433
434 dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE);
435
436 /* restart all parts */
437 dib7000p_write_word(state, 770, 0xffff);
438 dib7000p_write_word(state, 771, 0xffff);
439 dib7000p_write_word(state, 772, 0x001f);
440 dib7000p_write_word(state, 898, 0x0003);
441 /* except i2c, sdio, gpio - control interfaces */
442 dib7000p_write_word(state, 1280, 0x01fc - ((1 << 7) | (1 << 6) | (1 << 5)) );
443
444 dib7000p_write_word(state, 770, 0);
445 dib7000p_write_word(state, 771, 0);
446 dib7000p_write_word(state, 772, 0);
447 dib7000p_write_word(state, 898, 0);
448 dib7000p_write_word(state, 1280, 0);
449
450 /* default */
451 dib7000p_reset_pll(state);
452
453 if (dib7000p_reset_gpio(state) != 0)
b6884a17 454 dprintk( "GPIO reset was not successful.");
a75763ff
PB
455
456 if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
b6884a17 457 dprintk( "OUTPUT_MODE could not be reset.");
a75763ff
PB
458
459 /* unforce divstr regardless whether i2c enumeration was done or not */
460 dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1) );
461
b6884a17
PB
462 dib7000p_set_bandwidth(state, 8000);
463
464 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
465 dib7000p_sad_calib(state);
466 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
467
468 // P_iqc_alpha_pha, P_iqc_alpha_amp_dcc_alpha, ...
469 if(state->cfg.tuner_is_baseband)
470 dib7000p_write_word(state, 36,0x0755);
471 else
472 dib7000p_write_word(state, 36,0x1f55);
473
474 dib7000p_write_tab(state, dib7000p_defaults);
475
a75763ff
PB
476 dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
477
b6884a17 478
a75763ff
PB
479 return 0;
480}
481
b6884a17
PB
482static void dib7000p_pll_clk_cfg(struct dib7000p_state *state)
483{
484 u16 tmp = 0;
485 tmp = dib7000p_read_word(state, 903);
486 dib7000p_write_word(state, 903, (tmp | 0x1)); //pwr-up pll
487 tmp = dib7000p_read_word(state, 900);
488 dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6)); //use High freq clock
489}
490
a75763ff
PB
491static void dib7000p_restart_agc(struct dib7000p_state *state)
492{
493 // P_restart_iqc & P_restart_agc
b6884a17 494 dib7000p_write_word(state, 770, (1 << 11) | (1 << 9));
a75763ff
PB
495 dib7000p_write_word(state, 770, 0x0000);
496}
497
b6884a17 498static int dib7000p_update_lna(struct dib7000p_state *state)
a75763ff 499{
a75763ff
PB
500 u16 dyn_gain;
501
502 // when there is no LNA to program return immediatly
b6884a17 503 if (state->cfg.update_lna) {
a75763ff
PB
504 // read dyn_gain here (because it is demod-dependent and not tuner)
505 dyn_gain = dib7000p_read_word(state, 394);
a75763ff
PB
506 if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed
507 dib7000p_restart_agc(state);
b6884a17
PB
508 return 1;
509 }
510 }
511
512 return 0;
513}
514
515static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
516{
517 struct dibx000_agc_config *agc = NULL;
518 int i;
519 if (state->current_band == band && state->current_agc != NULL)
520 return 0;
521 state->current_band = band;
522
523 for (i = 0; i < state->cfg.agc_config_count; i++)
524 if (state->cfg.agc[i].band_caps & band) {
525 agc = &state->cfg.agc[i];
a75763ff 526 break;
b6884a17
PB
527 }
528
529 if (agc == NULL) {
530 dprintk( "no valid AGC configuration found for band 0x%02x",band);
531 return -EINVAL;
a75763ff 532 }
b6884a17
PB
533
534 state->current_agc = agc;
535
536 /* AGC */
537 dib7000p_write_word(state, 75 , agc->setup );
538 dib7000p_write_word(state, 76 , agc->inv_gain );
539 dib7000p_write_word(state, 77 , agc->time_stabiliz );
540 dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);
541
542 // Demod AGC loop configuration
543 dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);
544 dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp);
545
546 /* AGC continued */
547 dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d",
548 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
549
550 if (state->wbd_ref != 0)
551 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref);
552 else
553 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref);
554
555 dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
556
557 dib7000p_write_word(state, 107, agc->agc1_max);
558 dib7000p_write_word(state, 108, agc->agc1_min);
559 dib7000p_write_word(state, 109, agc->agc2_max);
560 dib7000p_write_word(state, 110, agc->agc2_min);
561 dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
562 dib7000p_write_word(state, 112, agc->agc1_pt3);
563 dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
564 dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
565 dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
566 return 0;
a75763ff
PB
567}
568
b6884a17 569static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
a75763ff 570{
b6884a17
PB
571 struct dib7000p_state *state = demod->demodulator_priv;
572 int ret = -1;
573 u8 *agc_state = &state->agc_state;
574 u8 agc_split;
575
576 switch (state->agc_state) {
577 case 0:
578 // set power-up level: interf+analog+AGC
579 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
580 dib7000p_set_adc_state(state, DIBX000_ADC_ON);
581 dib7000p_pll_clk_cfg(state);
582
583 if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0)
584 return -1;
585
586 ret = 7;
587 (*agc_state)++;
588 break;
589
590 case 1:
591 // AGC initialization
592 if (state->cfg.agc_control)
593 state->cfg.agc_control(&state->demod, 1);
594
595 dib7000p_write_word(state, 78, 32768);
596 if (!state->current_agc->perform_agc_softsplit) {
597 /* we are using the wbd - so slow AGC startup */
598 /* force 0 split on WBD and restart AGC */
599 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));
600 (*agc_state)++;
601 ret = 5;
602 } else {
603 /* default AGC startup */
604 (*agc_state) = 4;
605 /* wait AGC rough lock time */
606 ret = 7;
607 }
608
609 dib7000p_restart_agc(state);
610 break;
611
612 case 2: /* fast split search path after 5sec */
613 dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4)); /* freeze AGC loop */
614 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */
615 (*agc_state)++;
616 ret = 14;
617 break;
618
619 case 3: /* split search ended */
620 agc_split = (uint8_t)dib7000p_read_word(state, 396); /* store the split value for the next time */
621 dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */
622
623 dib7000p_write_word(state, 75, state->current_agc->setup); /* std AGC loop */
624 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
625
626 dib7000p_restart_agc(state);
627
628 dprintk( "SPLIT %p: %hd", demod, agc_split);
629
630 (*agc_state)++;
631 ret = 5;
632 break;
633
634 case 4: /* LNA startup */
635 // wait AGC accurate lock time
636 ret = 7;
637
638 if (dib7000p_update_lna(state))
639 // wait only AGC rough lock time
640 ret = 5;
641 else // nothing was done, go to the next state
642 (*agc_state)++;
643 break;
644
645 case 5:
646 if (state->cfg.agc_control)
647 state->cfg.agc_control(&state->demod, 0);
648 (*agc_state)++;
649 break;
650 default:
651 break;
652 }
653 return ret;
a75763ff
PB
654}
655
b6884a17 656static void dib7000p_update_timf(struct dib7000p_state *state)
a75763ff
PB
657{
658 u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428);
b6884a17 659 state->timf = timf * 160 / (state->current_bandwidth / 50);
a75763ff
PB
660 dib7000p_write_word(state, 23, (u16) (timf >> 16));
661 dib7000p_write_word(state, 24, (u16) (timf & 0xffff));
b6884a17
PB
662 dprintk( "updated timf_frequency: %d (default: %d)",state->timf, state->cfg.bw->timf);
663
a75763ff
PB
664}
665
b6884a17 666static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq)
a75763ff 667{
b6884a17
PB
668 u16 value, est[4];
669
670 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
a75763ff
PB
671
672 /* nfft, guard, qam, alpha */
b6884a17
PB
673 value = 0;
674 switch (ch->u.ofdm.transmission_mode) {
675 case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
676 case /* 4K MODE */ 255: value |= (2 << 7); break;
677 default:
678 case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
679 }
680 switch (ch->u.ofdm.guard_interval) {
681 case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
682 case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
683 case GUARD_INTERVAL_1_4: value |= (3 << 5); break;
684 default:
685 case GUARD_INTERVAL_1_8: value |= (2 << 5); break;
686 }
687 switch (ch->u.ofdm.constellation) {
688 case QPSK: value |= (0 << 3); break;
689 case QAM_16: value |= (1 << 3); break;
690 default:
691 case QAM_64: value |= (2 << 3); break;
692 }
693 switch (HIERARCHY_1) {
694 case HIERARCHY_2: value |= 2; break;
695 case HIERARCHY_4: value |= 4; break;
696 default:
697 case HIERARCHY_1: value |= 1; break;
698 }
699 dib7000p_write_word(state, 0, value);
a75763ff
PB
700 dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */
701
b6884a17
PB
702 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
703 value = 0;
704 if (1 != 0)
705 value |= (1 << 6);
706 if (ch->u.ofdm.hierarchy_information == 1)
707 value |= (1 << 4);
708 if (1 == 1)
709 value |= 1;
710 switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
711 case FEC_2_3: value |= (2 << 1); break;
712 case FEC_3_4: value |= (3 << 1); break;
713 case FEC_5_6: value |= (5 << 1); break;
714 case FEC_7_8: value |= (7 << 1); break;
715 default:
716 case FEC_1_2: value |= (1 << 1); break;
717 }
718 dib7000p_write_word(state, 208, value);
719
720 /* offset loop parameters */
721 dib7000p_write_word(state, 26, 0x6680); // timf(6xxx)
722 dib7000p_write_word(state, 29, 0x1273); // isi inh1273 on1073
723 dib7000p_write_word(state, 32, 0x0003); // pha_off_max(xxx3)
724 dib7000p_write_word(state, 33, 0x0005); // sfreq(xxx5)
a75763ff
PB
725
726 /* P_dvsy_sync_wait */
b6884a17
PB
727 switch (ch->u.ofdm.transmission_mode) {
728 case TRANSMISSION_MODE_8K: value = 256; break;
729 case /* 4K MODE */ 255: value = 128; break;
730 case TRANSMISSION_MODE_2K:
731 default: value = 64; break;
a75763ff 732 }
b6884a17
PB
733 switch (ch->u.ofdm.guard_interval) {
734 case GUARD_INTERVAL_1_16: value *= 2; break;
735 case GUARD_INTERVAL_1_8: value *= 4; break;
736 case GUARD_INTERVAL_1_4: value *= 8; break;
737 default:
738 case GUARD_INTERVAL_1_32: value *= 1; break;
739 }
740 state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO
a75763ff 741
b6884a17
PB
742 /* deactive the possibility of diversity reception if extended interleaver */
743 state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K;
744 dib7000p_set_diversity_in(&state->demod, state->div_state);
a75763ff
PB
745
746 /* channel estimation fine configuration */
b6884a17
PB
747 switch (ch->u.ofdm.constellation) {
748 case QAM_64:
a75763ff
PB
749 est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
750 est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
751 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
752 est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
753 break;
b6884a17 754 case QAM_16:
a75763ff
PB
755 est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
756 est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
757 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
758 est[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
759 break;
760 default:
761 est[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
762 est[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
763 est[2] = 0x0333; /* P_adp_regul_ext 0.1 */
764 est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
765 break;
766 }
b6884a17
PB
767 for (value = 0; value < 4; value++)
768 dib7000p_write_word(state, 187 + value, est[value]);
a75763ff
PB
769}
770
b6884a17 771static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
a75763ff
PB
772{
773 struct dib7000p_state *state = demod->demodulator_priv;
b6884a17
PB
774 struct dvb_frontend_parameters schan;
775 u32 value, factor;
776
777 schan = *ch;
778 schan.u.ofdm.constellation = QAM_64;
779 schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
780 schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
781 schan.u.ofdm.code_rate_HP = FEC_2_3;
782 schan.u.ofdm.code_rate_LP = FEC_3_4;
783 schan.u.ofdm.hierarchy_information = 0;
784
785 dib7000p_set_channel(state, &schan, 7);
786
787 factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth);
788 if (factor >= 5000)
789 factor = 1;
790 else
791 factor = 6;
a75763ff
PB
792
793 // always use the setting for 8MHz here lock_time for 7,6 MHz are longer
b6884a17 794 value = 30 * state->cfg.bw->internal * factor;
a75763ff
PB
795 dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff)); // lock0 wait time
796 dib7000p_write_word(state, 7, (u16) (value & 0xffff)); // lock0 wait time
b6884a17 797 value = 100 * state->cfg.bw->internal * factor;
a75763ff
PB
798 dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff)); // lock1 wait time
799 dib7000p_write_word(state, 9, (u16) (value & 0xffff)); // lock1 wait time
b6884a17 800 value = 500 * state->cfg.bw->internal * factor;
a75763ff
PB
801 dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
802 dib7000p_write_word(state, 11, (u16) (value & 0xffff)); // lock2 wait time
803
804 value = dib7000p_read_word(state, 0);
b6884a17 805 dib7000p_write_word(state, 0, (u16) ((1 << 9) | value));
a75763ff
PB
806 dib7000p_read_word(state, 1284);
807 dib7000p_write_word(state, 0, (u16) value);
808
809 return 0;
810}
811
812static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod)
813{
814 struct dib7000p_state *state = demod->demodulator_priv;
815 u16 irq_pending = dib7000p_read_word(state, 1284);
816
817 if (irq_pending & 0x1) // failed
818 return 1;
819
820 if (irq_pending & 0x2) // succeeded
821 return 2;
822
823 return 0; // still pending
824}
825
b6884a17
PB
826static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw)
827{
828 static s16 notch[]={16143, 14402, 12238, 9713, 6902, 3888, 759, -2392};
829 static u8 sine [] ={0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
830 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
831 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
832 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
833 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
834 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
835 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
836 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
837 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
838 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
839 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
840 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
841 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
842 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
843 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
844 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
845 255, 255, 255, 255, 255, 255};
846
847 u32 xtal = state->cfg.bw->xtal_hz / 1000;
848 int f_rel = ( (rf_khz + xtal/2) / xtal) * xtal - rf_khz;
849 int k;
850 int coef_re[8],coef_im[8];
851 int bw_khz = bw;
852 u32 pha;
853
854 dprintk( "relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal);
855
856
857 if (f_rel < -bw_khz/2 || f_rel > bw_khz/2)
858 return;
859
860 bw_khz /= 100;
861
862 dib7000p_write_word(state, 142 ,0x0610);
863
864 for (k = 0; k < 8; k++) {
865 pha = ((f_rel * (k+1) * 112 * 80/bw_khz) /1000) & 0x3ff;
866
867 if (pha==0) {
868 coef_re[k] = 256;
869 coef_im[k] = 0;
870 } else if(pha < 256) {
871 coef_re[k] = sine[256-(pha&0xff)];
872 coef_im[k] = sine[pha&0xff];
873 } else if (pha == 256) {
874 coef_re[k] = 0;
875 coef_im[k] = 256;
876 } else if (pha < 512) {
877 coef_re[k] = -sine[pha&0xff];
878 coef_im[k] = sine[256 - (pha&0xff)];
879 } else if (pha == 512) {
880 coef_re[k] = -256;
881 coef_im[k] = 0;
882 } else if (pha < 768) {
883 coef_re[k] = -sine[256-(pha&0xff)];
884 coef_im[k] = -sine[pha&0xff];
885 } else if (pha == 768) {
886 coef_re[k] = 0;
887 coef_im[k] = -256;
888 } else {
889 coef_re[k] = sine[pha&0xff];
890 coef_im[k] = -sine[256 - (pha&0xff)];
891 }
892
893 coef_re[k] *= notch[k];
894 coef_re[k] += (1<<14);
895 if (coef_re[k] >= (1<<24))
896 coef_re[k] = (1<<24) - 1;
897 coef_re[k] /= (1<<15);
898
899 coef_im[k] *= notch[k];
900 coef_im[k] += (1<<14);
901 if (coef_im[k] >= (1<<24))
902 coef_im[k] = (1<<24)-1;
903 coef_im[k] /= (1<<15);
904
905 dprintk( "PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]);
906
907 dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
908 dib7000p_write_word(state, 144, coef_im[k] & 0x3ff);
909 dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
910 }
911 dib7000p_write_word(state,143 ,0);
912}
913
914static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
a75763ff
PB
915{
916 struct dib7000p_state *state = demod->demodulator_priv;
917 u16 tmp = 0;
918
919 if (ch != NULL)
920 dib7000p_set_channel(state, ch, 0);
921 else
922 return -EINVAL;
923
924 // restart demod
925 dib7000p_write_word(state, 770, 0x4000);
926 dib7000p_write_word(state, 770, 0x0000);
927 msleep(45);
928
929 /* 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 */
930 dib7000p_write_word(state, 29, (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3));
931
932 // never achieved a lock with that bandwidth so far - wait for osc-freq to update
933 if (state->timf == 0)
934 msleep(200);
935
936 /* offset loop parameters */
937
938 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
939 tmp = (6 << 8) | 0x80;
b6884a17
PB
940 switch (ch->u.ofdm.transmission_mode) {
941 case TRANSMISSION_MODE_2K: tmp |= (7 << 12); break;
942 case /* 4K MODE */ 255: tmp |= (8 << 12); break;
943 default:
944 case TRANSMISSION_MODE_8K: tmp |= (9 << 12); break;
a75763ff
PB
945 }
946 dib7000p_write_word(state, 26, tmp); /* timf_a(6xxx) */
947
948 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
949 tmp = (0 << 4);
b6884a17
PB
950 switch (ch->u.ofdm.transmission_mode) {
951 case TRANSMISSION_MODE_2K: tmp |= 0x6; break;
952 case /* 4K MODE */ 255: tmp |= 0x7; break;
953 default:
954 case TRANSMISSION_MODE_8K: tmp |= 0x8; break;
a75763ff
PB
955 }
956 dib7000p_write_word(state, 32, tmp);
957
958 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
959 tmp = (0 << 4);
b6884a17
PB
960 switch (ch->u.ofdm.transmission_mode) {
961 case TRANSMISSION_MODE_2K: tmp |= 0x6; break;
962 case /* 4K MODE */ 255: tmp |= 0x7; break;
963 default:
964 case TRANSMISSION_MODE_8K: tmp |= 0x8; break;
a75763ff
PB
965 }
966 dib7000p_write_word(state, 33, tmp);
967
968 tmp = dib7000p_read_word(state,509);
969 if (!((tmp >> 6) & 0x1)) {
970 /* restart the fec */
971 tmp = dib7000p_read_word(state,771);
972 dib7000p_write_word(state, 771, tmp | (1 << 1));
973 dib7000p_write_word(state, 771, tmp);
974 msleep(10);
975 tmp = dib7000p_read_word(state,509);
976 }
977
978 // we achieved a lock - it's time to update the osc freq
979 if ((tmp >> 6) & 0x1)
b6884a17
PB
980 dib7000p_update_timf(state);
981
982 if (state->cfg.spur_protect)
983 dib7000p_spur_protect(state, ch->frequency/1000, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
a75763ff 984
b6884a17 985 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
a75763ff
PB
986 return 0;
987}
988
b6884a17 989static int dib7000p_wakeup(struct dvb_frontend *demod)
a75763ff 990{
a75763ff 991 struct dib7000p_state *state = demod->demodulator_priv;
a75763ff
PB
992 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
993 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
b6884a17 994 return 0;
a75763ff
PB
995}
996
997static int dib7000p_sleep(struct dvb_frontend *demod)
998{
999 struct dib7000p_state *state = demod->demodulator_priv;
1000 return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1001}
1002
1003static int dib7000p_identify(struct dib7000p_state *st)
1004{
1005 u16 value;
b6884a17 1006 dprintk( "checking demod on I2C address: %d (%x)",
a75763ff
PB
1007 st->i2c_addr, st->i2c_addr);
1008
1009 if ((value = dib7000p_read_word(st, 768)) != 0x01b3) {
b6884a17 1010 dprintk( "wrong Vendor ID (read=0x%x)",value);
a75763ff
PB
1011 return -EREMOTEIO;
1012 }
1013
1014 if ((value = dib7000p_read_word(st, 769)) != 0x4000) {
b6884a17 1015 dprintk( "wrong Device ID (%x)",value);
a75763ff
PB
1016 return -EREMOTEIO;
1017 }
1018
1019 return 0;
1020}
1021
1022
1023static int dib7000p_get_frontend(struct dvb_frontend* fe,
1024 struct dvb_frontend_parameters *fep)
1025{
1026 struct dib7000p_state *state = fe->demodulator_priv;
1027 u16 tps = dib7000p_read_word(state,463);
1028
1029 fep->inversion = INVERSION_AUTO;
1030
1031 fep->u.ofdm.bandwidth = state->current_bandwidth;
1032
1033 switch ((tps >> 8) & 0x3) {
1034 case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break;
1035 case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break;
1036 /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */
1037 }
1038
1039 switch (tps & 0x3) {
1040 case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break;
1041 case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break;
1042 case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break;
1043 case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break;
1044 }
1045
1046 switch ((tps >> 14) & 0x3) {
1047 case 0: fep->u.ofdm.constellation = QPSK; break;
1048 case 1: fep->u.ofdm.constellation = QAM_16; break;
1049 case 2:
1050 default: fep->u.ofdm.constellation = QAM_64; break;
1051 }
1052
1053 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1054 /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1055
1056 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
1057 switch ((tps >> 5) & 0x7) {
1058 case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break;
1059 case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break;
1060 case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break;
1061 case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break;
1062 case 7:
1063 default: fep->u.ofdm.code_rate_HP = FEC_7_8; break;
1064
1065 }
1066
1067 switch ((tps >> 2) & 0x7) {
1068 case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break;
1069 case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break;
1070 case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break;
1071 case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break;
1072 case 7:
1073 default: fep->u.ofdm.code_rate_LP = FEC_7_8; break;
1074 }
1075
1076 /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */
1077
1078 return 0;
1079}
1080
1081static int dib7000p_set_frontend(struct dvb_frontend* fe,
1082 struct dvb_frontend_parameters *fep)
1083{
1084 struct dib7000p_state *state = fe->demodulator_priv;
b6884a17 1085 int time;
a75763ff
PB
1086
1087 state->current_bandwidth = fep->u.ofdm.bandwidth;
b6884a17 1088 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth));
a75763ff
PB
1089
1090 if (fe->ops.tuner_ops.set_params)
1091 fe->ops.tuner_ops.set_params(fe, fep);
1092
b6884a17
PB
1093 /* start up the AGC */
1094 state->agc_state = 0;
1095 do {
1096 time = dib7000p_agc_startup(fe, fep);
1097 if (time != -1)
1098 msleep(time);
1099 } while (time != -1);
1100
a75763ff
PB
1101 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
1102 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ||
1103 fep->u.ofdm.constellation == QAM_AUTO ||
1104 fep->u.ofdm.code_rate_HP == FEC_AUTO) {
1105 int i = 800, found;
1106
b6884a17 1107 dib7000p_autosearch_start(fe, fep);
a75763ff
PB
1108 do {
1109 msleep(1);
1110 found = dib7000p_autosearch_is_irq(fe);
1111 } while (found == 0 && i--);
1112
b6884a17 1113 dprintk("autosearch returns: %d",found);
a75763ff
PB
1114 if (found == 0 || found == 1)
1115 return 0; // no channel found
1116
1117 dib7000p_get_frontend(fe, fep);
a75763ff
PB
1118 }
1119
1120 /* make this a config parameter */
1121 dib7000p_set_output_mode(state, OUTMODE_MPEG2_FIFO);
1122
b6884a17 1123 return dib7000p_tune(fe, fep);
a75763ff
PB
1124}
1125
1126static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t *stat)
1127{
1128 struct dib7000p_state *state = fe->demodulator_priv;
1129 u16 lock = dib7000p_read_word(state, 509);
1130
1131 *stat = 0;
1132
1133 if (lock & 0x8000)
1134 *stat |= FE_HAS_SIGNAL;
1135 if (lock & 0x3000)
1136 *stat |= FE_HAS_CARRIER;
1137 if (lock & 0x0100)
1138 *stat |= FE_HAS_VITERBI;
1139 if (lock & 0x0010)
1140 *stat |= FE_HAS_SYNC;
1141 if (lock & 0x0008)
1142 *stat |= FE_HAS_LOCK;
1143
1144 return 0;
1145}
1146
1147static int dib7000p_read_ber(struct dvb_frontend *fe, u32 *ber)
1148{
1149 struct dib7000p_state *state = fe->demodulator_priv;
1150 *ber = (dib7000p_read_word(state, 500) << 16) | dib7000p_read_word(state, 501);
1151 return 0;
1152}
1153
1154static int dib7000p_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
1155{
1156 struct dib7000p_state *state = fe->demodulator_priv;
1157 *unc = dib7000p_read_word(state, 506);
1158 return 0;
1159}
1160
1161static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1162{
1163 struct dib7000p_state *state = fe->demodulator_priv;
1164 u16 val = dib7000p_read_word(state, 394);
1165 *strength = 65535 - val;
1166 return 0;
1167}
1168
1169static int dib7000p_read_snr(struct dvb_frontend* fe, u16 *snr)
1170{
1171 *snr = 0x0000;
1172 return 0;
1173}
1174
1175static int dib7000p_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
1176{
1177 tune->min_delay_ms = 1000;
1178 return 0;
1179}
1180
1181static void dib7000p_release(struct dvb_frontend *demod)
1182{
1183 struct dib7000p_state *st = demod->demodulator_priv;
1184 dibx000_exit_i2c_master(&st->i2c_master);
1185 kfree(st);
1186}
1187
1188int dib7000pc_detection(struct i2c_adapter *i2c_adap)
1189{
1190 u8 tx[2], rx[2];
1191 struct i2c_msg msg[2] = {
1192 { .addr = 18 >> 1, .flags = 0, .buf = tx, .len = 2 },
1193 { .addr = 18 >> 1, .flags = I2C_M_RD, .buf = rx, .len = 2 },
1194 };
1195
1196 tx[0] = 0x03;
1197 tx[1] = 0x00;
1198
1199 if (i2c_transfer(i2c_adap, msg, 2) == 2)
1200 if (rx[0] == 0x01 && rx[1] == 0xb3) {
b6884a17 1201 dprintk("-D- DiB7000PC detected");
a75763ff
PB
1202 return 1;
1203 }
1204
1205 msg[0].addr = msg[1].addr = 0x40;
1206
1207 if (i2c_transfer(i2c_adap, msg, 2) == 2)
1208 if (rx[0] == 0x01 && rx[1] == 0xb3) {
b6884a17 1209 dprintk("-D- DiB7000PC detected");
a75763ff
PB
1210 return 1;
1211 }
1212
b6884a17 1213 dprintk("-D- DiB7000PC not detected");
a75763ff
PB
1214 return 0;
1215}
1216EXPORT_SYMBOL(dib7000pc_detection);
1217
1218struct i2c_adapter * dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
1219{
1220 struct dib7000p_state *st = demod->demodulator_priv;
1221 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1222}
1223EXPORT_SYMBOL(dib7000p_get_i2c_master);
1224
1225int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
1226{
1227 struct dib7000p_state st = { .i2c_adap = i2c };
1228 int k = 0;
1229 u8 new_addr = 0;
1230
1231 for (k = no_of_demods-1; k >= 0; k--) {
1232 st.cfg = cfg[k];
1233
1234 /* designated i2c address */
1235 new_addr = (0x40 + k) << 1;
1236 st.i2c_addr = new_addr;
1237 if (dib7000p_identify(&st) != 0) {
1238 st.i2c_addr = default_addr;
1239 if (dib7000p_identify(&st) != 0) {
1240 dprintk("DiB7000P #%d: not identified\n", k);
1241 return -EIO;
1242 }
1243 }
1244
1245 /* start diversity to pull_down div_str - just for i2c-enumeration */
1246 dib7000p_set_output_mode(&st, OUTMODE_DIVERSITY);
1247
1248 /* set new i2c address and force divstart */
1249 dib7000p_write_word(&st, 1285, (new_addr << 2) | 0x2);
1250
b6884a17 1251 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
a75763ff
PB
1252 }
1253
1254 for (k = 0; k < no_of_demods; k++) {
1255 st.cfg = cfg[k];
1256 st.i2c_addr = (0x40 + k) << 1;
1257
1258 // unforce divstr
1259 dib7000p_write_word(&st, 1285, st.i2c_addr << 2);
1260
1261 /* deactivate div - it was just for i2c-enumeration */
1262 dib7000p_set_output_mode(&st, OUTMODE_HIGH_Z);
1263 }
1264
1265 return 0;
1266}
1267EXPORT_SYMBOL(dib7000p_i2c_enumeration);
1268
1269static struct dvb_frontend_ops dib7000p_ops;
1270struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
1271{
1272 struct dvb_frontend *demod;
1273 struct dib7000p_state *st;
1274 st = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
1275 if (st == NULL)
1276 return NULL;
1277
1278 memcpy(&st->cfg, cfg, sizeof(struct dib7000p_config));
1279 st->i2c_adap = i2c_adap;
1280 st->i2c_addr = i2c_addr;
1281 st->gpio_val = cfg->gpio_val;
1282 st->gpio_dir = cfg->gpio_dir;
1283
1284 demod = &st->demod;
1285 demod->demodulator_priv = st;
1286 memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));
1287
1288 if (dib7000p_identify(st) != 0)
1289 goto error;
1290
1291 dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr);
1292
1293 dib7000p_demod_reset(st);
1294
1295 return demod;
1296
1297error:
1298 kfree(st);
1299 return NULL;
1300}
1301EXPORT_SYMBOL(dib7000p_attach);
1302
1303static struct dvb_frontend_ops dib7000p_ops = {
1304 .info = {
1305 .name = "DiBcom 7000PC",
1306 .type = FE_OFDM,
1307 .frequency_min = 44250000,
1308 .frequency_max = 867250000,
1309 .frequency_stepsize = 62500,
1310 .caps = FE_CAN_INVERSION_AUTO |
1311 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1312 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1313 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1314 FE_CAN_TRANSMISSION_MODE_AUTO |
1315 FE_CAN_GUARD_INTERVAL_AUTO |
1316 FE_CAN_RECOVER |
1317 FE_CAN_HIERARCHY_AUTO,
1318 },
1319
1320 .release = dib7000p_release,
1321
b6884a17 1322 .init = dib7000p_wakeup,
a75763ff
PB
1323 .sleep = dib7000p_sleep,
1324
1325 .set_frontend = dib7000p_set_frontend,
1326 .get_tune_settings = dib7000p_fe_get_tune_settings,
1327 .get_frontend = dib7000p_get_frontend,
1328
1329 .read_status = dib7000p_read_status,
1330 .read_ber = dib7000p_read_ber,
1331 .read_signal_strength = dib7000p_read_signal_strength,
1332 .read_snr = dib7000p_read_snr,
1333 .read_ucblocks = dib7000p_read_unc_blocks,
1334};
1335
1336MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
1337MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
1338MODULE_LICENSE("GPL");