sh_eth: fix EESIPR values for SH77{34|63}
[linux/fpc-iii.git] / drivers / media / dvb-frontends / dib7000p.c
bloba27c0001f2d6dfe4031eacda011c4e790288476f
1 /*
2 * Linux-DVB Driver for DiBcom's second generation DiB7000P (PC).
4 * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
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 */
11 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13 #include <linux/kernel.h>
14 #include <linux/slab.h>
15 #include <linux/i2c.h>
16 #include <linux/mutex.h>
17 #include <asm/div64.h>
19 #include "dvb_math.h"
20 #include "dvb_frontend.h"
22 #include "dib7000p.h"
24 static int debug;
25 module_param(debug, int, 0644);
26 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
28 static int buggy_sfn_workaround;
29 module_param(buggy_sfn_workaround, int, 0644);
30 MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
32 #define dprintk(fmt, arg...) do { \
33 if (debug) \
34 printk(KERN_DEBUG pr_fmt("%s: " fmt), \
35 __func__, ##arg); \
36 } while (0)
38 struct i2c_device {
39 struct i2c_adapter *i2c_adap;
40 u8 i2c_addr;
43 struct dib7000p_state {
44 struct dvb_frontend demod;
45 struct dib7000p_config cfg;
47 u8 i2c_addr;
48 struct i2c_adapter *i2c_adap;
50 struct dibx000_i2c_master i2c_master;
52 u16 wbd_ref;
54 u8 current_band;
55 u32 current_bandwidth;
56 struct dibx000_agc_config *current_agc;
57 u32 timf;
59 u8 div_force_off:1;
60 u8 div_state:1;
61 u16 div_sync_wait;
63 u8 agc_state;
65 u16 gpio_dir;
66 u16 gpio_val;
68 u8 sfn_workaround_active:1;
70 #define SOC7090 0x7090
71 u16 version;
73 u16 tuner_enable;
74 struct i2c_adapter dib7090_tuner_adap;
76 /* for the I2C transfer */
77 struct i2c_msg msg[2];
78 u8 i2c_write_buffer[4];
79 u8 i2c_read_buffer[2];
80 struct mutex i2c_buffer_lock;
82 u8 input_mode_mpeg;
84 /* for DVBv5 stats */
85 s64 old_ucb;
86 unsigned long per_jiffies_stats;
87 unsigned long ber_jiffies_stats;
88 unsigned long get_stats_time;
91 enum dib7000p_power_mode {
92 DIB7000P_POWER_ALL = 0,
93 DIB7000P_POWER_ANALOG_ADC,
94 DIB7000P_POWER_INTERFACE_ONLY,
97 /* dib7090 specific fonctions */
98 static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode);
99 static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff);
100 static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode);
101 static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode);
103 static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
105 u16 ret;
107 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
108 dprintk("could not acquire lock\n");
109 return 0;
112 state->i2c_write_buffer[0] = reg >> 8;
113 state->i2c_write_buffer[1] = reg & 0xff;
115 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
116 state->msg[0].addr = state->i2c_addr >> 1;
117 state->msg[0].flags = 0;
118 state->msg[0].buf = state->i2c_write_buffer;
119 state->msg[0].len = 2;
120 state->msg[1].addr = state->i2c_addr >> 1;
121 state->msg[1].flags = I2C_M_RD;
122 state->msg[1].buf = state->i2c_read_buffer;
123 state->msg[1].len = 2;
125 if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
126 dprintk("i2c read error on %d\n", reg);
128 ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
129 mutex_unlock(&state->i2c_buffer_lock);
130 return ret;
133 static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
135 int ret;
137 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
138 dprintk("could not acquire lock\n");
139 return -EINVAL;
142 state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
143 state->i2c_write_buffer[1] = reg & 0xff;
144 state->i2c_write_buffer[2] = (val >> 8) & 0xff;
145 state->i2c_write_buffer[3] = val & 0xff;
147 memset(&state->msg[0], 0, sizeof(struct i2c_msg));
148 state->msg[0].addr = state->i2c_addr >> 1;
149 state->msg[0].flags = 0;
150 state->msg[0].buf = state->i2c_write_buffer;
151 state->msg[0].len = 4;
153 ret = (i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ?
154 -EREMOTEIO : 0);
155 mutex_unlock(&state->i2c_buffer_lock);
156 return ret;
159 static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf)
161 u16 l = 0, r, *n;
162 n = buf;
163 l = *n++;
164 while (l) {
165 r = *n++;
167 do {
168 dib7000p_write_word(state, r, *n++);
169 r++;
170 } while (--l);
171 l = *n++;
175 static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
177 int ret = 0;
178 u16 outreg, fifo_threshold, smo_mode;
180 outreg = 0;
181 fifo_threshold = 1792;
182 smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
184 dprintk("setting output mode for demod %p to %d\n", &state->demod, mode);
186 switch (mode) {
187 case OUTMODE_MPEG2_PAR_GATED_CLK:
188 outreg = (1 << 10); /* 0x0400 */
189 break;
190 case OUTMODE_MPEG2_PAR_CONT_CLK:
191 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
192 break;
193 case OUTMODE_MPEG2_SERIAL:
194 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */
195 break;
196 case OUTMODE_DIVERSITY:
197 if (state->cfg.hostbus_diversity)
198 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
199 else
200 outreg = (1 << 11);
201 break;
202 case OUTMODE_MPEG2_FIFO:
203 smo_mode |= (3 << 1);
204 fifo_threshold = 512;
205 outreg = (1 << 10) | (5 << 6);
206 break;
207 case OUTMODE_ANALOG_ADC:
208 outreg = (1 << 10) | (3 << 6);
209 break;
210 case OUTMODE_HIGH_Z:
211 outreg = 0;
212 break;
213 default:
214 dprintk("Unhandled output_mode passed to be set for demod %p\n", &state->demod);
215 break;
218 if (state->cfg.output_mpeg2_in_188_bytes)
219 smo_mode |= (1 << 5);
221 ret |= dib7000p_write_word(state, 235, smo_mode);
222 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
223 if (state->version != SOC7090)
224 ret |= dib7000p_write_word(state, 1286, outreg); /* P_Div_active */
226 return ret;
229 static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
231 struct dib7000p_state *state = demod->demodulator_priv;
233 if (state->div_force_off) {
234 dprintk("diversity combination deactivated - forced by COFDM parameters\n");
235 onoff = 0;
236 dib7000p_write_word(state, 207, 0);
237 } else
238 dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
240 state->div_state = (u8) onoff;
242 if (onoff) {
243 dib7000p_write_word(state, 204, 6);
244 dib7000p_write_word(state, 205, 16);
245 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
246 } else {
247 dib7000p_write_word(state, 204, 1);
248 dib7000p_write_word(state, 205, 0);
251 return 0;
254 static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode)
256 /* by default everything is powered off */
257 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0x0007, reg_899 = 0x0003, reg_1280 = (0xfe00) | (dib7000p_read_word(state, 1280) & 0x01ff);
259 /* now, depending on the requested mode, we power on */
260 switch (mode) {
261 /* power up everything in the demod */
262 case DIB7000P_POWER_ALL:
263 reg_774 = 0x0000;
264 reg_775 = 0x0000;
265 reg_776 = 0x0;
266 reg_899 = 0x0;
267 if (state->version == SOC7090)
268 reg_1280 &= 0x001f;
269 else
270 reg_1280 &= 0x01ff;
271 break;
273 case DIB7000P_POWER_ANALOG_ADC:
274 /* dem, cfg, iqc, sad, agc */
275 reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
276 /* nud */
277 reg_776 &= ~((1 << 0));
278 /* Dout */
279 if (state->version != SOC7090)
280 reg_1280 &= ~((1 << 11));
281 reg_1280 &= ~(1 << 6);
282 /* fall through wanted to enable the interfaces */
284 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
285 case DIB7000P_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C */
286 if (state->version == SOC7090)
287 reg_1280 &= ~((1 << 7) | (1 << 5));
288 else
289 reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
290 break;
292 /* TODO following stuff is just converted from the dib7000-driver - check when is used what */
295 dib7000p_write_word(state, 774, reg_774);
296 dib7000p_write_word(state, 775, reg_775);
297 dib7000p_write_word(state, 776, reg_776);
298 dib7000p_write_word(state, 1280, reg_1280);
299 if (state->version != SOC7090)
300 dib7000p_write_word(state, 899, reg_899);
302 return 0;
305 static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no)
307 u16 reg_908 = 0, reg_909 = 0;
308 u16 reg;
310 if (state->version != SOC7090) {
311 reg_908 = dib7000p_read_word(state, 908);
312 reg_909 = dib7000p_read_word(state, 909);
315 switch (no) {
316 case DIBX000_SLOW_ADC_ON:
317 if (state->version == SOC7090) {
318 reg = dib7000p_read_word(state, 1925);
320 dib7000p_write_word(state, 1925, reg | (1 << 4) | (1 << 2)); /* en_slowAdc = 1 & reset_sladc = 1 */
322 reg = dib7000p_read_word(state, 1925); /* read acces to make it works... strange ... */
323 msleep(200);
324 dib7000p_write_word(state, 1925, reg & ~(1 << 4)); /* en_slowAdc = 1 & reset_sladc = 0 */
326 reg = dib7000p_read_word(state, 72) & ~((0x3 << 14) | (0x3 << 12));
327 dib7000p_write_word(state, 72, reg | (1 << 14) | (3 << 12) | 524); /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ; (Vin2 = Vcm) */
328 } else {
329 reg_909 |= (1 << 1) | (1 << 0);
330 dib7000p_write_word(state, 909, reg_909);
331 reg_909 &= ~(1 << 1);
333 break;
335 case DIBX000_SLOW_ADC_OFF:
336 if (state->version == SOC7090) {
337 reg = dib7000p_read_word(state, 1925);
338 dib7000p_write_word(state, 1925, (reg & ~(1 << 2)) | (1 << 4)); /* reset_sladc = 1 en_slowAdc = 0 */
339 } else
340 reg_909 |= (1 << 1) | (1 << 0);
341 break;
343 case DIBX000_ADC_ON:
344 reg_908 &= 0x0fff;
345 reg_909 &= 0x0003;
346 break;
348 case DIBX000_ADC_OFF:
349 reg_908 |= (1 << 14) | (1 << 13) | (1 << 12);
350 reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
351 break;
353 case DIBX000_VBG_ENABLE:
354 reg_908 &= ~(1 << 15);
355 break;
357 case DIBX000_VBG_DISABLE:
358 reg_908 |= (1 << 15);
359 break;
361 default:
362 break;
365 // dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
367 reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4;
368 reg_908 |= (state->cfg.enable_current_mirror & 1) << 7;
370 if (state->version != SOC7090) {
371 dib7000p_write_word(state, 908, reg_908);
372 dib7000p_write_word(state, 909, reg_909);
376 static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
378 u32 timf;
380 // store the current bandwidth for later use
381 state->current_bandwidth = bw;
383 if (state->timf == 0) {
384 dprintk("using default timf\n");
385 timf = state->cfg.bw->timf;
386 } else {
387 dprintk("using updated timf\n");
388 timf = state->timf;
391 timf = timf * (bw / 50) / 160;
393 dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
394 dib7000p_write_word(state, 24, (u16) ((timf) & 0xffff));
396 return 0;
399 static int dib7000p_sad_calib(struct dib7000p_state *state)
401 /* internal */
402 dib7000p_write_word(state, 73, (0 << 1) | (0 << 0));
404 if (state->version == SOC7090)
405 dib7000p_write_word(state, 74, 2048);
406 else
407 dib7000p_write_word(state, 74, 776);
409 /* do the calibration */
410 dib7000p_write_word(state, 73, (1 << 0));
411 dib7000p_write_word(state, 73, (0 << 0));
413 msleep(1);
415 return 0;
418 static int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
420 struct dib7000p_state *state = demod->demodulator_priv;
421 if (value > 4095)
422 value = 4095;
423 state->wbd_ref = value;
424 return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value);
427 static int dib7000p_get_agc_values(struct dvb_frontend *fe,
428 u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd)
430 struct dib7000p_state *state = fe->demodulator_priv;
432 if (agc_global != NULL)
433 *agc_global = dib7000p_read_word(state, 394);
434 if (agc1 != NULL)
435 *agc1 = dib7000p_read_word(state, 392);
436 if (agc2 != NULL)
437 *agc2 = dib7000p_read_word(state, 393);
438 if (wbd != NULL)
439 *wbd = dib7000p_read_word(state, 397);
441 return 0;
444 static int dib7000p_set_agc1_min(struct dvb_frontend *fe, u16 v)
446 struct dib7000p_state *state = fe->demodulator_priv;
447 return dib7000p_write_word(state, 108, v);
450 static void dib7000p_reset_pll(struct dib7000p_state *state)
452 struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
453 u16 clk_cfg0;
455 if (state->version == SOC7090) {
456 dib7000p_write_word(state, 1856, (!bw->pll_reset << 13) | (bw->pll_range << 12) | (bw->pll_ratio << 6) | (bw->pll_prediv));
458 while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
461 dib7000p_write_word(state, 1857, dib7000p_read_word(state, 1857) | (!bw->pll_bypass << 15));
462 } else {
463 /* force PLL bypass */
464 clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) |
465 (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0);
467 dib7000p_write_word(state, 900, clk_cfg0);
469 /* P_pll_cfg */
470 dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset);
471 clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff);
472 dib7000p_write_word(state, 900, clk_cfg0);
475 dib7000p_write_word(state, 18, (u16) (((bw->internal * 1000) >> 16) & 0xffff));
476 dib7000p_write_word(state, 19, (u16) ((bw->internal * 1000) & 0xffff));
477 dib7000p_write_word(state, 21, (u16) ((bw->ifreq >> 16) & 0xffff));
478 dib7000p_write_word(state, 22, (u16) ((bw->ifreq) & 0xffff));
480 dib7000p_write_word(state, 72, bw->sad_cfg);
483 static u32 dib7000p_get_internal_freq(struct dib7000p_state *state)
485 u32 internal = (u32) dib7000p_read_word(state, 18) << 16;
486 internal |= (u32) dib7000p_read_word(state, 19);
487 internal /= 1000;
489 return internal;
492 static int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
494 struct dib7000p_state *state = fe->demodulator_priv;
495 u16 reg_1857, reg_1856 = dib7000p_read_word(state, 1856);
496 u8 loopdiv, prediv;
497 u32 internal, xtal;
499 /* get back old values */
500 prediv = reg_1856 & 0x3f;
501 loopdiv = (reg_1856 >> 6) & 0x3f;
503 if ((bw != NULL) && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) {
504 dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)\n", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio);
505 reg_1856 &= 0xf000;
506 reg_1857 = dib7000p_read_word(state, 1857);
507 dib7000p_write_word(state, 1857, reg_1857 & ~(1 << 15));
509 dib7000p_write_word(state, 1856, reg_1856 | ((bw->pll_ratio & 0x3f) << 6) | (bw->pll_prediv & 0x3f));
511 /* write new system clk into P_sec_len */
512 internal = dib7000p_get_internal_freq(state);
513 xtal = (internal / loopdiv) * prediv;
514 internal = 1000 * (xtal / bw->pll_prediv) * bw->pll_ratio; /* new internal */
515 dib7000p_write_word(state, 18, (u16) ((internal >> 16) & 0xffff));
516 dib7000p_write_word(state, 19, (u16) (internal & 0xffff));
518 dib7000p_write_word(state, 1857, reg_1857 | (1 << 15));
520 while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
521 dprintk("Waiting for PLL to lock\n");
523 return 0;
525 return -EIO;
528 static int dib7000p_reset_gpio(struct dib7000p_state *st)
530 /* reset the GPIOs */
531 dprintk("gpio dir: %x: val: %x, pwm_pos: %x\n", st->gpio_dir, st->gpio_val, st->cfg.gpio_pwm_pos);
533 dib7000p_write_word(st, 1029, st->gpio_dir);
534 dib7000p_write_word(st, 1030, st->gpio_val);
536 /* TODO 1031 is P_gpio_od */
538 dib7000p_write_word(st, 1032, st->cfg.gpio_pwm_pos);
540 dib7000p_write_word(st, 1037, st->cfg.pwm_freq_div);
541 return 0;
544 static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val)
546 st->gpio_dir = dib7000p_read_word(st, 1029);
547 st->gpio_dir &= ~(1 << num); /* reset the direction bit */
548 st->gpio_dir |= (dir & 0x1) << num; /* set the new direction */
549 dib7000p_write_word(st, 1029, st->gpio_dir);
551 st->gpio_val = dib7000p_read_word(st, 1030);
552 st->gpio_val &= ~(1 << num); /* reset the direction bit */
553 st->gpio_val |= (val & 0x01) << num; /* set the new value */
554 dib7000p_write_word(st, 1030, st->gpio_val);
556 return 0;
559 static int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val)
561 struct dib7000p_state *state = demod->demodulator_priv;
562 return dib7000p_cfg_gpio(state, num, dir, val);
565 static u16 dib7000p_defaults[] = {
566 // auto search configuration
567 3, 2,
568 0x0004,
569 (1<<3)|(1<<11)|(1<<12)|(1<<13),
570 0x0814, /* Equal Lock */
572 12, 6,
573 0x001b,
574 0x7740,
575 0x005b,
576 0x8d80,
577 0x01c9,
578 0xc380,
579 0x0000,
580 0x0080,
581 0x0000,
582 0x0090,
583 0x0001,
584 0xd4c0,
586 1, 26,
587 0x6680,
589 /* set ADC level to -16 */
590 11, 79,
591 (1 << 13) - 825 - 117,
592 (1 << 13) - 837 - 117,
593 (1 << 13) - 811 - 117,
594 (1 << 13) - 766 - 117,
595 (1 << 13) - 737 - 117,
596 (1 << 13) - 693 - 117,
597 (1 << 13) - 648 - 117,
598 (1 << 13) - 619 - 117,
599 (1 << 13) - 575 - 117,
600 (1 << 13) - 531 - 117,
601 (1 << 13) - 501 - 117,
603 1, 142,
604 0x0410,
606 /* disable power smoothing */
607 8, 145,
617 1, 154,
618 1 << 13,
620 1, 168,
621 0x0ccd,
623 1, 183,
624 0x200f,
626 1, 212,
627 0x169,
629 5, 187,
630 0x023d,
631 0x00a4,
632 0x00a4,
633 0x7ff0,
634 0x3ccc,
636 1, 198,
637 0x800,
639 1, 222,
640 0x0010,
642 1, 235,
643 0x0062,
648 static void dib7000p_reset_stats(struct dvb_frontend *fe);
650 static int dib7000p_demod_reset(struct dib7000p_state *state)
652 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
654 if (state->version == SOC7090)
655 dibx000_reset_i2c_master(&state->i2c_master);
657 dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE);
659 /* restart all parts */
660 dib7000p_write_word(state, 770, 0xffff);
661 dib7000p_write_word(state, 771, 0xffff);
662 dib7000p_write_word(state, 772, 0x001f);
663 dib7000p_write_word(state, 1280, 0x001f - ((1 << 4) | (1 << 3)));
665 dib7000p_write_word(state, 770, 0);
666 dib7000p_write_word(state, 771, 0);
667 dib7000p_write_word(state, 772, 0);
668 dib7000p_write_word(state, 1280, 0);
670 if (state->version != SOC7090) {
671 dib7000p_write_word(state, 898, 0x0003);
672 dib7000p_write_word(state, 898, 0);
675 /* default */
676 dib7000p_reset_pll(state);
678 if (dib7000p_reset_gpio(state) != 0)
679 dprintk("GPIO reset was not successful.\n");
681 if (state->version == SOC7090) {
682 dib7000p_write_word(state, 899, 0);
684 /* impulse noise */
685 dib7000p_write_word(state, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */
686 dib7000p_write_word(state, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */
687 dib7000p_write_word(state, 44, 300); /* 300 fag P_iqc_dect_min = +280 */
688 dib7000p_write_word(state, 273, (0<<6) | 30);
690 if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
691 dprintk("OUTPUT_MODE could not be reset.\n");
693 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
694 dib7000p_sad_calib(state);
695 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
697 /* unforce divstr regardless whether i2c enumeration was done or not */
698 dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1));
700 dib7000p_set_bandwidth(state, 8000);
702 if (state->version == SOC7090) {
703 dib7000p_write_word(state, 36, 0x0755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */
704 } else {
705 if (state->cfg.tuner_is_baseband)
706 dib7000p_write_word(state, 36, 0x0755);
707 else
708 dib7000p_write_word(state, 36, 0x1f55);
711 dib7000p_write_tab(state, dib7000p_defaults);
712 if (state->version != SOC7090) {
713 dib7000p_write_word(state, 901, 0x0006);
714 dib7000p_write_word(state, 902, (3 << 10) | (1 << 6));
715 dib7000p_write_word(state, 905, 0x2c8e);
718 dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
720 return 0;
723 static void dib7000p_pll_clk_cfg(struct dib7000p_state *state)
725 u16 tmp = 0;
726 tmp = dib7000p_read_word(state, 903);
727 dib7000p_write_word(state, 903, (tmp | 0x1));
728 tmp = dib7000p_read_word(state, 900);
729 dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6));
732 static void dib7000p_restart_agc(struct dib7000p_state *state)
734 // P_restart_iqc & P_restart_agc
735 dib7000p_write_word(state, 770, (1 << 11) | (1 << 9));
736 dib7000p_write_word(state, 770, 0x0000);
739 static int dib7000p_update_lna(struct dib7000p_state *state)
741 u16 dyn_gain;
743 if (state->cfg.update_lna) {
744 dyn_gain = dib7000p_read_word(state, 394);
745 if (state->cfg.update_lna(&state->demod, dyn_gain)) {
746 dib7000p_restart_agc(state);
747 return 1;
751 return 0;
754 static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
756 struct dibx000_agc_config *agc = NULL;
757 int i;
758 if (state->current_band == band && state->current_agc != NULL)
759 return 0;
760 state->current_band = band;
762 for (i = 0; i < state->cfg.agc_config_count; i++)
763 if (state->cfg.agc[i].band_caps & band) {
764 agc = &state->cfg.agc[i];
765 break;
768 if (agc == NULL) {
769 dprintk("no valid AGC configuration found for band 0x%02x\n", band);
770 return -EINVAL;
773 state->current_agc = agc;
775 /* AGC */
776 dib7000p_write_word(state, 75, agc->setup);
777 dib7000p_write_word(state, 76, agc->inv_gain);
778 dib7000p_write_word(state, 77, agc->time_stabiliz);
779 dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);
781 // Demod AGC loop configuration
782 dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);
783 dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp);
785 /* AGC continued */
786 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d\n",
787 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
789 if (state->wbd_ref != 0)
790 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref);
791 else
792 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref);
794 dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
796 dib7000p_write_word(state, 107, agc->agc1_max);
797 dib7000p_write_word(state, 108, agc->agc1_min);
798 dib7000p_write_word(state, 109, agc->agc2_max);
799 dib7000p_write_word(state, 110, agc->agc2_min);
800 dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
801 dib7000p_write_word(state, 112, agc->agc1_pt3);
802 dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
803 dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
804 dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
805 return 0;
808 static void dib7000p_set_dds(struct dib7000p_state *state, s32 offset_khz)
810 u32 internal = dib7000p_get_internal_freq(state);
811 s32 unit_khz_dds_val = 67108864 / (internal); /* 2**26 / Fsampling is the unit 1KHz offset */
812 u32 abs_offset_khz = ABS(offset_khz);
813 u32 dds = state->cfg.bw->ifreq & 0x1ffffff;
814 u8 invert = !!(state->cfg.bw->ifreq & (1 << 25));
816 dprintk("setting a frequency offset of %dkHz internal freq = %d invert = %d\n", offset_khz, internal, invert);
818 if (offset_khz < 0)
819 unit_khz_dds_val *= -1;
821 /* IF tuner */
822 if (invert)
823 dds -= (abs_offset_khz * unit_khz_dds_val); /* /100 because of /100 on the unit_khz_dds_val line calc for better accuracy */
824 else
825 dds += (abs_offset_khz * unit_khz_dds_val);
827 if (abs_offset_khz <= (internal / 2)) { /* Max dds offset is the half of the demod freq */
828 dib7000p_write_word(state, 21, (u16) (((dds >> 16) & 0x1ff) | (0 << 10) | (invert << 9)));
829 dib7000p_write_word(state, 22, (u16) (dds & 0xffff));
833 static int dib7000p_agc_startup(struct dvb_frontend *demod)
835 struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
836 struct dib7000p_state *state = demod->demodulator_priv;
837 int ret = -1;
838 u8 *agc_state = &state->agc_state;
839 u8 agc_split;
840 u16 reg;
841 u32 upd_demod_gain_period = 0x1000;
842 s32 frequency_offset = 0;
844 switch (state->agc_state) {
845 case 0:
846 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
847 if (state->version == SOC7090) {
848 reg = dib7000p_read_word(state, 0x79b) & 0xff00;
849 dib7000p_write_word(state, 0x79a, upd_demod_gain_period & 0xFFFF); /* lsb */
850 dib7000p_write_word(state, 0x79b, reg | (1 << 14) | ((upd_demod_gain_period >> 16) & 0xFF));
852 /* enable adc i & q */
853 reg = dib7000p_read_word(state, 0x780);
854 dib7000p_write_word(state, 0x780, (reg | (0x3)) & (~(1 << 7)));
855 } else {
856 dib7000p_set_adc_state(state, DIBX000_ADC_ON);
857 dib7000p_pll_clk_cfg(state);
860 if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency / 1000)) != 0)
861 return -1;
863 if (demod->ops.tuner_ops.get_frequency) {
864 u32 frequency_tuner;
866 demod->ops.tuner_ops.get_frequency(demod, &frequency_tuner);
867 frequency_offset = (s32)frequency_tuner / 1000 - ch->frequency / 1000;
870 dib7000p_set_dds(state, frequency_offset);
871 ret = 7;
872 (*agc_state)++;
873 break;
875 case 1:
876 if (state->cfg.agc_control)
877 state->cfg.agc_control(&state->demod, 1);
879 dib7000p_write_word(state, 78, 32768);
880 if (!state->current_agc->perform_agc_softsplit) {
881 /* we are using the wbd - so slow AGC startup */
882 /* force 0 split on WBD and restart AGC */
883 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));
884 (*agc_state)++;
885 ret = 5;
886 } else {
887 /* default AGC startup */
888 (*agc_state) = 4;
889 /* wait AGC rough lock time */
890 ret = 7;
893 dib7000p_restart_agc(state);
894 break;
896 case 2: /* fast split search path after 5sec */
897 dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4)); /* freeze AGC loop */
898 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */
899 (*agc_state)++;
900 ret = 14;
901 break;
903 case 3: /* split search ended */
904 agc_split = (u8) dib7000p_read_word(state, 396); /* store the split value for the next time */
905 dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */
907 dib7000p_write_word(state, 75, state->current_agc->setup); /* std AGC loop */
908 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
910 dib7000p_restart_agc(state);
912 dprintk("SPLIT %p: %hd\n", demod, agc_split);
914 (*agc_state)++;
915 ret = 5;
916 break;
918 case 4: /* LNA startup */
919 ret = 7;
921 if (dib7000p_update_lna(state))
922 ret = 5;
923 else
924 (*agc_state)++;
925 break;
927 case 5:
928 if (state->cfg.agc_control)
929 state->cfg.agc_control(&state->demod, 0);
930 (*agc_state)++;
931 break;
932 default:
933 break;
935 return ret;
938 static void dib7000p_update_timf(struct dib7000p_state *state)
940 u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428);
941 state->timf = timf * 160 / (state->current_bandwidth / 50);
942 dib7000p_write_word(state, 23, (u16) (timf >> 16));
943 dib7000p_write_word(state, 24, (u16) (timf & 0xffff));
944 dprintk("updated timf_frequency: %d (default: %d)\n", state->timf, state->cfg.bw->timf);
948 static u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
950 struct dib7000p_state *state = fe->demodulator_priv;
951 switch (op) {
952 case DEMOD_TIMF_SET:
953 state->timf = timf;
954 break;
955 case DEMOD_TIMF_UPDATE:
956 dib7000p_update_timf(state);
957 break;
958 case DEMOD_TIMF_GET:
959 break;
961 dib7000p_set_bandwidth(state, state->current_bandwidth);
962 return state->timf;
965 static void dib7000p_set_channel(struct dib7000p_state *state,
966 struct dtv_frontend_properties *ch, u8 seq)
968 u16 value, est[4];
970 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
972 /* nfft, guard, qam, alpha */
973 value = 0;
974 switch (ch->transmission_mode) {
975 case TRANSMISSION_MODE_2K:
976 value |= (0 << 7);
977 break;
978 case TRANSMISSION_MODE_4K:
979 value |= (2 << 7);
980 break;
981 default:
982 case TRANSMISSION_MODE_8K:
983 value |= (1 << 7);
984 break;
986 switch (ch->guard_interval) {
987 case GUARD_INTERVAL_1_32:
988 value |= (0 << 5);
989 break;
990 case GUARD_INTERVAL_1_16:
991 value |= (1 << 5);
992 break;
993 case GUARD_INTERVAL_1_4:
994 value |= (3 << 5);
995 break;
996 default:
997 case GUARD_INTERVAL_1_8:
998 value |= (2 << 5);
999 break;
1001 switch (ch->modulation) {
1002 case QPSK:
1003 value |= (0 << 3);
1004 break;
1005 case QAM_16:
1006 value |= (1 << 3);
1007 break;
1008 default:
1009 case QAM_64:
1010 value |= (2 << 3);
1011 break;
1013 switch (HIERARCHY_1) {
1014 case HIERARCHY_2:
1015 value |= 2;
1016 break;
1017 case HIERARCHY_4:
1018 value |= 4;
1019 break;
1020 default:
1021 case HIERARCHY_1:
1022 value |= 1;
1023 break;
1025 dib7000p_write_word(state, 0, value);
1026 dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */
1028 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
1029 value = 0;
1030 if (1 != 0)
1031 value |= (1 << 6);
1032 if (ch->hierarchy == 1)
1033 value |= (1 << 4);
1034 if (1 == 1)
1035 value |= 1;
1036 switch ((ch->hierarchy == 0 || 1 == 1) ? ch->code_rate_HP : ch->code_rate_LP) {
1037 case FEC_2_3:
1038 value |= (2 << 1);
1039 break;
1040 case FEC_3_4:
1041 value |= (3 << 1);
1042 break;
1043 case FEC_5_6:
1044 value |= (5 << 1);
1045 break;
1046 case FEC_7_8:
1047 value |= (7 << 1);
1048 break;
1049 default:
1050 case FEC_1_2:
1051 value |= (1 << 1);
1052 break;
1054 dib7000p_write_word(state, 208, value);
1056 /* offset loop parameters */
1057 dib7000p_write_word(state, 26, 0x6680);
1058 dib7000p_write_word(state, 32, 0x0003);
1059 dib7000p_write_word(state, 29, 0x1273);
1060 dib7000p_write_word(state, 33, 0x0005);
1062 /* P_dvsy_sync_wait */
1063 switch (ch->transmission_mode) {
1064 case TRANSMISSION_MODE_8K:
1065 value = 256;
1066 break;
1067 case TRANSMISSION_MODE_4K:
1068 value = 128;
1069 break;
1070 case TRANSMISSION_MODE_2K:
1071 default:
1072 value = 64;
1073 break;
1075 switch (ch->guard_interval) {
1076 case GUARD_INTERVAL_1_16:
1077 value *= 2;
1078 break;
1079 case GUARD_INTERVAL_1_8:
1080 value *= 4;
1081 break;
1082 case GUARD_INTERVAL_1_4:
1083 value *= 8;
1084 break;
1085 default:
1086 case GUARD_INTERVAL_1_32:
1087 value *= 1;
1088 break;
1090 if (state->cfg.diversity_delay == 0)
1091 state->div_sync_wait = (value * 3) / 2 + 48;
1092 else
1093 state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay;
1095 /* deactive the possibility of diversity reception if extended interleaver */
1096 state->div_force_off = !1 && ch->transmission_mode != TRANSMISSION_MODE_8K;
1097 dib7000p_set_diversity_in(&state->demod, state->div_state);
1099 /* channel estimation fine configuration */
1100 switch (ch->modulation) {
1101 case QAM_64:
1102 est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
1103 est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
1104 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1105 est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
1106 break;
1107 case QAM_16:
1108 est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
1109 est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
1110 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1111 est[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
1112 break;
1113 default:
1114 est[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
1115 est[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
1116 est[2] = 0x0333; /* P_adp_regul_ext 0.1 */
1117 est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
1118 break;
1120 for (value = 0; value < 4; value++)
1121 dib7000p_write_word(state, 187 + value, est[value]);
1124 static int dib7000p_autosearch_start(struct dvb_frontend *demod)
1126 struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
1127 struct dib7000p_state *state = demod->demodulator_priv;
1128 struct dtv_frontend_properties schan;
1129 u32 value, factor;
1130 u32 internal = dib7000p_get_internal_freq(state);
1132 schan = *ch;
1133 schan.modulation = QAM_64;
1134 schan.guard_interval = GUARD_INTERVAL_1_32;
1135 schan.transmission_mode = TRANSMISSION_MODE_8K;
1136 schan.code_rate_HP = FEC_2_3;
1137 schan.code_rate_LP = FEC_3_4;
1138 schan.hierarchy = 0;
1140 dib7000p_set_channel(state, &schan, 7);
1142 factor = BANDWIDTH_TO_KHZ(ch->bandwidth_hz);
1143 if (factor >= 5000) {
1144 if (state->version == SOC7090)
1145 factor = 2;
1146 else
1147 factor = 1;
1148 } else
1149 factor = 6;
1151 value = 30 * internal * factor;
1152 dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff));
1153 dib7000p_write_word(state, 7, (u16) (value & 0xffff));
1154 value = 100 * internal * factor;
1155 dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff));
1156 dib7000p_write_word(state, 9, (u16) (value & 0xffff));
1157 value = 500 * internal * factor;
1158 dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff));
1159 dib7000p_write_word(state, 11, (u16) (value & 0xffff));
1161 value = dib7000p_read_word(state, 0);
1162 dib7000p_write_word(state, 0, (u16) ((1 << 9) | value));
1163 dib7000p_read_word(state, 1284);
1164 dib7000p_write_word(state, 0, (u16) value);
1166 return 0;
1169 static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod)
1171 struct dib7000p_state *state = demod->demodulator_priv;
1172 u16 irq_pending = dib7000p_read_word(state, 1284);
1174 if (irq_pending & 0x1)
1175 return 1;
1177 if (irq_pending & 0x2)
1178 return 2;
1180 return 0;
1183 static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw)
1185 static s16 notch[] = { 16143, 14402, 12238, 9713, 6902, 3888, 759, -2392 };
1186 static u8 sine[] = { 0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
1187 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
1188 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
1189 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
1190 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
1191 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
1192 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
1193 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
1194 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
1195 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
1196 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
1197 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
1198 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
1199 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
1200 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
1201 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1202 255, 255, 255, 255, 255, 255
1205 u32 xtal = state->cfg.bw->xtal_hz / 1000;
1206 int f_rel = DIV_ROUND_CLOSEST(rf_khz, xtal) * xtal - rf_khz;
1207 int k;
1208 int coef_re[8], coef_im[8];
1209 int bw_khz = bw;
1210 u32 pha;
1212 dprintk("relative position of the Spur: %dk (RF: %dk, XTAL: %dk)\n", f_rel, rf_khz, xtal);
1214 if (f_rel < -bw_khz / 2 || f_rel > bw_khz / 2)
1215 return;
1217 bw_khz /= 100;
1219 dib7000p_write_word(state, 142, 0x0610);
1221 for (k = 0; k < 8; k++) {
1222 pha = ((f_rel * (k + 1) * 112 * 80 / bw_khz) / 1000) & 0x3ff;
1224 if (pha == 0) {
1225 coef_re[k] = 256;
1226 coef_im[k] = 0;
1227 } else if (pha < 256) {
1228 coef_re[k] = sine[256 - (pha & 0xff)];
1229 coef_im[k] = sine[pha & 0xff];
1230 } else if (pha == 256) {
1231 coef_re[k] = 0;
1232 coef_im[k] = 256;
1233 } else if (pha < 512) {
1234 coef_re[k] = -sine[pha & 0xff];
1235 coef_im[k] = sine[256 - (pha & 0xff)];
1236 } else if (pha == 512) {
1237 coef_re[k] = -256;
1238 coef_im[k] = 0;
1239 } else if (pha < 768) {
1240 coef_re[k] = -sine[256 - (pha & 0xff)];
1241 coef_im[k] = -sine[pha & 0xff];
1242 } else if (pha == 768) {
1243 coef_re[k] = 0;
1244 coef_im[k] = -256;
1245 } else {
1246 coef_re[k] = sine[pha & 0xff];
1247 coef_im[k] = -sine[256 - (pha & 0xff)];
1250 coef_re[k] *= notch[k];
1251 coef_re[k] += (1 << 14);
1252 if (coef_re[k] >= (1 << 24))
1253 coef_re[k] = (1 << 24) - 1;
1254 coef_re[k] /= (1 << 15);
1256 coef_im[k] *= notch[k];
1257 coef_im[k] += (1 << 14);
1258 if (coef_im[k] >= (1 << 24))
1259 coef_im[k] = (1 << 24) - 1;
1260 coef_im[k] /= (1 << 15);
1262 dprintk("PALF COEF: %d re: %d im: %d\n", k, coef_re[k], coef_im[k]);
1264 dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
1265 dib7000p_write_word(state, 144, coef_im[k] & 0x3ff);
1266 dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
1268 dib7000p_write_word(state, 143, 0);
1271 static int dib7000p_tune(struct dvb_frontend *demod)
1273 struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
1274 struct dib7000p_state *state = demod->demodulator_priv;
1275 u16 tmp = 0;
1277 if (ch != NULL)
1278 dib7000p_set_channel(state, ch, 0);
1279 else
1280 return -EINVAL;
1282 // restart demod
1283 dib7000p_write_word(state, 770, 0x4000);
1284 dib7000p_write_word(state, 770, 0x0000);
1285 msleep(45);
1287 /* 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 */
1288 tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
1289 if (state->sfn_workaround_active) {
1290 dprintk("SFN workaround is active\n");
1291 tmp |= (1 << 9);
1292 dib7000p_write_word(state, 166, 0x4000);
1293 } else {
1294 dib7000p_write_word(state, 166, 0x0000);
1296 dib7000p_write_word(state, 29, tmp);
1298 // never achieved a lock with that bandwidth so far - wait for osc-freq to update
1299 if (state->timf == 0)
1300 msleep(200);
1302 /* offset loop parameters */
1304 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
1305 tmp = (6 << 8) | 0x80;
1306 switch (ch->transmission_mode) {
1307 case TRANSMISSION_MODE_2K:
1308 tmp |= (2 << 12);
1309 break;
1310 case TRANSMISSION_MODE_4K:
1311 tmp |= (3 << 12);
1312 break;
1313 default:
1314 case TRANSMISSION_MODE_8K:
1315 tmp |= (4 << 12);
1316 break;
1318 dib7000p_write_word(state, 26, tmp); /* timf_a(6xxx) */
1320 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1321 tmp = (0 << 4);
1322 switch (ch->transmission_mode) {
1323 case TRANSMISSION_MODE_2K:
1324 tmp |= 0x6;
1325 break;
1326 case TRANSMISSION_MODE_4K:
1327 tmp |= 0x7;
1328 break;
1329 default:
1330 case TRANSMISSION_MODE_8K:
1331 tmp |= 0x8;
1332 break;
1334 dib7000p_write_word(state, 32, tmp);
1336 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1337 tmp = (0 << 4);
1338 switch (ch->transmission_mode) {
1339 case TRANSMISSION_MODE_2K:
1340 tmp |= 0x6;
1341 break;
1342 case TRANSMISSION_MODE_4K:
1343 tmp |= 0x7;
1344 break;
1345 default:
1346 case TRANSMISSION_MODE_8K:
1347 tmp |= 0x8;
1348 break;
1350 dib7000p_write_word(state, 33, tmp);
1352 tmp = dib7000p_read_word(state, 509);
1353 if (!((tmp >> 6) & 0x1)) {
1354 /* restart the fec */
1355 tmp = dib7000p_read_word(state, 771);
1356 dib7000p_write_word(state, 771, tmp | (1 << 1));
1357 dib7000p_write_word(state, 771, tmp);
1358 msleep(40);
1359 tmp = dib7000p_read_word(state, 509);
1361 // we achieved a lock - it's time to update the osc freq
1362 if ((tmp >> 6) & 0x1) {
1363 dib7000p_update_timf(state);
1364 /* P_timf_alpha += 2 */
1365 tmp = dib7000p_read_word(state, 26);
1366 dib7000p_write_word(state, 26, (tmp & ~(0xf << 12)) | ((((tmp >> 12) & 0xf) + 5) << 12));
1369 if (state->cfg.spur_protect)
1370 dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
1372 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
1374 dib7000p_reset_stats(demod);
1376 return 0;
1379 static int dib7000p_wakeup(struct dvb_frontend *demod)
1381 struct dib7000p_state *state = demod->demodulator_priv;
1382 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
1383 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
1384 if (state->version == SOC7090)
1385 dib7000p_sad_calib(state);
1386 return 0;
1389 static int dib7000p_sleep(struct dvb_frontend *demod)
1391 struct dib7000p_state *state = demod->demodulator_priv;
1392 if (state->version == SOC7090)
1393 return dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1394 return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1397 static int dib7000p_identify(struct dib7000p_state *st)
1399 u16 value;
1400 dprintk("checking demod on I2C address: %d (%x)\n", st->i2c_addr, st->i2c_addr);
1402 if ((value = dib7000p_read_word(st, 768)) != 0x01b3) {
1403 dprintk("wrong Vendor ID (read=0x%x)\n", value);
1404 return -EREMOTEIO;
1407 if ((value = dib7000p_read_word(st, 769)) != 0x4000) {
1408 dprintk("wrong Device ID (%x)\n", value);
1409 return -EREMOTEIO;
1412 return 0;
1415 static int dib7000p_get_frontend(struct dvb_frontend *fe,
1416 struct dtv_frontend_properties *fep)
1418 struct dib7000p_state *state = fe->demodulator_priv;
1419 u16 tps = dib7000p_read_word(state, 463);
1421 fep->inversion = INVERSION_AUTO;
1423 fep->bandwidth_hz = BANDWIDTH_TO_HZ(state->current_bandwidth);
1425 switch ((tps >> 8) & 0x3) {
1426 case 0:
1427 fep->transmission_mode = TRANSMISSION_MODE_2K;
1428 break;
1429 case 1:
1430 fep->transmission_mode = TRANSMISSION_MODE_8K;
1431 break;
1432 /* case 2: fep->transmission_mode = TRANSMISSION_MODE_4K; break; */
1435 switch (tps & 0x3) {
1436 case 0:
1437 fep->guard_interval = GUARD_INTERVAL_1_32;
1438 break;
1439 case 1:
1440 fep->guard_interval = GUARD_INTERVAL_1_16;
1441 break;
1442 case 2:
1443 fep->guard_interval = GUARD_INTERVAL_1_8;
1444 break;
1445 case 3:
1446 fep->guard_interval = GUARD_INTERVAL_1_4;
1447 break;
1450 switch ((tps >> 14) & 0x3) {
1451 case 0:
1452 fep->modulation = QPSK;
1453 break;
1454 case 1:
1455 fep->modulation = QAM_16;
1456 break;
1457 case 2:
1458 default:
1459 fep->modulation = QAM_64;
1460 break;
1463 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1464 /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1466 fep->hierarchy = HIERARCHY_NONE;
1467 switch ((tps >> 5) & 0x7) {
1468 case 1:
1469 fep->code_rate_HP = FEC_1_2;
1470 break;
1471 case 2:
1472 fep->code_rate_HP = FEC_2_3;
1473 break;
1474 case 3:
1475 fep->code_rate_HP = FEC_3_4;
1476 break;
1477 case 5:
1478 fep->code_rate_HP = FEC_5_6;
1479 break;
1480 case 7:
1481 default:
1482 fep->code_rate_HP = FEC_7_8;
1483 break;
1487 switch ((tps >> 2) & 0x7) {
1488 case 1:
1489 fep->code_rate_LP = FEC_1_2;
1490 break;
1491 case 2:
1492 fep->code_rate_LP = FEC_2_3;
1493 break;
1494 case 3:
1495 fep->code_rate_LP = FEC_3_4;
1496 break;
1497 case 5:
1498 fep->code_rate_LP = FEC_5_6;
1499 break;
1500 case 7:
1501 default:
1502 fep->code_rate_LP = FEC_7_8;
1503 break;
1506 /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */
1508 return 0;
1511 static int dib7000p_set_frontend(struct dvb_frontend *fe)
1513 struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
1514 struct dib7000p_state *state = fe->demodulator_priv;
1515 int time, ret;
1517 if (state->version == SOC7090)
1518 dib7090_set_diversity_in(fe, 0);
1519 else
1520 dib7000p_set_output_mode(state, OUTMODE_HIGH_Z);
1522 /* maybe the parameter has been changed */
1523 state->sfn_workaround_active = buggy_sfn_workaround;
1525 if (fe->ops.tuner_ops.set_params)
1526 fe->ops.tuner_ops.set_params(fe);
1528 /* start up the AGC */
1529 state->agc_state = 0;
1530 do {
1531 time = dib7000p_agc_startup(fe);
1532 if (time != -1)
1533 msleep(time);
1534 } while (time != -1);
1536 if (fep->transmission_mode == TRANSMISSION_MODE_AUTO ||
1537 fep->guard_interval == GUARD_INTERVAL_AUTO || fep->modulation == QAM_AUTO || fep->code_rate_HP == FEC_AUTO) {
1538 int i = 800, found;
1540 dib7000p_autosearch_start(fe);
1541 do {
1542 msleep(1);
1543 found = dib7000p_autosearch_is_irq(fe);
1544 } while (found == 0 && i--);
1546 dprintk("autosearch returns: %d\n", found);
1547 if (found == 0 || found == 1)
1548 return 0;
1550 dib7000p_get_frontend(fe, fep);
1553 ret = dib7000p_tune(fe);
1555 /* make this a config parameter */
1556 if (state->version == SOC7090) {
1557 dib7090_set_output_mode(fe, state->cfg.output_mode);
1558 if (state->cfg.enMpegOutput == 0) {
1559 dib7090_setDibTxMux(state, MPEG_ON_DIBTX);
1560 dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS);
1562 } else
1563 dib7000p_set_output_mode(state, state->cfg.output_mode);
1565 return ret;
1568 static int dib7000p_get_stats(struct dvb_frontend *fe, enum fe_status stat);
1570 static int dib7000p_read_status(struct dvb_frontend *fe, enum fe_status *stat)
1572 struct dib7000p_state *state = fe->demodulator_priv;
1573 u16 lock = dib7000p_read_word(state, 509);
1575 *stat = 0;
1577 if (lock & 0x8000)
1578 *stat |= FE_HAS_SIGNAL;
1579 if (lock & 0x3000)
1580 *stat |= FE_HAS_CARRIER;
1581 if (lock & 0x0100)
1582 *stat |= FE_HAS_VITERBI;
1583 if (lock & 0x0010)
1584 *stat |= FE_HAS_SYNC;
1585 if ((lock & 0x0038) == 0x38)
1586 *stat |= FE_HAS_LOCK;
1588 dib7000p_get_stats(fe, *stat);
1590 return 0;
1593 static int dib7000p_read_ber(struct dvb_frontend *fe, u32 * ber)
1595 struct dib7000p_state *state = fe->demodulator_priv;
1596 *ber = (dib7000p_read_word(state, 500) << 16) | dib7000p_read_word(state, 501);
1597 return 0;
1600 static int dib7000p_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
1602 struct dib7000p_state *state = fe->demodulator_priv;
1603 *unc = dib7000p_read_word(state, 506);
1604 return 0;
1607 static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
1609 struct dib7000p_state *state = fe->demodulator_priv;
1610 u16 val = dib7000p_read_word(state, 394);
1611 *strength = 65535 - val;
1612 return 0;
1615 static u32 dib7000p_get_snr(struct dvb_frontend *fe)
1617 struct dib7000p_state *state = fe->demodulator_priv;
1618 u16 val;
1619 s32 signal_mant, signal_exp, noise_mant, noise_exp;
1620 u32 result = 0;
1622 val = dib7000p_read_word(state, 479);
1623 noise_mant = (val >> 4) & 0xff;
1624 noise_exp = ((val & 0xf) << 2);
1625 val = dib7000p_read_word(state, 480);
1626 noise_exp += ((val >> 14) & 0x3);
1627 if ((noise_exp & 0x20) != 0)
1628 noise_exp -= 0x40;
1630 signal_mant = (val >> 6) & 0xFF;
1631 signal_exp = (val & 0x3F);
1632 if ((signal_exp & 0x20) != 0)
1633 signal_exp -= 0x40;
1635 if (signal_mant != 0)
1636 result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
1637 else
1638 result = intlog10(2) * 10 * signal_exp - 100;
1640 if (noise_mant != 0)
1641 result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
1642 else
1643 result -= intlog10(2) * 10 * noise_exp - 100;
1645 return result;
1648 static int dib7000p_read_snr(struct dvb_frontend *fe, u16 *snr)
1650 u32 result;
1652 result = dib7000p_get_snr(fe);
1654 *snr = result / ((1 << 24) / 10);
1655 return 0;
1658 static void dib7000p_reset_stats(struct dvb_frontend *demod)
1660 struct dib7000p_state *state = demod->demodulator_priv;
1661 struct dtv_frontend_properties *c = &demod->dtv_property_cache;
1662 u32 ucb;
1664 memset(&c->strength, 0, sizeof(c->strength));
1665 memset(&c->cnr, 0, sizeof(c->cnr));
1666 memset(&c->post_bit_error, 0, sizeof(c->post_bit_error));
1667 memset(&c->post_bit_count, 0, sizeof(c->post_bit_count));
1668 memset(&c->block_error, 0, sizeof(c->block_error));
1670 c->strength.len = 1;
1671 c->cnr.len = 1;
1672 c->block_error.len = 1;
1673 c->block_count.len = 1;
1674 c->post_bit_error.len = 1;
1675 c->post_bit_count.len = 1;
1677 c->strength.stat[0].scale = FE_SCALE_DECIBEL;
1678 c->strength.stat[0].uvalue = 0;
1680 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1681 c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1682 c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1683 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1684 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1686 dib7000p_read_unc_blocks(demod, &ucb);
1688 state->old_ucb = ucb;
1689 state->ber_jiffies_stats = 0;
1690 state->per_jiffies_stats = 0;
1693 struct linear_segments {
1694 unsigned x;
1695 signed y;
1699 * Table to estimate signal strength in dBm.
1700 * This table should be empirically determinated by measuring the signal
1701 * strength generated by a RF generator directly connected into
1702 * a device.
1703 * This table was determinated by measuring the signal strength generated
1704 * by a DTA-2111 RF generator directly connected into a dib7000p device
1705 * (a Hauppauge Nova-TD stick), using a good quality 3 meters length
1706 * RC6 cable and good RC6 connectors, connected directly to antenna 1.
1707 * As the minimum output power of DTA-2111 is -31dBm, a 16 dBm attenuator
1708 * were used, for the lower power values.
1709 * The real value can actually be on other devices, or even at the
1710 * second antena input, depending on several factors, like if LNA
1711 * is enabled or not, if diversity is enabled, type of connectors, etc.
1712 * Yet, it is better to use this measure in dB than a random non-linear
1713 * percentage value, especially for antenna adjustments.
1714 * On my tests, the precision of the measure using this table is about
1715 * 0.5 dB, with sounds reasonable enough to adjust antennas.
1717 #define DB_OFFSET 131000
1719 static struct linear_segments strength_to_db_table[] = {
1720 { 63630, DB_OFFSET - 20500},
1721 { 62273, DB_OFFSET - 21000},
1722 { 60162, DB_OFFSET - 22000},
1723 { 58730, DB_OFFSET - 23000},
1724 { 58294, DB_OFFSET - 24000},
1725 { 57778, DB_OFFSET - 25000},
1726 { 57320, DB_OFFSET - 26000},
1727 { 56779, DB_OFFSET - 27000},
1728 { 56293, DB_OFFSET - 28000},
1729 { 55724, DB_OFFSET - 29000},
1730 { 55145, DB_OFFSET - 30000},
1731 { 54680, DB_OFFSET - 31000},
1732 { 54293, DB_OFFSET - 32000},
1733 { 53813, DB_OFFSET - 33000},
1734 { 53427, DB_OFFSET - 34000},
1735 { 52981, DB_OFFSET - 35000},
1737 { 52636, DB_OFFSET - 36000},
1738 { 52014, DB_OFFSET - 37000},
1739 { 51674, DB_OFFSET - 38000},
1740 { 50692, DB_OFFSET - 39000},
1741 { 49824, DB_OFFSET - 40000},
1742 { 49052, DB_OFFSET - 41000},
1743 { 48436, DB_OFFSET - 42000},
1744 { 47836, DB_OFFSET - 43000},
1745 { 47368, DB_OFFSET - 44000},
1746 { 46468, DB_OFFSET - 45000},
1747 { 45597, DB_OFFSET - 46000},
1748 { 44586, DB_OFFSET - 47000},
1749 { 43667, DB_OFFSET - 48000},
1750 { 42673, DB_OFFSET - 49000},
1751 { 41816, DB_OFFSET - 50000},
1752 { 40876, DB_OFFSET - 51000},
1753 { 0, 0},
1756 static u32 interpolate_value(u32 value, struct linear_segments *segments,
1757 unsigned len)
1759 u64 tmp64;
1760 u32 dx;
1761 s32 dy;
1762 int i, ret;
1764 if (value >= segments[0].x)
1765 return segments[0].y;
1766 if (value < segments[len-1].x)
1767 return segments[len-1].y;
1769 for (i = 1; i < len - 1; i++) {
1770 /* If value is identical, no need to interpolate */
1771 if (value == segments[i].x)
1772 return segments[i].y;
1773 if (value > segments[i].x)
1774 break;
1777 /* Linear interpolation between the two (x,y) points */
1778 dy = segments[i - 1].y - segments[i].y;
1779 dx = segments[i - 1].x - segments[i].x;
1781 tmp64 = value - segments[i].x;
1782 tmp64 *= dy;
1783 do_div(tmp64, dx);
1784 ret = segments[i].y + tmp64;
1786 return ret;
1789 /* FIXME: may require changes - this one was borrowed from dib8000 */
1790 static u32 dib7000p_get_time_us(struct dvb_frontend *demod)
1792 struct dtv_frontend_properties *c = &demod->dtv_property_cache;
1793 u64 time_us, tmp64;
1794 u32 tmp, denom;
1795 int guard, rate_num, rate_denum = 1, bits_per_symbol;
1796 int interleaving = 0, fft_div;
1798 switch (c->guard_interval) {
1799 case GUARD_INTERVAL_1_4:
1800 guard = 4;
1801 break;
1802 case GUARD_INTERVAL_1_8:
1803 guard = 8;
1804 break;
1805 case GUARD_INTERVAL_1_16:
1806 guard = 16;
1807 break;
1808 default:
1809 case GUARD_INTERVAL_1_32:
1810 guard = 32;
1811 break;
1814 switch (c->transmission_mode) {
1815 case TRANSMISSION_MODE_2K:
1816 fft_div = 4;
1817 break;
1818 case TRANSMISSION_MODE_4K:
1819 fft_div = 2;
1820 break;
1821 default:
1822 case TRANSMISSION_MODE_8K:
1823 fft_div = 1;
1824 break;
1827 switch (c->modulation) {
1828 case DQPSK:
1829 case QPSK:
1830 bits_per_symbol = 2;
1831 break;
1832 case QAM_16:
1833 bits_per_symbol = 4;
1834 break;
1835 default:
1836 case QAM_64:
1837 bits_per_symbol = 6;
1838 break;
1841 switch ((c->hierarchy == 0 || 1 == 1) ? c->code_rate_HP : c->code_rate_LP) {
1842 case FEC_1_2:
1843 rate_num = 1;
1844 rate_denum = 2;
1845 break;
1846 case FEC_2_3:
1847 rate_num = 2;
1848 rate_denum = 3;
1849 break;
1850 case FEC_3_4:
1851 rate_num = 3;
1852 rate_denum = 4;
1853 break;
1854 case FEC_5_6:
1855 rate_num = 5;
1856 rate_denum = 6;
1857 break;
1858 default:
1859 case FEC_7_8:
1860 rate_num = 7;
1861 rate_denum = 8;
1862 break;
1865 interleaving = interleaving;
1867 denom = bits_per_symbol * rate_num * fft_div * 384;
1869 /* If calculus gets wrong, wait for 1s for the next stats */
1870 if (!denom)
1871 return 0;
1873 /* Estimate the period for the total bit rate */
1874 time_us = rate_denum * (1008 * 1562500L);
1875 tmp64 = time_us;
1876 do_div(tmp64, guard);
1877 time_us = time_us + tmp64;
1878 time_us += denom / 2;
1879 do_div(time_us, denom);
1881 tmp = 1008 * 96 * interleaving;
1882 time_us += tmp + tmp / guard;
1884 return time_us;
1887 static int dib7000p_get_stats(struct dvb_frontend *demod, enum fe_status stat)
1889 struct dib7000p_state *state = demod->demodulator_priv;
1890 struct dtv_frontend_properties *c = &demod->dtv_property_cache;
1891 int show_per_stats = 0;
1892 u32 time_us = 0, val, snr;
1893 u64 blocks, ucb;
1894 s32 db;
1895 u16 strength;
1897 /* Get Signal strength */
1898 dib7000p_read_signal_strength(demod, &strength);
1899 val = strength;
1900 db = interpolate_value(val,
1901 strength_to_db_table,
1902 ARRAY_SIZE(strength_to_db_table)) - DB_OFFSET;
1903 c->strength.stat[0].svalue = db;
1905 /* UCB/BER/CNR measures require lock */
1906 if (!(stat & FE_HAS_LOCK)) {
1907 c->cnr.len = 1;
1908 c->block_count.len = 1;
1909 c->block_error.len = 1;
1910 c->post_bit_error.len = 1;
1911 c->post_bit_count.len = 1;
1912 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1913 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1914 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1915 c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1916 c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
1917 return 0;
1920 /* Check if time for stats was elapsed */
1921 if (time_after(jiffies, state->per_jiffies_stats)) {
1922 state->per_jiffies_stats = jiffies + msecs_to_jiffies(1000);
1924 /* Get SNR */
1925 snr = dib7000p_get_snr(demod);
1926 if (snr)
1927 snr = (1000L * snr) >> 24;
1928 else
1929 snr = 0;
1930 c->cnr.stat[0].svalue = snr;
1931 c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
1933 /* Get UCB measures */
1934 dib7000p_read_unc_blocks(demod, &val);
1935 ucb = val - state->old_ucb;
1936 if (val < state->old_ucb)
1937 ucb += 0x100000000LL;
1939 c->block_error.stat[0].scale = FE_SCALE_COUNTER;
1940 c->block_error.stat[0].uvalue = ucb;
1942 /* Estimate the number of packets based on bitrate */
1943 if (!time_us)
1944 time_us = dib7000p_get_time_us(demod);
1946 if (time_us) {
1947 blocks = 1250000ULL * 1000000ULL;
1948 do_div(blocks, time_us * 8 * 204);
1949 c->block_count.stat[0].scale = FE_SCALE_COUNTER;
1950 c->block_count.stat[0].uvalue += blocks;
1953 show_per_stats = 1;
1956 /* Get post-BER measures */
1957 if (time_after(jiffies, state->ber_jiffies_stats)) {
1958 time_us = dib7000p_get_time_us(demod);
1959 state->ber_jiffies_stats = jiffies + msecs_to_jiffies((time_us + 500) / 1000);
1961 dprintk("Next all layers stats available in %u us.\n", time_us);
1963 dib7000p_read_ber(demod, &val);
1964 c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
1965 c->post_bit_error.stat[0].uvalue += val;
1967 c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
1968 c->post_bit_count.stat[0].uvalue += 100000000;
1971 /* Get PER measures */
1972 if (show_per_stats) {
1973 dib7000p_read_unc_blocks(demod, &val);
1975 c->block_error.stat[0].scale = FE_SCALE_COUNTER;
1976 c->block_error.stat[0].uvalue += val;
1978 time_us = dib7000p_get_time_us(demod);
1979 if (time_us) {
1980 blocks = 1250000ULL * 1000000ULL;
1981 do_div(blocks, time_us * 8 * 204);
1982 c->block_count.stat[0].scale = FE_SCALE_COUNTER;
1983 c->block_count.stat[0].uvalue += blocks;
1986 return 0;
1989 static int dib7000p_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
1991 tune->min_delay_ms = 1000;
1992 return 0;
1995 static void dib7000p_release(struct dvb_frontend *demod)
1997 struct dib7000p_state *st = demod->demodulator_priv;
1998 dibx000_exit_i2c_master(&st->i2c_master);
1999 i2c_del_adapter(&st->dib7090_tuner_adap);
2000 kfree(st);
2003 static int dib7000pc_detection(struct i2c_adapter *i2c_adap)
2005 u8 *tx, *rx;
2006 struct i2c_msg msg[2] = {
2007 {.addr = 18 >> 1, .flags = 0, .len = 2},
2008 {.addr = 18 >> 1, .flags = I2C_M_RD, .len = 2},
2010 int ret = 0;
2012 tx = kzalloc(2*sizeof(u8), GFP_KERNEL);
2013 if (!tx)
2014 return -ENOMEM;
2015 rx = kzalloc(2*sizeof(u8), GFP_KERNEL);
2016 if (!rx) {
2017 ret = -ENOMEM;
2018 goto rx_memory_error;
2021 msg[0].buf = tx;
2022 msg[1].buf = rx;
2024 tx[0] = 0x03;
2025 tx[1] = 0x00;
2027 if (i2c_transfer(i2c_adap, msg, 2) == 2)
2028 if (rx[0] == 0x01 && rx[1] == 0xb3) {
2029 dprintk("-D- DiB7000PC detected\n");
2030 return 1;
2033 msg[0].addr = msg[1].addr = 0x40;
2035 if (i2c_transfer(i2c_adap, msg, 2) == 2)
2036 if (rx[0] == 0x01 && rx[1] == 0xb3) {
2037 dprintk("-D- DiB7000PC detected\n");
2038 return 1;
2041 dprintk("-D- DiB7000PC not detected\n");
2043 kfree(rx);
2044 rx_memory_error:
2045 kfree(tx);
2046 return ret;
2049 static struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
2051 struct dib7000p_state *st = demod->demodulator_priv;
2052 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
2055 static int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
2057 struct dib7000p_state *state = fe->demodulator_priv;
2058 u16 val = dib7000p_read_word(state, 235) & 0xffef;
2059 val |= (onoff & 0x1) << 4;
2060 dprintk("PID filter enabled %d\n", onoff);
2061 return dib7000p_write_word(state, 235, val);
2064 static int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
2066 struct dib7000p_state *state = fe->demodulator_priv;
2067 dprintk("PID filter: index %x, PID %d, OnOff %d\n", id, pid, onoff);
2068 return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0);
2071 static int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
2073 struct dib7000p_state *dpst;
2074 int k = 0;
2075 u8 new_addr = 0;
2077 dpst = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
2078 if (!dpst)
2079 return -ENOMEM;
2081 dpst->i2c_adap = i2c;
2082 mutex_init(&dpst->i2c_buffer_lock);
2084 for (k = no_of_demods - 1; k >= 0; k--) {
2085 dpst->cfg = cfg[k];
2087 /* designated i2c address */
2088 if (cfg[k].default_i2c_addr != 0)
2089 new_addr = cfg[k].default_i2c_addr + (k << 1);
2090 else
2091 new_addr = (0x40 + k) << 1;
2092 dpst->i2c_addr = new_addr;
2093 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */
2094 if (dib7000p_identify(dpst) != 0) {
2095 dpst->i2c_addr = default_addr;
2096 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */
2097 if (dib7000p_identify(dpst) != 0) {
2098 dprintk("DiB7000P #%d: not identified\n", k);
2099 kfree(dpst);
2100 return -EIO;
2104 /* start diversity to pull_down div_str - just for i2c-enumeration */
2105 dib7000p_set_output_mode(dpst, OUTMODE_DIVERSITY);
2107 /* set new i2c address and force divstart */
2108 dib7000p_write_word(dpst, 1285, (new_addr << 2) | 0x2);
2110 dprintk("IC %d initialized (to i2c_address 0x%x)\n", k, new_addr);
2113 for (k = 0; k < no_of_demods; k++) {
2114 dpst->cfg = cfg[k];
2115 if (cfg[k].default_i2c_addr != 0)
2116 dpst->i2c_addr = (cfg[k].default_i2c_addr + k) << 1;
2117 else
2118 dpst->i2c_addr = (0x40 + k) << 1;
2120 // unforce divstr
2121 dib7000p_write_word(dpst, 1285, dpst->i2c_addr << 2);
2123 /* deactivate div - it was just for i2c-enumeration */
2124 dib7000p_set_output_mode(dpst, OUTMODE_HIGH_Z);
2127 kfree(dpst);
2128 return 0;
2131 static const s32 lut_1000ln_mant[] = {
2132 6908, 6956, 7003, 7047, 7090, 7131, 7170, 7208, 7244, 7279, 7313, 7346, 7377, 7408, 7438, 7467, 7495, 7523, 7549, 7575, 7600
2135 static s32 dib7000p_get_adc_power(struct dvb_frontend *fe)
2137 struct dib7000p_state *state = fe->demodulator_priv;
2138 u32 tmp_val = 0, exp = 0, mant = 0;
2139 s32 pow_i;
2140 u16 buf[2];
2141 u8 ix = 0;
2143 buf[0] = dib7000p_read_word(state, 0x184);
2144 buf[1] = dib7000p_read_word(state, 0x185);
2145 pow_i = (buf[0] << 16) | buf[1];
2146 dprintk("raw pow_i = %d\n", pow_i);
2148 tmp_val = pow_i;
2149 while (tmp_val >>= 1)
2150 exp++;
2152 mant = (pow_i * 1000 / (1 << exp));
2153 dprintk(" mant = %d exp = %d\n", mant / 1000, exp);
2155 ix = (u8) ((mant - 1000) / 100); /* index of the LUT */
2156 dprintk(" ix = %d\n", ix);
2158 pow_i = (lut_1000ln_mant[ix] + 693 * (exp - 20) - 6908);
2159 pow_i = (pow_i << 8) / 1000;
2160 dprintk(" pow_i = %d\n", pow_i);
2162 return pow_i;
2165 static int map_addr_to_serpar_number(struct i2c_msg *msg)
2167 if ((msg->buf[0] <= 15))
2168 msg->buf[0] -= 1;
2169 else if (msg->buf[0] == 17)
2170 msg->buf[0] = 15;
2171 else if (msg->buf[0] == 16)
2172 msg->buf[0] = 17;
2173 else if (msg->buf[0] == 19)
2174 msg->buf[0] = 16;
2175 else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
2176 msg->buf[0] -= 3;
2177 else if (msg->buf[0] == 28)
2178 msg->buf[0] = 23;
2179 else
2180 return -EINVAL;
2181 return 0;
2184 static int w7090p_tuner_write_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
2186 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
2187 u8 n_overflow = 1;
2188 u16 i = 1000;
2189 u16 serpar_num = msg[0].buf[0];
2191 while (n_overflow == 1 && i) {
2192 n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
2193 i--;
2194 if (i == 0)
2195 dprintk("Tuner ITF: write busy (overflow)\n");
2197 dib7000p_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
2198 dib7000p_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
2200 return num;
2203 static int w7090p_tuner_read_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
2205 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
2206 u8 n_overflow = 1, n_empty = 1;
2207 u16 i = 1000;
2208 u16 serpar_num = msg[0].buf[0];
2209 u16 read_word;
2211 while (n_overflow == 1 && i) {
2212 n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
2213 i--;
2214 if (i == 0)
2215 dprintk("TunerITF: read busy (overflow)\n");
2217 dib7000p_write_word(state, 1985, (0 << 6) | (serpar_num & 0x3f));
2219 i = 1000;
2220 while (n_empty == 1 && i) {
2221 n_empty = dib7000p_read_word(state, 1984) & 0x1;
2222 i--;
2223 if (i == 0)
2224 dprintk("TunerITF: read busy (empty)\n");
2226 read_word = dib7000p_read_word(state, 1987);
2227 msg[1].buf[0] = (read_word >> 8) & 0xff;
2228 msg[1].buf[1] = (read_word) & 0xff;
2230 return num;
2233 static int w7090p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
2235 if (map_addr_to_serpar_number(&msg[0]) == 0) { /* else = Tuner regs to ignore : DIG_CFG, CTRL_RF_LT, PLL_CFG, PWM1_REG, ADCCLK, DIG_CFG_3; SLEEP_EN... */
2236 if (num == 1) { /* write */
2237 return w7090p_tuner_write_serpar(i2c_adap, msg, 1);
2238 } else { /* read */
2239 return w7090p_tuner_read_serpar(i2c_adap, msg, 2);
2242 return num;
2245 static int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap,
2246 struct i2c_msg msg[], int num, u16 apb_address)
2248 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
2249 u16 word;
2251 if (num == 1) { /* write */
2252 dib7000p_write_word(state, apb_address, ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
2253 } else {
2254 word = dib7000p_read_word(state, apb_address);
2255 msg[1].buf[0] = (word >> 8) & 0xff;
2256 msg[1].buf[1] = (word) & 0xff;
2259 return num;
2262 static int dib7090_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
2264 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
2266 u16 apb_address = 0, word;
2267 int i = 0;
2268 switch (msg[0].buf[0]) {
2269 case 0x12:
2270 apb_address = 1920;
2271 break;
2272 case 0x14:
2273 apb_address = 1921;
2274 break;
2275 case 0x24:
2276 apb_address = 1922;
2277 break;
2278 case 0x1a:
2279 apb_address = 1923;
2280 break;
2281 case 0x22:
2282 apb_address = 1924;
2283 break;
2284 case 0x33:
2285 apb_address = 1926;
2286 break;
2287 case 0x34:
2288 apb_address = 1927;
2289 break;
2290 case 0x35:
2291 apb_address = 1928;
2292 break;
2293 case 0x36:
2294 apb_address = 1929;
2295 break;
2296 case 0x37:
2297 apb_address = 1930;
2298 break;
2299 case 0x38:
2300 apb_address = 1931;
2301 break;
2302 case 0x39:
2303 apb_address = 1932;
2304 break;
2305 case 0x2a:
2306 apb_address = 1935;
2307 break;
2308 case 0x2b:
2309 apb_address = 1936;
2310 break;
2311 case 0x2c:
2312 apb_address = 1937;
2313 break;
2314 case 0x2d:
2315 apb_address = 1938;
2316 break;
2317 case 0x2e:
2318 apb_address = 1939;
2319 break;
2320 case 0x2f:
2321 apb_address = 1940;
2322 break;
2323 case 0x30:
2324 apb_address = 1941;
2325 break;
2326 case 0x31:
2327 apb_address = 1942;
2328 break;
2329 case 0x32:
2330 apb_address = 1943;
2331 break;
2332 case 0x3e:
2333 apb_address = 1944;
2334 break;
2335 case 0x3f:
2336 apb_address = 1945;
2337 break;
2338 case 0x40:
2339 apb_address = 1948;
2340 break;
2341 case 0x25:
2342 apb_address = 914;
2343 break;
2344 case 0x26:
2345 apb_address = 915;
2346 break;
2347 case 0x27:
2348 apb_address = 917;
2349 break;
2350 case 0x28:
2351 apb_address = 916;
2352 break;
2353 case 0x1d:
2354 i = ((dib7000p_read_word(state, 72) >> 12) & 0x3);
2355 word = dib7000p_read_word(state, 384 + i);
2356 msg[1].buf[0] = (word >> 8) & 0xff;
2357 msg[1].buf[1] = (word) & 0xff;
2358 return num;
2359 case 0x1f:
2360 if (num == 1) { /* write */
2361 word = (u16) ((msg[0].buf[1] << 8) | msg[0].buf[2]);
2362 word &= 0x3;
2363 word = (dib7000p_read_word(state, 72) & ~(3 << 12)) | (word << 12);
2364 dib7000p_write_word(state, 72, word); /* Set the proper input */
2365 return num;
2369 if (apb_address != 0) /* R/W acces via APB */
2370 return dib7090p_rw_on_apb(i2c_adap, msg, num, apb_address);
2371 else /* R/W access via SERPAR */
2372 return w7090p_tuner_rw_serpar(i2c_adap, msg, num);
2374 return 0;
2377 static u32 dib7000p_i2c_func(struct i2c_adapter *adapter)
2379 return I2C_FUNC_I2C;
2382 static struct i2c_algorithm dib7090_tuner_xfer_algo = {
2383 .master_xfer = dib7090_tuner_xfer,
2384 .functionality = dib7000p_i2c_func,
2387 static struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
2389 struct dib7000p_state *st = fe->demodulator_priv;
2390 return &st->dib7090_tuner_adap;
2393 static int dib7090_host_bus_drive(struct dib7000p_state *state, u8 drive)
2395 u16 reg;
2397 /* drive host bus 2, 3, 4 */
2398 reg = dib7000p_read_word(state, 1798) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
2399 reg |= (drive << 12) | (drive << 6) | drive;
2400 dib7000p_write_word(state, 1798, reg);
2402 /* drive host bus 5,6 */
2403 reg = dib7000p_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
2404 reg |= (drive << 8) | (drive << 2);
2405 dib7000p_write_word(state, 1799, reg);
2407 /* drive host bus 7, 8, 9 */
2408 reg = dib7000p_read_word(state, 1800) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
2409 reg |= (drive << 12) | (drive << 6) | drive;
2410 dib7000p_write_word(state, 1800, reg);
2412 /* drive host bus 10, 11 */
2413 reg = dib7000p_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
2414 reg |= (drive << 8) | (drive << 2);
2415 dib7000p_write_word(state, 1801, reg);
2417 /* drive host bus 12, 13, 14 */
2418 reg = dib7000p_read_word(state, 1802) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
2419 reg |= (drive << 12) | (drive << 6) | drive;
2420 dib7000p_write_word(state, 1802, reg);
2422 return 0;
2425 static u32 dib7090_calcSyncFreq(u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 syncSize)
2427 u32 quantif = 3;
2428 u32 nom = (insertExtSynchro * P_Kin + syncSize);
2429 u32 denom = P_Kout;
2430 u32 syncFreq = ((nom << quantif) / denom);
2432 if ((syncFreq & ((1 << quantif) - 1)) != 0)
2433 syncFreq = (syncFreq >> quantif) + 1;
2434 else
2435 syncFreq = (syncFreq >> quantif);
2437 if (syncFreq != 0)
2438 syncFreq = syncFreq - 1;
2440 return syncFreq;
2443 static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize)
2445 dprintk("Configure DibStream Tx\n");
2447 dib7000p_write_word(state, 1615, 1);
2448 dib7000p_write_word(state, 1603, P_Kin);
2449 dib7000p_write_word(state, 1605, P_Kout);
2450 dib7000p_write_word(state, 1606, insertExtSynchro);
2451 dib7000p_write_word(state, 1608, synchroMode);
2452 dib7000p_write_word(state, 1609, (syncWord >> 16) & 0xffff);
2453 dib7000p_write_word(state, 1610, syncWord & 0xffff);
2454 dib7000p_write_word(state, 1612, syncSize);
2455 dib7000p_write_word(state, 1615, 0);
2457 return 0;
2460 static int dib7090_cfg_DibRx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 synchroMode, u32 insertExtSynchro, u32 syncWord, u32 syncSize,
2461 u32 dataOutRate)
2463 u32 syncFreq;
2465 dprintk("Configure DibStream Rx\n");
2466 if ((P_Kin != 0) && (P_Kout != 0)) {
2467 syncFreq = dib7090_calcSyncFreq(P_Kin, P_Kout, insertExtSynchro, syncSize);
2468 dib7000p_write_word(state, 1542, syncFreq);
2470 dib7000p_write_word(state, 1554, 1);
2471 dib7000p_write_word(state, 1536, P_Kin);
2472 dib7000p_write_word(state, 1537, P_Kout);
2473 dib7000p_write_word(state, 1539, synchroMode);
2474 dib7000p_write_word(state, 1540, (syncWord >> 16) & 0xffff);
2475 dib7000p_write_word(state, 1541, syncWord & 0xffff);
2476 dib7000p_write_word(state, 1543, syncSize);
2477 dib7000p_write_word(state, 1544, dataOutRate);
2478 dib7000p_write_word(state, 1554, 0);
2480 return 0;
2483 static void dib7090_enMpegMux(struct dib7000p_state *state, int onoff)
2485 u16 reg_1287 = dib7000p_read_word(state, 1287);
2487 switch (onoff) {
2488 case 1:
2489 reg_1287 &= ~(1<<7);
2490 break;
2491 case 0:
2492 reg_1287 |= (1<<7);
2493 break;
2496 dib7000p_write_word(state, 1287, reg_1287);
2499 static void dib7090_configMpegMux(struct dib7000p_state *state,
2500 u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
2502 dprintk("Enable Mpeg mux\n");
2504 dib7090_enMpegMux(state, 0);
2506 /* If the input mode is MPEG do not divide the serial clock */
2507 if ((enSerialMode == 1) && (state->input_mode_mpeg == 1))
2508 enSerialClkDiv2 = 0;
2510 dib7000p_write_word(state, 1287, ((pulseWidth & 0x1f) << 2)
2511 | ((enSerialMode & 0x1) << 1)
2512 | (enSerialClkDiv2 & 0x1));
2514 dib7090_enMpegMux(state, 1);
2517 static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode)
2519 u16 reg_1288 = dib7000p_read_word(state, 1288) & ~(0x7 << 7);
2521 switch (mode) {
2522 case MPEG_ON_DIBTX:
2523 dprintk("SET MPEG ON DIBSTREAM TX\n");
2524 dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
2525 reg_1288 |= (1<<9);
2526 break;
2527 case DIV_ON_DIBTX:
2528 dprintk("SET DIV_OUT ON DIBSTREAM TX\n");
2529 dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
2530 reg_1288 |= (1<<8);
2531 break;
2532 case ADC_ON_DIBTX:
2533 dprintk("SET ADC_OUT ON DIBSTREAM TX\n");
2534 dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
2535 reg_1288 |= (1<<7);
2536 break;
2537 default:
2538 break;
2540 dib7000p_write_word(state, 1288, reg_1288);
2543 static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode)
2545 u16 reg_1288 = dib7000p_read_word(state, 1288) & ~(0x7 << 4);
2547 switch (mode) {
2548 case DEMOUT_ON_HOSTBUS:
2549 dprintk("SET DEM OUT OLD INTERF ON HOST BUS\n");
2550 dib7090_enMpegMux(state, 0);
2551 reg_1288 |= (1<<6);
2552 break;
2553 case DIBTX_ON_HOSTBUS:
2554 dprintk("SET DIBSTREAM TX ON HOST BUS\n");
2555 dib7090_enMpegMux(state, 0);
2556 reg_1288 |= (1<<5);
2557 break;
2558 case MPEG_ON_HOSTBUS:
2559 dprintk("SET MPEG MUX ON HOST BUS\n");
2560 reg_1288 |= (1<<4);
2561 break;
2562 default:
2563 break;
2565 dib7000p_write_word(state, 1288, reg_1288);
2568 static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff)
2570 struct dib7000p_state *state = fe->demodulator_priv;
2571 u16 reg_1287;
2573 switch (onoff) {
2574 case 0: /* only use the internal way - not the diversity input */
2575 dprintk("%s mode OFF : by default Enable Mpeg INPUT\n", __func__);
2576 dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0);
2578 /* Do not divide the serial clock of MPEG MUX */
2579 /* in SERIAL MODE in case input mode MPEG is used */
2580 reg_1287 = dib7000p_read_word(state, 1287);
2581 /* enSerialClkDiv2 == 1 ? */
2582 if ((reg_1287 & 0x1) == 1) {
2583 /* force enSerialClkDiv2 = 0 */
2584 reg_1287 &= ~0x1;
2585 dib7000p_write_word(state, 1287, reg_1287);
2587 state->input_mode_mpeg = 1;
2588 break;
2589 case 1: /* both ways */
2590 case 2: /* only the diversity input */
2591 dprintk("%s ON : Enable diversity INPUT\n", __func__);
2592 dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
2593 state->input_mode_mpeg = 0;
2594 break;
2597 dib7000p_set_diversity_in(&state->demod, onoff);
2598 return 0;
2601 static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode)
2603 struct dib7000p_state *state = fe->demodulator_priv;
2605 u16 outreg, smo_mode, fifo_threshold;
2606 u8 prefer_mpeg_mux_use = 1;
2607 int ret = 0;
2609 dib7090_host_bus_drive(state, 1);
2611 fifo_threshold = 1792;
2612 smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
2613 outreg = dib7000p_read_word(state, 1286) & ~((1 << 10) | (0x7 << 6) | (1 << 1));
2615 switch (mode) {
2616 case OUTMODE_HIGH_Z:
2617 outreg = 0;
2618 break;
2620 case OUTMODE_MPEG2_SERIAL:
2621 if (prefer_mpeg_mux_use) {
2622 dprintk("setting output mode TS_SERIAL using Mpeg Mux\n");
2623 dib7090_configMpegMux(state, 3, 1, 1);
2624 dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS);
2625 } else {/* Use Smooth block */
2626 dprintk("setting output mode TS_SERIAL using Smooth bloc\n");
2627 dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
2628 outreg |= (2<<6) | (0 << 1);
2630 break;
2632 case OUTMODE_MPEG2_PAR_GATED_CLK:
2633 if (prefer_mpeg_mux_use) {
2634 dprintk("setting output mode TS_PARALLEL_GATED using Mpeg Mux\n");
2635 dib7090_configMpegMux(state, 2, 0, 0);
2636 dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS);
2637 } else { /* Use Smooth block */
2638 dprintk("setting output mode TS_PARALLEL_GATED using Smooth block\n");
2639 dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
2640 outreg |= (0<<6);
2642 break;
2644 case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */
2645 dprintk("setting output mode TS_PARALLEL_CONT using Smooth block\n");
2646 dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
2647 outreg |= (1<<6);
2648 break;
2650 case OUTMODE_MPEG2_FIFO: /* Using Smooth block because not supported by new Mpeg Mux bloc */
2651 dprintk("setting output mode TS_FIFO using Smooth block\n");
2652 dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
2653 outreg |= (5<<6);
2654 smo_mode |= (3 << 1);
2655 fifo_threshold = 512;
2656 break;
2658 case OUTMODE_DIVERSITY:
2659 dprintk("setting output mode MODE_DIVERSITY\n");
2660 dib7090_setDibTxMux(state, DIV_ON_DIBTX);
2661 dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS);
2662 break;
2664 case OUTMODE_ANALOG_ADC:
2665 dprintk("setting output mode MODE_ANALOG_ADC\n");
2666 dib7090_setDibTxMux(state, ADC_ON_DIBTX);
2667 dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS);
2668 break;
2670 if (mode != OUTMODE_HIGH_Z)
2671 outreg |= (1 << 10);
2673 if (state->cfg.output_mpeg2_in_188_bytes)
2674 smo_mode |= (1 << 5);
2676 ret |= dib7000p_write_word(state, 235, smo_mode);
2677 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
2678 ret |= dib7000p_write_word(state, 1286, outreg);
2680 return ret;
2683 static int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
2685 struct dib7000p_state *state = fe->demodulator_priv;
2686 u16 en_cur_state;
2688 dprintk("sleep dib7090: %d\n", onoff);
2690 en_cur_state = dib7000p_read_word(state, 1922);
2692 if (en_cur_state > 0xff)
2693 state->tuner_enable = en_cur_state;
2695 if (onoff)
2696 en_cur_state &= 0x00ff;
2697 else {
2698 if (state->tuner_enable != 0)
2699 en_cur_state = state->tuner_enable;
2702 dib7000p_write_word(state, 1922, en_cur_state);
2704 return 0;
2707 static int dib7090_get_adc_power(struct dvb_frontend *fe)
2709 return dib7000p_get_adc_power(fe);
2712 static int dib7090_slave_reset(struct dvb_frontend *fe)
2714 struct dib7000p_state *state = fe->demodulator_priv;
2715 u16 reg;
2717 reg = dib7000p_read_word(state, 1794);
2718 dib7000p_write_word(state, 1794, reg | (4 << 12));
2720 dib7000p_write_word(state, 1032, 0xffff);
2721 return 0;
2724 static const struct dvb_frontend_ops dib7000p_ops;
2725 static struct dvb_frontend *dib7000p_init(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
2727 struct dvb_frontend *demod;
2728 struct dib7000p_state *st;
2729 st = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
2730 if (st == NULL)
2731 return NULL;
2733 memcpy(&st->cfg, cfg, sizeof(struct dib7000p_config));
2734 st->i2c_adap = i2c_adap;
2735 st->i2c_addr = i2c_addr;
2736 st->gpio_val = cfg->gpio_val;
2737 st->gpio_dir = cfg->gpio_dir;
2739 /* Ensure the output mode remains at the previous default if it's
2740 * not specifically set by the caller.
2742 if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2743 st->cfg.output_mode = OUTMODE_MPEG2_FIFO;
2745 demod = &st->demod;
2746 demod->demodulator_priv = st;
2747 memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));
2748 mutex_init(&st->i2c_buffer_lock);
2750 dib7000p_write_word(st, 1287, 0x0003); /* sram lead in, rdy */
2752 if (dib7000p_identify(st) != 0)
2753 goto error;
2755 st->version = dib7000p_read_word(st, 897);
2757 /* FIXME: make sure the dev.parent field is initialized, or else
2758 request_firmware() will hit an OOPS (this should be moved somewhere
2759 more common) */
2760 st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent;
2762 dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr);
2764 /* init 7090 tuner adapter */
2765 strncpy(st->dib7090_tuner_adap.name, "DiB7090 tuner interface", sizeof(st->dib7090_tuner_adap.name));
2766 st->dib7090_tuner_adap.algo = &dib7090_tuner_xfer_algo;
2767 st->dib7090_tuner_adap.algo_data = NULL;
2768 st->dib7090_tuner_adap.dev.parent = st->i2c_adap->dev.parent;
2769 i2c_set_adapdata(&st->dib7090_tuner_adap, st);
2770 i2c_add_adapter(&st->dib7090_tuner_adap);
2772 dib7000p_demod_reset(st);
2774 dib7000p_reset_stats(demod);
2776 if (st->version == SOC7090) {
2777 dib7090_set_output_mode(demod, st->cfg.output_mode);
2778 dib7090_set_diversity_in(demod, 0);
2781 return demod;
2783 error:
2784 kfree(st);
2785 return NULL;
2788 void *dib7000p_attach(struct dib7000p_ops *ops)
2790 if (!ops)
2791 return NULL;
2793 ops->slave_reset = dib7090_slave_reset;
2794 ops->get_adc_power = dib7090_get_adc_power;
2795 ops->dib7000pc_detection = dib7000pc_detection;
2796 ops->get_i2c_tuner = dib7090_get_i2c_tuner;
2797 ops->tuner_sleep = dib7090_tuner_sleep;
2798 ops->init = dib7000p_init;
2799 ops->set_agc1_min = dib7000p_set_agc1_min;
2800 ops->set_gpio = dib7000p_set_gpio;
2801 ops->i2c_enumeration = dib7000p_i2c_enumeration;
2802 ops->pid_filter = dib7000p_pid_filter;
2803 ops->pid_filter_ctrl = dib7000p_pid_filter_ctrl;
2804 ops->get_i2c_master = dib7000p_get_i2c_master;
2805 ops->update_pll = dib7000p_update_pll;
2806 ops->ctrl_timf = dib7000p_ctrl_timf;
2807 ops->get_agc_values = dib7000p_get_agc_values;
2808 ops->set_wbd_ref = dib7000p_set_wbd_ref;
2810 return ops;
2812 EXPORT_SYMBOL(dib7000p_attach);
2814 static const struct dvb_frontend_ops dib7000p_ops = {
2815 .delsys = { SYS_DVBT },
2816 .info = {
2817 .name = "DiBcom 7000PC",
2818 .frequency_min = 44250000,
2819 .frequency_max = 867250000,
2820 .frequency_stepsize = 62500,
2821 .caps = FE_CAN_INVERSION_AUTO |
2822 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2823 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2824 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2825 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2828 .release = dib7000p_release,
2830 .init = dib7000p_wakeup,
2831 .sleep = dib7000p_sleep,
2833 .set_frontend = dib7000p_set_frontend,
2834 .get_tune_settings = dib7000p_fe_get_tune_settings,
2835 .get_frontend = dib7000p_get_frontend,
2837 .read_status = dib7000p_read_status,
2838 .read_ber = dib7000p_read_ber,
2839 .read_signal_strength = dib7000p_read_signal_strength,
2840 .read_snr = dib7000p_read_snr,
2841 .read_ucblocks = dib7000p_read_unc_blocks,
2844 MODULE_AUTHOR("Olivier Grenie <olivie.grenie@parrot.com>");
2845 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
2846 MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
2847 MODULE_LICENSE("GPL");