treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / drivers / media / dvb-frontends / dib7000m.c
blob97ce97789c9e34bdfeeff162088dbf61c93ab6f5
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Linux-DVB Driver for DiBcom's DiB7000M and
4 * first generation DiB7000P-demodulator-family.
6 * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
7 */
9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11 #include <linux/kernel.h>
12 #include <linux/slab.h>
13 #include <linux/i2c.h>
14 #include <linux/mutex.h>
16 #include <media/dvb_frontend.h>
18 #include "dib7000m.h"
20 static int debug;
21 module_param(debug, int, 0644);
22 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
24 #define dprintk(fmt, arg...) do { \
25 if (debug) \
26 printk(KERN_DEBUG pr_fmt("%s: " fmt), \
27 __func__, ##arg); \
28 } while (0)
30 struct dib7000m_state {
31 struct dvb_frontend demod;
32 struct dib7000m_config cfg;
34 u8 i2c_addr;
35 struct i2c_adapter *i2c_adap;
37 struct dibx000_i2c_master i2c_master;
39 /* offset is 1 in case of the 7000MC */
40 u8 reg_offs;
42 u16 wbd_ref;
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;
51 u8 div_force_off : 1;
52 u8 div_state : 1;
53 u16 div_sync_wait;
55 u16 revision;
57 u8 agc_state;
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;
66 enum dib7000m_power_mode {
67 DIB7000M_POWER_ALL = 0,
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,
76 static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg)
78 u16 ret;
80 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
81 dprintk("could not acquire lock\n");
82 return 0;
85 state->i2c_write_buffer[0] = (reg >> 8) | 0x80;
86 state->i2c_write_buffer[1] = reg & 0xff;
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;
98 if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
99 dprintk("i2c read error on %d\n", reg);
101 ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
102 mutex_unlock(&state->i2c_buffer_lock);
104 return ret;
107 static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val)
109 int ret;
111 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
112 dprintk("could not acquire lock\n");
113 return -EINVAL;
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;
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;
127 ret = (i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ?
128 -EREMOTEIO : 0);
129 mutex_unlock(&state->i2c_buffer_lock);
130 return ret;
132 static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf)
134 u16 l = 0, r, *n;
135 n = buf;
136 l = *n++;
137 while (l) {
138 r = *n++;
140 if (state->reg_offs && (r >= 112 && r <= 331)) // compensate for 7000MC
141 r++;
143 do {
144 dib7000m_write_word(state, r, *n++);
145 r++;
146 } while (--l);
147 l = *n++;
151 static int dib7000m_set_output_mode(struct dib7000m_state *state, int mode)
153 int ret = 0;
154 u16 outreg, fifo_threshold, smo_mode,
155 sram = 0x0005; /* by default SRAM output is disabled */
157 outreg = 0;
158 fifo_threshold = 1792;
159 smo_mode = (dib7000m_read_word(state, 294 + state->reg_offs) & 0x0010) | (1 << 1);
161 dprintk("setting output mode for demod %p to %d\n", &state->demod, mode);
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;
192 if (state->cfg.output_mpeg2_in_188_bytes)
193 smo_mode |= (1 << 5) ;
195 ret |= dib7000m_write_word(state, 294 + state->reg_offs, smo_mode);
196 ret |= dib7000m_write_word(state, 295 + state->reg_offs, fifo_threshold); /* synchronous fread */
197 ret |= dib7000m_write_word(state, 1795, outreg);
198 ret |= dib7000m_write_word(state, 1805, sram);
200 if (state->revision == 0x4003) {
201 u16 clk_cfg1 = dib7000m_read_word(state, 909) & 0xfffd;
202 if (mode == OUTMODE_DIVERSITY)
203 clk_cfg1 |= (1 << 1); // P_O_CLK_en
204 dib7000m_write_word(state, 909, clk_cfg1);
206 return ret;
209 static void dib7000m_set_power_mode(struct dib7000m_state *state, enum dib7000m_power_mode mode)
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;
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;
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;
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;
233 case DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD:
234 reg_903 = 0x0000; reg_904 = 0x801f; reg_905 = 0x0000; reg_906 = 0x0000;
235 break;
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;
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);
248 /* P_sdio_select_clk = 0 on MC and after*/
249 if (state->revision != 0x4000)
250 reg_906 <<= 1;
252 if (state->revision == 0x4003)
253 offset = 1;
255 dib7000m_write_word(state, 903 + offset, reg_903);
256 dib7000m_write_word(state, 904 + offset, reg_904);
257 dib7000m_write_word(state, 905 + offset, reg_905);
258 dib7000m_write_word(state, 906 + offset, reg_906);
261 static int dib7000m_set_adc_state(struct dib7000m_state *state, enum dibx000_adc_states no)
263 int ret = 0;
264 u16 reg_913 = dib7000m_read_word(state, 913),
265 reg_914 = dib7000m_read_word(state, 914);
267 switch (no) {
268 case DIBX000_SLOW_ADC_ON:
269 reg_914 |= (1 << 1) | (1 << 0);
270 ret |= dib7000m_write_word(state, 914, reg_914);
271 reg_914 &= ~(1 << 1);
272 break;
274 case DIBX000_SLOW_ADC_OFF:
275 reg_914 |= (1 << 1) | (1 << 0);
276 break;
278 case DIBX000_ADC_ON:
279 if (state->revision == 0x4000) { // workaround for PA/MA
280 // power-up ADC
281 dib7000m_write_word(state, 913, 0);
282 dib7000m_write_word(state, 914, reg_914 & 0x3);
283 // power-down bandgag
284 dib7000m_write_word(state, 913, (1 << 15));
285 dib7000m_write_word(state, 914, reg_914 & 0x3);
288 reg_913 &= 0x0fff;
289 reg_914 &= 0x0003;
290 break;
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;
297 case DIBX000_VBG_ENABLE:
298 reg_913 &= ~(1 << 15);
299 break;
301 case DIBX000_VBG_DISABLE:
302 reg_913 |= (1 << 15);
303 break;
305 default:
306 break;
309 // dprintk("913: %x, 914: %x\n", reg_913, reg_914);
310 ret |= dib7000m_write_word(state, 913, reg_913);
311 ret |= dib7000m_write_word(state, 914, reg_914);
313 return ret;
316 static int dib7000m_set_bandwidth(struct dib7000m_state *state, u32 bw)
318 u32 timf;
320 if (!bw)
321 bw = 8000;
323 // store the current bandwidth for later use
324 state->current_bandwidth = bw;
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;
334 timf = timf * (bw / 50) / 160;
336 dib7000m_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
337 dib7000m_write_word(state, 24, (u16) ((timf ) & 0xffff));
339 return 0;
342 static int dib7000m_set_diversity_in(struct dvb_frontend *demod, int onoff)
344 struct dib7000m_state *state = demod->demodulator_priv;
346 if (state->div_force_off) {
347 dprintk("diversity combination deactivated - forced by COFDM parameters\n");
348 onoff = 0;
350 state->div_state = (u8)onoff;
352 if (onoff) {
353 dib7000m_write_word(state, 263 + state->reg_offs, 6);
354 dib7000m_write_word(state, 264 + state->reg_offs, 6);
355 dib7000m_write_word(state, 266 + state->reg_offs, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
356 } else {
357 dib7000m_write_word(state, 263 + state->reg_offs, 1);
358 dib7000m_write_word(state, 264 + state->reg_offs, 0);
359 dib7000m_write_word(state, 266 + state->reg_offs, 0);
362 return 0;
365 static int dib7000m_sad_calib(struct dib7000m_state *state)
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, 929, (0 << 1) | (0 << 0));
371 dib7000m_write_word(state, 930, 776); // 0.625*3.3 / 4096
373 /* do the calibration */
374 dib7000m_write_word(state, 929, (1 << 0));
375 dib7000m_write_word(state, 929, (0 << 0));
377 msleep(1);
379 return 0;
382 static void dib7000m_reset_pll_common(struct dib7000m_state *state, const struct dibx000_bandwidth_config *bw)
384 dib7000m_write_word(state, 18, (u16) (((bw->internal*1000) >> 16) & 0xffff));
385 dib7000m_write_word(state, 19, (u16) ( (bw->internal*1000) & 0xffff));
386 dib7000m_write_word(state, 21, (u16) ( (bw->ifreq >> 16) & 0xffff));
387 dib7000m_write_word(state, 22, (u16) ( bw->ifreq & 0xffff));
389 dib7000m_write_word(state, 928, bw->sad_cfg);
392 static void dib7000m_reset_pll(struct dib7000m_state *state)
394 const struct dibx000_bandwidth_config *bw = state->cfg.bw;
395 u16 reg_907,reg_910;
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;
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
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);
418 dib7000m_write_word(state, 910, reg_910); // pll cfg
419 dib7000m_write_word(state, 907, reg_907); // clk cfg0
420 dib7000m_write_word(state, 908, 0x0006); // clk_cfg1
422 dib7000m_reset_pll_common(state, bw);
425 static void dib7000mc_reset_pll(struct dib7000m_state *state)
427 const struct dibx000_bandwidth_config *bw = state->cfg.bw;
428 u16 clk_cfg1;
430 // clk_cfg0
431 dib7000m_write_word(state, 907, (bw->pll_prediv << 8) | (bw->pll_ratio << 0));
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, 908, clk_cfg1);
439 clk_cfg1 = (clk_cfg1 & 0xfff7) | (bw->pll_bypass << 3);
440 dib7000m_write_word(state, 908, clk_cfg1);
442 // smpl_cfg
443 dib7000m_write_word(state, 910, (1 << 12) | (2 << 10) | (bw->modulo << 8) | (bw->ADClkSrc << 7));
445 dib7000m_reset_pll_common(state, bw);
448 static int dib7000m_reset_gpio(struct dib7000m_state *st)
450 /* reset the GPIOs */
451 dib7000m_write_word(st, 773, st->cfg.gpio_dir);
452 dib7000m_write_word(st, 774, st->cfg.gpio_val);
454 /* TODO 782 is P_gpio_od */
456 dib7000m_write_word(st, 775, st->cfg.gpio_pwm_pos);
458 dib7000m_write_word(st, 780, st->cfg.pwm_freq_div);
459 return 0;
462 static u16 dib7000m_defaults_common[] =
465 // auto search configuration
466 3, 2,
467 0x0004,
468 0x1000,
469 0x0814,
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,
485 1, 26,
486 0x6680, // P_corm_thres Lock algorithms configuration
488 1, 170,
489 0x0410, // P_palf_alpha_regul, P_palf_filter_freeze, P_palf_filter_on
491 8, 173,
501 1, 182,
502 8192, // P_fft_nb_to_cut
504 2, 195,
505 0x0ccd, // P_pha3_thres
506 0, // P_cti_use_cpe, P_cti_use_prog
508 1, 205,
509 0x200f, // P_cspu_regul, P_cspu_win_cut
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
518 1, 226,
519 0, // P_2d_byp_ti_num
521 1, 255,
522 0x800, // P_equal_thres_wgn
524 1, 263,
525 0x0001,
527 1, 281,
528 0x0010, // P_fec_*
530 1, 294,
531 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
536 static u16 dib7000m_defaults[] =
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,
553 // Tuner IO bank: max drive (14mA)
554 1, 912,
555 0x2c8a,
557 1, 1817,
563 static int dib7000m_demod_reset(struct dib7000m_state *state)
565 dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
567 /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
568 dib7000m_set_adc_state(state, DIBX000_VBG_ENABLE);
570 /* restart all parts */
571 dib7000m_write_word(state, 898, 0xffff);
572 dib7000m_write_word(state, 899, 0xffff);
573 dib7000m_write_word(state, 900, 0xff0f);
574 dib7000m_write_word(state, 901, 0xfffc);
576 dib7000m_write_word(state, 898, 0);
577 dib7000m_write_word(state, 899, 0);
578 dib7000m_write_word(state, 900, 0);
579 dib7000m_write_word(state, 901, 0);
581 if (state->revision == 0x4000)
582 dib7000m_reset_pll(state);
583 else
584 dib7000mc_reset_pll(state);
586 if (dib7000m_reset_gpio(state) != 0)
587 dprintk("GPIO reset was not successful.\n");
589 if (dib7000m_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
590 dprintk("OUTPUT_MODE could not be reset.\n");
592 /* unforce divstr regardless whether i2c enumeration was done or not */
593 dib7000m_write_word(state, 1794, dib7000m_read_word(state, 1794) & ~(1 << 1) );
595 dib7000m_set_bandwidth(state, 8000);
597 dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON);
598 dib7000m_sad_calib(state);
599 dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
601 if (state->cfg.dvbt_mode)
602 dib7000m_write_word(state, 1796, 0x0); // select DVB-T output
604 if (state->cfg.mobile_mode)
605 dib7000m_write_word(state, 261 + state->reg_offs, 2);
606 else
607 dib7000m_write_word(state, 224 + state->reg_offs, 1);
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, 36, 0x0755);
612 else
613 dib7000m_write_word(state, 36, 0x1f55);
615 // P_divclksel=3 P_divbitsel=1
616 if (state->revision == 0x4000)
617 dib7000m_write_word(state, 909, (3 << 10) | (1 << 6));
618 else
619 dib7000m_write_word(state, 909, (3 << 4) | 1);
621 dib7000m_write_tab(state, dib7000m_defaults_common);
622 dib7000m_write_tab(state, dib7000m_defaults);
624 dib7000m_set_power_mode(state, DIB7000M_POWER_INTERFACE_ONLY);
626 state->internal_clk = state->cfg.bw->internal;
628 return 0;
631 static void dib7000m_restart_agc(struct dib7000m_state *state)
633 // P_restart_iqc & P_restart_agc
634 dib7000m_write_word(state, 898, 0x0c00);
635 dib7000m_write_word(state, 898, 0x0000);
638 static int dib7000m_agc_soft_split(struct dib7000m_state *state)
640 u16 agc,split_offset;
642 if(!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
643 return 0;
645 // n_agc_global
646 agc = dib7000m_read_word(state, 390);
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);
657 dprintk("AGC split_offset: %d\n", split_offset);
659 // P_agc_force_split and P_agc_split_offset
660 return dib7000m_write_word(state, 103, (dib7000m_read_word(state, 103) & 0xff00) | split_offset);
663 static int dib7000m_update_lna(struct dib7000m_state *state)
665 u16 dyn_gain;
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, 390);
671 if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed
672 dib7000m_restart_agc(state);
673 return 1;
676 return 0;
679 static int dib7000m_set_agc_config(struct dib7000m_state *state, u8 band)
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;
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;
693 if (agc == NULL) {
694 dprintk("no valid AGC configuration found for band 0x%02x\n", band);
695 return -EINVAL;
698 state->current_agc = agc;
700 /* AGC */
701 dib7000m_write_word(state, 72 , agc->setup);
702 dib7000m_write_word(state, 73 , agc->inv_gain);
703 dib7000m_write_word(state, 74 , agc->time_stabiliz);
704 dib7000m_write_word(state, 97 , (agc->alpha_level << 12) | agc->thlock);
706 // Demod AGC loop configuration
707 dib7000m_write_word(state, 98, (agc->alpha_mant << 5) | agc->alpha_exp);
708 dib7000m_write_word(state, 99, (agc->beta_mant << 6) | agc->beta_exp);
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);
713 /* AGC continued */
714 if (state->wbd_ref != 0)
715 dib7000m_write_word(state, 102, state->wbd_ref);
716 else // use default
717 dib7000m_write_word(state, 102, agc->wbd_ref);
719 dib7000m_write_word(state, 103, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8) );
720 dib7000m_write_word(state, 104, agc->agc1_max);
721 dib7000m_write_word(state, 105, agc->agc1_min);
722 dib7000m_write_word(state, 106, agc->agc2_max);
723 dib7000m_write_word(state, 107, agc->agc2_min);
724 dib7000m_write_word(state, 108, (agc->agc1_pt1 << 8) | agc->agc1_pt2 );
725 dib7000m_write_word(state, 109, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
726 dib7000m_write_word(state, 110, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
727 dib7000m_write_word(state, 111, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
729 if (state->revision > 0x4000) { // settings for the MC
730 dib7000m_write_word(state, 71, 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, 929, (dib7000m_read_word(state, 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, 88 + i, b[i]);
740 return 0;
743 static void dib7000m_update_timf(struct dib7000m_state *state)
745 u32 timf = (dib7000m_read_word(state, 436) << 16) | dib7000m_read_word(state, 437);
746 state->timf = timf * 160 / (state->current_bandwidth / 50);
747 dib7000m_write_word(state, 23, (u16) (timf >> 16));
748 dib7000m_write_word(state, 24, (u16) (timf & 0xffff));
749 dprintk("updated timf_frequency: %d (default: %d)\n", state->timf, state->timf_default);
752 static int dib7000m_agc_startup(struct dvb_frontend *demod)
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, 72);
757 int ret = -1;
758 u8 *agc_state = &state->agc_state;
759 u8 agc_split;
761 switch (state->agc_state) {
762 case 0:
763 // set power-up level: interf+analog+AGC
764 dib7000m_set_power_mode(state, DIB7000M_POWER_INTERF_ANALOG_AGC);
765 dib7000m_set_adc_state(state, DIBX000_ADC_ON);
767 if (dib7000m_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0)
768 return -1;
770 ret = 7; /* ADC power up */
771 (*agc_state)++;
772 break;
774 case 1:
775 /* AGC initialization */
776 if (state->cfg.agc_control)
777 state->cfg.agc_control(&state->demod, 1);
779 dib7000m_write_word(state, 75, 32768);
780 if (!state->current_agc->perform_agc_softsplit) {
781 /* we are using the wbd - so slow AGC startup */
782 dib7000m_write_word(state, 103, 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;
792 dib7000m_restart_agc(state);
793 break;
795 case 2: /* fast split search path after 5sec */
796 dib7000m_write_word(state, 72, cfg_72 | (1 << 4)); /* freeze AGC loop */
797 dib7000m_write_word(state, 103, 2 << 9); /* fast split search 0.25kHz */
798 (*agc_state)++;
799 ret = 14;
800 break;
802 case 3: /* split search ended */
803 agc_split = (u8)dib7000m_read_word(state, 392); /* store the split value for the next time */
804 dib7000m_write_word(state, 75, dib7000m_read_word(state, 390)); /* set AGC gain start value */
806 dib7000m_write_word(state, 72, cfg_72 & ~(1 << 4)); /* std AGC loop */
807 dib7000m_write_word(state, 103, (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
809 dib7000m_restart_agc(state);
811 dprintk("SPLIT %p: %u\n", demod, agc_split);
813 (*agc_state)++;
814 ret = 5;
815 break;
817 case 4: /* LNA startup */
818 /* wait AGC accurate lock time */
819 ret = 7;
821 if (dib7000m_update_lna(state))
822 // wait only AGC rough lock time
823 ret = 5;
824 else
825 (*agc_state)++;
826 break;
828 case 5:
829 dib7000m_agc_soft_split(state);
831 if (state->cfg.agc_control)
832 state->cfg.agc_control(&state->demod, 0);
834 (*agc_state)++;
835 break;
837 default:
838 break;
840 return ret;
843 static void dib7000m_set_channel(struct dib7000m_state *state, struct dtv_frontend_properties *ch,
844 u8 seq)
846 u16 value, est[4];
848 dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
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;
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;
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;
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;
877 dib7000m_write_word(state, 0, value);
878 dib7000m_write_word(state, 5, (seq << 4));
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;
896 dib7000m_write_word(state, 267 + state->reg_offs, value);
898 /* offset loop parameters */
900 /* P_timf_alpha = 6, P_corm_alpha=6, P_corm_thres=0x80 */
901 dib7000m_write_word(state, 26, (6 << 12) | (6 << 8) | 0x80);
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, 29, (0 << 14) | (4 << 10) | (1 << 9) | (3 << 5) | (1 << 4) | (0x3));
906 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max=3 */
907 dib7000m_write_word(state, 32, (0 << 4) | 0x3);
909 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step=5 */
910 dib7000m_write_word(state, 33, (0 << 4) | 0x5);
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;
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;
926 state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO
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(&state->demod, state->div_state);
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;
957 for (value = 0; value < 4; value++)
958 dib7000m_write_word(state, 214 + value + state->reg_offs, est[value]);
960 // set power-up level: autosearch
961 dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD);
964 static int dib7000m_autosearch_start(struct dvb_frontend *demod)
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;
972 schan = *ch;
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;
981 dib7000m_set_channel(state, &schan, 7);
983 factor = BANDWIDTH_TO_KHZ(schan.bandwidth_hz);
984 if (factor >= 5000)
985 factor = 1;
986 else
987 factor = 6;
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, 6, (u16) ((value >> 16) & 0xffff)); // lock0 wait time
992 ret |= dib7000m_write_word(state, 7, (u16) (value & 0xffff)); // lock0 wait time
993 value = 100 * state->internal_clk * factor;
994 ret |= dib7000m_write_word(state, 8, (u16) ((value >> 16) & 0xffff)); // lock1 wait time
995 ret |= dib7000m_write_word(state, 9, (u16) (value & 0xffff)); // lock1 wait time
996 value = 500 * state->internal_clk * factor;
997 ret |= dib7000m_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
998 ret |= dib7000m_write_word(state, 11, (u16) (value & 0xffff)); // lock2 wait time
1000 // start search
1001 value = dib7000m_read_word(state, 0);
1002 ret |= dib7000m_write_word(state, 0, (u16) (value | (1 << 9)));
1004 /* clear n_irq_pending */
1005 if (state->revision == 0x4000)
1006 dib7000m_write_word(state, 1793, 0);
1007 else
1008 dib7000m_read_word(state, 537);
1010 ret |= dib7000m_write_word(state, 0, (u16) value);
1012 return ret;
1015 static int dib7000m_autosearch_irq(struct dib7000m_state *state, u16 reg)
1017 u16 irq_pending = dib7000m_read_word(state, reg);
1019 if (irq_pending & 0x1) { // failed
1020 dprintk("autosearch failed\n");
1021 return 1;
1024 if (irq_pending & 0x2) { // succeeded
1025 dprintk("autosearch succeeded\n");
1026 return 2;
1028 return 0; // still pending
1031 static int dib7000m_autosearch_is_irq(struct dvb_frontend *demod)
1033 struct dib7000m_state *state = demod->demodulator_priv;
1034 if (state->revision == 0x4000)
1035 return dib7000m_autosearch_irq(state, 1793);
1036 else
1037 return dib7000m_autosearch_irq(state, 537);
1040 static int dib7000m_tune(struct dvb_frontend *demod)
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;
1047 // we are already tuned - just resuming from suspend
1048 dib7000m_set_channel(state, ch, 0);
1050 // restart demod
1051 ret |= dib7000m_write_word(state, 898, 0x4000);
1052 ret |= dib7000m_write_word(state, 898, 0x0000);
1053 msleep(45);
1055 dib7000m_set_power_mode(state, 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, 29, (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3));
1059 // never achieved a lock before - wait for timfreq to update
1060 if (state->timf == 0)
1061 msleep(200);
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;
1072 ret |= dib7000m_write_word(state, 26, value);
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;
1082 ret |= dib7000m_write_word(state, 32, value);
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;
1092 ret |= dib7000m_write_word(state, 33, value);
1094 // we achieved a lock - it's time to update the timf freq
1095 if ((dib7000m_read_word(state, 535) >> 6) & 0x1)
1096 dib7000m_update_timf(state);
1098 dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
1099 return ret;
1102 static int dib7000m_wakeup(struct dvb_frontend *demod)
1104 struct dib7000m_state *state = demod->demodulator_priv;
1106 dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
1108 if (dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
1109 dprintk("could not start Slow ADC\n");
1111 return 0;
1114 static int dib7000m_sleep(struct dvb_frontend *demod)
1116 struct dib7000m_state *st = demod->demodulator_priv;
1117 dib7000m_set_output_mode(st, OUTMODE_HIGH_Z);
1118 dib7000m_set_power_mode(st, DIB7000M_POWER_INTERFACE_ONLY);
1119 return dib7000m_set_adc_state(st, DIBX000_SLOW_ADC_OFF) |
1120 dib7000m_set_adc_state(st, DIBX000_ADC_OFF);
1123 static int dib7000m_identify(struct dib7000m_state *state)
1125 u16 value;
1127 if ((value = dib7000m_read_word(state, 896)) != 0x01b3) {
1128 dprintk("wrong Vendor ID (0x%x)\n", value);
1129 return -EREMOTEIO;
1132 state->revision = dib7000m_read_word(state, 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;
1141 /* protect this driver to be used with 7000PC */
1142 if (state->revision == 0x4000 && dib7000m_read_word(state, 769) == 0x4000) {
1143 dprintk("this driver does not work with DiB7000PC\n");
1144 return -EREMOTEIO;
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;
1154 return 0;
1158 static int dib7000m_get_frontend(struct dvb_frontend* fe,
1159 struct dtv_frontend_properties *fep)
1161 struct dib7000m_state *state = fe->demodulator_priv;
1162 u16 tps = dib7000m_read_word(state,480);
1164 fep->inversion = INVERSION_AUTO;
1166 fep->bandwidth_hz = BANDWIDTH_TO_HZ(state->current_bandwidth);
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; */
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;
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;
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 */
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;
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;
1211 /* native interleaver: (dib7000m_read_word(state, 481) >> 5) & 0x1 */
1213 return 0;
1216 static int dib7000m_set_frontend(struct dvb_frontend *fe)
1218 struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
1219 struct dib7000m_state *state = fe->demodulator_priv;
1220 int time, ret;
1222 dib7000m_set_output_mode(state, OUTMODE_HIGH_Z);
1224 dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->bandwidth_hz));
1226 if (fe->ops.tuner_ops.set_params)
1227 fe->ops.tuner_ops.set_params(fe);
1229 /* start up the AGC */
1230 state->agc_state = 0;
1231 do {
1232 time = dib7000m_agc_startup(fe);
1233 if (time != -1)
1234 msleep(time);
1235 } while (time != -1);
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;
1243 dib7000m_autosearch_start(fe);
1244 do {
1245 msleep(1);
1246 found = dib7000m_autosearch_is_irq(fe);
1247 } while (found == 0 && i--);
1249 dprintk("autosearch returns: %d\n", found);
1250 if (found == 0 || found == 1)
1251 return 0; // no channel found
1253 dib7000m_get_frontend(fe, fep);
1256 ret = dib7000m_tune(fe);
1258 /* make this a config parameter */
1259 dib7000m_set_output_mode(state, OUTMODE_MPEG2_FIFO);
1260 return ret;
1263 static int dib7000m_read_status(struct dvb_frontend *fe, enum fe_status *stat)
1265 struct dib7000m_state *state = fe->demodulator_priv;
1266 u16 lock = dib7000m_read_word(state, 535);
1268 *stat = 0;
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;
1281 return 0;
1284 static int dib7000m_read_ber(struct dvb_frontend *fe, u32 *ber)
1286 struct dib7000m_state *state = fe->demodulator_priv;
1287 *ber = (dib7000m_read_word(state, 526) << 16) | dib7000m_read_word(state, 527);
1288 return 0;
1291 static int dib7000m_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
1293 struct dib7000m_state *state = fe->demodulator_priv;
1294 *unc = dib7000m_read_word(state, 534);
1295 return 0;
1298 static int dib7000m_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1300 struct dib7000m_state *state = fe->demodulator_priv;
1301 u16 val = dib7000m_read_word(state, 390);
1302 *strength = 65535 - val;
1303 return 0;
1306 static int dib7000m_read_snr(struct dvb_frontend* fe, u16 *snr)
1308 *snr = 0x0000;
1309 return 0;
1312 static int dib7000m_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
1314 tune->min_delay_ms = 1000;
1315 return 0;
1318 static void dib7000m_release(struct dvb_frontend *demod)
1320 struct dib7000m_state *st = demod->demodulator_priv;
1321 dibx000_exit_i2c_master(&st->i2c_master);
1322 kfree(st);
1325 struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
1327 struct dib7000m_state *st = demod->demodulator_priv;
1328 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1330 EXPORT_SYMBOL(dib7000m_get_i2c_master);
1332 int dib7000m_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1334 struct dib7000m_state *state = fe->demodulator_priv;
1335 u16 val = dib7000m_read_word(state, 294 + state->reg_offs) & 0xffef;
1336 val |= (onoff & 0x1) << 4;
1337 dprintk("PID filter enabled %d\n", onoff);
1338 return dib7000m_write_word(state, 294 + state->reg_offs, val);
1340 EXPORT_SYMBOL(dib7000m_pid_filter_ctrl);
1342 int dib7000m_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
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, 300 + state->reg_offs + id,
1347 onoff ? (1 << 13) | pid : 0);
1349 EXPORT_SYMBOL(dib7000m_pid_filter);
1351 #if 0
1352 /* used with some prototype boards */
1353 int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods,
1354 u8 default_addr, struct dib7000m_config cfg[])
1356 struct dib7000m_state st = { .i2c_adap = i2c };
1357 int k = 0;
1358 u8 new_addr = 0;
1360 for (k = no_of_demods-1; k >= 0; k--) {
1361 st.cfg = cfg[k];
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;
1374 /* start diversity to pull_down div_str - just for i2c-enumeration */
1375 dib7000m_set_output_mode(&st, OUTMODE_DIVERSITY);
1377 dib7000m_write_word(&st, 1796, 0x0); // select DVB-T output
1379 /* set new i2c address and force divstart */
1380 dib7000m_write_word(&st, 1794, (new_addr << 2) | 0x2);
1382 dprintk("IC %d initialized (to i2c_address 0x%x)\n", k, new_addr);
1385 for (k = 0; k < no_of_demods; k++) {
1386 st.cfg = cfg[k];
1387 st.i2c_addr = (0x40 + k) << 1;
1389 // unforce divstr
1390 dib7000m_write_word(&st,1794, st.i2c_addr << 2);
1392 /* deactivate div - it was just for i2c-enumeration */
1393 dib7000m_set_output_mode(&st, OUTMODE_HIGH_Z);
1396 return 0;
1398 EXPORT_SYMBOL(dib7000m_i2c_enumeration);
1399 #endif
1401 static const struct dvb_frontend_ops dib7000m_ops;
1402 struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg)
1404 struct dvb_frontend *demod;
1405 struct dib7000m_state *st;
1406 st = kzalloc(sizeof(struct dib7000m_state), GFP_KERNEL);
1407 if (st == NULL)
1408 return NULL;
1410 memcpy(&st->cfg, cfg, sizeof(struct dib7000m_config));
1411 st->i2c_adap = i2c_adap;
1412 st->i2c_addr = i2c_addr;
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);
1419 st->timf_default = cfg->bw->timf;
1421 if (dib7000m_identify(st) != 0)
1422 goto error;
1424 if (st->revision == 0x4000)
1425 dibx000_init_i2c_master(&st->i2c_master, DIB7000, st->i2c_adap, st->i2c_addr);
1426 else
1427 dibx000_init_i2c_master(&st->i2c_master, DIB7000MC, st->i2c_adap, st->i2c_addr);
1429 dib7000m_demod_reset(st);
1431 return demod;
1433 error:
1434 kfree(st);
1435 return NULL;
1437 EXPORT_SYMBOL(dib7000m_attach);
1439 static 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,
1456 .release = dib7000m_release,
1458 .init = dib7000m_wakeup,
1459 .sleep = dib7000m_sleep,
1461 .set_frontend = dib7000m_set_frontend,
1462 .get_tune_settings = dib7000m_fe_get_tune_settings,
1463 .get_frontend = dib7000m_get_frontend,
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,
1472 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
1473 MODULE_DESCRIPTION("Driver for the DiBcom 7000MA/MB/PA/PB/MC COFDM demodulator");
1474 MODULE_LICENSE("GPL");