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