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