Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/*
2 * Linux-DVB Driver for DiBcom's second generation DiB7000P (PC).
3 *
4 * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 */
10#include <linux/kernel.h>
11#include <linux/slab.h>
12#include <linux/i2c.h>
13
14#include "dvb_math.h"
15#include "dvb_frontend.h"
16
17#include "dib7000p.h"
18
19static int debug;
20module_param(debug, int, 0644);
21MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
22
23static int buggy_sfn_workaround;
24module_param(buggy_sfn_workaround, int, 0644);
25MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
26
27#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0)
28
29struct i2c_device {
30 struct i2c_adapter *i2c_adap;
31 u8 i2c_addr;
32};
33
34struct dib7000p_state {
35 struct dvb_frontend demod;
36 struct dib7000p_config cfg;
37
38 u8 i2c_addr;
39 struct i2c_adapter *i2c_adap;
40
41 struct dibx000_i2c_master i2c_master;
42
43 u16 wbd_ref;
44
45 u8 current_band;
46 u32 current_bandwidth;
47 struct dibx000_agc_config *current_agc;
48 u32 timf;
49
50 u8 div_force_off:1;
51 u8 div_state:1;
52 u16 div_sync_wait;
53
54 u8 agc_state;
55
56 u16 gpio_dir;
57 u16 gpio_val;
58
59 u8 sfn_workaround_active:1;
60
61#define SOC7090 0x7090
62 u16 version;
63
64 u16 tuner_enable;
65 struct i2c_adapter dib7090_tuner_adap;
66
67 /* for the I2C transfer */
68 struct i2c_msg msg[2];
69 u8 i2c_write_buffer[4];
70 u8 i2c_read_buffer[2];
71};
72
73enum dib7000p_power_mode {
74 DIB7000P_POWER_ALL = 0,
75 DIB7000P_POWER_ANALOG_ADC,
76 DIB7000P_POWER_INTERFACE_ONLY,
77};
78
79static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode);
80static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff);
81
82static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
83{
84 state->i2c_write_buffer[0] = reg >> 8;
85 state->i2c_write_buffer[1] = reg & 0xff;
86
87 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
88 state->msg[0].addr = state->i2c_addr >> 1;
89 state->msg[0].flags = 0;
90 state->msg[0].buf = state->i2c_write_buffer;
91 state->msg[0].len = 2;
92 state->msg[1].addr = state->i2c_addr >> 1;
93 state->msg[1].flags = I2C_M_RD;
94 state->msg[1].buf = state->i2c_read_buffer;
95 state->msg[1].len = 2;
96
97 if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
98 dprintk("i2c read error on %d", reg);
99
100 return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
101}
102
103static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
104{
105 state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
106 state->i2c_write_buffer[1] = reg & 0xff;
107 state->i2c_write_buffer[2] = (val >> 8) & 0xff;
108 state->i2c_write_buffer[3] = val & 0xff;
109
110 memset(&state->msg[0], 0, sizeof(struct i2c_msg));
111 state->msg[0].addr = state->i2c_addr >> 1;
112 state->msg[0].flags = 0;
113 state->msg[0].buf = state->i2c_write_buffer;
114 state->msg[0].len = 4;
115
116 return i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
117}
118
119static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf)
120{
121 u16 l = 0, r, *n;
122 n = buf;
123 l = *n++;
124 while (l) {
125 r = *n++;
126
127 do {
128 dib7000p_write_word(state, r, *n++);
129 r++;
130 } while (--l);
131 l = *n++;
132 }
133}
134
135static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
136{
137 int ret = 0;
138 u16 outreg, fifo_threshold, smo_mode;
139
140 outreg = 0;
141 fifo_threshold = 1792;
142 smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
143
144 dprintk("setting output mode for demod %p to %d", &state->demod, mode);
145
146 switch (mode) {
147 case OUTMODE_MPEG2_PAR_GATED_CLK:
148 outreg = (1 << 10); /* 0x0400 */
149 break;
150 case OUTMODE_MPEG2_PAR_CONT_CLK:
151 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
152 break;
153 case OUTMODE_MPEG2_SERIAL:
154 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */
155 break;
156 case OUTMODE_DIVERSITY:
157 if (state->cfg.hostbus_diversity)
158 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
159 else
160 outreg = (1 << 11);
161 break;
162 case OUTMODE_MPEG2_FIFO:
163 smo_mode |= (3 << 1);
164 fifo_threshold = 512;
165 outreg = (1 << 10) | (5 << 6);
166 break;
167 case OUTMODE_ANALOG_ADC:
168 outreg = (1 << 10) | (3 << 6);
169 break;
170 case OUTMODE_HIGH_Z:
171 outreg = 0;
172 break;
173 default:
174 dprintk("Unhandled output_mode passed to be set for demod %p", &state->demod);
175 break;
176 }
177
178 if (state->cfg.output_mpeg2_in_188_bytes)
179 smo_mode |= (1 << 5);
180
181 ret |= dib7000p_write_word(state, 235, smo_mode);
182 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
183 if (state->version != SOC7090)
184 ret |= dib7000p_write_word(state, 1286, outreg); /* P_Div_active */
185
186 return ret;
187}
188
189static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
190{
191 struct dib7000p_state *state = demod->demodulator_priv;
192
193 if (state->div_force_off) {
194 dprintk("diversity combination deactivated - forced by COFDM parameters");
195 onoff = 0;
196 dib7000p_write_word(state, 207, 0);
197 } else
198 dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
199
200 state->div_state = (u8) onoff;
201
202 if (onoff) {
203 dib7000p_write_word(state, 204, 6);
204 dib7000p_write_word(state, 205, 16);
205 /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
206 } else {
207 dib7000p_write_word(state, 204, 1);
208 dib7000p_write_word(state, 205, 0);
209 }
210
211 return 0;
212}
213
214static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode)
215{
216 /* by default everything is powered off */
217 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0x0007, reg_899 = 0x0003, reg_1280 = (0xfe00) | (dib7000p_read_word(state, 1280) & 0x01ff);
218
219 /* now, depending on the requested mode, we power on */
220 switch (mode) {
221 /* power up everything in the demod */
222 case DIB7000P_POWER_ALL:
223 reg_774 = 0x0000;
224 reg_775 = 0x0000;
225 reg_776 = 0x0;
226 reg_899 = 0x0;
227 if (state->version == SOC7090)
228 reg_1280 &= 0x001f;
229 else
230 reg_1280 &= 0x01ff;
231 break;
232
233 case DIB7000P_POWER_ANALOG_ADC:
234 /* dem, cfg, iqc, sad, agc */
235 reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
236 /* nud */
237 reg_776 &= ~((1 << 0));
238 /* Dout */
239 if (state->version != SOC7090)
240 reg_1280 &= ~((1 << 11));
241 reg_1280 &= ~(1 << 6);
242 /* fall through wanted to enable the interfaces */
243
244 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
245 case DIB7000P_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C */
246 if (state->version == SOC7090)
247 reg_1280 &= ~((1 << 7) | (1 << 5));
248 else
249 reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
250 break;
251
252/* TODO following stuff is just converted from the dib7000-driver - check when is used what */
253 }
254
255 dib7000p_write_word(state, 774, reg_774);
256 dib7000p_write_word(state, 775, reg_775);
257 dib7000p_write_word(state, 776, reg_776);
258 dib7000p_write_word(state, 899, reg_899);
259 dib7000p_write_word(state, 1280, reg_1280);
260
261 return 0;
262}
263
264static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no)
265{
266 u16 reg_908 = dib7000p_read_word(state, 908), reg_909 = dib7000p_read_word(state, 909);
267 u16 reg;
268
269 switch (no) {
270 case DIBX000_SLOW_ADC_ON:
271 if (state->version == SOC7090) {
272 reg = dib7000p_read_word(state, 1925);
273
274 dib7000p_write_word(state, 1925, reg | (1 << 4) | (1 << 2)); /* en_slowAdc = 1 & reset_sladc = 1 */
275
276 reg = dib7000p_read_word(state, 1925); /* read acces to make it works... strange ... */
277 msleep(200);
278 dib7000p_write_word(state, 1925, reg & ~(1 << 4)); /* en_slowAdc = 1 & reset_sladc = 0 */
279
280 reg = dib7000p_read_word(state, 72) & ~((0x3 << 14) | (0x3 << 12));
281 dib7000p_write_word(state, 72, reg | (1 << 14) | (3 << 12) | 524); /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ; (Vin2 = Vcm) */
282 } else {
283 reg_909 |= (1 << 1) | (1 << 0);
284 dib7000p_write_word(state, 909, reg_909);
285 reg_909 &= ~(1 << 1);
286 }
287 break;
288
289 case DIBX000_SLOW_ADC_OFF:
290 if (state->version == SOC7090) {
291 reg = dib7000p_read_word(state, 1925);
292 dib7000p_write_word(state, 1925, (reg & ~(1 << 2)) | (1 << 4)); /* reset_sladc = 1 en_slowAdc = 0 */
293 } else
294 reg_909 |= (1 << 1) | (1 << 0);
295 break;
296
297 case DIBX000_ADC_ON:
298 reg_908 &= 0x0fff;
299 reg_909 &= 0x0003;
300 break;
301
302 case DIBX000_ADC_OFF:
303 reg_908 |= (1 << 14) | (1 << 13) | (1 << 12);
304 reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
305 break;
306
307 case DIBX000_VBG_ENABLE:
308 reg_908 &= ~(1 << 15);
309 break;
310
311 case DIBX000_VBG_DISABLE:
312 reg_908 |= (1 << 15);
313 break;
314
315 default:
316 break;
317 }
318
319// dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
320
321 reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4;
322 reg_908 |= (state->cfg.enable_current_mirror & 1) << 7;
323
324 dib7000p_write_word(state, 908, reg_908);
325 dib7000p_write_word(state, 909, reg_909);
326}
327
328static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
329{
330 u32 timf;
331
332 // store the current bandwidth for later use
333 state->current_bandwidth = bw;
334
335 if (state->timf == 0) {
336 dprintk("using default timf");
337 timf = state->cfg.bw->timf;
338 } else {
339 dprintk("using updated timf");
340 timf = state->timf;
341 }
342
343 timf = timf * (bw / 50) / 160;
344
345 dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
346 dib7000p_write_word(state, 24, (u16) ((timf) & 0xffff));
347
348 return 0;
349}
350
351static int dib7000p_sad_calib(struct dib7000p_state *state)
352{
353/* internal */
354 dib7000p_write_word(state, 73, (0 << 1) | (0 << 0));
355
356 if (state->version == SOC7090)
357 dib7000p_write_word(state, 74, 2048);
358 else
359 dib7000p_write_word(state, 74, 776);
360
361 /* do the calibration */
362 dib7000p_write_word(state, 73, (1 << 0));
363 dib7000p_write_word(state, 73, (0 << 0));
364
365 msleep(1);
366
367 return 0;
368}
369
370int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
371{
372 struct dib7000p_state *state = demod->demodulator_priv;
373 if (value > 4095)
374 value = 4095;
375 state->wbd_ref = value;
376 return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value);
377}
378EXPORT_SYMBOL(dib7000p_set_wbd_ref);
379
380static void dib7000p_reset_pll(struct dib7000p_state *state)
381{
382 struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
383 u16 clk_cfg0;
384
385 if (state->version == SOC7090) {
386 dib7000p_write_word(state, 1856, (!bw->pll_reset << 13) | (bw->pll_range << 12) | (bw->pll_ratio << 6) | (bw->pll_prediv));
387
388 while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
389 ;
390
391 dib7000p_write_word(state, 1857, dib7000p_read_word(state, 1857) | (!bw->pll_bypass << 15));
392 } else {
393 /* force PLL bypass */
394 clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) |
395 (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0);
396
397 dib7000p_write_word(state, 900, clk_cfg0);
398
399 /* P_pll_cfg */
400 dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset);
401 clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff);
402 dib7000p_write_word(state, 900, clk_cfg0);
403 }
404
405 dib7000p_write_word(state, 18, (u16) (((bw->internal * 1000) >> 16) & 0xffff));
406 dib7000p_write_word(state, 19, (u16) ((bw->internal * 1000) & 0xffff));
407 dib7000p_write_word(state, 21, (u16) ((bw->ifreq >> 16) & 0xffff));
408 dib7000p_write_word(state, 22, (u16) ((bw->ifreq) & 0xffff));
409
410 dib7000p_write_word(state, 72, bw->sad_cfg);
411}
412
413static u32 dib7000p_get_internal_freq(struct dib7000p_state *state)
414{
415 u32 internal = (u32) dib7000p_read_word(state, 18) << 16;
416 internal |= (u32) dib7000p_read_word(state, 19);
417 internal /= 1000;
418
419 return internal;
420}
421
422int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
423{
424 struct dib7000p_state *state = fe->demodulator_priv;
425 u16 reg_1857, reg_1856 = dib7000p_read_word(state, 1856);
426 u8 loopdiv, prediv;
427 u32 internal, xtal;
428
429 /* get back old values */
430 prediv = reg_1856 & 0x3f;
431 loopdiv = (reg_1856 >> 6) & 0x3f;
432
433 if ((bw != NULL) && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) {
434 dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio);
435 reg_1856 &= 0xf000;
436 reg_1857 = dib7000p_read_word(state, 1857);
437 dib7000p_write_word(state, 1857, reg_1857 & ~(1 << 15));
438
439 dib7000p_write_word(state, 1856, reg_1856 | ((bw->pll_ratio & 0x3f) << 6) | (bw->pll_prediv & 0x3f));
440
441 /* write new system clk into P_sec_len */
442 internal = dib7000p_get_internal_freq(state);
443 xtal = (internal / loopdiv) * prediv;
444 internal = 1000 * (xtal / bw->pll_prediv) * bw->pll_ratio; /* new internal */
445 dib7000p_write_word(state, 18, (u16) ((internal >> 16) & 0xffff));
446 dib7000p_write_word(state, 19, (u16) (internal & 0xffff));
447
448 dib7000p_write_word(state, 1857, reg_1857 | (1 << 15));
449
450 while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
451 dprintk("Waiting for PLL to lock");
452
453 return 0;
454 }
455 return -EIO;
456}
457EXPORT_SYMBOL(dib7000p_update_pll);
458
459static int dib7000p_reset_gpio(struct dib7000p_state *st)
460{
461 /* reset the GPIOs */
462 dprintk("gpio dir: %x: val: %x, pwm_pos: %x", st->gpio_dir, st->gpio_val, st->cfg.gpio_pwm_pos);
463
464 dib7000p_write_word(st, 1029, st->gpio_dir);
465 dib7000p_write_word(st, 1030, st->gpio_val);
466
467 /* TODO 1031 is P_gpio_od */
468
469 dib7000p_write_word(st, 1032, st->cfg.gpio_pwm_pos);
470
471 dib7000p_write_word(st, 1037, st->cfg.pwm_freq_div);
472 return 0;
473}
474
475static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val)
476{
477 st->gpio_dir = dib7000p_read_word(st, 1029);
478 st->gpio_dir &= ~(1 << num); /* reset the direction bit */
479 st->gpio_dir |= (dir & 0x1) << num; /* set the new direction */
480 dib7000p_write_word(st, 1029, st->gpio_dir);
481
482 st->gpio_val = dib7000p_read_word(st, 1030);
483 st->gpio_val &= ~(1 << num); /* reset the direction bit */
484 st->gpio_val |= (val & 0x01) << num; /* set the new value */
485 dib7000p_write_word(st, 1030, st->gpio_val);
486
487 return 0;
488}
489
490int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val)
491{
492 struct dib7000p_state *state = demod->demodulator_priv;
493 return dib7000p_cfg_gpio(state, num, dir, val);
494}
495EXPORT_SYMBOL(dib7000p_set_gpio);
496
497static u16 dib7000p_defaults[] = {
498 // auto search configuration
499 3, 2,
500 0x0004,
501 0x1000,
502 0x0814, /* Equal Lock */
503
504 12, 6,
505 0x001b,
506 0x7740,
507 0x005b,
508 0x8d80,
509 0x01c9,
510 0xc380,
511 0x0000,
512 0x0080,
513 0x0000,
514 0x0090,
515 0x0001,
516 0xd4c0,
517
518 1, 26,
519 0x6680,
520
521 /* set ADC level to -16 */
522 11, 79,
523 (1 << 13) - 825 - 117,
524 (1 << 13) - 837 - 117,
525 (1 << 13) - 811 - 117,
526 (1 << 13) - 766 - 117,
527 (1 << 13) - 737 - 117,
528 (1 << 13) - 693 - 117,
529 (1 << 13) - 648 - 117,
530 (1 << 13) - 619 - 117,
531 (1 << 13) - 575 - 117,
532 (1 << 13) - 531 - 117,
533 (1 << 13) - 501 - 117,
534
535 1, 142,
536 0x0410,
537
538 /* disable power smoothing */
539 8, 145,
540 0,
541 0,
542 0,
543 0,
544 0,
545 0,
546 0,
547 0,
548
549 1, 154,
550 1 << 13,
551
552 1, 168,
553 0x0ccd,
554
555 1, 183,
556 0x200f,
557
558 1, 212,
559 0x169,
560
561 5, 187,
562 0x023d,
563 0x00a4,
564 0x00a4,
565 0x7ff0,
566 0x3ccc,
567
568 1, 198,
569 0x800,
570
571 1, 222,
572 0x0010,
573
574 1, 235,
575 0x0062,
576
577 2, 901,
578 0x0006,
579 (3 << 10) | (1 << 6),
580
581 1, 905,
582 0x2c8e,
583
584 0,
585};
586
587static int dib7000p_demod_reset(struct dib7000p_state *state)
588{
589 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
590
591 if (state->version == SOC7090)
592 dibx000_reset_i2c_master(&state->i2c_master);
593
594 dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE);
595
596 /* restart all parts */
597 dib7000p_write_word(state, 770, 0xffff);
598 dib7000p_write_word(state, 771, 0xffff);
599 dib7000p_write_word(state, 772, 0x001f);
600 dib7000p_write_word(state, 898, 0x0003);
601 dib7000p_write_word(state, 1280, 0x001f - ((1 << 4) | (1 << 3)));
602
603 dib7000p_write_word(state, 770, 0);
604 dib7000p_write_word(state, 771, 0);
605 dib7000p_write_word(state, 772, 0);
606 dib7000p_write_word(state, 898, 0);
607 dib7000p_write_word(state, 1280, 0);
608
609 /* default */
610 dib7000p_reset_pll(state);
611
612 if (dib7000p_reset_gpio(state) != 0)
613 dprintk("GPIO reset was not successful.");
614
615 if (state->version == SOC7090) {
616 dib7000p_write_word(state, 899, 0);
617
618 /* impulse noise */
619 dib7000p_write_word(state, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */
620 dib7000p_write_word(state, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */
621 dib7000p_write_word(state, 44, 300); /* 300 fag P_iqc_dect_min = +280 */
622 dib7000p_write_word(state, 273, (1<<6) | 30);
623 }
624 if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
625 dprintk("OUTPUT_MODE could not be reset.");
626
627 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
628 dib7000p_sad_calib(state);
629 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
630
631 /* unforce divstr regardless whether i2c enumeration was done or not */
632 dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1));
633
634 dib7000p_set_bandwidth(state, 8000);
635
636 if (state->version == SOC7090) {
637 dib7000p_write_word(state, 36, 0x5755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */
638 } else {
639 if (state->cfg.tuner_is_baseband)
640 dib7000p_write_word(state, 36, 0x0755);
641 else
642 dib7000p_write_word(state, 36, 0x1f55);
643 }
644
645 dib7000p_write_tab(state, dib7000p_defaults);
646
647 dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
648
649 return 0;
650}
651
652static void dib7000p_pll_clk_cfg(struct dib7000p_state *state)
653{
654 u16 tmp = 0;
655 tmp = dib7000p_read_word(state, 903);
656 dib7000p_write_word(state, 903, (tmp | 0x1));
657 tmp = dib7000p_read_word(state, 900);
658 dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6));
659}
660
661static void dib7000p_restart_agc(struct dib7000p_state *state)
662{
663 // P_restart_iqc & P_restart_agc
664 dib7000p_write_word(state, 770, (1 << 11) | (1 << 9));
665 dib7000p_write_word(state, 770, 0x0000);
666}
667
668static int dib7000p_update_lna(struct dib7000p_state *state)
669{
670 u16 dyn_gain;
671
672 if (state->cfg.update_lna) {
673 dyn_gain = dib7000p_read_word(state, 394);
674 if (state->cfg.update_lna(&state->demod, dyn_gain)) {
675 dib7000p_restart_agc(state);
676 return 1;
677 }
678 }
679
680 return 0;
681}
682
683static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
684{
685 struct dibx000_agc_config *agc = NULL;
686 int i;
687 if (state->current_band == band && state->current_agc != NULL)
688 return 0;
689 state->current_band = band;
690
691 for (i = 0; i < state->cfg.agc_config_count; i++)
692 if (state->cfg.agc[i].band_caps & band) {
693 agc = &state->cfg.agc[i];
694 break;
695 }
696
697 if (agc == NULL) {
698 dprintk("no valid AGC configuration found for band 0x%02x", band);
699 return -EINVAL;
700 }
701
702 state->current_agc = agc;
703
704 /* AGC */
705 dib7000p_write_word(state, 75, agc->setup);
706 dib7000p_write_word(state, 76, agc->inv_gain);
707 dib7000p_write_word(state, 77, agc->time_stabiliz);
708 dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);
709
710 // Demod AGC loop configuration
711 dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);
712 dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp);
713
714 /* AGC continued */
715 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
716 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
717
718 if (state->wbd_ref != 0)
719 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref);
720 else
721 dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref);
722
723 dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
724
725 dib7000p_write_word(state, 107, agc->agc1_max);
726 dib7000p_write_word(state, 108, agc->agc1_min);
727 dib7000p_write_word(state, 109, agc->agc2_max);
728 dib7000p_write_word(state, 110, agc->agc2_min);
729 dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
730 dib7000p_write_word(state, 112, agc->agc1_pt3);
731 dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
732 dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
733 dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
734 return 0;
735}
736
737static void dib7000p_set_dds(struct dib7000p_state *state, s32 offset_khz)
738{
739 u32 internal = dib7000p_get_internal_freq(state);
740 s32 unit_khz_dds_val = 67108864 / (internal); /* 2**26 / Fsampling is the unit 1KHz offset */
741 u32 abs_offset_khz = ABS(offset_khz);
742 u32 dds = state->cfg.bw->ifreq & 0x1ffffff;
743 u8 invert = !!(state->cfg.bw->ifreq & (1 << 25));
744
745 dprintk("setting a frequency offset of %dkHz internal freq = %d invert = %d", offset_khz, internal, invert);
746
747 if (offset_khz < 0)
748 unit_khz_dds_val *= -1;
749
750 /* IF tuner */
751 if (invert)
752 dds -= (abs_offset_khz * unit_khz_dds_val); /* /100 because of /100 on the unit_khz_dds_val line calc for better accuracy */
753 else
754 dds += (abs_offset_khz * unit_khz_dds_val);
755
756 if (abs_offset_khz <= (internal / 2)) { /* Max dds offset is the half of the demod freq */
757 dib7000p_write_word(state, 21, (u16) (((dds >> 16) & 0x1ff) | (0 << 10) | (invert << 9)));
758 dib7000p_write_word(state, 22, (u16) (dds & 0xffff));
759 }
760}
761
762static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
763{
764 struct dib7000p_state *state = demod->demodulator_priv;
765 int ret = -1;
766 u8 *agc_state = &state->agc_state;
767 u8 agc_split;
768 u16 reg;
769 u32 upd_demod_gain_period = 0x1000;
770
771 switch (state->agc_state) {
772 case 0:
773 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
774 if (state->version == SOC7090) {
775 reg = dib7000p_read_word(state, 0x79b) & 0xff00;
776 dib7000p_write_word(state, 0x79a, upd_demod_gain_period & 0xFFFF); /* lsb */
777 dib7000p_write_word(state, 0x79b, reg | (1 << 14) | ((upd_demod_gain_period >> 16) & 0xFF));
778
779 /* enable adc i & q */
780 reg = dib7000p_read_word(state, 0x780);
781 dib7000p_write_word(state, 0x780, (reg | (0x3)) & (~(1 << 7)));
782 } else {
783 dib7000p_set_adc_state(state, DIBX000_ADC_ON);
784 dib7000p_pll_clk_cfg(state);
785 }
786
787 if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency / 1000)) != 0)
788 return -1;
789
790 dib7000p_set_dds(state, 0);
791 ret = 7;
792 (*agc_state)++;
793 break;
794
795 case 1:
796 if (state->cfg.agc_control)
797 state->cfg.agc_control(&state->demod, 1);
798
799 dib7000p_write_word(state, 78, 32768);
800 if (!state->current_agc->perform_agc_softsplit) {
801 /* we are using the wbd - so slow AGC startup */
802 /* force 0 split on WBD and restart AGC */
803 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));
804 (*agc_state)++;
805 ret = 5;
806 } else {
807 /* default AGC startup */
808 (*agc_state) = 4;
809 /* wait AGC rough lock time */
810 ret = 7;
811 }
812
813 dib7000p_restart_agc(state);
814 break;
815
816 case 2: /* fast split search path after 5sec */
817 dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4)); /* freeze AGC loop */
818 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */
819 (*agc_state)++;
820 ret = 14;
821 break;
822
823 case 3: /* split search ended */
824 agc_split = (u8) dib7000p_read_word(state, 396); /* store the split value for the next time */
825 dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */
826
827 dib7000p_write_word(state, 75, state->current_agc->setup); /* std AGC loop */
828 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
829
830 dib7000p_restart_agc(state);
831
832 dprintk("SPLIT %p: %hd", demod, agc_split);
833
834 (*agc_state)++;
835 ret = 5;
836 break;
837
838 case 4: /* LNA startup */
839 ret = 7;
840
841 if (dib7000p_update_lna(state))
842 ret = 5;
843 else
844 (*agc_state)++;
845 break;
846
847 case 5:
848 if (state->cfg.agc_control)
849 state->cfg.agc_control(&state->demod, 0);
850 (*agc_state)++;
851 break;
852 default:
853 break;
854 }
855 return ret;
856}
857
858static void dib7000p_update_timf(struct dib7000p_state *state)
859{
860 u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428);
861 state->timf = timf * 160 / (state->current_bandwidth / 50);
862 dib7000p_write_word(state, 23, (u16) (timf >> 16));
863 dib7000p_write_word(state, 24, (u16) (timf & 0xffff));
864 dprintk("updated timf_frequency: %d (default: %d)", state->timf, state->cfg.bw->timf);
865
866}
867
868u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
869{
870 struct dib7000p_state *state = fe->demodulator_priv;
871 switch (op) {
872 case DEMOD_TIMF_SET:
873 state->timf = timf;
874 break;
875 case DEMOD_TIMF_UPDATE:
876 dib7000p_update_timf(state);
877 break;
878 case DEMOD_TIMF_GET:
879 break;
880 }
881 dib7000p_set_bandwidth(state, state->current_bandwidth);
882 return state->timf;
883}
884EXPORT_SYMBOL(dib7000p_ctrl_timf);
885
886static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq)
887{
888 u16 value, est[4];
889
890 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
891
892 /* nfft, guard, qam, alpha */
893 value = 0;
894 switch (ch->u.ofdm.transmission_mode) {
895 case TRANSMISSION_MODE_2K:
896 value |= (0 << 7);
897 break;
898 case TRANSMISSION_MODE_4K:
899 value |= (2 << 7);
900 break;
901 default:
902 case TRANSMISSION_MODE_8K:
903 value |= (1 << 7);
904 break;
905 }
906 switch (ch->u.ofdm.guard_interval) {
907 case GUARD_INTERVAL_1_32:
908 value |= (0 << 5);
909 break;
910 case GUARD_INTERVAL_1_16:
911 value |= (1 << 5);
912 break;
913 case GUARD_INTERVAL_1_4:
914 value |= (3 << 5);
915 break;
916 default:
917 case GUARD_INTERVAL_1_8:
918 value |= (2 << 5);
919 break;
920 }
921 switch (ch->u.ofdm.constellation) {
922 case QPSK:
923 value |= (0 << 3);
924 break;
925 case QAM_16:
926 value |= (1 << 3);
927 break;
928 default:
929 case QAM_64:
930 value |= (2 << 3);
931 break;
932 }
933 switch (HIERARCHY_1) {
934 case HIERARCHY_2:
935 value |= 2;
936 break;
937 case HIERARCHY_4:
938 value |= 4;
939 break;
940 default:
941 case HIERARCHY_1:
942 value |= 1;
943 break;
944 }
945 dib7000p_write_word(state, 0, value);
946 dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */
947
948 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
949 value = 0;
950 if (1 != 0)
951 value |= (1 << 6);
952 if (ch->u.ofdm.hierarchy_information == 1)
953 value |= (1 << 4);
954 if (1 == 1)
955 value |= 1;
956 switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
957 case FEC_2_3:
958 value |= (2 << 1);
959 break;
960 case FEC_3_4:
961 value |= (3 << 1);
962 break;
963 case FEC_5_6:
964 value |= (5 << 1);
965 break;
966 case FEC_7_8:
967 value |= (7 << 1);
968 break;
969 default:
970 case FEC_1_2:
971 value |= (1 << 1);
972 break;
973 }
974 dib7000p_write_word(state, 208, value);
975
976 /* offset loop parameters */
977 dib7000p_write_word(state, 26, 0x6680);
978 dib7000p_write_word(state, 32, 0x0003);
979 dib7000p_write_word(state, 29, 0x1273);
980 dib7000p_write_word(state, 33, 0x0005);
981
982 /* P_dvsy_sync_wait */
983 switch (ch->u.ofdm.transmission_mode) {
984 case TRANSMISSION_MODE_8K:
985 value = 256;
986 break;
987 case TRANSMISSION_MODE_4K:
988 value = 128;
989 break;
990 case TRANSMISSION_MODE_2K:
991 default:
992 value = 64;
993 break;
994 }
995 switch (ch->u.ofdm.guard_interval) {
996 case GUARD_INTERVAL_1_16:
997 value *= 2;
998 break;
999 case GUARD_INTERVAL_1_8:
1000 value *= 4;
1001 break;
1002 case GUARD_INTERVAL_1_4:
1003 value *= 8;
1004 break;
1005 default:
1006 case GUARD_INTERVAL_1_32:
1007 value *= 1;
1008 break;
1009 }
1010 if (state->cfg.diversity_delay == 0)
1011 state->div_sync_wait = (value * 3) / 2 + 48;
1012 else
1013 state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay;
1014
1015 /* deactive the possibility of diversity reception if extended interleaver */
1016 state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K;
1017 dib7000p_set_diversity_in(&state->demod, state->div_state);
1018
1019 /* channel estimation fine configuration */
1020 switch (ch->u.ofdm.constellation) {
1021 case QAM_64:
1022 est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
1023 est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
1024 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1025 est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
1026 break;
1027 case QAM_16:
1028 est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
1029 est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
1030 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1031 est[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
1032 break;
1033 default:
1034 est[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
1035 est[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
1036 est[2] = 0x0333; /* P_adp_regul_ext 0.1 */
1037 est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
1038 break;
1039 }
1040 for (value = 0; value < 4; value++)
1041 dib7000p_write_word(state, 187 + value, est[value]);
1042}
1043
1044static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
1045{
1046 struct dib7000p_state *state = demod->demodulator_priv;
1047 struct dvb_frontend_parameters schan;
1048 u32 value, factor;
1049 u32 internal = dib7000p_get_internal_freq(state);
1050
1051 schan = *ch;
1052 schan.u.ofdm.constellation = QAM_64;
1053 schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
1054 schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
1055 schan.u.ofdm.code_rate_HP = FEC_2_3;
1056 schan.u.ofdm.code_rate_LP = FEC_3_4;
1057 schan.u.ofdm.hierarchy_information = 0;
1058
1059 dib7000p_set_channel(state, &schan, 7);
1060
1061 factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth);
1062 if (factor >= 5000)
1063 factor = 1;
1064 else
1065 factor = 6;
1066
1067 value = 30 * internal * factor;
1068 dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff));
1069 dib7000p_write_word(state, 7, (u16) (value & 0xffff));
1070 value = 100 * internal * factor;
1071 dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff));
1072 dib7000p_write_word(state, 9, (u16) (value & 0xffff));
1073 value = 500 * internal * factor;
1074 dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff));
1075 dib7000p_write_word(state, 11, (u16) (value & 0xffff));
1076
1077 value = dib7000p_read_word(state, 0);
1078 dib7000p_write_word(state, 0, (u16) ((1 << 9) | value));
1079 dib7000p_read_word(state, 1284);
1080 dib7000p_write_word(state, 0, (u16) value);
1081
1082 return 0;
1083}
1084
1085static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod)
1086{
1087 struct dib7000p_state *state = demod->demodulator_priv;
1088 u16 irq_pending = dib7000p_read_word(state, 1284);
1089
1090 if (irq_pending & 0x1)
1091 return 1;
1092
1093 if (irq_pending & 0x2)
1094 return 2;
1095
1096 return 0;
1097}
1098
1099static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw)
1100{
1101 static s16 notch[] = { 16143, 14402, 12238, 9713, 6902, 3888, 759, -2392 };
1102 static u8 sine[] = { 0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
1103 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
1104 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
1105 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
1106 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
1107 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
1108 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
1109 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
1110 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
1111 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
1112 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
1113 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
1114 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
1115 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
1116 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
1117 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1118 255, 255, 255, 255, 255, 255
1119 };
1120
1121 u32 xtal = state->cfg.bw->xtal_hz / 1000;
1122 int f_rel = DIV_ROUND_CLOSEST(rf_khz, xtal) * xtal - rf_khz;
1123 int k;
1124 int coef_re[8], coef_im[8];
1125 int bw_khz = bw;
1126 u32 pha;
1127
1128 dprintk("relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal);
1129
1130 if (f_rel < -bw_khz / 2 || f_rel > bw_khz / 2)
1131 return;
1132
1133 bw_khz /= 100;
1134
1135 dib7000p_write_word(state, 142, 0x0610);
1136
1137 for (k = 0; k < 8; k++) {
1138 pha = ((f_rel * (k + 1) * 112 * 80 / bw_khz) / 1000) & 0x3ff;
1139
1140 if (pha == 0) {
1141 coef_re[k] = 256;
1142 coef_im[k] = 0;
1143 } else if (pha < 256) {
1144 coef_re[k] = sine[256 - (pha & 0xff)];
1145 coef_im[k] = sine[pha & 0xff];
1146 } else if (pha == 256) {
1147 coef_re[k] = 0;
1148 coef_im[k] = 256;
1149 } else if (pha < 512) {
1150 coef_re[k] = -sine[pha & 0xff];
1151 coef_im[k] = sine[256 - (pha & 0xff)];
1152 } else if (pha == 512) {
1153 coef_re[k] = -256;
1154 coef_im[k] = 0;
1155 } else if (pha < 768) {
1156 coef_re[k] = -sine[256 - (pha & 0xff)];
1157 coef_im[k] = -sine[pha & 0xff];
1158 } else if (pha == 768) {
1159 coef_re[k] = 0;
1160 coef_im[k] = -256;
1161 } else {
1162 coef_re[k] = sine[pha & 0xff];
1163 coef_im[k] = -sine[256 - (pha & 0xff)];
1164 }
1165
1166 coef_re[k] *= notch[k];
1167 coef_re[k] += (1 << 14);
1168 if (coef_re[k] >= (1 << 24))
1169 coef_re[k] = (1 << 24) - 1;
1170 coef_re[k] /= (1 << 15);
1171
1172 coef_im[k] *= notch[k];
1173 coef_im[k] += (1 << 14);
1174 if (coef_im[k] >= (1 << 24))
1175 coef_im[k] = (1 << 24) - 1;
1176 coef_im[k] /= (1 << 15);
1177
1178 dprintk("PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]);
1179
1180 dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
1181 dib7000p_write_word(state, 144, coef_im[k] & 0x3ff);
1182 dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
1183 }
1184 dib7000p_write_word(state, 143, 0);
1185}
1186
1187static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
1188{
1189 struct dib7000p_state *state = demod->demodulator_priv;
1190 u16 tmp = 0;
1191
1192 if (ch != NULL)
1193 dib7000p_set_channel(state, ch, 0);
1194 else
1195 return -EINVAL;
1196
1197 // restart demod
1198 dib7000p_write_word(state, 770, 0x4000);
1199 dib7000p_write_word(state, 770, 0x0000);
1200 msleep(45);
1201
1202 /* 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 */
1203 tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
1204 if (state->sfn_workaround_active) {
1205 dprintk("SFN workaround is active");
1206 tmp |= (1 << 9);
1207 dib7000p_write_word(state, 166, 0x4000);
1208 } else {
1209 dib7000p_write_word(state, 166, 0x0000);
1210 }
1211 dib7000p_write_word(state, 29, tmp);
1212
1213 // never achieved a lock with that bandwidth so far - wait for osc-freq to update
1214 if (state->timf == 0)
1215 msleep(200);
1216
1217 /* offset loop parameters */
1218
1219 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
1220 tmp = (6 << 8) | 0x80;
1221 switch (ch->u.ofdm.transmission_mode) {
1222 case TRANSMISSION_MODE_2K:
1223 tmp |= (2 << 12);
1224 break;
1225 case TRANSMISSION_MODE_4K:
1226 tmp |= (3 << 12);
1227 break;
1228 default:
1229 case TRANSMISSION_MODE_8K:
1230 tmp |= (4 << 12);
1231 break;
1232 }
1233 dib7000p_write_word(state, 26, tmp); /* timf_a(6xxx) */
1234
1235 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1236 tmp = (0 << 4);
1237 switch (ch->u.ofdm.transmission_mode) {
1238 case TRANSMISSION_MODE_2K:
1239 tmp |= 0x6;
1240 break;
1241 case TRANSMISSION_MODE_4K:
1242 tmp |= 0x7;
1243 break;
1244 default:
1245 case TRANSMISSION_MODE_8K:
1246 tmp |= 0x8;
1247 break;
1248 }
1249 dib7000p_write_word(state, 32, tmp);
1250
1251 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1252 tmp = (0 << 4);
1253 switch (ch->u.ofdm.transmission_mode) {
1254 case TRANSMISSION_MODE_2K:
1255 tmp |= 0x6;
1256 break;
1257 case TRANSMISSION_MODE_4K:
1258 tmp |= 0x7;
1259 break;
1260 default:
1261 case TRANSMISSION_MODE_8K:
1262 tmp |= 0x8;
1263 break;
1264 }
1265 dib7000p_write_word(state, 33, tmp);
1266
1267 tmp = dib7000p_read_word(state, 509);
1268 if (!((tmp >> 6) & 0x1)) {
1269 /* restart the fec */
1270 tmp = dib7000p_read_word(state, 771);
1271 dib7000p_write_word(state, 771, tmp | (1 << 1));
1272 dib7000p_write_word(state, 771, tmp);
1273 msleep(40);
1274 tmp = dib7000p_read_word(state, 509);
1275 }
1276 // we achieved a lock - it's time to update the osc freq
1277 if ((tmp >> 6) & 0x1) {
1278 dib7000p_update_timf(state);
1279 /* P_timf_alpha += 2 */
1280 tmp = dib7000p_read_word(state, 26);
1281 dib7000p_write_word(state, 26, (tmp & ~(0xf << 12)) | ((((tmp >> 12) & 0xf) + 5) << 12));
1282 }
1283
1284 if (state->cfg.spur_protect)
1285 dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1286
1287 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1288 return 0;
1289}
1290
1291static int dib7000p_wakeup(struct dvb_frontend *demod)
1292{
1293 struct dib7000p_state *state = demod->demodulator_priv;
1294 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
1295 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
1296 if (state->version == SOC7090)
1297 dib7000p_sad_calib(state);
1298 return 0;
1299}
1300
1301static int dib7000p_sleep(struct dvb_frontend *demod)
1302{
1303 struct dib7000p_state *state = demod->demodulator_priv;
1304 if (state->version == SOC7090)
1305 return dib7090_set_output_mode(demod, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1306 return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1307}
1308
1309static int dib7000p_identify(struct dib7000p_state *st)
1310{
1311 u16 value;
1312 dprintk("checking demod on I2C address: %d (%x)", st->i2c_addr, st->i2c_addr);
1313
1314 if ((value = dib7000p_read_word(st, 768)) != 0x01b3) {
1315 dprintk("wrong Vendor ID (read=0x%x)", value);
1316 return -EREMOTEIO;
1317 }
1318
1319 if ((value = dib7000p_read_word(st, 769)) != 0x4000) {
1320 dprintk("wrong Device ID (%x)", value);
1321 return -EREMOTEIO;
1322 }
1323
1324 return 0;
1325}
1326
1327static int dib7000p_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1328{
1329 struct dib7000p_state *state = fe->demodulator_priv;
1330 u16 tps = dib7000p_read_word(state, 463);
1331
1332 fep->inversion = INVERSION_AUTO;
1333
1334 fep->u.ofdm.bandwidth = BANDWIDTH_TO_INDEX(state->current_bandwidth);
1335
1336 switch ((tps >> 8) & 0x3) {
1337 case 0:
1338 fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
1339 break;
1340 case 1:
1341 fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
1342 break;
1343 /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */
1344 }
1345
1346 switch (tps & 0x3) {
1347 case 0:
1348 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
1349 break;
1350 case 1:
1351 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
1352 break;
1353 case 2:
1354 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
1355 break;
1356 case 3:
1357 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
1358 break;
1359 }
1360
1361 switch ((tps >> 14) & 0x3) {
1362 case 0:
1363 fep->u.ofdm.constellation = QPSK;
1364 break;
1365 case 1:
1366 fep->u.ofdm.constellation = QAM_16;
1367 break;
1368 case 2:
1369 default:
1370 fep->u.ofdm.constellation = QAM_64;
1371 break;
1372 }
1373
1374 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1375 /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1376
1377 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
1378 switch ((tps >> 5) & 0x7) {
1379 case 1:
1380 fep->u.ofdm.code_rate_HP = FEC_1_2;
1381 break;
1382 case 2:
1383 fep->u.ofdm.code_rate_HP = FEC_2_3;
1384 break;
1385 case 3:
1386 fep->u.ofdm.code_rate_HP = FEC_3_4;
1387 break;
1388 case 5:
1389 fep->u.ofdm.code_rate_HP = FEC_5_6;
1390 break;
1391 case 7:
1392 default:
1393 fep->u.ofdm.code_rate_HP = FEC_7_8;
1394 break;
1395
1396 }
1397
1398 switch ((tps >> 2) & 0x7) {
1399 case 1:
1400 fep->u.ofdm.code_rate_LP = FEC_1_2;
1401 break;
1402 case 2:
1403 fep->u.ofdm.code_rate_LP = FEC_2_3;
1404 break;
1405 case 3:
1406 fep->u.ofdm.code_rate_LP = FEC_3_4;
1407 break;
1408 case 5:
1409 fep->u.ofdm.code_rate_LP = FEC_5_6;
1410 break;
1411 case 7:
1412 default:
1413 fep->u.ofdm.code_rate_LP = FEC_7_8;
1414 break;
1415 }
1416
1417 /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */
1418
1419 return 0;
1420}
1421
1422static int dib7000p_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1423{
1424 struct dib7000p_state *state = fe->demodulator_priv;
1425 int time, ret;
1426
1427 if (state->version == SOC7090) {
1428 dib7090_set_diversity_in(fe, 0);
1429 dib7090_set_output_mode(fe, OUTMODE_HIGH_Z);
1430 } else
1431 dib7000p_set_output_mode(state, OUTMODE_HIGH_Z);
1432
1433 /* maybe the parameter has been changed */
1434 state->sfn_workaround_active = buggy_sfn_workaround;
1435
1436 if (fe->ops.tuner_ops.set_params)
1437 fe->ops.tuner_ops.set_params(fe, fep);
1438
1439 /* start up the AGC */
1440 state->agc_state = 0;
1441 do {
1442 time = dib7000p_agc_startup(fe, fep);
1443 if (time != -1)
1444 msleep(time);
1445 } while (time != -1);
1446
1447 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
1448 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || fep->u.ofdm.constellation == QAM_AUTO || fep->u.ofdm.code_rate_HP == FEC_AUTO) {
1449 int i = 800, found;
1450
1451 dib7000p_autosearch_start(fe, fep);
1452 do {
1453 msleep(1);
1454 found = dib7000p_autosearch_is_irq(fe);
1455 } while (found == 0 && i--);
1456
1457 dprintk("autosearch returns: %d", found);
1458 if (found == 0 || found == 1)
1459 return 0;
1460
1461 dib7000p_get_frontend(fe, fep);
1462 }
1463
1464 ret = dib7000p_tune(fe, fep);
1465
1466 /* make this a config parameter */
1467 if (state->version == SOC7090)
1468 dib7090_set_output_mode(fe, state->cfg.output_mode);
1469 else
1470 dib7000p_set_output_mode(state, state->cfg.output_mode);
1471
1472 return ret;
1473}
1474
1475static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t * stat)
1476{
1477 struct dib7000p_state *state = fe->demodulator_priv;
1478 u16 lock = dib7000p_read_word(state, 509);
1479
1480 *stat = 0;
1481
1482 if (lock & 0x8000)
1483 *stat |= FE_HAS_SIGNAL;
1484 if (lock & 0x3000)
1485 *stat |= FE_HAS_CARRIER;
1486 if (lock & 0x0100)
1487 *stat |= FE_HAS_VITERBI;
1488 if (lock & 0x0010)
1489 *stat |= FE_HAS_SYNC;
1490 if ((lock & 0x0038) == 0x38)
1491 *stat |= FE_HAS_LOCK;
1492
1493 return 0;
1494}
1495
1496static int dib7000p_read_ber(struct dvb_frontend *fe, u32 * ber)
1497{
1498 struct dib7000p_state *state = fe->demodulator_priv;
1499 *ber = (dib7000p_read_word(state, 500) << 16) | dib7000p_read_word(state, 501);
1500 return 0;
1501}
1502
1503static int dib7000p_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
1504{
1505 struct dib7000p_state *state = fe->demodulator_priv;
1506 *unc = dib7000p_read_word(state, 506);
1507 return 0;
1508}
1509
1510static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
1511{
1512 struct dib7000p_state *state = fe->demodulator_priv;
1513 u16 val = dib7000p_read_word(state, 394);
1514 *strength = 65535 - val;
1515 return 0;
1516}
1517
1518static int dib7000p_read_snr(struct dvb_frontend *fe, u16 * snr)
1519{
1520 struct dib7000p_state *state = fe->demodulator_priv;
1521 u16 val;
1522 s32 signal_mant, signal_exp, noise_mant, noise_exp;
1523 u32 result = 0;
1524
1525 val = dib7000p_read_word(state, 479);
1526 noise_mant = (val >> 4) & 0xff;
1527 noise_exp = ((val & 0xf) << 2);
1528 val = dib7000p_read_word(state, 480);
1529 noise_exp += ((val >> 14) & 0x3);
1530 if ((noise_exp & 0x20) != 0)
1531 noise_exp -= 0x40;
1532
1533 signal_mant = (val >> 6) & 0xFF;
1534 signal_exp = (val & 0x3F);
1535 if ((signal_exp & 0x20) != 0)
1536 signal_exp -= 0x40;
1537
1538 if (signal_mant != 0)
1539 result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
1540 else
1541 result = intlog10(2) * 10 * signal_exp - 100;
1542
1543 if (noise_mant != 0)
1544 result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
1545 else
1546 result -= intlog10(2) * 10 * noise_exp - 100;
1547
1548 *snr = result / ((1 << 24) / 10);
1549 return 0;
1550}
1551
1552static int dib7000p_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
1553{
1554 tune->min_delay_ms = 1000;
1555 return 0;
1556}
1557
1558static void dib7000p_release(struct dvb_frontend *demod)
1559{
1560 struct dib7000p_state *st = demod->demodulator_priv;
1561 dibx000_exit_i2c_master(&st->i2c_master);
1562 i2c_del_adapter(&st->dib7090_tuner_adap);
1563 kfree(st);
1564}
1565
1566int dib7000pc_detection(struct i2c_adapter *i2c_adap)
1567{
1568 u8 *tx, *rx;
1569 struct i2c_msg msg[2] = {
1570 {.addr = 18 >> 1, .flags = 0, .len = 2},
1571 {.addr = 18 >> 1, .flags = I2C_M_RD, .len = 2},
1572 };
1573 int ret = 0;
1574
1575 tx = kzalloc(2*sizeof(u8), GFP_KERNEL);
1576 if (!tx)
1577 return -ENOMEM;
1578 rx = kzalloc(2*sizeof(u8), GFP_KERNEL);
1579 if (!rx) {
1580 goto rx_memory_error;
1581 ret = -ENOMEM;
1582 }
1583
1584 msg[0].buf = tx;
1585 msg[1].buf = rx;
1586
1587 tx[0] = 0x03;
1588 tx[1] = 0x00;
1589
1590 if (i2c_transfer(i2c_adap, msg, 2) == 2)
1591 if (rx[0] == 0x01 && rx[1] == 0xb3) {
1592 dprintk("-D- DiB7000PC detected");
1593 return 1;
1594 }
1595
1596 msg[0].addr = msg[1].addr = 0x40;
1597
1598 if (i2c_transfer(i2c_adap, msg, 2) == 2)
1599 if (rx[0] == 0x01 && rx[1] == 0xb3) {
1600 dprintk("-D- DiB7000PC detected");
1601 return 1;
1602 }
1603
1604 dprintk("-D- DiB7000PC not detected");
1605
1606 kfree(rx);
1607rx_memory_error:
1608 kfree(tx);
1609 return ret;
1610}
1611EXPORT_SYMBOL(dib7000pc_detection);
1612
1613struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
1614{
1615 struct dib7000p_state *st = demod->demodulator_priv;
1616 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1617}
1618EXPORT_SYMBOL(dib7000p_get_i2c_master);
1619
1620int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1621{
1622 struct dib7000p_state *state = fe->demodulator_priv;
1623 u16 val = dib7000p_read_word(state, 235) & 0xffef;
1624 val |= (onoff & 0x1) << 4;
1625 dprintk("PID filter enabled %d", onoff);
1626 return dib7000p_write_word(state, 235, val);
1627}
1628EXPORT_SYMBOL(dib7000p_pid_filter_ctrl);
1629
1630int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1631{
1632 struct dib7000p_state *state = fe->demodulator_priv;
1633 dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
1634 return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0);
1635}
1636EXPORT_SYMBOL(dib7000p_pid_filter);
1637
1638int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
1639{
1640 struct dib7000p_state *dpst;
1641 int k = 0;
1642 u8 new_addr = 0;
1643
1644 dpst = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
1645 if (!dpst)
1646 return -ENOMEM;
1647
1648 dpst->i2c_adap = i2c;
1649
1650 for (k = no_of_demods - 1; k >= 0; k--) {
1651 dpst->cfg = cfg[k];
1652
1653 /* designated i2c address */
1654 if (cfg[k].default_i2c_addr != 0)
1655 new_addr = cfg[k].default_i2c_addr + (k << 1);
1656 else
1657 new_addr = (0x40 + k) << 1;
1658 dpst->i2c_addr = new_addr;
1659 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */
1660 if (dib7000p_identify(dpst) != 0) {
1661 dpst->i2c_addr = default_addr;
1662 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */
1663 if (dib7000p_identify(dpst) != 0) {
1664 dprintk("DiB7000P #%d: not identified\n", k);
1665 kfree(dpst);
1666 return -EIO;
1667 }
1668 }
1669
1670 /* start diversity to pull_down div_str - just for i2c-enumeration */
1671 dib7000p_set_output_mode(dpst, OUTMODE_DIVERSITY);
1672
1673 /* set new i2c address and force divstart */
1674 dib7000p_write_word(dpst, 1285, (new_addr << 2) | 0x2);
1675
1676 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
1677 }
1678
1679 for (k = 0; k < no_of_demods; k++) {
1680 dpst->cfg = cfg[k];
1681 if (cfg[k].default_i2c_addr != 0)
1682 dpst->i2c_addr = (cfg[k].default_i2c_addr + k) << 1;
1683 else
1684 dpst->i2c_addr = (0x40 + k) << 1;
1685
1686 // unforce divstr
1687 dib7000p_write_word(dpst, 1285, dpst->i2c_addr << 2);
1688
1689 /* deactivate div - it was just for i2c-enumeration */
1690 dib7000p_set_output_mode(dpst, OUTMODE_HIGH_Z);
1691 }
1692
1693 kfree(dpst);
1694 return 0;
1695}
1696EXPORT_SYMBOL(dib7000p_i2c_enumeration);
1697
1698static const s32 lut_1000ln_mant[] = {
1699 6908, 6956, 7003, 7047, 7090, 7131, 7170, 7208, 7244, 7279, 7313, 7346, 7377, 7408, 7438, 7467, 7495, 7523, 7549, 7575, 7600
1700};
1701
1702static s32 dib7000p_get_adc_power(struct dvb_frontend *fe)
1703{
1704 struct dib7000p_state *state = fe->demodulator_priv;
1705 u32 tmp_val = 0, exp = 0, mant = 0;
1706 s32 pow_i;
1707 u16 buf[2];
1708 u8 ix = 0;
1709
1710 buf[0] = dib7000p_read_word(state, 0x184);
1711 buf[1] = dib7000p_read_word(state, 0x185);
1712 pow_i = (buf[0] << 16) | buf[1];
1713 dprintk("raw pow_i = %d", pow_i);
1714
1715 tmp_val = pow_i;
1716 while (tmp_val >>= 1)
1717 exp++;
1718
1719 mant = (pow_i * 1000 / (1 << exp));
1720 dprintk(" mant = %d exp = %d", mant / 1000, exp);
1721
1722 ix = (u8) ((mant - 1000) / 100); /* index of the LUT */
1723 dprintk(" ix = %d", ix);
1724
1725 pow_i = (lut_1000ln_mant[ix] + 693 * (exp - 20) - 6908);
1726 pow_i = (pow_i << 8) / 1000;
1727 dprintk(" pow_i = %d", pow_i);
1728
1729 return pow_i;
1730}
1731
1732static int map_addr_to_serpar_number(struct i2c_msg *msg)
1733{
1734 if ((msg->buf[0] <= 15))
1735 msg->buf[0] -= 1;
1736 else if (msg->buf[0] == 17)
1737 msg->buf[0] = 15;
1738 else if (msg->buf[0] == 16)
1739 msg->buf[0] = 17;
1740 else if (msg->buf[0] == 19)
1741 msg->buf[0] = 16;
1742 else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
1743 msg->buf[0] -= 3;
1744 else if (msg->buf[0] == 28)
1745 msg->buf[0] = 23;
1746 else
1747 return -EINVAL;
1748 return 0;
1749}
1750
1751static int w7090p_tuner_write_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1752{
1753 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1754 u8 n_overflow = 1;
1755 u16 i = 1000;
1756 u16 serpar_num = msg[0].buf[0];
1757
1758 while (n_overflow == 1 && i) {
1759 n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
1760 i--;
1761 if (i == 0)
1762 dprintk("Tuner ITF: write busy (overflow)");
1763 }
1764 dib7000p_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
1765 dib7000p_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
1766
1767 return num;
1768}
1769
1770static int w7090p_tuner_read_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1771{
1772 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1773 u8 n_overflow = 1, n_empty = 1;
1774 u16 i = 1000;
1775 u16 serpar_num = msg[0].buf[0];
1776 u16 read_word;
1777
1778 while (n_overflow == 1 && i) {
1779 n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
1780 i--;
1781 if (i == 0)
1782 dprintk("TunerITF: read busy (overflow)");
1783 }
1784 dib7000p_write_word(state, 1985, (0 << 6) | (serpar_num & 0x3f));
1785
1786 i = 1000;
1787 while (n_empty == 1 && i) {
1788 n_empty = dib7000p_read_word(state, 1984) & 0x1;
1789 i--;
1790 if (i == 0)
1791 dprintk("TunerITF: read busy (empty)");
1792 }
1793 read_word = dib7000p_read_word(state, 1987);
1794 msg[1].buf[0] = (read_word >> 8) & 0xff;
1795 msg[1].buf[1] = (read_word) & 0xff;
1796
1797 return num;
1798}
1799
1800static int w7090p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1801{
1802 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... */
1803 if (num == 1) { /* write */
1804 return w7090p_tuner_write_serpar(i2c_adap, msg, 1);
1805 } else { /* read */
1806 return w7090p_tuner_read_serpar(i2c_adap, msg, 2);
1807 }
1808 }
1809 return num;
1810}
1811
1812int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num, u16 apb_address)
1813{
1814 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1815 u16 word;
1816
1817 if (num == 1) { /* write */
1818 dib7000p_write_word(state, apb_address, ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
1819 } else {
1820 word = dib7000p_read_word(state, apb_address);
1821 msg[1].buf[0] = (word >> 8) & 0xff;
1822 msg[1].buf[1] = (word) & 0xff;
1823 }
1824
1825 return num;
1826}
1827
1828static int dib7090_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1829{
1830 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1831
1832 u16 apb_address = 0, word;
1833 int i = 0;
1834 switch (msg[0].buf[0]) {
1835 case 0x12:
1836 apb_address = 1920;
1837 break;
1838 case 0x14:
1839 apb_address = 1921;
1840 break;
1841 case 0x24:
1842 apb_address = 1922;
1843 break;
1844 case 0x1a:
1845 apb_address = 1923;
1846 break;
1847 case 0x22:
1848 apb_address = 1924;
1849 break;
1850 case 0x33:
1851 apb_address = 1926;
1852 break;
1853 case 0x34:
1854 apb_address = 1927;
1855 break;
1856 case 0x35:
1857 apb_address = 1928;
1858 break;
1859 case 0x36:
1860 apb_address = 1929;
1861 break;
1862 case 0x37:
1863 apb_address = 1930;
1864 break;
1865 case 0x38:
1866 apb_address = 1931;
1867 break;
1868 case 0x39:
1869 apb_address = 1932;
1870 break;
1871 case 0x2a:
1872 apb_address = 1935;
1873 break;
1874 case 0x2b:
1875 apb_address = 1936;
1876 break;
1877 case 0x2c:
1878 apb_address = 1937;
1879 break;
1880 case 0x2d:
1881 apb_address = 1938;
1882 break;
1883 case 0x2e:
1884 apb_address = 1939;
1885 break;
1886 case 0x2f:
1887 apb_address = 1940;
1888 break;
1889 case 0x30:
1890 apb_address = 1941;
1891 break;
1892 case 0x31:
1893 apb_address = 1942;
1894 break;
1895 case 0x32:
1896 apb_address = 1943;
1897 break;
1898 case 0x3e:
1899 apb_address = 1944;
1900 break;
1901 case 0x3f:
1902 apb_address = 1945;
1903 break;
1904 case 0x40:
1905 apb_address = 1948;
1906 break;
1907 case 0x25:
1908 apb_address = 914;
1909 break;
1910 case 0x26:
1911 apb_address = 915;
1912 break;
1913 case 0x27:
1914 apb_address = 916;
1915 break;
1916 case 0x28:
1917 apb_address = 917;
1918 break;
1919 case 0x1d:
1920 i = ((dib7000p_read_word(state, 72) >> 12) & 0x3);
1921 word = dib7000p_read_word(state, 384 + i);
1922 msg[1].buf[0] = (word >> 8) & 0xff;
1923 msg[1].buf[1] = (word) & 0xff;
1924 return num;
1925 case 0x1f:
1926 if (num == 1) { /* write */
1927 word = (u16) ((msg[0].buf[1] << 8) | msg[0].buf[2]);
1928 word &= 0x3;
1929 word = (dib7000p_read_word(state, 72) & ~(3 << 12)) | (word << 12);
1930 dib7000p_write_word(state, 72, word); /* Set the proper input */
1931 return num;
1932 }
1933 }
1934
1935 if (apb_address != 0) /* R/W acces via APB */
1936 return dib7090p_rw_on_apb(i2c_adap, msg, num, apb_address);
1937 else /* R/W access via SERPAR */
1938 return w7090p_tuner_rw_serpar(i2c_adap, msg, num);
1939
1940 return 0;
1941}
1942
1943static u32 dib7000p_i2c_func(struct i2c_adapter *adapter)
1944{
1945 return I2C_FUNC_I2C;
1946}
1947
1948static struct i2c_algorithm dib7090_tuner_xfer_algo = {
1949 .master_xfer = dib7090_tuner_xfer,
1950 .functionality = dib7000p_i2c_func,
1951};
1952
1953struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
1954{
1955 struct dib7000p_state *st = fe->demodulator_priv;
1956 return &st->dib7090_tuner_adap;
1957}
1958EXPORT_SYMBOL(dib7090_get_i2c_tuner);
1959
1960static int dib7090_host_bus_drive(struct dib7000p_state *state, u8 drive)
1961{
1962 u16 reg;
1963
1964 /* drive host bus 2, 3, 4 */
1965 reg = dib7000p_read_word(state, 1798) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1966 reg |= (drive << 12) | (drive << 6) | drive;
1967 dib7000p_write_word(state, 1798, reg);
1968
1969 /* drive host bus 5,6 */
1970 reg = dib7000p_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
1971 reg |= (drive << 8) | (drive << 2);
1972 dib7000p_write_word(state, 1799, reg);
1973
1974 /* drive host bus 7, 8, 9 */
1975 reg = dib7000p_read_word(state, 1800) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1976 reg |= (drive << 12) | (drive << 6) | drive;
1977 dib7000p_write_word(state, 1800, reg);
1978
1979 /* drive host bus 10, 11 */
1980 reg = dib7000p_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
1981 reg |= (drive << 8) | (drive << 2);
1982 dib7000p_write_word(state, 1801, reg);
1983
1984 /* drive host bus 12, 13, 14 */
1985 reg = dib7000p_read_word(state, 1802) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1986 reg |= (drive << 12) | (drive << 6) | drive;
1987 dib7000p_write_word(state, 1802, reg);
1988
1989 return 0;
1990}
1991
1992static u32 dib7090_calcSyncFreq(u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 syncSize)
1993{
1994 u32 quantif = 3;
1995 u32 nom = (insertExtSynchro * P_Kin + syncSize);
1996 u32 denom = P_Kout;
1997 u32 syncFreq = ((nom << quantif) / denom);
1998
1999 if ((syncFreq & ((1 << quantif) - 1)) != 0)
2000 syncFreq = (syncFreq >> quantif) + 1;
2001 else
2002 syncFreq = (syncFreq >> quantif);
2003
2004 if (syncFreq != 0)
2005 syncFreq = syncFreq - 1;
2006
2007 return syncFreq;
2008}
2009
2010static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize)
2011{
2012 u8 index_buf;
2013 u16 rx_copy_buf[22];
2014
2015 dprintk("Configure DibStream Tx");
2016 for (index_buf = 0; index_buf < 22; index_buf++)
2017 rx_copy_buf[index_buf] = dib7000p_read_word(state, 1536+index_buf);
2018
2019 dib7000p_write_word(state, 1615, 1);
2020 dib7000p_write_word(state, 1603, P_Kin);
2021 dib7000p_write_word(state, 1605, P_Kout);
2022 dib7000p_write_word(state, 1606, insertExtSynchro);
2023 dib7000p_write_word(state, 1608, synchroMode);
2024 dib7000p_write_word(state, 1609, (syncWord >> 16) & 0xffff);
2025 dib7000p_write_word(state, 1610, syncWord & 0xffff);
2026 dib7000p_write_word(state, 1612, syncSize);
2027 dib7000p_write_word(state, 1615, 0);
2028
2029 for (index_buf = 0; index_buf < 22; index_buf++)
2030 dib7000p_write_word(state, 1536+index_buf, rx_copy_buf[index_buf]);
2031
2032 return 0;
2033}
2034
2035static int dib7090_cfg_DibRx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 synchroMode, u32 insertExtSynchro, u32 syncWord, u32 syncSize,
2036 u32 dataOutRate)
2037{
2038 u32 syncFreq;
2039
2040 dprintk("Configure DibStream Rx");
2041 if ((P_Kin != 0) && (P_Kout != 0)) {
2042 syncFreq = dib7090_calcSyncFreq(P_Kin, P_Kout, insertExtSynchro, syncSize);
2043 dib7000p_write_word(state, 1542, syncFreq);
2044 }
2045 dib7000p_write_word(state, 1554, 1);
2046 dib7000p_write_word(state, 1536, P_Kin);
2047 dib7000p_write_word(state, 1537, P_Kout);
2048 dib7000p_write_word(state, 1539, synchroMode);
2049 dib7000p_write_word(state, 1540, (syncWord >> 16) & 0xffff);
2050 dib7000p_write_word(state, 1541, syncWord & 0xffff);
2051 dib7000p_write_word(state, 1543, syncSize);
2052 dib7000p_write_word(state, 1544, dataOutRate);
2053 dib7000p_write_word(state, 1554, 0);
2054
2055 return 0;
2056}
2057
2058static int dib7090_enDivOnHostBus(struct dib7000p_state *state)
2059{
2060 u16 reg;
2061
2062 dprintk("Enable Diversity on host bus");
2063 reg = (1 << 8) | (1 << 5);
2064 dib7000p_write_word(state, 1288, reg);
2065
2066 return dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
2067}
2068
2069static int dib7090_enAdcOnHostBus(struct dib7000p_state *state)
2070{
2071 u16 reg;
2072
2073 dprintk("Enable ADC on host bus");
2074 reg = (1 << 7) | (1 << 5);
2075 dib7000p_write_word(state, 1288, reg);
2076
2077 return dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
2078}
2079
2080static int dib7090_enMpegOnHostBus(struct dib7000p_state *state)
2081{
2082 u16 reg;
2083
2084 dprintk("Enable Mpeg on host bus");
2085 reg = (1 << 9) | (1 << 5);
2086 dib7000p_write_word(state, 1288, reg);
2087
2088 return dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
2089}
2090
2091static int dib7090_enMpegInput(struct dib7000p_state *state)
2092{
2093 dprintk("Enable Mpeg input");
2094 return dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */
2095}
2096
2097static int dib7090_enMpegMux(struct dib7000p_state *state, u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
2098{
2099 u16 reg = (1 << 7) | ((pulseWidth & 0x1f) << 2) | ((enSerialMode & 0x1) << 1) | (enSerialClkDiv2 & 0x1);
2100
2101 dprintk("Enable Mpeg mux");
2102 dib7000p_write_word(state, 1287, reg);
2103
2104 reg &= ~(1 << 7);
2105 dib7000p_write_word(state, 1287, reg);
2106
2107 reg = (1 << 4);
2108 dib7000p_write_word(state, 1288, reg);
2109
2110 return 0;
2111}
2112
2113static int dib7090_disableMpegMux(struct dib7000p_state *state)
2114{
2115 u16 reg;
2116
2117 dprintk("Disable Mpeg mux");
2118 dib7000p_write_word(state, 1288, 0);
2119
2120 reg = dib7000p_read_word(state, 1287);
2121 reg &= ~(1 << 7);
2122 dib7000p_write_word(state, 1287, reg);
2123
2124 return 0;
2125}
2126
2127static int dib7090_set_input_mode(struct dvb_frontend *fe, int mode)
2128{
2129 struct dib7000p_state *state = fe->demodulator_priv;
2130
2131 switch (mode) {
2132 case INPUT_MODE_DIVERSITY:
2133 dprintk("Enable diversity INPUT");
2134 dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
2135 break;
2136 case INPUT_MODE_MPEG:
2137 dprintk("Enable Mpeg INPUT");
2138 dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */
2139 break;
2140 case INPUT_MODE_OFF:
2141 default:
2142 dprintk("Disable INPUT");
2143 dib7090_cfg_DibRx(state, 0, 0, 0, 0, 0, 0, 0);
2144 break;
2145 }
2146 return 0;
2147}
2148
2149static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff)
2150{
2151 switch (onoff) {
2152 case 0: /* only use the internal way - not the diversity input */
2153 dib7090_set_input_mode(fe, INPUT_MODE_MPEG);
2154 break;
2155 case 1: /* both ways */
2156 case 2: /* only the diversity input */
2157 dib7090_set_input_mode(fe, INPUT_MODE_DIVERSITY);
2158 break;
2159 }
2160
2161 return 0;
2162}
2163
2164static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode)
2165{
2166 struct dib7000p_state *state = fe->demodulator_priv;
2167
2168 u16 outreg, smo_mode, fifo_threshold;
2169 u8 prefer_mpeg_mux_use = 1;
2170 int ret = 0;
2171
2172 dib7090_host_bus_drive(state, 1);
2173
2174 fifo_threshold = 1792;
2175 smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
2176 outreg = dib7000p_read_word(state, 1286) & ~((1 << 10) | (0x7 << 6) | (1 << 1));
2177
2178 switch (mode) {
2179 case OUTMODE_HIGH_Z:
2180 outreg = 0;
2181 break;
2182
2183 case OUTMODE_MPEG2_SERIAL:
2184 if (prefer_mpeg_mux_use) {
2185 dprintk("Sip 7090P setting output mode TS_SERIAL using Mpeg Mux");
2186 dib7090_enMpegOnHostBus(state);
2187 dib7090_enMpegInput(state);
2188 if (state->cfg.enMpegOutput == 1)
2189 dib7090_enMpegMux(state, 3, 1, 1);
2190
2191 } else { /* Use Smooth block */
2192 dprintk("Sip 7090P setting output mode TS_SERIAL using Smooth bloc");
2193 dib7090_disableMpegMux(state);
2194 dib7000p_write_word(state, 1288, (1 << 6));
2195 outreg |= (2 << 6) | (0 << 1);
2196 }
2197 break;
2198
2199 case OUTMODE_MPEG2_PAR_GATED_CLK:
2200 if (prefer_mpeg_mux_use) {
2201 dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Mpeg Mux");
2202 dib7090_enMpegOnHostBus(state);
2203 dib7090_enMpegInput(state);
2204 if (state->cfg.enMpegOutput == 1)
2205 dib7090_enMpegMux(state, 2, 0, 0);
2206 } else { /* Use Smooth block */
2207 dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Smooth block");
2208 dib7090_disableMpegMux(state);
2209 dib7000p_write_word(state, 1288, (1 << 6));
2210 outreg |= (0 << 6);
2211 }
2212 break;
2213
2214 case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */
2215 dprintk("Sip 7090P setting output mode TS_PARALLEL_CONT using Smooth block");
2216 dib7090_disableMpegMux(state);
2217 dib7000p_write_word(state, 1288, (1 << 6));
2218 outreg |= (1 << 6);
2219 break;
2220
2221 case OUTMODE_MPEG2_FIFO: /* Using Smooth block because not supported by new Mpeg Mux bloc */
2222 dprintk("Sip 7090P setting output mode TS_FIFO using Smooth block");
2223 dib7090_disableMpegMux(state);
2224 dib7000p_write_word(state, 1288, (1 << 6));
2225 outreg |= (5 << 6);
2226 smo_mode |= (3 << 1);
2227 fifo_threshold = 512;
2228 break;
2229
2230 case OUTMODE_DIVERSITY:
2231 dprintk("Sip 7090P setting output mode MODE_DIVERSITY");
2232 dib7090_disableMpegMux(state);
2233 dib7090_enDivOnHostBus(state);
2234 break;
2235
2236 case OUTMODE_ANALOG_ADC:
2237 dprintk("Sip 7090P setting output mode MODE_ANALOG_ADC");
2238 dib7090_enAdcOnHostBus(state);
2239 break;
2240 }
2241
2242 if (state->cfg.output_mpeg2_in_188_bytes)
2243 smo_mode |= (1 << 5);
2244
2245 ret |= dib7000p_write_word(state, 235, smo_mode);
2246 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
2247 ret |= dib7000p_write_word(state, 1286, outreg | (1 << 10)); /* allways set Dout active = 1 !!! */
2248
2249 return ret;
2250}
2251
2252int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
2253{
2254 struct dib7000p_state *state = fe->demodulator_priv;
2255 u16 en_cur_state;
2256
2257 dprintk("sleep dib7090: %d", onoff);
2258
2259 en_cur_state = dib7000p_read_word(state, 1922);
2260
2261 if (en_cur_state > 0xff)
2262 state->tuner_enable = en_cur_state;
2263
2264 if (onoff)
2265 en_cur_state &= 0x00ff;
2266 else {
2267 if (state->tuner_enable != 0)
2268 en_cur_state = state->tuner_enable;
2269 }
2270
2271 dib7000p_write_word(state, 1922, en_cur_state);
2272
2273 return 0;
2274}
2275EXPORT_SYMBOL(dib7090_tuner_sleep);
2276
2277int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart)
2278{
2279 dprintk("AGC restart callback: %d", restart);
2280 return 0;
2281}
2282EXPORT_SYMBOL(dib7090_agc_restart);
2283
2284int dib7090_get_adc_power(struct dvb_frontend *fe)
2285{
2286 return dib7000p_get_adc_power(fe);
2287}
2288EXPORT_SYMBOL(dib7090_get_adc_power);
2289
2290int dib7090_slave_reset(struct dvb_frontend *fe)
2291{
2292 struct dib7000p_state *state = fe->demodulator_priv;
2293 u16 reg;
2294
2295 reg = dib7000p_read_word(state, 1794);
2296 dib7000p_write_word(state, 1794, reg | (4 << 12));
2297
2298 dib7000p_write_word(state, 1032, 0xffff);
2299 return 0;
2300}
2301EXPORT_SYMBOL(dib7090_slave_reset);
2302
2303static struct dvb_frontend_ops dib7000p_ops;
2304struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
2305{
2306 struct dvb_frontend *demod;
2307 struct dib7000p_state *st;
2308 st = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
2309 if (st == NULL)
2310 return NULL;
2311
2312 memcpy(&st->cfg, cfg, sizeof(struct dib7000p_config));
2313 st->i2c_adap = i2c_adap;
2314 st->i2c_addr = i2c_addr;
2315 st->gpio_val = cfg->gpio_val;
2316 st->gpio_dir = cfg->gpio_dir;
2317
2318 /* Ensure the output mode remains at the previous default if it's
2319 * not specifically set by the caller.
2320 */
2321 if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2322 st->cfg.output_mode = OUTMODE_MPEG2_FIFO;
2323
2324 demod = &st->demod;
2325 demod->demodulator_priv = st;
2326 memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));
2327
2328 dib7000p_write_word(st, 1287, 0x0003); /* sram lead in, rdy */
2329
2330 if (dib7000p_identify(st) != 0)
2331 goto error;
2332
2333 st->version = dib7000p_read_word(st, 897);
2334
2335 /* FIXME: make sure the dev.parent field is initialized, or else
2336 request_firmware() will hit an OOPS (this should be moved somewhere
2337 more common) */
2338
2339 dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr);
2340
2341 /* init 7090 tuner adapter */
2342 strncpy(st->dib7090_tuner_adap.name, "DiB7090 tuner interface", sizeof(st->dib7090_tuner_adap.name));
2343 st->dib7090_tuner_adap.algo = &dib7090_tuner_xfer_algo;
2344 st->dib7090_tuner_adap.algo_data = NULL;
2345 st->dib7090_tuner_adap.dev.parent = st->i2c_adap->dev.parent;
2346 i2c_set_adapdata(&st->dib7090_tuner_adap, st);
2347 i2c_add_adapter(&st->dib7090_tuner_adap);
2348
2349 dib7000p_demod_reset(st);
2350
2351 if (st->version == SOC7090) {
2352 dib7090_set_output_mode(demod, st->cfg.output_mode);
2353 dib7090_set_diversity_in(demod, 0);
2354 }
2355
2356 return demod;
2357
2358error:
2359 kfree(st);
2360 return NULL;
2361}
2362EXPORT_SYMBOL(dib7000p_attach);
2363
2364static struct dvb_frontend_ops dib7000p_ops = {
2365 .info = {
2366 .name = "DiBcom 7000PC",
2367 .type = FE_OFDM,
2368 .frequency_min = 44250000,
2369 .frequency_max = 867250000,
2370 .frequency_stepsize = 62500,
2371 .caps = FE_CAN_INVERSION_AUTO |
2372 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2373 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2374 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2375 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2376 },
2377
2378 .release = dib7000p_release,
2379
2380 .init = dib7000p_wakeup,
2381 .sleep = dib7000p_sleep,
2382
2383 .set_frontend = dib7000p_set_frontend,
2384 .get_tune_settings = dib7000p_fe_get_tune_settings,
2385 .get_frontend = dib7000p_get_frontend,
2386
2387 .read_status = dib7000p_read_status,
2388 .read_ber = dib7000p_read_ber,
2389 .read_signal_strength = dib7000p_read_signal_strength,
2390 .read_snr = dib7000p_read_snr,
2391 .read_ucblocks = dib7000p_read_unc_blocks,
2392};
2393
2394MODULE_AUTHOR("Olivier Grenie <ogrenie@dibcom.fr>");
2395MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
2396MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
2397MODULE_LICENSE("GPL");