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