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