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