Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

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