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