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

source code of linux/drivers/media/dvb-frontends/dib7000m.c