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