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