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