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;
40 fe_bandwidth_t current_bandwidth;
45 static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
47 u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
49 struct i2c_msg msg[2] = {
50 { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 },
51 { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
54 if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
55 dprintk("i2c read error on %d\n",reg);
57 return (rb[0] << 8) | rb[1];
60 static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
63 (reg >> 8) & 0xff, reg & 0xff,
64 (val >> 8) & 0xff, val & 0xff,
66 struct i2c_msg msg = {
67 .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
69 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
72 static void dump_fep(struct dibx000_ofdm_channel *cd)
74 printk(KERN_DEBUG "DiB3000MC: ");
76 case 1: printk("8K "); break;
77 case 2: printk("4K "); break;
78 case 0: printk("2K "); break;
79 default: printk("FFT_UNK "); break;
82 printk("1/%i ", 32 / (1 << cd->guard));
84 case 0: printk("QPSK "); break;
85 case 1: printk("16QAM "); break;
86 case 2: printk("64QAM "); break;
87 default: printk("QAM_UNK "); break;
89 printk("ALPHA %i ", cd->vit_alpha);
90 printk("Code Rate HP %i/%i ", cd->vit_code_rate_hp, cd->vit_code_rate_hp + 1);
91 printk("Code Rate LP %i/%i ", cd->vit_code_rate_lp, cd->vit_code_rate_lp + 1);
92 printk("HRCH %i\n", cd->vit_hrch);
96 static int dib3000mc_identify(struct dib3000mc_state *state)
99 if ((value = dib3000mc_read_word(state, 1025)) != 0x01b3) {
100 dprintk("-E- DiB3000MC/P: wrong Vendor ID (read=0x%x)\n",value);
104 value = dib3000mc_read_word(state, 1026);
105 if (value != 0x3001 && value != 0x3002) {
106 dprintk("-E- DiB3000MC/P: wrong Device ID (%x)\n",value);
109 state->dev_id = value;
111 dprintk("-I- found DiB3000MC/P: %x\n",state->dev_id);
116 static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u8 bw, u8 update_offset)
119 u32 timf_msb, timf_lsb, i;
121 LUInt comp1, comp2, comp ;
123 comp = 27700 * BW_INDEX_TO_KHZ(bw) / 1000;
124 timf_msb = (comp >> 16) & 0x00FF;
125 timf_lsb = comp & 0xFFFF;
127 // Update the timing offset ;
129 if (state->timing_offset_comp_done == 0) {
131 state->timing_offset_comp_done = 1;
133 tim_offset = dib3000mc_read_word(state, 416);
134 if ((tim_offset & 0x2000) == 0x2000)
135 tim_offset |= 0xC000; // PB: This only works if tim_offset is s16 - weird
138 tim_offset = tim_offset << 2; // PB: Do not store the offset for different things in one variable
139 state->timing_offset += tim_offset;
141 tim_offset = state->timing_offset;
143 if (tim_offset < 0) {
145 tim_offset = -tim_offset;
149 comp1 = tim_offset * timf_lsb;
150 comp2 = tim_offset * timf_msb;
151 comp = ((comp1 >> 16) + comp2) >> 7;
154 comp = timf_msb * (1<<16) + timf_lsb + comp;
156 comp = timf_msb * (1<<16) + timf_lsb - comp;
158 timf_msb = (comp>>16)&0xFF ;
159 timf_lsb = comp&0xFFFF;
161 u32 timf = 1384402 * (BW_INDEX_TO_KHZ(bw) / 1000);
163 dib3000mc_write_word(state, 23, timf >> 16);
164 dib3000mc_write_word(state, 24, timf & 0xffff);
169 static int dib3000mc_setup_pwm3_state(struct dib3000mc_state *state)
171 if (state->cfg->pwm3_inversion) {
172 dib3000mc_write_word(state, 51, (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0));
173 dib3000mc_write_word(state, 52, (0 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (2 << 0));
175 dib3000mc_write_word(state, 51, (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0));
176 dib3000mc_write_word(state, 52, (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0));
179 if (state->cfg->use_pwm3)
180 dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0));
182 dib3000mc_write_word(state, 245, 0);
184 dib3000mc_write_word(state, 1040, 0x3);
188 static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode)
191 u16 fifo_threshold = 1792;
195 u16 smo_reg = (0 << 6) | (0 << 5) | (0 << 4) | (0 << 3) | (1 << 1) | 0 ; //smo_mode = 1
197 dprintk("-I- Setting output mode for demod %p to %d\n",
198 &state->demod, mode);
201 case OUTMODE_HIGH_Z: // disable
204 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
207 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
210 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
213 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
216 P_smo_error_discard [1;6:6] = 0
217 P_smo_rs_discard [1;5:5] = 0
218 P_smo_pid_parse [1;4:4] = 0
219 P_smo_fifo_flush [1;3:3] = 0
220 P_smo_mode [2;2:1] = 11
221 P_smo_ovf_prot [1;0:0] = 0
223 smo_reg = (0 << 6) | (0 << 5) | (0 << 4) | (0 << 3) |(3 << 1) | 0;
224 fifo_threshold = 512;
227 case OUTMODE_DIVERSITY:
232 dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod);
237 if ((state->cfg->output_mpeg2_in_188_bytes))
238 smo_reg |= (1 << 5) ; //P_smo_rs_discard [1;5:5] = 1
240 outreg = dib3000mc_read_word(state, 244) & 0x07FF;
241 outreg |= (outmode << 11);
242 ret |= dib3000mc_write_word(state, 244, outreg);
243 ret |= dib3000mc_write_word(state, 206, smo_reg); /*smo_ mode*/
244 ret |= dib3000mc_write_word(state, 207, fifo_threshold); /* synchronous fread */
245 ret |= dib3000mc_write_word(state, 1040, elecout); /* P_out_cfg */
249 static int dib3000mc_set_bandwidth(struct dvb_frontend *demod, u8 bw)
251 struct dib3000mc_state *state = demod->demodulator_priv;
252 u16 bw_cfg[6] = { 0 };
253 u16 imp_bw_cfg[3] = { 0 };
256 /* settings here are for 27.7MHz */
258 case BANDWIDTH_8_MHZ:
259 bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20;
260 imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7;
263 case BANDWIDTH_7_MHZ:
264 bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7;
265 imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0;
268 case BANDWIDTH_6_MHZ:
269 bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5;
270 imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089;
273 case 255 /* BANDWIDTH_5_MHZ */:
274 bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500;
275 imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072;
278 default: return -EINVAL;
281 for (reg = 6; reg < 12; reg++)
282 dib3000mc_write_word(state, reg, bw_cfg[reg - 6]);
283 dib3000mc_write_word(state, 12, 0x0000);
284 dib3000mc_write_word(state, 13, 0x03e8);
285 dib3000mc_write_word(state, 14, 0x0000);
286 dib3000mc_write_word(state, 15, 0x03f2);
287 dib3000mc_write_word(state, 16, 0x0001);
288 dib3000mc_write_word(state, 17, 0xb0d0);
290 dib3000mc_write_word(state, 18, 0x0393);
291 dib3000mc_write_word(state, 19, 0x8700);
293 for (reg = 55; reg < 58; reg++)
294 dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]);
296 // Timing configuration
297 dib3000mc_set_timing(state, 0, bw, 0);
302 static u16 impulse_noise_val[29] =
305 0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, 0x3ffe, 0x7f3,
306 0x2d94, 0x76, 0x53d, 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, 0x3feb, 0x7d2,
307 0x365e, 0x76, 0x48c, 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0000, 0xd
310 static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft)
313 for (i = 58; i < 87; i++)
314 dib3000mc_write_word(state, i, impulse_noise_val[i-58]);
317 dib3000mc_write_word(state, 58, 0x3b);
318 dib3000mc_write_word(state, 84, 0x00);
319 dib3000mc_write_word(state, 85, 0x8200);
322 dib3000mc_write_word(state, 34, 0x1294);
323 dib3000mc_write_word(state, 35, 0x1ff8);
325 dib3000mc_write_word(state, 55, dib3000mc_read_word(state, 55) | (1 << 10));
328 static int dib3000mc_init(struct dvb_frontend *demod)
330 struct dib3000mc_state *state = demod->demodulator_priv;
331 struct dibx000_agc_config *agc = state->cfg->agc;
333 // Restart Configuration
334 dib3000mc_write_word(state, 1027, 0x8000);
335 dib3000mc_write_word(state, 1027, 0x0000);
337 // power up the demod + mobility configuration
338 dib3000mc_write_word(state, 140, 0x0000);
339 dib3000mc_write_word(state, 1031, 0);
341 if (state->cfg->mobile_mode) {
342 dib3000mc_write_word(state, 139, 0x0000);
343 dib3000mc_write_word(state, 141, 0x0000);
344 dib3000mc_write_word(state, 175, 0x0002);
345 dib3000mc_write_word(state, 1032, 0x0000);
347 dib3000mc_write_word(state, 139, 0x0001);
348 dib3000mc_write_word(state, 141, 0x0000);
349 dib3000mc_write_word(state, 175, 0x0000);
350 dib3000mc_write_word(state, 1032, 0x012C);
352 dib3000mc_write_word(state, 1033, 0);
355 dib3000mc_write_word(state, 1037, 12592);
357 // other configurations
360 dib3000mc_write_word(state, 33, (5 << 0));
361 dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0));
363 // Phase noise control
364 // P_fft_phacor_inh, P_fft_phacor_cpe, P_fft_powrange
365 dib3000mc_write_word(state, 99, (1 << 9) | (0x20 << 0));
367 if (state->cfg->phase_noise_mode == 0)
368 dib3000mc_write_word(state, 111, 0x00);
370 dib3000mc_write_word(state, 111, 0x02);
373 dib3000mc_write_word(state, 50, 0x8000);
376 dib3000mc_setup_pwm3_state(state);
378 // P_agc_counter_lock
379 dib3000mc_write_word(state, 53, 0x87);
380 // P_agc_counter_unlock
381 dib3000mc_write_word(state, 54, 0x87);
384 dib3000mc_write_word(state, 36, state->cfg->max_time);
385 dib3000mc_write_word(state, 37, agc->setup);
386 dib3000mc_write_word(state, 38, state->cfg->pwm3_value);
387 dib3000mc_write_word(state, 39, state->cfg->ln_adc_level);
390 dib3000mc_write_word(state, 40, 0x0179);
391 dib3000mc_write_word(state, 41, 0x03f0);
393 dib3000mc_write_word(state, 42, agc->agc1_max);
394 dib3000mc_write_word(state, 43, agc->agc1_min);
395 dib3000mc_write_word(state, 44, agc->agc2_max);
396 dib3000mc_write_word(state, 45, agc->agc2_min);
397 dib3000mc_write_word(state, 46, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
398 dib3000mc_write_word(state, 47, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
399 dib3000mc_write_word(state, 48, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
400 dib3000mc_write_word(state, 49, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
402 // Begin: TimeOut registers
404 dib3000mc_write_word(state, 110, 3277);
405 // P_timf_alpha = 6, P_corm_alpha = 6, P_corm_thres = 0x80
406 dib3000mc_write_word(state, 26, 0x6680);
408 dib3000mc_write_word(state, 1, 4);
410 dib3000mc_write_word(state, 2, 4);
412 dib3000mc_write_word(state, 3, 0x1000);
413 // P_search_maxtrial=1
414 dib3000mc_write_word(state, 5, 1);
416 dib3000mc_set_bandwidth(&state->demod, BANDWIDTH_8_MHZ);
419 dib3000mc_write_word(state, 4, 0x814);
421 dib3000mc_write_word(state, 21, (1 << 9) | 0x164);
422 dib3000mc_write_word(state, 22, 0x463d);
425 // P_cspu_regul, P_cspu_win_cut
426 dib3000mc_write_word(state, 120, 0x200f);
428 dib3000mc_write_word(state, 134, 0);
431 dib3000mc_write_word(state, 195, 0x10);
433 // diversity register: P_dvsy_sync_wait..
434 dib3000mc_write_word(state, 180, 0x2FF0);
436 // Impulse noise configuration
437 dib3000mc_set_impulse_noise(state, 0, 1);
439 // output mode set-up
440 dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
442 /* close the i2c-gate */
443 dib3000mc_write_word(state, 769, (1 << 7) );
448 static int dib3000mc_sleep(struct dvb_frontend *demod)
450 struct dib3000mc_state *state = demod->demodulator_priv;
452 dib3000mc_write_word(state, 1037, dib3000mc_read_word(state, 1037) | 0x0003);
453 dib3000mc_write_word(state, 1031, 0xFFFF);
454 dib3000mc_write_word(state, 1032, 0xFFFF);
455 dib3000mc_write_word(state, 1033, 0xFFF4); // **** Bin2
460 static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
462 u16 cfg[4] = { 0 },reg;
465 cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0;
468 cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0;
471 cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8;
474 for (reg = 129; reg < 133; reg++)
475 dib3000mc_write_word(state, reg, cfg[reg - 129]);
478 static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dibx000_ofdm_channel *chan, u16 seq)
482 dib3000mc_set_timing(state, chan->nfft, chan->Bw, 0);
485 // dib3000mc_write_word(state, 100, (11 << 6) + 6);
487 dib3000mc_write_word(state, 100, (16 << 6) + 9);
489 dib3000mc_write_word(state, 1027, 0x0800);
490 dib3000mc_write_word(state, 1027, 0x0000);
492 //Default cfg isi offset adp
493 dib3000mc_write_word(state, 26, 0x6680);
494 dib3000mc_write_word(state, 29, 0x1273);
495 dib3000mc_write_word(state, 33, 5);
496 dib3000mc_set_adp_cfg(state, 1);
497 dib3000mc_write_word(state, 133, 15564);
499 dib3000mc_write_word(state, 12 , 0x0);
500 dib3000mc_write_word(state, 13 , 0x3e8);
501 dib3000mc_write_word(state, 14 , 0x0);
502 dib3000mc_write_word(state, 15 , 0x3f2);
504 dib3000mc_write_word(state, 93,0);
505 dib3000mc_write_word(state, 94,0);
506 dib3000mc_write_word(state, 95,0);
507 dib3000mc_write_word(state, 96,0);
508 dib3000mc_write_word(state, 97,0);
509 dib3000mc_write_word(state, 98,0);
511 dib3000mc_set_impulse_noise(state, 0, chan->nfft);
513 tmp = ((chan->nfft & 0x1) << 7) | (chan->guard << 5) | (chan->nqam << 3) | chan->vit_alpha;
514 dib3000mc_write_word(state, 0, tmp);
516 dib3000mc_write_word(state, 5, seq);
518 tmp = (chan->vit_hrch << 4) | (chan->vit_select_hp);
519 if (!chan->vit_hrch || (chan->vit_hrch && chan->vit_select_hp))
520 tmp |= chan->vit_code_rate_hp << 1;
522 tmp |= chan->vit_code_rate_lp << 1;
523 dib3000mc_write_word(state, 181, tmp);
525 // diversity synchro delay
526 tmp = dib3000mc_read_word(state, 180) & 0x000f;
527 tmp |= ((chan->nfft == 0) ? 64 : 256) * ((1 << (chan->guard)) * 3 / 2) << 4; // add 50% SFN margin
528 dib3000mc_write_word(state, 180, tmp);
531 tmp = dib3000mc_read_word(state, 0);
532 dib3000mc_write_word(state, 0, tmp | (1 << 9));
533 dib3000mc_write_word(state, 0, tmp);
537 dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, chan->nfft);
540 static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dibx000_ofdm_channel *chan)
542 struct dib3000mc_state *state = demod->demodulator_priv;
545 struct dibx000_ofdm_channel fchan;
547 INIT_OFDM_CHANNEL(&fchan);
551 /* a channel for autosearch */
553 if (chan->nfft == -1 && chan->guard == -1) reg = 7;
554 if (chan->nfft == -1 && chan->guard != -1) reg = 2;
555 if (chan->nfft != -1 && chan->guard == -1) reg = 3;
557 fchan.nfft = 1; fchan.guard = 0; fchan.nqam = 2;
558 fchan.vit_alpha = 1; fchan.vit_code_rate_hp = 2; fchan.vit_code_rate_lp = 2;
559 fchan.vit_hrch = 0; fchan.vit_select_hp = 1;
561 dib3000mc_set_channel_cfg(state, &fchan, reg);
563 reg = dib3000mc_read_word(state, 0);
564 dib3000mc_write_word(state, 0, reg | (1 << 8));
565 dib3000mc_write_word(state, 0, reg);
570 static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod)
572 struct dib3000mc_state *state = demod->demodulator_priv;
573 u16 irq_pending = dib3000mc_read_word(state, 511);
575 if (irq_pending & 0x1) // failed
578 if (irq_pending & 0x2) // succeeded
581 return 0; // still pending
584 static int dib3000mc_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel *ch)
586 struct dib3000mc_state *state = demod->demodulator_priv;
588 // ** configure demod **
589 dib3000mc_set_channel_cfg(state, ch, 0);
592 dib3000mc_write_word(state, 29, 0x1073);
594 dib3000mc_set_adp_cfg(state, (u8)ch->nqam);
597 dib3000mc_write_word(state, 26, 38528);
598 dib3000mc_write_word(state, 33, 8);
600 dib3000mc_write_word(state, 26, 30336);
601 dib3000mc_write_word(state, 33, 6);
605 // dib3000mc_set_timing(state, ch->nfft, ch->Bw, 1);
610 static int dib3000mc_demod_output_mode(struct dvb_frontend *demod, int mode)
612 struct dib3000mc_state *state = demod->demodulator_priv;
613 return dib3000mc_set_output_mode(state, mode);
616 static int dib3000mc_i2c_enumeration(struct dvb_frontend *demod[], int no_of_demods, u8 default_addr)
618 struct dib3000mc_state *st;
622 static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
624 for (k = no_of_demods-1; k >= 0; k--) {
625 st = demod[k]->demodulator_priv;
627 /* designated i2c address */
628 new_addr = DIB3000MC_I2C_ADDRESS[k];
630 st->i2c_addr = new_addr;
631 if (dib3000mc_identify(st) != 0) {
632 st->i2c_addr = default_addr;
633 if (dib3000mc_identify(st) != 0) {
634 dprintk("-E- DiB3000P/MC #%d: not identified\n", k);
639 /* turn on div_out */
640 dib3000mc_demod_output_mode(demod[k], OUTMODE_MPEG2_PAR_CONT_CLK);
642 // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
643 ret |= dib3000mc_write_word(st, 1024, (new_addr << 3) | 0x1);
644 st->i2c_addr = new_addr;
647 for (k = 0; k < no_of_demods; k++) {
648 st = demod[k]->demodulator_priv;
650 ret |= dib3000mc_write_word(st, 1024, st->i2c_addr << 3);
652 /* turn off data output */
653 dib3000mc_demod_output_mode(demod[k],OUTMODE_HIGH_Z);
654 dib3000mc_write_word(st, 769, (1 << 7) );
660 struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating)
662 struct dib3000mc_state *st = demod->demodulator_priv;
663 return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating);
666 EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master);
668 static int dib3000mc_get_frontend(struct dvb_frontend* fe,
669 struct dvb_frontend_parameters *fep)
671 struct dib3000mc_state *state = fe->demodulator_priv;
672 u16 tps = dib3000mc_read_word(state,458);
674 fep->inversion = INVERSION_AUTO;
676 fep->u.ofdm.bandwidth = state->current_bandwidth;
678 switch ((tps >> 8) & 0x1) {
679 case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break;
680 case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break;
684 case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break;
685 case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break;
686 case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break;
687 case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break;
690 switch ((tps >> 13) & 0x3) {
691 case 0: fep->u.ofdm.constellation = QPSK; break;
692 case 1: fep->u.ofdm.constellation = QAM_16; break;
694 default: fep->u.ofdm.constellation = QAM_64; break;
697 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
698 /* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */
700 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
701 switch ((tps >> 5) & 0x7) {
702 case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break;
703 case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break;
704 case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break;
705 case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break;
707 default: fep->u.ofdm.code_rate_HP = FEC_7_8; break;
711 switch ((tps >> 2) & 0x7) {
712 case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break;
713 case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break;
714 case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break;
715 case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break;
717 default: fep->u.ofdm.code_rate_LP = FEC_7_8; break;
723 static int dib3000mc_set_frontend(struct dvb_frontend* fe,
724 struct dvb_frontend_parameters *fep)
726 struct dib3000mc_state *state = fe->demodulator_priv;
727 struct dibx000_ofdm_channel ch;
729 INIT_OFDM_CHANNEL(&ch);
734 state->current_bandwidth = fep->u.ofdm.bandwidth;
735 dib3000mc_set_bandwidth(fe, fep->u.ofdm.bandwidth);
737 if (fe->ops.tuner_ops.set_params) {
738 fe->ops.tuner_ops.set_params(fe, fep);
742 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
743 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ||
744 fep->u.ofdm.constellation == QAM_AUTO ||
745 fep->u.ofdm.code_rate_HP == FEC_AUTO) {
748 dib3000mc_autosearch_start(fe, &ch);
751 found = dib3000mc_autosearch_is_irq(fe);
752 } while (found == 0 && i--);
754 dprintk("autosearch returns: %d\n",found);
755 if (found == 0 || found == 1)
756 return 0; // no channel found
758 dib3000mc_get_frontend(fe, fep);
762 /* make this a config parameter */
763 dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
765 return dib3000mc_tune(fe, &ch);
768 static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat)
770 struct dib3000mc_state *state = fe->demodulator_priv;
771 u16 lock = dib3000mc_read_word(state, 509);
776 *stat |= FE_HAS_SIGNAL;
778 *stat |= FE_HAS_CARRIER;
780 *stat |= FE_HAS_VITERBI;
782 *stat |= FE_HAS_SYNC;
784 *stat |= FE_HAS_LOCK;
789 static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber)
791 struct dib3000mc_state *state = fe->demodulator_priv;
792 *ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501);
796 static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
798 struct dib3000mc_state *state = fe->demodulator_priv;
799 *unc = dib3000mc_read_word(state, 508);
803 static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
805 struct dib3000mc_state *state = fe->demodulator_priv;
806 u16 val = dib3000mc_read_word(state, 392);
807 *strength = 65535 - val;
811 static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
817 static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
819 tune->min_delay_ms = 1000;
823 static void dib3000mc_release(struct dvb_frontend *fe)
825 struct dib3000mc_state *state = fe->demodulator_priv;
826 dibx000_exit_i2c_master(&state->i2c_master);
830 int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff)
832 struct dib3000mc_state *state = fe->demodulator_priv;
833 dib3000mc_write_word(state, 212 + index, onoff ? (1 << 13) | pid : 0);
836 EXPORT_SYMBOL(dib3000mc_pid_control);
838 int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
840 struct dib3000mc_state *state = fe->demodulator_priv;
841 u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4);
843 return dib3000mc_write_word(state, 206, tmp);
845 EXPORT_SYMBOL(dib3000mc_pid_parse);
847 void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg)
849 struct dib3000mc_state *state = fe->demodulator_priv;
852 EXPORT_SYMBOL(dib3000mc_set_config);
854 static struct dvb_frontend_ops dib3000mc_ops;
856 int dib3000mc_attach(struct i2c_adapter *i2c_adap, int no_of_demods, u8 default_addr, u8 do_i2c_enum, struct dib3000mc_config cfg[], struct dvb_frontend *demod[])
858 struct dib3000mc_state *st;
861 if (no_of_demods < 1)
864 for (k = 0; k < no_of_demods; k++) {
865 st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
872 // st->gpio_val = cfg[k].gpio_val;
873 // st->gpio_dir = cfg[k].gpio_dir;
874 st->i2c_adap = i2c_adap;
876 demod[k] = &st->demod;
877 demod[k]->demodulator_priv = st;
878 memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
880 // INIT_COMPONENT_REGISTER_ACCESS(&st->register_access, 12, 16, dib7000p_register_read, dib7000p_register_write, st);
881 // demod[k]->register_access = &st->register_access;
885 if (dib3000mc_i2c_enumeration(demod,no_of_demods,default_addr) != 0)
888 st = demod[0]->demodulator_priv;
889 st->i2c_addr = default_addr;
890 if (dib3000mc_identify(st) != 0)
894 for (k = 0; k < num; k++) {
895 st = demod[k]->demodulator_priv;
896 dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
902 for (k = 0; k < num; k++)
903 kfree(demod[k]->demodulator_priv);
908 EXPORT_SYMBOL(dib3000mc_attach);
910 static struct dvb_frontend_ops dib3000mc_ops = {
912 .name = "DiBcom 3000MC/P",
914 .frequency_min = 44250000,
915 .frequency_max = 867250000,
916 .frequency_stepsize = 62500,
917 .caps = FE_CAN_INVERSION_AUTO |
918 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
919 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
920 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
921 FE_CAN_TRANSMISSION_MODE_AUTO |
922 FE_CAN_GUARD_INTERVAL_AUTO |
924 FE_CAN_HIERARCHY_AUTO,
927 .release = dib3000mc_release,
929 .init = dib3000mc_init,
930 .sleep = dib3000mc_sleep,
932 .set_frontend = dib3000mc_set_frontend,
933 .get_tune_settings = dib3000mc_fe_get_tune_settings,
934 .get_frontend = dib3000mc_get_frontend,
936 .read_status = dib3000mc_read_status,
937 .read_ber = dib3000mc_read_ber,
938 .read_signal_strength = dib3000mc_read_signal_strength,
939 .read_snr = dib3000mc_read_snr,
940 .read_ucblocks = dib3000mc_read_unc_blocks,
943 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
944 MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator");
945 MODULE_LICENSE("GPL");