2 * Driver for DiBcom DiB3000MC/P-demodulator.
4 * Copyright (C) 2004-6 DiBcom (http://www.dibcom.fr/)
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
7 * This code is partially based on the previous dib3000mc.c .
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation, version 2.
14 #include <linux/kernel.h>
15 #include <linux/i2c.h>
16 //#include <linux/init.h>
17 //#include <linux/delay.h>
18 //#include <linux/string.h>
19 //#include <linux/slab.h>
21 #include "dvb_frontend.h"
23 #include "dib3000mc.h"
26 module_param(debug, int, 0644);
27 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
29 #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); } } while (0)
31 struct dib3000mc_state {
32 struct dvb_frontend demod;
33 struct dib3000mc_config *cfg;
36 struct i2c_adapter *i2c_adap;
38 struct dibx000_i2c_master i2c_master;
42 fe_bandwidth_t current_bandwidth;
47 static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
49 u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
51 struct i2c_msg msg[2] = {
52 { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 },
53 { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
56 if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
57 dprintk("i2c read error on %d\n",reg);
59 return (rb[0] << 8) | rb[1];
62 static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
65 (reg >> 8) & 0xff, reg & 0xff,
66 (val >> 8) & 0xff, val & 0xff,
68 struct i2c_msg msg = {
69 .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
71 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
75 static int dib3000mc_identify(struct dib3000mc_state *state)
78 if ((value = dib3000mc_read_word(state, 1025)) != 0x01b3) {
79 dprintk("-E- DiB3000MC/P: wrong Vendor ID (read=0x%x)\n",value);
83 value = dib3000mc_read_word(state, 1026);
84 if (value != 0x3001 && value != 0x3002) {
85 dprintk("-E- DiB3000MC/P: wrong Device ID (%x)\n",value);
88 state->dev_id = value;
90 dprintk("-I- found DiB3000MC/P: %x\n",state->dev_id);
95 static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u8 bw, u8 update_offset)
99 if (state->timf == 0) {
100 timf = 1384402; // default value for 8MHz
102 msleep(200); // first time we do an update
106 timf *= (BW_INDEX_TO_KHZ(bw) / 1000);
109 s16 tim_offs = dib3000mc_read_word(state, 416);
111 if (tim_offs & 0x2000)
118 state->timf = timf / (BW_INDEX_TO_KHZ(bw) / 1000);
121 dprintk("timf: %d\n", timf);
123 dib3000mc_write_word(state, 23, timf >> 16);
124 dib3000mc_write_word(state, 24, timf & 0xffff);
129 static int dib3000mc_setup_pwm_state(struct dib3000mc_state *state)
131 u16 reg_51, reg_52 = state->cfg->agc->setup & 0xfefb;
132 if (state->cfg->pwm3_inversion) {
133 reg_51 = (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
136 reg_51 = (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
139 dib3000mc_write_word(state, 51, reg_51);
140 dib3000mc_write_word(state, 52, reg_52);
142 if (state->cfg->use_pwm3)
143 dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0));
145 dib3000mc_write_word(state, 245, 0);
147 dib3000mc_write_word(state, 1040, 0x3);
151 static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode)
154 u16 fifo_threshold = 1792;
158 u16 smo_reg = dib3000mc_read_word(state, 206) & 0x0010; /* keep the pid_parse bit */
160 dprintk("-I- Setting output mode for demod %p to %d\n",
161 &state->demod, mode);
164 case OUTMODE_HIGH_Z: // disable
167 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
170 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
173 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
176 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
179 P_smo_error_discard [1;6:6] = 0
180 P_smo_rs_discard [1;5:5] = 0
181 P_smo_pid_parse [1;4:4] = 0
182 P_smo_fifo_flush [1;3:3] = 0
183 P_smo_mode [2;2:1] = 11
184 P_smo_ovf_prot [1;0:0] = 0
187 fifo_threshold = 512;
190 case OUTMODE_DIVERSITY:
195 dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod);
200 if ((state->cfg->output_mpeg2_in_188_bytes))
201 smo_reg |= (1 << 5); // P_smo_rs_discard [1;5:5] = 1
203 outreg = dib3000mc_read_word(state, 244) & 0x07FF;
204 outreg |= (outmode << 11);
205 ret |= dib3000mc_write_word(state, 244, outreg);
206 ret |= dib3000mc_write_word(state, 206, smo_reg); /*smo_ mode*/
207 ret |= dib3000mc_write_word(state, 207, fifo_threshold); /* synchronous fread */
208 ret |= dib3000mc_write_word(state, 1040, elecout); /* P_out_cfg */
212 static int dib3000mc_set_bandwidth(struct dvb_frontend *demod, u8 bw)
214 struct dib3000mc_state *state = demod->demodulator_priv;
215 u16 bw_cfg[6] = { 0 };
216 u16 imp_bw_cfg[3] = { 0 };
219 /* settings here are for 27.7MHz */
221 case BANDWIDTH_8_MHZ:
222 bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20;
223 imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7;
226 case BANDWIDTH_7_MHZ:
227 bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7;
228 imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0;
231 case BANDWIDTH_6_MHZ:
232 bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5;
233 imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089;
236 case 255 /* BANDWIDTH_5_MHZ */:
237 bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500;
238 imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072;
241 default: return -EINVAL;
244 for (reg = 6; reg < 12; reg++)
245 dib3000mc_write_word(state, reg, bw_cfg[reg - 6]);
246 dib3000mc_write_word(state, 12, 0x0000);
247 dib3000mc_write_word(state, 13, 0x03e8);
248 dib3000mc_write_word(state, 14, 0x0000);
249 dib3000mc_write_word(state, 15, 0x03f2);
250 dib3000mc_write_word(state, 16, 0x0001);
251 dib3000mc_write_word(state, 17, 0xb0d0);
253 dib3000mc_write_word(state, 18, 0x0393);
254 dib3000mc_write_word(state, 19, 0x8700);
256 for (reg = 55; reg < 58; reg++)
257 dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]);
259 // Timing configuration
260 dib3000mc_set_timing(state, 0, bw, 0);
265 static u16 impulse_noise_val[29] =
268 0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, 0x3ffe, 0x7f3,
269 0x2d94, 0x76, 0x53d, 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, 0x3feb, 0x7d2,
270 0x365e, 0x76, 0x48c, 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0000, 0xd
273 static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft)
276 for (i = 58; i < 87; i++)
277 dib3000mc_write_word(state, i, impulse_noise_val[i-58]);
280 dib3000mc_write_word(state, 58, 0x3b);
281 dib3000mc_write_word(state, 84, 0x00);
282 dib3000mc_write_word(state, 85, 0x8200);
285 dib3000mc_write_word(state, 34, 0x1294);
286 dib3000mc_write_word(state, 35, 0x1ff8);
288 dib3000mc_write_word(state, 55, dib3000mc_read_word(state, 55) | (1 << 10));
291 static int dib3000mc_init(struct dvb_frontend *demod)
293 struct dib3000mc_state *state = demod->demodulator_priv;
294 struct dibx000_agc_config *agc = state->cfg->agc;
296 // Restart Configuration
297 dib3000mc_write_word(state, 1027, 0x8000);
298 dib3000mc_write_word(state, 1027, 0x0000);
300 // power up the demod + mobility configuration
301 dib3000mc_write_word(state, 140, 0x0000);
302 dib3000mc_write_word(state, 1031, 0);
304 if (state->cfg->mobile_mode) {
305 dib3000mc_write_word(state, 139, 0x0000);
306 dib3000mc_write_word(state, 141, 0x0000);
307 dib3000mc_write_word(state, 175, 0x0002);
308 dib3000mc_write_word(state, 1032, 0x0000);
310 dib3000mc_write_word(state, 139, 0x0001);
311 dib3000mc_write_word(state, 141, 0x0000);
312 dib3000mc_write_word(state, 175, 0x0000);
313 dib3000mc_write_word(state, 1032, 0x012C);
315 dib3000mc_write_word(state, 1033, 0);
318 dib3000mc_write_word(state, 1037, 12592);
320 // other configurations
323 dib3000mc_write_word(state, 33, (5 << 0));
324 dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0));
326 // Phase noise control
327 // P_fft_phacor_inh, P_fft_phacor_cpe, P_fft_powrange
328 dib3000mc_write_word(state, 99, (1 << 9) | (0x20 << 0));
330 if (state->cfg->phase_noise_mode == 0)
331 dib3000mc_write_word(state, 111, 0x00);
333 dib3000mc_write_word(state, 111, 0x02);
336 dib3000mc_write_word(state, 50, 0x8000);
339 dib3000mc_setup_pwm_state(state);
341 // P_agc_counter_lock
342 dib3000mc_write_word(state, 53, 0x87);
343 // P_agc_counter_unlock
344 dib3000mc_write_word(state, 54, 0x87);
347 dib3000mc_write_word(state, 36, state->cfg->max_time);
348 dib3000mc_write_word(state, 37, agc->setup);
349 dib3000mc_write_word(state, 38, state->cfg->pwm3_value);
350 dib3000mc_write_word(state, 39, state->cfg->ln_adc_level);
353 dib3000mc_write_word(state, 40, 0x0179);
354 dib3000mc_write_word(state, 41, 0x03f0);
356 dib3000mc_write_word(state, 42, agc->agc1_max);
357 dib3000mc_write_word(state, 43, agc->agc1_min);
358 dib3000mc_write_word(state, 44, agc->agc2_max);
359 dib3000mc_write_word(state, 45, agc->agc2_min);
360 dib3000mc_write_word(state, 46, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
361 dib3000mc_write_word(state, 47, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
362 dib3000mc_write_word(state, 48, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
363 dib3000mc_write_word(state, 49, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
365 // Begin: TimeOut registers
367 dib3000mc_write_word(state, 110, 3277);
368 // P_timf_alpha = 6, P_corm_alpha = 6, P_corm_thres = 0x80
369 dib3000mc_write_word(state, 26, 0x6680);
371 dib3000mc_write_word(state, 1, 4);
373 dib3000mc_write_word(state, 2, 4);
375 dib3000mc_write_word(state, 3, 0x1000);
376 // P_search_maxtrial=1
377 dib3000mc_write_word(state, 5, 1);
379 dib3000mc_set_bandwidth(&state->demod, BANDWIDTH_8_MHZ);
382 dib3000mc_write_word(state, 4, 0x814);
384 dib3000mc_write_word(state, 21, (1 << 9) | 0x164);
385 dib3000mc_write_word(state, 22, 0x463d);
388 // P_cspu_regul, P_cspu_win_cut
389 dib3000mc_write_word(state, 120, 0x200f);
391 dib3000mc_write_word(state, 134, 0);
394 dib3000mc_write_word(state, 195, 0x10);
396 // diversity register: P_dvsy_sync_wait..
397 dib3000mc_write_word(state, 180, 0x2FF0);
399 // Impulse noise configuration
400 dib3000mc_set_impulse_noise(state, 0, 1);
402 // output mode set-up
403 dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
405 /* close the i2c-gate */
406 dib3000mc_write_word(state, 769, (1 << 7) );
411 static int dib3000mc_sleep(struct dvb_frontend *demod)
413 struct dib3000mc_state *state = demod->demodulator_priv;
415 dib3000mc_write_word(state, 1037, dib3000mc_read_word(state, 1037) | 0x0003);
416 dib3000mc_write_word(state, 1031, 0xFFFF);
417 dib3000mc_write_word(state, 1032, 0xFFFF);
418 dib3000mc_write_word(state, 1033, 0xFFF4); // **** Bin2
423 static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
425 u16 cfg[4] = { 0 },reg;
428 cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0;
431 cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0;
434 cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8;
437 for (reg = 129; reg < 133; reg++)
438 dib3000mc_write_word(state, reg, cfg[reg - 129]);
441 static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dibx000_ofdm_channel *chan, u16 seq)
445 dib3000mc_set_timing(state, chan->nfft, chan->Bw, 0);
448 // dib3000mc_write_word(state, 100, (11 << 6) + 6);
450 dib3000mc_write_word(state, 100, (16 << 6) + 9);
452 dib3000mc_write_word(state, 1027, 0x0800);
453 dib3000mc_write_word(state, 1027, 0x0000);
455 //Default cfg isi offset adp
456 dib3000mc_write_word(state, 26, 0x6680);
457 dib3000mc_write_word(state, 29, 0x1273);
458 dib3000mc_write_word(state, 33, 5);
459 dib3000mc_set_adp_cfg(state, 1);
460 dib3000mc_write_word(state, 133, 15564);
462 dib3000mc_write_word(state, 12 , 0x0);
463 dib3000mc_write_word(state, 13 , 0x3e8);
464 dib3000mc_write_word(state, 14 , 0x0);
465 dib3000mc_write_word(state, 15 , 0x3f2);
467 dib3000mc_write_word(state, 93,0);
468 dib3000mc_write_word(state, 94,0);
469 dib3000mc_write_word(state, 95,0);
470 dib3000mc_write_word(state, 96,0);
471 dib3000mc_write_word(state, 97,0);
472 dib3000mc_write_word(state, 98,0);
474 dib3000mc_set_impulse_noise(state, 0, chan->nfft);
476 tmp = ((chan->nfft & 0x1) << 7) | (chan->guard << 5) | (chan->nqam << 3) | chan->vit_alpha;
477 dib3000mc_write_word(state, 0, tmp);
479 dib3000mc_write_word(state, 5, seq);
481 tmp = (chan->vit_hrch << 4) | (chan->vit_select_hp);
482 if (!chan->vit_hrch || (chan->vit_hrch && chan->vit_select_hp))
483 tmp |= chan->vit_code_rate_hp << 1;
485 tmp |= chan->vit_code_rate_lp << 1;
486 dib3000mc_write_word(state, 181, tmp);
488 // diversity synchro delay
489 tmp = dib3000mc_read_word(state, 180) & 0x000f;
490 tmp |= ((chan->nfft == 0) ? 64 : 256) * ((1 << (chan->guard)) * 3 / 2) << 4; // add 50% SFN margin
491 dib3000mc_write_word(state, 180, tmp);
494 tmp = dib3000mc_read_word(state, 0);
495 dib3000mc_write_word(state, 0, tmp | (1 << 9));
496 dib3000mc_write_word(state, 0, tmp);
500 dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, chan->nfft);
503 static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dibx000_ofdm_channel *chan)
505 struct dib3000mc_state *state = demod->demodulator_priv;
508 struct dibx000_ofdm_channel fchan;
510 INIT_OFDM_CHANNEL(&fchan);
514 /* a channel for autosearch */
516 if (chan->nfft == -1 && chan->guard == -1) reg = 7;
517 if (chan->nfft == -1 && chan->guard != -1) reg = 2;
518 if (chan->nfft != -1 && chan->guard == -1) reg = 3;
520 fchan.nfft = 1; fchan.guard = 0; fchan.nqam = 2;
521 fchan.vit_alpha = 1; fchan.vit_code_rate_hp = 2; fchan.vit_code_rate_lp = 2;
522 fchan.vit_hrch = 0; fchan.vit_select_hp = 1;
524 dib3000mc_set_channel_cfg(state, &fchan, reg);
526 reg = dib3000mc_read_word(state, 0);
527 dib3000mc_write_word(state, 0, reg | (1 << 8));
528 dib3000mc_read_word(state, 511);
529 dib3000mc_write_word(state, 0, reg);
534 static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod)
536 struct dib3000mc_state *state = demod->demodulator_priv;
537 u16 irq_pending = dib3000mc_read_word(state, 511);
539 if (irq_pending & 0x1) // failed
542 if (irq_pending & 0x2) // succeeded
545 return 0; // still pending
548 static int dib3000mc_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel *ch)
550 struct dib3000mc_state *state = demod->demodulator_priv;
552 // ** configure demod **
553 dib3000mc_set_channel_cfg(state, ch, 0);
556 dib3000mc_write_word(state, 29, 0x1073);
558 dib3000mc_set_adp_cfg(state, (u8)ch->nqam);
561 dib3000mc_write_word(state, 26, 38528);
562 dib3000mc_write_word(state, 33, 8);
564 dib3000mc_write_word(state, 26, 30336);
565 dib3000mc_write_word(state, 33, 6);
568 if (dib3000mc_read_word(state, 509) & 0x80)
569 dib3000mc_set_timing(state, ch->nfft, ch->Bw, 1);
574 struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating)
576 struct dib3000mc_state *st = demod->demodulator_priv;
577 return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating);
580 EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master);
582 static int dib3000mc_get_frontend(struct dvb_frontend* fe,
583 struct dvb_frontend_parameters *fep)
585 struct dib3000mc_state *state = fe->demodulator_priv;
586 u16 tps = dib3000mc_read_word(state,458);
588 fep->inversion = INVERSION_AUTO;
590 fep->u.ofdm.bandwidth = state->current_bandwidth;
592 switch ((tps >> 8) & 0x1) {
593 case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break;
594 case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break;
598 case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break;
599 case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break;
600 case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break;
601 case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break;
604 switch ((tps >> 13) & 0x3) {
605 case 0: fep->u.ofdm.constellation = QPSK; break;
606 case 1: fep->u.ofdm.constellation = QAM_16; break;
608 default: fep->u.ofdm.constellation = QAM_64; break;
611 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
612 /* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */
614 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
615 switch ((tps >> 5) & 0x7) {
616 case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break;
617 case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break;
618 case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break;
619 case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break;
621 default: fep->u.ofdm.code_rate_HP = FEC_7_8; break;
625 switch ((tps >> 2) & 0x7) {
626 case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break;
627 case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break;
628 case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break;
629 case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break;
631 default: fep->u.ofdm.code_rate_LP = FEC_7_8; break;
637 static int dib3000mc_set_frontend(struct dvb_frontend* fe,
638 struct dvb_frontend_parameters *fep)
640 struct dib3000mc_state *state = fe->demodulator_priv;
641 struct dibx000_ofdm_channel ch;
643 INIT_OFDM_CHANNEL(&ch);
646 state->current_bandwidth = fep->u.ofdm.bandwidth;
647 dib3000mc_set_bandwidth(fe, fep->u.ofdm.bandwidth);
649 if (fe->ops.tuner_ops.set_params) {
650 fe->ops.tuner_ops.set_params(fe, fep);
654 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
655 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ||
656 fep->u.ofdm.constellation == QAM_AUTO ||
657 fep->u.ofdm.code_rate_HP == FEC_AUTO) {
660 dib3000mc_autosearch_start(fe, &ch);
663 found = dib3000mc_autosearch_is_irq(fe);
664 } while (found == 0 && i--);
666 dprintk("autosearch returns: %d\n",found);
667 if (found == 0 || found == 1)
668 return 0; // no channel found
670 dib3000mc_get_frontend(fe, fep);
674 /* make this a config parameter */
675 dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
677 return dib3000mc_tune(fe, &ch);
680 static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat)
682 struct dib3000mc_state *state = fe->demodulator_priv;
683 u16 lock = dib3000mc_read_word(state, 509);
688 *stat |= FE_HAS_SIGNAL;
690 *stat |= FE_HAS_CARRIER;
692 *stat |= FE_HAS_VITERBI;
694 *stat |= FE_HAS_SYNC;
696 *stat |= FE_HAS_LOCK;
701 static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber)
703 struct dib3000mc_state *state = fe->demodulator_priv;
704 *ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501);
708 static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
710 struct dib3000mc_state *state = fe->demodulator_priv;
711 *unc = dib3000mc_read_word(state, 508);
715 static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
717 struct dib3000mc_state *state = fe->demodulator_priv;
718 u16 val = dib3000mc_read_word(state, 392);
719 *strength = 65535 - val;
723 static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
729 static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
731 tune->min_delay_ms = 1000;
735 static void dib3000mc_release(struct dvb_frontend *fe)
737 struct dib3000mc_state *state = fe->demodulator_priv;
738 dibx000_exit_i2c_master(&state->i2c_master);
742 int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff)
744 struct dib3000mc_state *state = fe->demodulator_priv;
745 dib3000mc_write_word(state, 212 + index, onoff ? (1 << 13) | pid : 0);
748 EXPORT_SYMBOL(dib3000mc_pid_control);
750 int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
752 struct dib3000mc_state *state = fe->demodulator_priv;
753 u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4);
755 return dib3000mc_write_word(state, 206, tmp);
757 EXPORT_SYMBOL(dib3000mc_pid_parse);
759 void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg)
761 struct dib3000mc_state *state = fe->demodulator_priv;
764 EXPORT_SYMBOL(dib3000mc_set_config);
766 int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[])
768 struct dib3000mc_state st = { .i2c_adap = i2c };
772 static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
774 for (k = no_of_demods-1; k >= 0; k--) {
777 /* designated i2c address */
778 new_addr = DIB3000MC_I2C_ADDRESS[k];
779 st.i2c_addr = new_addr;
780 if (dib3000mc_identify(&st) != 0) {
781 st.i2c_addr = default_addr;
782 if (dib3000mc_identify(&st) != 0) {
783 dprintk("-E- DiB3000P/MC #%d: not identified\n", k);
788 dib3000mc_set_output_mode(&st, OUTMODE_MPEG2_PAR_CONT_CLK);
790 // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
791 dib3000mc_write_word(&st, 1024, (new_addr << 3) | 0x1);
792 st.i2c_addr = new_addr;
795 for (k = 0; k < no_of_demods; k++) {
797 st.i2c_addr = DIB3000MC_I2C_ADDRESS[k];
799 dib3000mc_write_word(&st, 1024, st.i2c_addr << 3);
801 /* turn off data output */
802 dib3000mc_set_output_mode(&st, OUTMODE_HIGH_Z);
806 EXPORT_SYMBOL(dib3000mc_i2c_enumeration);
808 static struct dvb_frontend_ops dib3000mc_ops;
810 struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
812 struct dvb_frontend *demod;
813 struct dib3000mc_state *st;
814 st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
819 st->i2c_adap = i2c_adap;
820 st->i2c_addr = i2c_addr;
823 demod->demodulator_priv = st;
824 memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
826 if (dib3000mc_identify(st) != 0)
829 dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
837 EXPORT_SYMBOL(dib3000mc_attach);
839 static struct dvb_frontend_ops dib3000mc_ops = {
841 .name = "DiBcom 3000MC/P",
843 .frequency_min = 44250000,
844 .frequency_max = 867250000,
845 .frequency_stepsize = 62500,
846 .caps = FE_CAN_INVERSION_AUTO |
847 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
848 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
849 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
850 FE_CAN_TRANSMISSION_MODE_AUTO |
851 FE_CAN_GUARD_INTERVAL_AUTO |
853 FE_CAN_HIERARCHY_AUTO,
856 .release = dib3000mc_release,
858 .init = dib3000mc_init,
859 .sleep = dib3000mc_sleep,
861 .set_frontend = dib3000mc_set_frontend,
862 .get_tune_settings = dib3000mc_fe_get_tune_settings,
863 .get_frontend = dib3000mc_get_frontend,
865 .read_status = dib3000mc_read_status,
866 .read_ber = dib3000mc_read_ber,
867 .read_signal_strength = dib3000mc_read_signal_strength,
868 .read_snr = dib3000mc_read_snr,
869 .read_ucblocks = dib3000mc_read_unc_blocks,
872 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
873 MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator");
874 MODULE_LICENSE("GPL");