Merge branch 'sh-latest' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal...
[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/slab.h>
12 #include <linux/i2c.h>
13
14 #include "dvb_math.h"
15 #include "dvb_frontend.h"
16
17 #include "dib7000p.h"
18
19 static int debug;
20 module_param(debug, int, 0644);
21 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
22
23 static int buggy_sfn_workaround;
24 module_param(buggy_sfn_workaround, int, 0644);
25 MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
26
27 #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0)
28
29 struct i2c_device {
30         struct i2c_adapter *i2c_adap;
31         u8 i2c_addr;
32 };
33
34 struct dib7000p_state {
35         struct dvb_frontend demod;
36         struct dib7000p_config cfg;
37
38         u8 i2c_addr;
39         struct i2c_adapter *i2c_adap;
40
41         struct dibx000_i2c_master i2c_master;
42
43         u16 wbd_ref;
44
45         u8 current_band;
46         u32 current_bandwidth;
47         struct dibx000_agc_config *current_agc;
48         u32 timf;
49
50         u8 div_force_off:1;
51         u8 div_state:1;
52         u16 div_sync_wait;
53
54         u8 agc_state;
55
56         u16 gpio_dir;
57         u16 gpio_val;
58
59         u8 sfn_workaround_active:1;
60
61 #define SOC7090 0x7090
62         u16 version;
63
64         u16 tuner_enable;
65         struct i2c_adapter dib7090_tuner_adap;
66
67         /* for the I2C transfer */
68         struct i2c_msg msg[2];
69         u8 i2c_write_buffer[4];
70         u8 i2c_read_buffer[2];
71 };
72
73 enum dib7000p_power_mode {
74         DIB7000P_POWER_ALL = 0,
75         DIB7000P_POWER_ANALOG_ADC,
76         DIB7000P_POWER_INTERFACE_ONLY,
77 };
78
79 static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode);
80 static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff);
81
82 static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
83 {
84         state->i2c_write_buffer[0] = reg >> 8;
85         state->i2c_write_buffer[1] = reg & 0xff;
86
87         memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
88         state->msg[0].addr = state->i2c_addr >> 1;
89         state->msg[0].flags = 0;
90         state->msg[0].buf = state->i2c_write_buffer;
91         state->msg[0].len = 2;
92         state->msg[1].addr = state->i2c_addr >> 1;
93         state->msg[1].flags = I2C_M_RD;
94         state->msg[1].buf = state->i2c_read_buffer;
95         state->msg[1].len = 2;
96
97         if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
98                 dprintk("i2c read error on %d", reg);
99
100         return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
101 }
102
103 static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
104 {
105         state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
106         state->i2c_write_buffer[1] = reg & 0xff;
107         state->i2c_write_buffer[2] = (val >> 8) & 0xff;
108         state->i2c_write_buffer[3] = val & 0xff;
109
110         memset(&state->msg[0], 0, sizeof(struct i2c_msg));
111         state->msg[0].addr = state->i2c_addr >> 1;
112         state->msg[0].flags = 0;
113         state->msg[0].buf = state->i2c_write_buffer;
114         state->msg[0].len = 4;
115
116         return i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
117 }
118
119 static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf)
120 {
121         u16 l = 0, r, *n;
122         n = buf;
123         l = *n++;
124         while (l) {
125                 r = *n++;
126
127                 do {
128                         dib7000p_write_word(state, r, *n++);
129                         r++;
130                 } while (--l);
131                 l = *n++;
132         }
133 }
134
135 static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
136 {
137         int ret = 0;
138         u16 outreg, fifo_threshold, smo_mode;
139
140         outreg = 0;
141         fifo_threshold = 1792;
142         smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
143
144         dprintk("setting output mode for demod %p to %d", &state->demod, mode);
145
146         switch (mode) {
147         case OUTMODE_MPEG2_PAR_GATED_CLK:
148                 outreg = (1 << 10);     /* 0x0400 */
149                 break;
150         case OUTMODE_MPEG2_PAR_CONT_CLK:
151                 outreg = (1 << 10) | (1 << 6);  /* 0x0440 */
152                 break;
153         case OUTMODE_MPEG2_SERIAL:
154                 outreg = (1 << 10) | (2 << 6) | (0 << 1);       /* 0x0480 */
155                 break;
156         case OUTMODE_DIVERSITY:
157                 if (state->cfg.hostbus_diversity)
158                         outreg = (1 << 10) | (4 << 6);  /* 0x0500 */
159                 else
160                         outreg = (1 << 11);
161                 break;
162         case OUTMODE_MPEG2_FIFO:
163                 smo_mode |= (3 << 1);
164                 fifo_threshold = 512;
165                 outreg = (1 << 10) | (5 << 6);
166                 break;
167         case OUTMODE_ANALOG_ADC:
168                 outreg = (1 << 10) | (3 << 6);
169                 break;
170         case OUTMODE_HIGH_Z:
171                 outreg = 0;
172                 break;
173         default:
174                 dprintk("Unhandled output_mode passed to be set for demod %p", &state->demod);
175                 break;
176         }
177
178         if (state->cfg.output_mpeg2_in_188_bytes)
179                 smo_mode |= (1 << 5);
180
181         ret |= dib7000p_write_word(state, 235, smo_mode);
182         ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
183         if (state->version != SOC7090)
184                 ret |= dib7000p_write_word(state, 1286, outreg);        /* P_Div_active */
185
186         return ret;
187 }
188
189 static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
190 {
191         struct dib7000p_state *state = demod->demodulator_priv;
192
193         if (state->div_force_off) {
194                 dprintk("diversity combination deactivated - forced by COFDM parameters");
195                 onoff = 0;
196                 dib7000p_write_word(state, 207, 0);
197         } else
198                 dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
199
200         state->div_state = (u8) onoff;
201
202         if (onoff) {
203                 dib7000p_write_word(state, 204, 6);
204                 dib7000p_write_word(state, 205, 16);
205                 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
206         } else {
207                 dib7000p_write_word(state, 204, 1);
208                 dib7000p_write_word(state, 205, 0);
209         }
210
211         return 0;
212 }
213
214 static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode)
215 {
216         /* by default everything is powered off */
217         u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0x0007, reg_899 = 0x0003, reg_1280 = (0xfe00) | (dib7000p_read_word(state, 1280) & 0x01ff);
218
219         /* now, depending on the requested mode, we power on */
220         switch (mode) {
221                 /* power up everything in the demod */
222         case DIB7000P_POWER_ALL:
223                 reg_774 = 0x0000;
224                 reg_775 = 0x0000;
225                 reg_776 = 0x0;
226                 reg_899 = 0x0;
227                 if (state->version == SOC7090)
228                         reg_1280 &= 0x001f;
229                 else
230                         reg_1280 &= 0x01ff;
231                 break;
232
233         case DIB7000P_POWER_ANALOG_ADC:
234                 /* dem, cfg, iqc, sad, agc */
235                 reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
236                 /* nud */
237                 reg_776 &= ~((1 << 0));
238                 /* Dout */
239                 if (state->version != SOC7090)
240                         reg_1280 &= ~((1 << 11));
241                 reg_1280 &= ~(1 << 6);
242                 /* fall through wanted to enable the interfaces */
243
244                 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
245         case DIB7000P_POWER_INTERFACE_ONLY:     /* TODO power up either SDIO or I2C */
246                 if (state->version == SOC7090)
247                         reg_1280 &= ~((1 << 7) | (1 << 5));
248                 else
249                         reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
250                 break;
251
252 /* TODO following stuff is just converted from the dib7000-driver - check when is used what */
253         }
254
255         dib7000p_write_word(state, 774, reg_774);
256         dib7000p_write_word(state, 775, reg_775);
257         dib7000p_write_word(state, 776, reg_776);
258         dib7000p_write_word(state, 899, reg_899);
259         dib7000p_write_word(state, 1280, reg_1280);
260
261         return 0;
262 }
263
264 static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no)
265 {
266         u16 reg_908 = dib7000p_read_word(state, 908), reg_909 = dib7000p_read_word(state, 909);
267         u16 reg;
268
269         switch (no) {
270         case DIBX000_SLOW_ADC_ON:
271                 if (state->version == SOC7090) {
272                         reg = dib7000p_read_word(state, 1925);
273
274                         dib7000p_write_word(state, 1925, reg | (1 << 4) | (1 << 2));    /* en_slowAdc = 1 & reset_sladc = 1 */
275
276                         reg = dib7000p_read_word(state, 1925);  /* read acces to make it works... strange ... */
277                         msleep(200);
278                         dib7000p_write_word(state, 1925, reg & ~(1 << 4));      /* en_slowAdc = 1 & reset_sladc = 0 */
279
280                         reg = dib7000p_read_word(state, 72) & ~((0x3 << 14) | (0x3 << 12));
281                         dib7000p_write_word(state, 72, reg | (1 << 14) | (3 << 12) | 524);      /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ; (Vin2 = Vcm) */
282                 } else {
283                         reg_909 |= (1 << 1) | (1 << 0);
284                         dib7000p_write_word(state, 909, reg_909);
285                         reg_909 &= ~(1 << 1);
286                 }
287                 break;
288
289         case DIBX000_SLOW_ADC_OFF:
290                 if (state->version == SOC7090) {
291                         reg = dib7000p_read_word(state, 1925);
292                         dib7000p_write_word(state, 1925, (reg & ~(1 << 2)) | (1 << 4)); /* reset_sladc = 1 en_slowAdc = 0 */
293                 } else
294                         reg_909 |= (1 << 1) | (1 << 0);
295                 break;
296
297         case DIBX000_ADC_ON:
298                 reg_908 &= 0x0fff;
299                 reg_909 &= 0x0003;
300                 break;
301
302         case DIBX000_ADC_OFF:
303                 reg_908 |= (1 << 14) | (1 << 13) | (1 << 12);
304                 reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
305                 break;
306
307         case DIBX000_VBG_ENABLE:
308                 reg_908 &= ~(1 << 15);
309                 break;
310
311         case DIBX000_VBG_DISABLE:
312                 reg_908 |= (1 << 15);
313                 break;
314
315         default:
316                 break;
317         }
318
319 //      dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
320
321         reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4;
322         reg_908 |= (state->cfg.enable_current_mirror & 1) << 7;
323
324         dib7000p_write_word(state, 908, reg_908);
325         dib7000p_write_word(state, 909, reg_909);
326 }
327
328 static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
329 {
330         u32 timf;
331
332         // store the current bandwidth for later use
333         state->current_bandwidth = bw;
334
335         if (state->timf == 0) {
336                 dprintk("using default timf");
337                 timf = state->cfg.bw->timf;
338         } else {
339                 dprintk("using updated timf");
340                 timf = state->timf;
341         }
342
343         timf = timf * (bw / 50) / 160;
344
345         dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
346         dib7000p_write_word(state, 24, (u16) ((timf) & 0xffff));
347
348         return 0;
349 }
350
351 static int dib7000p_sad_calib(struct dib7000p_state *state)
352 {
353 /* internal */
354         dib7000p_write_word(state, 73, (0 << 1) | (0 << 0));
355
356         if (state->version == SOC7090)
357                 dib7000p_write_word(state, 74, 2048);
358         else
359                 dib7000p_write_word(state, 74, 776);
360
361         /* do the calibration */
362         dib7000p_write_word(state, 73, (1 << 0));
363         dib7000p_write_word(state, 73, (0 << 0));
364
365         msleep(1);
366
367         return 0;
368 }
369
370 int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
371 {
372         struct dib7000p_state *state = demod->demodulator_priv;
373         if (value > 4095)
374                 value = 4095;
375         state->wbd_ref = value;
376         return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value);
377 }
378 EXPORT_SYMBOL(dib7000p_set_wbd_ref);
379
380 static void dib7000p_reset_pll(struct dib7000p_state *state)
381 {
382         struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
383         u16 clk_cfg0;
384
385         if (state->version == SOC7090) {
386                 dib7000p_write_word(state, 1856, (!bw->pll_reset << 13) | (bw->pll_range << 12) | (bw->pll_ratio << 6) | (bw->pll_prediv));
387
388                 while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
389                         ;
390
391                 dib7000p_write_word(state, 1857, dib7000p_read_word(state, 1857) | (!bw->pll_bypass << 15));
392         } else {
393                 /* force PLL bypass */
394                 clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) |
395                         (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0);
396
397                 dib7000p_write_word(state, 900, clk_cfg0);
398
399                 /* P_pll_cfg */
400                 dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset);
401                 clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff);
402                 dib7000p_write_word(state, 900, clk_cfg0);
403         }
404
405         dib7000p_write_word(state, 18, (u16) (((bw->internal * 1000) >> 16) & 0xffff));
406         dib7000p_write_word(state, 19, (u16) ((bw->internal * 1000) & 0xffff));
407         dib7000p_write_word(state, 21, (u16) ((bw->ifreq >> 16) & 0xffff));
408         dib7000p_write_word(state, 22, (u16) ((bw->ifreq) & 0xffff));
409
410         dib7000p_write_word(state, 72, bw->sad_cfg);
411 }
412
413 static u32 dib7000p_get_internal_freq(struct dib7000p_state *state)
414 {
415         u32 internal = (u32) dib7000p_read_word(state, 18) << 16;
416         internal |= (u32) dib7000p_read_word(state, 19);
417         internal /= 1000;
418
419         return internal;
420 }
421
422 int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
423 {
424         struct dib7000p_state *state = fe->demodulator_priv;
425         u16 reg_1857, reg_1856 = dib7000p_read_word(state, 1856);
426         u8 loopdiv, prediv;
427         u32 internal, xtal;
428
429         /* get back old values */
430         prediv = reg_1856 & 0x3f;
431         loopdiv = (reg_1856 >> 6) & 0x3f;
432
433         if ((bw != NULL) && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) {
434                 dprintk("Updating pll (prediv: old =  %d new = %d ; loopdiv : old = %d new = %d)", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio);
435                 reg_1856 &= 0xf000;
436                 reg_1857 = dib7000p_read_word(state, 1857);
437                 dib7000p_write_word(state, 1857, reg_1857 & ~(1 << 15));
438
439                 dib7000p_write_word(state, 1856, reg_1856 | ((bw->pll_ratio & 0x3f) << 6) | (bw->pll_prediv & 0x3f));
440
441                 /* write new system clk into P_sec_len */
442                 internal = dib7000p_get_internal_freq(state);
443                 xtal = (internal / loopdiv) * prediv;
444                 internal = 1000 * (xtal / bw->pll_prediv) * bw->pll_ratio;      /* new internal */
445                 dib7000p_write_word(state, 18, (u16) ((internal >> 16) & 0xffff));
446                 dib7000p_write_word(state, 19, (u16) (internal & 0xffff));
447
448                 dib7000p_write_word(state, 1857, reg_1857 | (1 << 15));
449
450                 while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
451                         dprintk("Waiting for PLL to lock");
452
453                 return 0;
454         }
455         return -EIO;
456 }
457 EXPORT_SYMBOL(dib7000p_update_pll);
458
459 static int dib7000p_reset_gpio(struct dib7000p_state *st)
460 {
461         /* reset the GPIOs */
462         dprintk("gpio dir: %x: val: %x, pwm_pos: %x", st->gpio_dir, st->gpio_val, st->cfg.gpio_pwm_pos);
463
464         dib7000p_write_word(st, 1029, st->gpio_dir);
465         dib7000p_write_word(st, 1030, st->gpio_val);
466
467         /* TODO 1031 is P_gpio_od */
468
469         dib7000p_write_word(st, 1032, st->cfg.gpio_pwm_pos);
470
471         dib7000p_write_word(st, 1037, st->cfg.pwm_freq_div);
472         return 0;
473 }
474
475 static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val)
476 {
477         st->gpio_dir = dib7000p_read_word(st, 1029);
478         st->gpio_dir &= ~(1 << num);    /* reset the direction bit */
479         st->gpio_dir |= (dir & 0x1) << num;     /* set the new direction */
480         dib7000p_write_word(st, 1029, st->gpio_dir);
481
482         st->gpio_val = dib7000p_read_word(st, 1030);
483         st->gpio_val &= ~(1 << num);    /* reset the direction bit */
484         st->gpio_val |= (val & 0x01) << num;    /* set the new value */
485         dib7000p_write_word(st, 1030, st->gpio_val);
486
487         return 0;
488 }
489
490 int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val)
491 {
492         struct dib7000p_state *state = demod->demodulator_priv;
493         return dib7000p_cfg_gpio(state, num, dir, val);
494 }
495 EXPORT_SYMBOL(dib7000p_set_gpio);
496
497 static u16 dib7000p_defaults[] = {
498         // auto search configuration
499         3, 2,
500         0x0004,
501         0x1000,
502         0x0814,                 /* Equal Lock */
503
504         12, 6,
505         0x001b,
506         0x7740,
507         0x005b,
508         0x8d80,
509         0x01c9,
510         0xc380,
511         0x0000,
512         0x0080,
513         0x0000,
514         0x0090,
515         0x0001,
516         0xd4c0,
517
518         1, 26,
519         0x6680,
520
521         /* set ADC level to -16 */
522         11, 79,
523         (1 << 13) - 825 - 117,
524         (1 << 13) - 837 - 117,
525         (1 << 13) - 811 - 117,
526         (1 << 13) - 766 - 117,
527         (1 << 13) - 737 - 117,
528         (1 << 13) - 693 - 117,
529         (1 << 13) - 648 - 117,
530         (1 << 13) - 619 - 117,
531         (1 << 13) - 575 - 117,
532         (1 << 13) - 531 - 117,
533         (1 << 13) - 501 - 117,
534
535         1, 142,
536         0x0410,
537
538         /* disable power smoothing */
539         8, 145,
540         0,
541         0,
542         0,
543         0,
544         0,
545         0,
546         0,
547         0,
548
549         1, 154,
550         1 << 13,
551
552         1, 168,
553         0x0ccd,
554
555         1, 183,
556         0x200f,
557
558         1, 212,
559                 0x169,
560
561         5, 187,
562         0x023d,
563         0x00a4,
564         0x00a4,
565         0x7ff0,
566         0x3ccc,
567
568         1, 198,
569         0x800,
570
571         1, 222,
572         0x0010,
573
574         1, 235,
575         0x0062,
576
577         2, 901,
578         0x0006,
579         (3 << 10) | (1 << 6),
580
581         1, 905,
582         0x2c8e,
583
584         0,
585 };
586
587 static int dib7000p_demod_reset(struct dib7000p_state *state)
588 {
589         dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
590
591         if (state->version == SOC7090)
592                 dibx000_reset_i2c_master(&state->i2c_master);
593
594         dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE);
595
596         /* restart all parts */
597         dib7000p_write_word(state, 770, 0xffff);
598         dib7000p_write_word(state, 771, 0xffff);
599         dib7000p_write_word(state, 772, 0x001f);
600         dib7000p_write_word(state, 898, 0x0003);
601         dib7000p_write_word(state, 1280, 0x001f - ((1 << 4) | (1 << 3)));
602
603         dib7000p_write_word(state, 770, 0);
604         dib7000p_write_word(state, 771, 0);
605         dib7000p_write_word(state, 772, 0);
606         dib7000p_write_word(state, 898, 0);
607         dib7000p_write_word(state, 1280, 0);
608
609         /* default */
610         dib7000p_reset_pll(state);
611
612         if (dib7000p_reset_gpio(state) != 0)
613                 dprintk("GPIO reset was not successful.");
614
615         if (state->version == SOC7090) {
616                 dib7000p_write_word(state, 899, 0);
617
618                 /* impulse noise */
619                 dib7000p_write_word(state, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */
620                 dib7000p_write_word(state, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */
621                 dib7000p_write_word(state, 44, 300); /* 300 fag P_iqc_dect_min = +280 */
622                 dib7000p_write_word(state, 273, (1<<6) | 30);
623         }
624         if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
625                 dprintk("OUTPUT_MODE could not be reset.");
626
627         dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
628         dib7000p_sad_calib(state);
629         dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
630
631         /* unforce divstr regardless whether i2c enumeration was done or not */
632         dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1));
633
634         dib7000p_set_bandwidth(state, 8000);
635
636         if (state->version == SOC7090) {
637                 dib7000p_write_word(state, 36, 0x5755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */
638         } else {
639                 if (state->cfg.tuner_is_baseband)
640                         dib7000p_write_word(state, 36, 0x0755);
641                 else
642                         dib7000p_write_word(state, 36, 0x1f55);
643         }
644
645         dib7000p_write_tab(state, dib7000p_defaults);
646
647         dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
648
649         return 0;
650 }
651
652 static void dib7000p_pll_clk_cfg(struct dib7000p_state *state)
653 {
654         u16 tmp = 0;
655         tmp = dib7000p_read_word(state, 903);
656         dib7000p_write_word(state, 903, (tmp | 0x1));
657         tmp = dib7000p_read_word(state, 900);
658         dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6));
659 }
660
661 static void dib7000p_restart_agc(struct dib7000p_state *state)
662 {
663         // P_restart_iqc & P_restart_agc
664         dib7000p_write_word(state, 770, (1 << 11) | (1 << 9));
665         dib7000p_write_word(state, 770, 0x0000);
666 }
667
668 static int dib7000p_update_lna(struct dib7000p_state *state)
669 {
670         u16 dyn_gain;
671
672         if (state->cfg.update_lna) {
673                 dyn_gain = dib7000p_read_word(state, 394);
674                 if (state->cfg.update_lna(&state->demod, dyn_gain)) {
675                         dib7000p_restart_agc(state);
676                         return 1;
677                 }
678         }
679
680         return 0;
681 }
682
683 static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
684 {
685         struct dibx000_agc_config *agc = NULL;
686         int i;
687         if (state->current_band == band && state->current_agc != NULL)
688                 return 0;
689         state->current_band = band;
690
691         for (i = 0; i < state->cfg.agc_config_count; i++)
692                 if (state->cfg.agc[i].band_caps & band) {
693                         agc = &state->cfg.agc[i];
694                         break;
695                 }
696
697         if (agc == NULL) {
698                 dprintk("no valid AGC configuration found for band 0x%02x", band);
699                 return -EINVAL;
700         }
701
702         state->current_agc = agc;
703
704         /* AGC */
705         dib7000p_write_word(state, 75, agc->setup);
706         dib7000p_write_word(state, 76, agc->inv_gain);
707         dib7000p_write_word(state, 77, agc->time_stabiliz);
708         dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);
709
710         // Demod AGC loop configuration
711         dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);
712         dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp);
713
714         /* AGC continued */
715         dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
716                 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
717
718         if (state->wbd_ref != 0)
719                 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref);
720         else
721                 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref);
722
723         dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
724
725         dib7000p_write_word(state, 107, agc->agc1_max);
726         dib7000p_write_word(state, 108, agc->agc1_min);
727         dib7000p_write_word(state, 109, agc->agc2_max);
728         dib7000p_write_word(state, 110, agc->agc2_min);
729         dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
730         dib7000p_write_word(state, 112, agc->agc1_pt3);
731         dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
732         dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
733         dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
734         return 0;
735 }
736
737 static void dib7000p_set_dds(struct dib7000p_state *state, s32 offset_khz)
738 {
739         u32 internal = dib7000p_get_internal_freq(state);
740         s32 unit_khz_dds_val = 67108864 / (internal);   /* 2**26 / Fsampling is the unit 1KHz offset */
741         u32 abs_offset_khz = ABS(offset_khz);
742         u32 dds = state->cfg.bw->ifreq & 0x1ffffff;
743         u8 invert = !!(state->cfg.bw->ifreq & (1 << 25));
744
745         dprintk("setting a frequency offset of %dkHz internal freq = %d invert = %d", offset_khz, internal, invert);
746
747         if (offset_khz < 0)
748                 unit_khz_dds_val *= -1;
749
750         /* IF tuner */
751         if (invert)
752                 dds -= (abs_offset_khz * unit_khz_dds_val);     /* /100 because of /100 on the unit_khz_dds_val line calc for better accuracy */
753         else
754                 dds += (abs_offset_khz * unit_khz_dds_val);
755
756         if (abs_offset_khz <= (internal / 2)) { /* Max dds offset is the half of the demod freq */
757                 dib7000p_write_word(state, 21, (u16) (((dds >> 16) & 0x1ff) | (0 << 10) | (invert << 9)));
758                 dib7000p_write_word(state, 22, (u16) (dds & 0xffff));
759         }
760 }
761
762 static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
763 {
764         struct dib7000p_state *state = demod->demodulator_priv;
765         int ret = -1;
766         u8 *agc_state = &state->agc_state;
767         u8 agc_split;
768         u16 reg;
769         u32 upd_demod_gain_period = 0x1000;
770
771         switch (state->agc_state) {
772         case 0:
773                 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
774                 if (state->version == SOC7090) {
775                         reg = dib7000p_read_word(state, 0x79b) & 0xff00;
776                         dib7000p_write_word(state, 0x79a, upd_demod_gain_period & 0xFFFF);      /* lsb */
777                         dib7000p_write_word(state, 0x79b, reg | (1 << 14) | ((upd_demod_gain_period >> 16) & 0xFF));
778
779                         /* enable adc i & q */
780                         reg = dib7000p_read_word(state, 0x780);
781                         dib7000p_write_word(state, 0x780, (reg | (0x3)) & (~(1 << 7)));
782                 } else {
783                         dib7000p_set_adc_state(state, DIBX000_ADC_ON);
784                         dib7000p_pll_clk_cfg(state);
785                 }
786
787                 if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency / 1000)) != 0)
788                         return -1;
789
790                 dib7000p_set_dds(state, 0);
791                 ret = 7;
792                 (*agc_state)++;
793                 break;
794
795         case 1:
796                 if (state->cfg.agc_control)
797                         state->cfg.agc_control(&state->demod, 1);
798
799                 dib7000p_write_word(state, 78, 32768);
800                 if (!state->current_agc->perform_agc_softsplit) {
801                         /* we are using the wbd - so slow AGC startup */
802                         /* force 0 split on WBD and restart AGC */
803                         dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));
804                         (*agc_state)++;
805                         ret = 5;
806                 } else {
807                         /* default AGC startup */
808                         (*agc_state) = 4;
809                         /* wait AGC rough lock time */
810                         ret = 7;
811                 }
812
813                 dib7000p_restart_agc(state);
814                 break;
815
816         case 2:         /* fast split search path after 5sec */
817                 dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4));   /* freeze AGC loop */
818                 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8));     /* fast split search 0.25kHz */
819                 (*agc_state)++;
820                 ret = 14;
821                 break;
822
823         case 3:         /* split search ended */
824                 agc_split = (u8) dib7000p_read_word(state, 396);        /* store the split value for the next time */
825                 dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */
826
827                 dib7000p_write_word(state, 75, state->current_agc->setup);      /* std AGC loop */
828                 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split);        /* standard split search */
829
830                 dib7000p_restart_agc(state);
831
832                 dprintk("SPLIT %p: %hd", demod, agc_split);
833
834                 (*agc_state)++;
835                 ret = 5;
836                 break;
837
838         case 4:         /* LNA startup */
839                 ret = 7;
840
841                 if (dib7000p_update_lna(state))
842                         ret = 5;
843                 else
844                         (*agc_state)++;
845                 break;
846
847         case 5:
848                 if (state->cfg.agc_control)
849                         state->cfg.agc_control(&state->demod, 0);
850                 (*agc_state)++;
851                 break;
852         default:
853                 break;
854         }
855         return ret;
856 }
857
858 static void dib7000p_update_timf(struct dib7000p_state *state)
859 {
860         u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428);
861         state->timf = timf * 160 / (state->current_bandwidth / 50);
862         dib7000p_write_word(state, 23, (u16) (timf >> 16));
863         dib7000p_write_word(state, 24, (u16) (timf & 0xffff));
864         dprintk("updated timf_frequency: %d (default: %d)", state->timf, state->cfg.bw->timf);
865
866 }
867
868 u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
869 {
870         struct dib7000p_state *state = fe->demodulator_priv;
871         switch (op) {
872         case DEMOD_TIMF_SET:
873                 state->timf = timf;
874                 break;
875         case DEMOD_TIMF_UPDATE:
876                 dib7000p_update_timf(state);
877                 break;
878         case DEMOD_TIMF_GET:
879                 break;
880         }
881         dib7000p_set_bandwidth(state, state->current_bandwidth);
882         return state->timf;
883 }
884 EXPORT_SYMBOL(dib7000p_ctrl_timf);
885
886 static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq)
887 {
888         u16 value, est[4];
889
890         dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
891
892         /* nfft, guard, qam, alpha */
893         value = 0;
894         switch (ch->u.ofdm.transmission_mode) {
895         case TRANSMISSION_MODE_2K:
896                 value |= (0 << 7);
897                 break;
898         case TRANSMISSION_MODE_4K:
899                 value |= (2 << 7);
900                 break;
901         default:
902         case TRANSMISSION_MODE_8K:
903                 value |= (1 << 7);
904                 break;
905         }
906         switch (ch->u.ofdm.guard_interval) {
907         case GUARD_INTERVAL_1_32:
908                 value |= (0 << 5);
909                 break;
910         case GUARD_INTERVAL_1_16:
911                 value |= (1 << 5);
912                 break;
913         case GUARD_INTERVAL_1_4:
914                 value |= (3 << 5);
915                 break;
916         default:
917         case GUARD_INTERVAL_1_8:
918                 value |= (2 << 5);
919                 break;
920         }
921         switch (ch->u.ofdm.constellation) {
922         case QPSK:
923                 value |= (0 << 3);
924                 break;
925         case QAM_16:
926                 value |= (1 << 3);
927                 break;
928         default:
929         case QAM_64:
930                 value |= (2 << 3);
931                 break;
932         }
933         switch (HIERARCHY_1) {
934         case HIERARCHY_2:
935                 value |= 2;
936                 break;
937         case HIERARCHY_4:
938                 value |= 4;
939                 break;
940         default:
941         case HIERARCHY_1:
942                 value |= 1;
943                 break;
944         }
945         dib7000p_write_word(state, 0, value);
946         dib7000p_write_word(state, 5, (seq << 4) | 1);  /* do not force tps, search list 0 */
947
948         /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
949         value = 0;
950         if (1 != 0)
951                 value |= (1 << 6);
952         if (ch->u.ofdm.hierarchy_information == 1)
953                 value |= (1 << 4);
954         if (1 == 1)
955                 value |= 1;
956         switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
957         case FEC_2_3:
958                 value |= (2 << 1);
959                 break;
960         case FEC_3_4:
961                 value |= (3 << 1);
962                 break;
963         case FEC_5_6:
964                 value |= (5 << 1);
965                 break;
966         case FEC_7_8:
967                 value |= (7 << 1);
968                 break;
969         default:
970         case FEC_1_2:
971                 value |= (1 << 1);
972                 break;
973         }
974         dib7000p_write_word(state, 208, value);
975
976         /* offset loop parameters */
977         dib7000p_write_word(state, 26, 0x6680);
978         dib7000p_write_word(state, 32, 0x0003);
979         dib7000p_write_word(state, 29, 0x1273);
980         dib7000p_write_word(state, 33, 0x0005);
981
982         /* P_dvsy_sync_wait */
983         switch (ch->u.ofdm.transmission_mode) {
984         case TRANSMISSION_MODE_8K:
985                 value = 256;
986                 break;
987         case TRANSMISSION_MODE_4K:
988                 value = 128;
989                 break;
990         case TRANSMISSION_MODE_2K:
991         default:
992                 value = 64;
993                 break;
994         }
995         switch (ch->u.ofdm.guard_interval) {
996         case GUARD_INTERVAL_1_16:
997                 value *= 2;
998                 break;
999         case GUARD_INTERVAL_1_8:
1000                 value *= 4;
1001                 break;
1002         case GUARD_INTERVAL_1_4:
1003                 value *= 8;
1004                 break;
1005         default:
1006         case GUARD_INTERVAL_1_32:
1007                 value *= 1;
1008                 break;
1009         }
1010         if (state->cfg.diversity_delay == 0)
1011                 state->div_sync_wait = (value * 3) / 2 + 48;
1012         else
1013                 state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay;
1014
1015         /* deactive the possibility of diversity reception if extended interleaver */
1016         state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K;
1017         dib7000p_set_diversity_in(&state->demod, state->div_state);
1018
1019         /* channel estimation fine configuration */
1020         switch (ch->u.ofdm.constellation) {
1021         case QAM_64:
1022                 est[0] = 0x0148;        /* P_adp_regul_cnt 0.04 */
1023                 est[1] = 0xfff0;        /* P_adp_noise_cnt -0.002 */
1024                 est[2] = 0x00a4;        /* P_adp_regul_ext 0.02 */
1025                 est[3] = 0xfff8;        /* P_adp_noise_ext -0.001 */
1026                 break;
1027         case QAM_16:
1028                 est[0] = 0x023d;        /* P_adp_regul_cnt 0.07 */
1029                 est[1] = 0xffdf;        /* P_adp_noise_cnt -0.004 */
1030                 est[2] = 0x00a4;        /* P_adp_regul_ext 0.02 */
1031                 est[3] = 0xfff0;        /* P_adp_noise_ext -0.002 */
1032                 break;
1033         default:
1034                 est[0] = 0x099a;        /* P_adp_regul_cnt 0.3 */
1035                 est[1] = 0xffae;        /* P_adp_noise_cnt -0.01 */
1036                 est[2] = 0x0333;        /* P_adp_regul_ext 0.1 */
1037                 est[3] = 0xfff8;        /* P_adp_noise_ext -0.002 */
1038                 break;
1039         }
1040         for (value = 0; value < 4; value++)
1041                 dib7000p_write_word(state, 187 + value, est[value]);
1042 }
1043
1044 static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
1045 {
1046         struct dib7000p_state *state = demod->demodulator_priv;
1047         struct dvb_frontend_parameters schan;
1048         u32 value, factor;
1049         u32 internal = dib7000p_get_internal_freq(state);
1050
1051         schan = *ch;
1052         schan.u.ofdm.constellation = QAM_64;
1053         schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
1054         schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
1055         schan.u.ofdm.code_rate_HP = FEC_2_3;
1056         schan.u.ofdm.code_rate_LP = FEC_3_4;
1057         schan.u.ofdm.hierarchy_information = 0;
1058
1059         dib7000p_set_channel(state, &schan, 7);
1060
1061         factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth);
1062         if (factor >= 5000)
1063                 factor = 1;
1064         else
1065                 factor = 6;
1066
1067         value = 30 * internal * factor;
1068         dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff));
1069         dib7000p_write_word(state, 7, (u16) (value & 0xffff));
1070         value = 100 * internal * factor;
1071         dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff));
1072         dib7000p_write_word(state, 9, (u16) (value & 0xffff));
1073         value = 500 * internal * factor;
1074         dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff));
1075         dib7000p_write_word(state, 11, (u16) (value & 0xffff));
1076
1077         value = dib7000p_read_word(state, 0);
1078         dib7000p_write_word(state, 0, (u16) ((1 << 9) | value));
1079         dib7000p_read_word(state, 1284);
1080         dib7000p_write_word(state, 0, (u16) value);
1081
1082         return 0;
1083 }
1084
1085 static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod)
1086 {
1087         struct dib7000p_state *state = demod->demodulator_priv;
1088         u16 irq_pending = dib7000p_read_word(state, 1284);
1089
1090         if (irq_pending & 0x1)
1091                 return 1;
1092
1093         if (irq_pending & 0x2)
1094                 return 2;
1095
1096         return 0;
1097 }
1098
1099 static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw)
1100 {
1101         static s16 notch[] = { 16143, 14402, 12238, 9713, 6902, 3888, 759, -2392 };
1102         static u8 sine[] = { 0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
1103                 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
1104                 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
1105                 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
1106                 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
1107                 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
1108                 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
1109                 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
1110                 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
1111                 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
1112                 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
1113                 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
1114                 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
1115                 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
1116                 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
1117                 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1118                 255, 255, 255, 255, 255, 255
1119         };
1120
1121         u32 xtal = state->cfg.bw->xtal_hz / 1000;
1122         int f_rel = DIV_ROUND_CLOSEST(rf_khz, xtal) * xtal - rf_khz;
1123         int k;
1124         int coef_re[8], coef_im[8];
1125         int bw_khz = bw;
1126         u32 pha;
1127
1128         dprintk("relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal);
1129
1130         if (f_rel < -bw_khz / 2 || f_rel > bw_khz / 2)
1131                 return;
1132
1133         bw_khz /= 100;
1134
1135         dib7000p_write_word(state, 142, 0x0610);
1136
1137         for (k = 0; k < 8; k++) {
1138                 pha = ((f_rel * (k + 1) * 112 * 80 / bw_khz) / 1000) & 0x3ff;
1139
1140                 if (pha == 0) {
1141                         coef_re[k] = 256;
1142                         coef_im[k] = 0;
1143                 } else if (pha < 256) {
1144                         coef_re[k] = sine[256 - (pha & 0xff)];
1145                         coef_im[k] = sine[pha & 0xff];
1146                 } else if (pha == 256) {
1147                         coef_re[k] = 0;
1148                         coef_im[k] = 256;
1149                 } else if (pha < 512) {
1150                         coef_re[k] = -sine[pha & 0xff];
1151                         coef_im[k] = sine[256 - (pha & 0xff)];
1152                 } else if (pha == 512) {
1153                         coef_re[k] = -256;
1154                         coef_im[k] = 0;
1155                 } else if (pha < 768) {
1156                         coef_re[k] = -sine[256 - (pha & 0xff)];
1157                         coef_im[k] = -sine[pha & 0xff];
1158                 } else if (pha == 768) {
1159                         coef_re[k] = 0;
1160                         coef_im[k] = -256;
1161                 } else {
1162                         coef_re[k] = sine[pha & 0xff];
1163                         coef_im[k] = -sine[256 - (pha & 0xff)];
1164                 }
1165
1166                 coef_re[k] *= notch[k];
1167                 coef_re[k] += (1 << 14);
1168                 if (coef_re[k] >= (1 << 24))
1169                         coef_re[k] = (1 << 24) - 1;
1170                 coef_re[k] /= (1 << 15);
1171
1172                 coef_im[k] *= notch[k];
1173                 coef_im[k] += (1 << 14);
1174                 if (coef_im[k] >= (1 << 24))
1175                         coef_im[k] = (1 << 24) - 1;
1176                 coef_im[k] /= (1 << 15);
1177
1178                 dprintk("PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]);
1179
1180                 dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
1181                 dib7000p_write_word(state, 144, coef_im[k] & 0x3ff);
1182                 dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
1183         }
1184         dib7000p_write_word(state, 143, 0);
1185 }
1186
1187 static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
1188 {
1189         struct dib7000p_state *state = demod->demodulator_priv;
1190         u16 tmp = 0;
1191
1192         if (ch != NULL)
1193                 dib7000p_set_channel(state, ch, 0);
1194         else
1195                 return -EINVAL;
1196
1197         // restart demod
1198         dib7000p_write_word(state, 770, 0x4000);
1199         dib7000p_write_word(state, 770, 0x0000);
1200         msleep(45);
1201
1202         /* 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 */
1203         tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
1204         if (state->sfn_workaround_active) {
1205                 dprintk("SFN workaround is active");
1206                 tmp |= (1 << 9);
1207                 dib7000p_write_word(state, 166, 0x4000);
1208         } else {
1209                 dib7000p_write_word(state, 166, 0x0000);
1210         }
1211         dib7000p_write_word(state, 29, tmp);
1212
1213         // never achieved a lock with that bandwidth so far - wait for osc-freq to update
1214         if (state->timf == 0)
1215                 msleep(200);
1216
1217         /* offset loop parameters */
1218
1219         /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
1220         tmp = (6 << 8) | 0x80;
1221         switch (ch->u.ofdm.transmission_mode) {
1222         case TRANSMISSION_MODE_2K:
1223                 tmp |= (2 << 12);
1224                 break;
1225         case TRANSMISSION_MODE_4K:
1226                 tmp |= (3 << 12);
1227                 break;
1228         default:
1229         case TRANSMISSION_MODE_8K:
1230                 tmp |= (4 << 12);
1231                 break;
1232         }
1233         dib7000p_write_word(state, 26, tmp);    /* timf_a(6xxx) */
1234
1235         /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1236         tmp = (0 << 4);
1237         switch (ch->u.ofdm.transmission_mode) {
1238         case TRANSMISSION_MODE_2K:
1239                 tmp |= 0x6;
1240                 break;
1241         case TRANSMISSION_MODE_4K:
1242                 tmp |= 0x7;
1243                 break;
1244         default:
1245         case TRANSMISSION_MODE_8K:
1246                 tmp |= 0x8;
1247                 break;
1248         }
1249         dib7000p_write_word(state, 32, tmp);
1250
1251         /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1252         tmp = (0 << 4);
1253         switch (ch->u.ofdm.transmission_mode) {
1254         case TRANSMISSION_MODE_2K:
1255                 tmp |= 0x6;
1256                 break;
1257         case TRANSMISSION_MODE_4K:
1258                 tmp |= 0x7;
1259                 break;
1260         default:
1261         case TRANSMISSION_MODE_8K:
1262                 tmp |= 0x8;
1263                 break;
1264         }
1265         dib7000p_write_word(state, 33, tmp);
1266
1267         tmp = dib7000p_read_word(state, 509);
1268         if (!((tmp >> 6) & 0x1)) {
1269                 /* restart the fec */
1270                 tmp = dib7000p_read_word(state, 771);
1271                 dib7000p_write_word(state, 771, tmp | (1 << 1));
1272                 dib7000p_write_word(state, 771, tmp);
1273                 msleep(40);
1274                 tmp = dib7000p_read_word(state, 509);
1275         }
1276         // we achieved a lock - it's time to update the osc freq
1277         if ((tmp >> 6) & 0x1) {
1278                 dib7000p_update_timf(state);
1279                 /* P_timf_alpha += 2 */
1280                 tmp = dib7000p_read_word(state, 26);
1281                 dib7000p_write_word(state, 26, (tmp & ~(0xf << 12)) | ((((tmp >> 12) & 0xf) + 5) << 12));
1282         }
1283
1284         if (state->cfg.spur_protect)
1285                 dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1286
1287         dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1288         return 0;
1289 }
1290
1291 static int dib7000p_wakeup(struct dvb_frontend *demod)
1292 {
1293         struct dib7000p_state *state = demod->demodulator_priv;
1294         dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
1295         dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
1296         if (state->version == SOC7090)
1297                 dib7000p_sad_calib(state);
1298         return 0;
1299 }
1300
1301 static int dib7000p_sleep(struct dvb_frontend *demod)
1302 {
1303         struct dib7000p_state *state = demod->demodulator_priv;
1304         if (state->version == SOC7090)
1305                 return dib7090_set_output_mode(demod, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1306         return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1307 }
1308
1309 static int dib7000p_identify(struct dib7000p_state *st)
1310 {
1311         u16 value;
1312         dprintk("checking demod on I2C address: %d (%x)", st->i2c_addr, st->i2c_addr);
1313
1314         if ((value = dib7000p_read_word(st, 768)) != 0x01b3) {
1315                 dprintk("wrong Vendor ID (read=0x%x)", value);
1316                 return -EREMOTEIO;
1317         }
1318
1319         if ((value = dib7000p_read_word(st, 769)) != 0x4000) {
1320                 dprintk("wrong Device ID (%x)", value);
1321                 return -EREMOTEIO;
1322         }
1323
1324         return 0;
1325 }
1326
1327 static int dib7000p_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1328 {
1329         struct dib7000p_state *state = fe->demodulator_priv;
1330         u16 tps = dib7000p_read_word(state, 463);
1331
1332         fep->inversion = INVERSION_AUTO;
1333
1334         fep->u.ofdm.bandwidth = BANDWIDTH_TO_INDEX(state->current_bandwidth);
1335
1336         switch ((tps >> 8) & 0x3) {
1337         case 0:
1338                 fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
1339                 break;
1340         case 1:
1341                 fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
1342                 break;
1343         /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */
1344         }
1345
1346         switch (tps & 0x3) {
1347         case 0:
1348                 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
1349                 break;
1350         case 1:
1351                 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
1352                 break;
1353         case 2:
1354                 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
1355                 break;
1356         case 3:
1357                 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
1358                 break;
1359         }
1360
1361         switch ((tps >> 14) & 0x3) {
1362         case 0:
1363                 fep->u.ofdm.constellation = QPSK;
1364                 break;
1365         case 1:
1366                 fep->u.ofdm.constellation = QAM_16;
1367                 break;
1368         case 2:
1369         default:
1370                 fep->u.ofdm.constellation = QAM_64;
1371                 break;
1372         }
1373
1374         /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1375         /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1376
1377         fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
1378         switch ((tps >> 5) & 0x7) {
1379         case 1:
1380                 fep->u.ofdm.code_rate_HP = FEC_1_2;
1381                 break;
1382         case 2:
1383                 fep->u.ofdm.code_rate_HP = FEC_2_3;
1384                 break;
1385         case 3:
1386                 fep->u.ofdm.code_rate_HP = FEC_3_4;
1387                 break;
1388         case 5:
1389                 fep->u.ofdm.code_rate_HP = FEC_5_6;
1390                 break;
1391         case 7:
1392         default:
1393                 fep->u.ofdm.code_rate_HP = FEC_7_8;
1394                 break;
1395
1396         }
1397
1398         switch ((tps >> 2) & 0x7) {
1399         case 1:
1400                 fep->u.ofdm.code_rate_LP = FEC_1_2;
1401                 break;
1402         case 2:
1403                 fep->u.ofdm.code_rate_LP = FEC_2_3;
1404                 break;
1405         case 3:
1406                 fep->u.ofdm.code_rate_LP = FEC_3_4;
1407                 break;
1408         case 5:
1409                 fep->u.ofdm.code_rate_LP = FEC_5_6;
1410                 break;
1411         case 7:
1412         default:
1413                 fep->u.ofdm.code_rate_LP = FEC_7_8;
1414                 break;
1415         }
1416
1417         /* native interleaver: (dib7000p_read_word(state, 464) >>  5) & 0x1 */
1418
1419         return 0;
1420 }
1421
1422 static int dib7000p_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1423 {
1424         struct dib7000p_state *state = fe->demodulator_priv;
1425         int time, ret;
1426
1427         if (state->version == SOC7090) {
1428                 dib7090_set_diversity_in(fe, 0);
1429                 dib7090_set_output_mode(fe, OUTMODE_HIGH_Z);
1430         } else
1431                 dib7000p_set_output_mode(state, OUTMODE_HIGH_Z);
1432
1433         /* maybe the parameter has been changed */
1434         state->sfn_workaround_active = buggy_sfn_workaround;
1435
1436         if (fe->ops.tuner_ops.set_params)
1437                 fe->ops.tuner_ops.set_params(fe, fep);
1438
1439         /* start up the AGC */
1440         state->agc_state = 0;
1441         do {
1442                 time = dib7000p_agc_startup(fe, fep);
1443                 if (time != -1)
1444                         msleep(time);
1445         } while (time != -1);
1446
1447         if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
1448                 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || fep->u.ofdm.constellation == QAM_AUTO || fep->u.ofdm.code_rate_HP == FEC_AUTO) {
1449                 int i = 800, found;
1450
1451                 dib7000p_autosearch_start(fe, fep);
1452                 do {
1453                         msleep(1);
1454                         found = dib7000p_autosearch_is_irq(fe);
1455                 } while (found == 0 && i--);
1456
1457                 dprintk("autosearch returns: %d", found);
1458                 if (found == 0 || found == 1)
1459                         return 0;
1460
1461                 dib7000p_get_frontend(fe, fep);
1462         }
1463
1464         ret = dib7000p_tune(fe, fep);
1465
1466         /* make this a config parameter */
1467         if (state->version == SOC7090)
1468                 dib7090_set_output_mode(fe, state->cfg.output_mode);
1469         else
1470                 dib7000p_set_output_mode(state, state->cfg.output_mode);
1471
1472         return ret;
1473 }
1474
1475 static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t * stat)
1476 {
1477         struct dib7000p_state *state = fe->demodulator_priv;
1478         u16 lock = dib7000p_read_word(state, 509);
1479
1480         *stat = 0;
1481
1482         if (lock & 0x8000)
1483                 *stat |= FE_HAS_SIGNAL;
1484         if (lock & 0x3000)
1485                 *stat |= FE_HAS_CARRIER;
1486         if (lock & 0x0100)
1487                 *stat |= FE_HAS_VITERBI;
1488         if (lock & 0x0010)
1489                 *stat |= FE_HAS_SYNC;
1490         if ((lock & 0x0038) == 0x38)
1491                 *stat |= FE_HAS_LOCK;
1492
1493         return 0;
1494 }
1495
1496 static int dib7000p_read_ber(struct dvb_frontend *fe, u32 * ber)
1497 {
1498         struct dib7000p_state *state = fe->demodulator_priv;
1499         *ber = (dib7000p_read_word(state, 500) << 16) | dib7000p_read_word(state, 501);
1500         return 0;
1501 }
1502
1503 static int dib7000p_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
1504 {
1505         struct dib7000p_state *state = fe->demodulator_priv;
1506         *unc = dib7000p_read_word(state, 506);
1507         return 0;
1508 }
1509
1510 static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
1511 {
1512         struct dib7000p_state *state = fe->demodulator_priv;
1513         u16 val = dib7000p_read_word(state, 394);
1514         *strength = 65535 - val;
1515         return 0;
1516 }
1517
1518 static int dib7000p_read_snr(struct dvb_frontend *fe, u16 * snr)
1519 {
1520         struct dib7000p_state *state = fe->demodulator_priv;
1521         u16 val;
1522         s32 signal_mant, signal_exp, noise_mant, noise_exp;
1523         u32 result = 0;
1524
1525         val = dib7000p_read_word(state, 479);
1526         noise_mant = (val >> 4) & 0xff;
1527         noise_exp = ((val & 0xf) << 2);
1528         val = dib7000p_read_word(state, 480);
1529         noise_exp += ((val >> 14) & 0x3);
1530         if ((noise_exp & 0x20) != 0)
1531                 noise_exp -= 0x40;
1532
1533         signal_mant = (val >> 6) & 0xFF;
1534         signal_exp = (val & 0x3F);
1535         if ((signal_exp & 0x20) != 0)
1536                 signal_exp -= 0x40;
1537
1538         if (signal_mant != 0)
1539                 result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
1540         else
1541                 result = intlog10(2) * 10 * signal_exp - 100;
1542
1543         if (noise_mant != 0)
1544                 result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
1545         else
1546                 result -= intlog10(2) * 10 * noise_exp - 100;
1547
1548         *snr = result / ((1 << 24) / 10);
1549         return 0;
1550 }
1551
1552 static int dib7000p_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
1553 {
1554         tune->min_delay_ms = 1000;
1555         return 0;
1556 }
1557
1558 static void dib7000p_release(struct dvb_frontend *demod)
1559 {
1560         struct dib7000p_state *st = demod->demodulator_priv;
1561         dibx000_exit_i2c_master(&st->i2c_master);
1562         i2c_del_adapter(&st->dib7090_tuner_adap);
1563         kfree(st);
1564 }
1565
1566 int dib7000pc_detection(struct i2c_adapter *i2c_adap)
1567 {
1568         u8 *tx, *rx;
1569         struct i2c_msg msg[2] = {
1570                 {.addr = 18 >> 1, .flags = 0, .len = 2},
1571                 {.addr = 18 >> 1, .flags = I2C_M_RD, .len = 2},
1572         };
1573         int ret = 0;
1574
1575         tx = kzalloc(2*sizeof(u8), GFP_KERNEL);
1576         if (!tx)
1577                 return -ENOMEM;
1578         rx = kzalloc(2*sizeof(u8), GFP_KERNEL);
1579         if (!rx) {
1580                 goto rx_memory_error;
1581                 ret = -ENOMEM;
1582         }
1583
1584         msg[0].buf = tx;
1585         msg[1].buf = rx;
1586
1587         tx[0] = 0x03;
1588         tx[1] = 0x00;
1589
1590         if (i2c_transfer(i2c_adap, msg, 2) == 2)
1591                 if (rx[0] == 0x01 && rx[1] == 0xb3) {
1592                         dprintk("-D-  DiB7000PC detected");
1593                         return 1;
1594                 }
1595
1596         msg[0].addr = msg[1].addr = 0x40;
1597
1598         if (i2c_transfer(i2c_adap, msg, 2) == 2)
1599                 if (rx[0] == 0x01 && rx[1] == 0xb3) {
1600                         dprintk("-D-  DiB7000PC detected");
1601                         return 1;
1602                 }
1603
1604         dprintk("-D-  DiB7000PC not detected");
1605
1606         kfree(rx);
1607 rx_memory_error:
1608         kfree(tx);
1609         return ret;
1610 }
1611 EXPORT_SYMBOL(dib7000pc_detection);
1612
1613 struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
1614 {
1615         struct dib7000p_state *st = demod->demodulator_priv;
1616         return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1617 }
1618 EXPORT_SYMBOL(dib7000p_get_i2c_master);
1619
1620 int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1621 {
1622         struct dib7000p_state *state = fe->demodulator_priv;
1623         u16 val = dib7000p_read_word(state, 235) & 0xffef;
1624         val |= (onoff & 0x1) << 4;
1625         dprintk("PID filter enabled %d", onoff);
1626         return dib7000p_write_word(state, 235, val);
1627 }
1628 EXPORT_SYMBOL(dib7000p_pid_filter_ctrl);
1629
1630 int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1631 {
1632         struct dib7000p_state *state = fe->demodulator_priv;
1633         dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
1634         return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0);
1635 }
1636 EXPORT_SYMBOL(dib7000p_pid_filter);
1637
1638 int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
1639 {
1640         struct dib7000p_state *dpst;
1641         int k = 0;
1642         u8 new_addr = 0;
1643
1644         dpst = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
1645         if (!dpst)
1646                 return -ENOMEM;
1647
1648         dpst->i2c_adap = i2c;
1649
1650         for (k = no_of_demods - 1; k >= 0; k--) {
1651                 dpst->cfg = cfg[k];
1652
1653                 /* designated i2c address */
1654                 if (cfg[k].default_i2c_addr != 0)
1655                         new_addr = cfg[k].default_i2c_addr + (k << 1);
1656                 else
1657                         new_addr = (0x40 + k) << 1;
1658                 dpst->i2c_addr = new_addr;
1659                 dib7000p_write_word(dpst, 1287, 0x0003);        /* sram lead in, rdy */
1660                 if (dib7000p_identify(dpst) != 0) {
1661                         dpst->i2c_addr = default_addr;
1662                         dib7000p_write_word(dpst, 1287, 0x0003);        /* sram lead in, rdy */
1663                         if (dib7000p_identify(dpst) != 0) {
1664                                 dprintk("DiB7000P #%d: not identified\n", k);
1665                                 kfree(dpst);
1666                                 return -EIO;
1667                         }
1668                 }
1669
1670                 /* start diversity to pull_down div_str - just for i2c-enumeration */
1671                 dib7000p_set_output_mode(dpst, OUTMODE_DIVERSITY);
1672
1673                 /* set new i2c address and force divstart */
1674                 dib7000p_write_word(dpst, 1285, (new_addr << 2) | 0x2);
1675
1676                 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
1677         }
1678
1679         for (k = 0; k < no_of_demods; k++) {
1680                 dpst->cfg = cfg[k];
1681                 if (cfg[k].default_i2c_addr != 0)
1682                         dpst->i2c_addr = (cfg[k].default_i2c_addr + k) << 1;
1683                 else
1684                         dpst->i2c_addr = (0x40 + k) << 1;
1685
1686                 // unforce divstr
1687                 dib7000p_write_word(dpst, 1285, dpst->i2c_addr << 2);
1688
1689                 /* deactivate div - it was just for i2c-enumeration */
1690                 dib7000p_set_output_mode(dpst, OUTMODE_HIGH_Z);
1691         }
1692
1693         kfree(dpst);
1694         return 0;
1695 }
1696 EXPORT_SYMBOL(dib7000p_i2c_enumeration);
1697
1698 static const s32 lut_1000ln_mant[] = {
1699         6908, 6956, 7003, 7047, 7090, 7131, 7170, 7208, 7244, 7279, 7313, 7346, 7377, 7408, 7438, 7467, 7495, 7523, 7549, 7575, 7600
1700 };
1701
1702 static s32 dib7000p_get_adc_power(struct dvb_frontend *fe)
1703 {
1704         struct dib7000p_state *state = fe->demodulator_priv;
1705         u32 tmp_val = 0, exp = 0, mant = 0;
1706         s32 pow_i;
1707         u16 buf[2];
1708         u8 ix = 0;
1709
1710         buf[0] = dib7000p_read_word(state, 0x184);
1711         buf[1] = dib7000p_read_word(state, 0x185);
1712         pow_i = (buf[0] << 16) | buf[1];
1713         dprintk("raw pow_i = %d", pow_i);
1714
1715         tmp_val = pow_i;
1716         while (tmp_val >>= 1)
1717                 exp++;
1718
1719         mant = (pow_i * 1000 / (1 << exp));
1720         dprintk(" mant = %d exp = %d", mant / 1000, exp);
1721
1722         ix = (u8) ((mant - 1000) / 100);        /* index of the LUT */
1723         dprintk(" ix = %d", ix);
1724
1725         pow_i = (lut_1000ln_mant[ix] + 693 * (exp - 20) - 6908);
1726         pow_i = (pow_i << 8) / 1000;
1727         dprintk(" pow_i = %d", pow_i);
1728
1729         return pow_i;
1730 }
1731
1732 static int map_addr_to_serpar_number(struct i2c_msg *msg)
1733 {
1734         if ((msg->buf[0] <= 15))
1735                 msg->buf[0] -= 1;
1736         else if (msg->buf[0] == 17)
1737                 msg->buf[0] = 15;
1738         else if (msg->buf[0] == 16)
1739                 msg->buf[0] = 17;
1740         else if (msg->buf[0] == 19)
1741                 msg->buf[0] = 16;
1742         else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
1743                 msg->buf[0] -= 3;
1744         else if (msg->buf[0] == 28)
1745                 msg->buf[0] = 23;
1746         else
1747                 return -EINVAL;
1748         return 0;
1749 }
1750
1751 static int w7090p_tuner_write_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1752 {
1753         struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1754         u8 n_overflow = 1;
1755         u16 i = 1000;
1756         u16 serpar_num = msg[0].buf[0];
1757
1758         while (n_overflow == 1 && i) {
1759                 n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
1760                 i--;
1761                 if (i == 0)
1762                         dprintk("Tuner ITF: write busy (overflow)");
1763         }
1764         dib7000p_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
1765         dib7000p_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
1766
1767         return num;
1768 }
1769
1770 static int w7090p_tuner_read_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1771 {
1772         struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1773         u8 n_overflow = 1, n_empty = 1;
1774         u16 i = 1000;
1775         u16 serpar_num = msg[0].buf[0];
1776         u16 read_word;
1777
1778         while (n_overflow == 1 && i) {
1779                 n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
1780                 i--;
1781                 if (i == 0)
1782                         dprintk("TunerITF: read busy (overflow)");
1783         }
1784         dib7000p_write_word(state, 1985, (0 << 6) | (serpar_num & 0x3f));
1785
1786         i = 1000;
1787         while (n_empty == 1 && i) {
1788                 n_empty = dib7000p_read_word(state, 1984) & 0x1;
1789                 i--;
1790                 if (i == 0)
1791                         dprintk("TunerITF: read busy (empty)");
1792         }
1793         read_word = dib7000p_read_word(state, 1987);
1794         msg[1].buf[0] = (read_word >> 8) & 0xff;
1795         msg[1].buf[1] = (read_word) & 0xff;
1796
1797         return num;
1798 }
1799
1800 static int w7090p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1801 {
1802         if (map_addr_to_serpar_number(&msg[0]) == 0) {  /* else = Tuner regs to ignore : DIG_CFG, CTRL_RF_LT, PLL_CFG, PWM1_REG, ADCCLK, DIG_CFG_3; SLEEP_EN... */
1803                 if (num == 1) { /* write */
1804                         return w7090p_tuner_write_serpar(i2c_adap, msg, 1);
1805                 } else {        /* read */
1806                         return w7090p_tuner_read_serpar(i2c_adap, msg, 2);
1807                 }
1808         }
1809         return num;
1810 }
1811
1812 int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num, u16 apb_address)
1813 {
1814         struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1815         u16 word;
1816
1817         if (num == 1) {         /* write */
1818                 dib7000p_write_word(state, apb_address, ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
1819         } else {
1820                 word = dib7000p_read_word(state, apb_address);
1821                 msg[1].buf[0] = (word >> 8) & 0xff;
1822                 msg[1].buf[1] = (word) & 0xff;
1823         }
1824
1825         return num;
1826 }
1827
1828 static int dib7090_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1829 {
1830         struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1831
1832         u16 apb_address = 0, word;
1833         int i = 0;
1834         switch (msg[0].buf[0]) {
1835         case 0x12:
1836                 apb_address = 1920;
1837                 break;
1838         case 0x14:
1839                 apb_address = 1921;
1840                 break;
1841         case 0x24:
1842                 apb_address = 1922;
1843                 break;
1844         case 0x1a:
1845                 apb_address = 1923;
1846                 break;
1847         case 0x22:
1848                 apb_address = 1924;
1849                 break;
1850         case 0x33:
1851                 apb_address = 1926;
1852                 break;
1853         case 0x34:
1854                 apb_address = 1927;
1855                 break;
1856         case 0x35:
1857                 apb_address = 1928;
1858                 break;
1859         case 0x36:
1860                 apb_address = 1929;
1861                 break;
1862         case 0x37:
1863                 apb_address = 1930;
1864                 break;
1865         case 0x38:
1866                 apb_address = 1931;
1867                 break;
1868         case 0x39:
1869                 apb_address = 1932;
1870                 break;
1871         case 0x2a:
1872                 apb_address = 1935;
1873                 break;
1874         case 0x2b:
1875                 apb_address = 1936;
1876                 break;
1877         case 0x2c:
1878                 apb_address = 1937;
1879                 break;
1880         case 0x2d:
1881                 apb_address = 1938;
1882                 break;
1883         case 0x2e:
1884                 apb_address = 1939;
1885                 break;
1886         case 0x2f:
1887                 apb_address = 1940;
1888                 break;
1889         case 0x30:
1890                 apb_address = 1941;
1891                 break;
1892         case 0x31:
1893                 apb_address = 1942;
1894                 break;
1895         case 0x32:
1896                 apb_address = 1943;
1897                 break;
1898         case 0x3e:
1899                 apb_address = 1944;
1900                 break;
1901         case 0x3f:
1902                 apb_address = 1945;
1903                 break;
1904         case 0x40:
1905                 apb_address = 1948;
1906                 break;
1907         case 0x25:
1908                 apb_address = 914;
1909                 break;
1910         case 0x26:
1911                 apb_address = 915;
1912                 break;
1913         case 0x27:
1914                 apb_address = 916;
1915                 break;
1916         case 0x28:
1917                 apb_address = 917;
1918                 break;
1919         case 0x1d:
1920                 i = ((dib7000p_read_word(state, 72) >> 12) & 0x3);
1921                 word = dib7000p_read_word(state, 384 + i);
1922                 msg[1].buf[0] = (word >> 8) & 0xff;
1923                 msg[1].buf[1] = (word) & 0xff;
1924                 return num;
1925         case 0x1f:
1926                 if (num == 1) { /* write */
1927                         word = (u16) ((msg[0].buf[1] << 8) | msg[0].buf[2]);
1928                         word &= 0x3;
1929                         word = (dib7000p_read_word(state, 72) & ~(3 << 12)) | (word << 12);
1930                         dib7000p_write_word(state, 72, word);   /* Set the proper input */
1931                         return num;
1932                 }
1933         }
1934
1935         if (apb_address != 0)   /* R/W acces via APB */
1936                 return dib7090p_rw_on_apb(i2c_adap, msg, num, apb_address);
1937         else                    /* R/W access via SERPAR  */
1938                 return w7090p_tuner_rw_serpar(i2c_adap, msg, num);
1939
1940         return 0;
1941 }
1942
1943 static u32 dib7000p_i2c_func(struct i2c_adapter *adapter)
1944 {
1945         return I2C_FUNC_I2C;
1946 }
1947
1948 static struct i2c_algorithm dib7090_tuner_xfer_algo = {
1949         .master_xfer = dib7090_tuner_xfer,
1950         .functionality = dib7000p_i2c_func,
1951 };
1952
1953 struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
1954 {
1955         struct dib7000p_state *st = fe->demodulator_priv;
1956         return &st->dib7090_tuner_adap;
1957 }
1958 EXPORT_SYMBOL(dib7090_get_i2c_tuner);
1959
1960 static int dib7090_host_bus_drive(struct dib7000p_state *state, u8 drive)
1961 {
1962         u16 reg;
1963
1964         /* drive host bus 2, 3, 4 */
1965         reg = dib7000p_read_word(state, 1798) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1966         reg |= (drive << 12) | (drive << 6) | drive;
1967         dib7000p_write_word(state, 1798, reg);
1968
1969         /* drive host bus 5,6 */
1970         reg = dib7000p_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
1971         reg |= (drive << 8) | (drive << 2);
1972         dib7000p_write_word(state, 1799, reg);
1973
1974         /* drive host bus 7, 8, 9 */
1975         reg = dib7000p_read_word(state, 1800) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1976         reg |= (drive << 12) | (drive << 6) | drive;
1977         dib7000p_write_word(state, 1800, reg);
1978
1979         /* drive host bus 10, 11 */
1980         reg = dib7000p_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
1981         reg |= (drive << 8) | (drive << 2);
1982         dib7000p_write_word(state, 1801, reg);
1983
1984         /* drive host bus 12, 13, 14 */
1985         reg = dib7000p_read_word(state, 1802) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1986         reg |= (drive << 12) | (drive << 6) | drive;
1987         dib7000p_write_word(state, 1802, reg);
1988
1989         return 0;
1990 }
1991
1992 static u32 dib7090_calcSyncFreq(u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 syncSize)
1993 {
1994         u32 quantif = 3;
1995         u32 nom = (insertExtSynchro * P_Kin + syncSize);
1996         u32 denom = P_Kout;
1997         u32 syncFreq = ((nom << quantif) / denom);
1998
1999         if ((syncFreq & ((1 << quantif) - 1)) != 0)
2000                 syncFreq = (syncFreq >> quantif) + 1;
2001         else
2002                 syncFreq = (syncFreq >> quantif);
2003
2004         if (syncFreq != 0)
2005                 syncFreq = syncFreq - 1;
2006
2007         return syncFreq;
2008 }
2009
2010 static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize)
2011 {
2012         u8 index_buf;
2013         u16 rx_copy_buf[22];
2014
2015         dprintk("Configure DibStream Tx");
2016         for (index_buf = 0; index_buf < 22; index_buf++)
2017                 rx_copy_buf[index_buf] = dib7000p_read_word(state, 1536+index_buf);
2018
2019         dib7000p_write_word(state, 1615, 1);
2020         dib7000p_write_word(state, 1603, P_Kin);
2021         dib7000p_write_word(state, 1605, P_Kout);
2022         dib7000p_write_word(state, 1606, insertExtSynchro);
2023         dib7000p_write_word(state, 1608, synchroMode);
2024         dib7000p_write_word(state, 1609, (syncWord >> 16) & 0xffff);
2025         dib7000p_write_word(state, 1610, syncWord & 0xffff);
2026         dib7000p_write_word(state, 1612, syncSize);
2027         dib7000p_write_word(state, 1615, 0);
2028
2029         for (index_buf = 0; index_buf < 22; index_buf++)
2030                 dib7000p_write_word(state, 1536+index_buf, rx_copy_buf[index_buf]);
2031
2032         return 0;
2033 }
2034
2035 static int dib7090_cfg_DibRx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 synchroMode, u32 insertExtSynchro, u32 syncWord, u32 syncSize,
2036                 u32 dataOutRate)
2037 {
2038         u32 syncFreq;
2039
2040         dprintk("Configure DibStream Rx");
2041         if ((P_Kin != 0) && (P_Kout != 0)) {
2042                 syncFreq = dib7090_calcSyncFreq(P_Kin, P_Kout, insertExtSynchro, syncSize);
2043                 dib7000p_write_word(state, 1542, syncFreq);
2044         }
2045         dib7000p_write_word(state, 1554, 1);
2046         dib7000p_write_word(state, 1536, P_Kin);
2047         dib7000p_write_word(state, 1537, P_Kout);
2048         dib7000p_write_word(state, 1539, synchroMode);
2049         dib7000p_write_word(state, 1540, (syncWord >> 16) & 0xffff);
2050         dib7000p_write_word(state, 1541, syncWord & 0xffff);
2051         dib7000p_write_word(state, 1543, syncSize);
2052         dib7000p_write_word(state, 1544, dataOutRate);
2053         dib7000p_write_word(state, 1554, 0);
2054
2055         return 0;
2056 }
2057
2058 static int dib7090_enDivOnHostBus(struct dib7000p_state *state)
2059 {
2060         u16 reg;
2061
2062         dprintk("Enable Diversity on host bus");
2063         reg = (1 << 8) | (1 << 5);
2064         dib7000p_write_word(state, 1288, reg);
2065
2066         return dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
2067 }
2068
2069 static int dib7090_enAdcOnHostBus(struct dib7000p_state *state)
2070 {
2071         u16 reg;
2072
2073         dprintk("Enable ADC on host bus");
2074         reg = (1 << 7) | (1 << 5);
2075         dib7000p_write_word(state, 1288, reg);
2076
2077         return dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
2078 }
2079
2080 static int dib7090_enMpegOnHostBus(struct dib7000p_state *state)
2081 {
2082         u16 reg;
2083
2084         dprintk("Enable Mpeg on host bus");
2085         reg = (1 << 9) | (1 << 5);
2086         dib7000p_write_word(state, 1288, reg);
2087
2088         return dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
2089 }
2090
2091 static int dib7090_enMpegInput(struct dib7000p_state *state)
2092 {
2093         dprintk("Enable Mpeg input");
2094         return dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0);   /*outputRate = 8 */
2095 }
2096
2097 static int dib7090_enMpegMux(struct dib7000p_state *state, u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
2098 {
2099         u16 reg = (1 << 7) | ((pulseWidth & 0x1f) << 2) | ((enSerialMode & 0x1) << 1) | (enSerialClkDiv2 & 0x1);
2100
2101         dprintk("Enable Mpeg mux");
2102         dib7000p_write_word(state, 1287, reg);
2103
2104         reg &= ~(1 << 7);
2105         dib7000p_write_word(state, 1287, reg);
2106
2107         reg = (1 << 4);
2108         dib7000p_write_word(state, 1288, reg);
2109
2110         return 0;
2111 }
2112
2113 static int dib7090_disableMpegMux(struct dib7000p_state *state)
2114 {
2115         u16 reg;
2116
2117         dprintk("Disable Mpeg mux");
2118         dib7000p_write_word(state, 1288, 0);
2119
2120         reg = dib7000p_read_word(state, 1287);
2121         reg &= ~(1 << 7);
2122         dib7000p_write_word(state, 1287, reg);
2123
2124         return 0;
2125 }
2126
2127 static int dib7090_set_input_mode(struct dvb_frontend *fe, int mode)
2128 {
2129         struct dib7000p_state *state = fe->demodulator_priv;
2130
2131         switch (mode) {
2132         case INPUT_MODE_DIVERSITY:
2133                         dprintk("Enable diversity INPUT");
2134                         dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
2135                         break;
2136         case INPUT_MODE_MPEG:
2137                         dprintk("Enable Mpeg INPUT");
2138                         dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */
2139                         break;
2140         case INPUT_MODE_OFF:
2141         default:
2142                         dprintk("Disable INPUT");
2143                         dib7090_cfg_DibRx(state, 0, 0, 0, 0, 0, 0, 0);
2144                         break;
2145         }
2146         return 0;
2147 }
2148
2149 static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff)
2150 {
2151         switch (onoff) {
2152         case 0:         /* only use the internal way - not the diversity input */
2153                 dib7090_set_input_mode(fe, INPUT_MODE_MPEG);
2154                 break;
2155         case 1:         /* both ways */
2156         case 2:         /* only the diversity input */
2157                 dib7090_set_input_mode(fe, INPUT_MODE_DIVERSITY);
2158                 break;
2159         }
2160
2161         return 0;
2162 }
2163
2164 static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode)
2165 {
2166         struct dib7000p_state *state = fe->demodulator_priv;
2167
2168         u16 outreg, smo_mode, fifo_threshold;
2169         u8 prefer_mpeg_mux_use = 1;
2170         int ret = 0;
2171
2172         dib7090_host_bus_drive(state, 1);
2173
2174         fifo_threshold = 1792;
2175         smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
2176         outreg = dib7000p_read_word(state, 1286) & ~((1 << 10) | (0x7 << 6) | (1 << 1));
2177
2178         switch (mode) {
2179         case OUTMODE_HIGH_Z:
2180                 outreg = 0;
2181                 break;
2182
2183         case OUTMODE_MPEG2_SERIAL:
2184                 if (prefer_mpeg_mux_use) {
2185                         dprintk("Sip 7090P setting output mode TS_SERIAL using Mpeg Mux");
2186                         dib7090_enMpegOnHostBus(state);
2187                         dib7090_enMpegInput(state);
2188                         if (state->cfg.enMpegOutput == 1)
2189                                 dib7090_enMpegMux(state, 3, 1, 1);
2190
2191                 } else {        /* Use Smooth block */
2192                         dprintk("Sip 7090P setting output mode TS_SERIAL using Smooth bloc");
2193                         dib7090_disableMpegMux(state);
2194                         dib7000p_write_word(state, 1288, (1 << 6));
2195                         outreg |= (2 << 6) | (0 << 1);
2196                 }
2197                 break;
2198
2199         case OUTMODE_MPEG2_PAR_GATED_CLK:
2200                 if (prefer_mpeg_mux_use) {
2201                         dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Mpeg Mux");
2202                         dib7090_enMpegOnHostBus(state);
2203                         dib7090_enMpegInput(state);
2204                         if (state->cfg.enMpegOutput == 1)
2205                                 dib7090_enMpegMux(state, 2, 0, 0);
2206                 } else {        /* Use Smooth block */
2207                         dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Smooth block");
2208                         dib7090_disableMpegMux(state);
2209                         dib7000p_write_word(state, 1288, (1 << 6));
2210                         outreg |= (0 << 6);
2211                 }
2212                 break;
2213
2214         case OUTMODE_MPEG2_PAR_CONT_CLK:        /* Using Smooth block only */
2215                 dprintk("Sip 7090P setting output mode TS_PARALLEL_CONT using Smooth block");
2216                 dib7090_disableMpegMux(state);
2217                 dib7000p_write_word(state, 1288, (1 << 6));
2218                 outreg |= (1 << 6);
2219                 break;
2220
2221         case OUTMODE_MPEG2_FIFO:        /* Using Smooth block because not supported by new Mpeg Mux bloc */
2222                 dprintk("Sip 7090P setting output mode TS_FIFO using Smooth block");
2223                 dib7090_disableMpegMux(state);
2224                 dib7000p_write_word(state, 1288, (1 << 6));
2225                 outreg |= (5 << 6);
2226                 smo_mode |= (3 << 1);
2227                 fifo_threshold = 512;
2228                 break;
2229
2230         case OUTMODE_DIVERSITY:
2231                 dprintk("Sip 7090P setting output mode MODE_DIVERSITY");
2232                 dib7090_disableMpegMux(state);
2233                 dib7090_enDivOnHostBus(state);
2234                 break;
2235
2236         case OUTMODE_ANALOG_ADC:
2237                 dprintk("Sip 7090P setting output mode MODE_ANALOG_ADC");
2238                 dib7090_enAdcOnHostBus(state);
2239                 break;
2240         }
2241
2242         if (state->cfg.output_mpeg2_in_188_bytes)
2243                 smo_mode |= (1 << 5);
2244
2245         ret |= dib7000p_write_word(state, 235, smo_mode);
2246         ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
2247         ret |= dib7000p_write_word(state, 1286, outreg | (1 << 10));    /* allways set Dout active = 1 !!! */
2248
2249         return ret;
2250 }
2251
2252 int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
2253 {
2254         struct dib7000p_state *state = fe->demodulator_priv;
2255         u16 en_cur_state;
2256
2257         dprintk("sleep dib7090: %d", onoff);
2258
2259         en_cur_state = dib7000p_read_word(state, 1922);
2260
2261         if (en_cur_state > 0xff)
2262                 state->tuner_enable = en_cur_state;
2263
2264         if (onoff)
2265                 en_cur_state &= 0x00ff;
2266         else {
2267                 if (state->tuner_enable != 0)
2268                         en_cur_state = state->tuner_enable;
2269         }
2270
2271         dib7000p_write_word(state, 1922, en_cur_state);
2272
2273         return 0;
2274 }
2275 EXPORT_SYMBOL(dib7090_tuner_sleep);
2276
2277 int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart)
2278 {
2279         dprintk("AGC restart callback: %d", restart);
2280         return 0;
2281 }
2282 EXPORT_SYMBOL(dib7090_agc_restart);
2283
2284 int dib7090_get_adc_power(struct dvb_frontend *fe)
2285 {
2286         return dib7000p_get_adc_power(fe);
2287 }
2288 EXPORT_SYMBOL(dib7090_get_adc_power);
2289
2290 int dib7090_slave_reset(struct dvb_frontend *fe)
2291 {
2292         struct dib7000p_state *state = fe->demodulator_priv;
2293         u16 reg;
2294
2295         reg = dib7000p_read_word(state, 1794);
2296         dib7000p_write_word(state, 1794, reg | (4 << 12));
2297
2298         dib7000p_write_word(state, 1032, 0xffff);
2299         return 0;
2300 }
2301 EXPORT_SYMBOL(dib7090_slave_reset);
2302
2303 static struct dvb_frontend_ops dib7000p_ops;
2304 struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
2305 {
2306         struct dvb_frontend *demod;
2307         struct dib7000p_state *st;
2308         st = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
2309         if (st == NULL)
2310                 return NULL;
2311
2312         memcpy(&st->cfg, cfg, sizeof(struct dib7000p_config));
2313         st->i2c_adap = i2c_adap;
2314         st->i2c_addr = i2c_addr;
2315         st->gpio_val = cfg->gpio_val;
2316         st->gpio_dir = cfg->gpio_dir;
2317
2318         /* Ensure the output mode remains at the previous default if it's
2319          * not specifically set by the caller.
2320          */
2321         if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2322                 st->cfg.output_mode = OUTMODE_MPEG2_FIFO;
2323
2324         demod = &st->demod;
2325         demod->demodulator_priv = st;
2326         memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));
2327
2328         dib7000p_write_word(st, 1287, 0x0003);  /* sram lead in, rdy */
2329
2330         if (dib7000p_identify(st) != 0)
2331                 goto error;
2332
2333         st->version = dib7000p_read_word(st, 897);
2334
2335         /* FIXME: make sure the dev.parent field is initialized, or else
2336                 request_firmware() will hit an OOPS (this should be moved somewhere
2337                 more common) */
2338
2339         dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr);
2340
2341         /* init 7090 tuner adapter */
2342         strncpy(st->dib7090_tuner_adap.name, "DiB7090 tuner interface", sizeof(st->dib7090_tuner_adap.name));
2343         st->dib7090_tuner_adap.algo = &dib7090_tuner_xfer_algo;
2344         st->dib7090_tuner_adap.algo_data = NULL;
2345         st->dib7090_tuner_adap.dev.parent = st->i2c_adap->dev.parent;
2346         i2c_set_adapdata(&st->dib7090_tuner_adap, st);
2347         i2c_add_adapter(&st->dib7090_tuner_adap);
2348
2349         dib7000p_demod_reset(st);
2350
2351         if (st->version == SOC7090) {
2352                 dib7090_set_output_mode(demod, st->cfg.output_mode);
2353                 dib7090_set_diversity_in(demod, 0);
2354         }
2355
2356         return demod;
2357
2358 error:
2359         kfree(st);
2360         return NULL;
2361 }
2362 EXPORT_SYMBOL(dib7000p_attach);
2363
2364 static struct dvb_frontend_ops dib7000p_ops = {
2365         .info = {
2366                  .name = "DiBcom 7000PC",
2367                  .type = FE_OFDM,
2368                  .frequency_min = 44250000,
2369                  .frequency_max = 867250000,
2370                  .frequency_stepsize = 62500,
2371                  .caps = FE_CAN_INVERSION_AUTO |
2372                  FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2373                  FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2374                  FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2375                  FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2376                  },
2377
2378         .release = dib7000p_release,
2379
2380         .init = dib7000p_wakeup,
2381         .sleep = dib7000p_sleep,
2382
2383         .set_frontend = dib7000p_set_frontend,
2384         .get_tune_settings = dib7000p_fe_get_tune_settings,
2385         .get_frontend = dib7000p_get_frontend,
2386
2387         .read_status = dib7000p_read_status,
2388         .read_ber = dib7000p_read_ber,
2389         .read_signal_strength = dib7000p_read_signal_strength,
2390         .read_snr = dib7000p_read_snr,
2391         .read_ucblocks = dib7000p_read_unc_blocks,
2392 };
2393
2394 MODULE_AUTHOR("Olivier Grenie <ogrenie@dibcom.fr>");
2395 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
2396 MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
2397 MODULE_LICENSE("GPL");