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