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;
73 static int dib3000mc_identify(struct dib3000mc_state *state)
76 if ((value = dib3000mc_read_word(state, 1025)) != 0x01b3) {
77 dprintk("-E- DiB3000MC/P: wrong Vendor ID (read=0x%x)\n",value);
81 value = dib3000mc_read_word(state, 1026);
82 if (value != 0x3001 && value != 0x3002) {
83 dprintk("-E- DiB3000MC/P: wrong Device ID (%x)\n",value);
86 state->dev_id = value;
88 dprintk("-I- found DiB3000MC/P: %x\n",state->dev_id);
93 static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u8 bw, u8 update_offset)
96 u32 timf_msb, timf_lsb, i;
98 LUInt comp1, comp2, comp ;
100 comp = 27700 * BW_INDEX_TO_KHZ(bw) / 1000;
101 timf_msb = (comp >> 16) & 0x00FF;
102 timf_lsb = comp & 0xFFFF;
104 // Update the timing offset ;
106 if (state->timing_offset_comp_done == 0) {
108 state->timing_offset_comp_done = 1;
110 tim_offset = dib3000mc_read_word(state, 416);
111 if ((tim_offset & 0x2000) == 0x2000)
112 tim_offset |= 0xC000; // PB: This only works if tim_offset is s16 - weird
115 tim_offset = tim_offset << 2; // PB: Do not store the offset for different things in one variable
116 state->timing_offset += tim_offset;
118 tim_offset = state->timing_offset;
120 if (tim_offset < 0) {
122 tim_offset = -tim_offset;
126 comp1 = tim_offset * timf_lsb;
127 comp2 = tim_offset * timf_msb;
128 comp = ((comp1 >> 16) + comp2) >> 7;
131 comp = timf_msb * (1<<16) + timf_lsb + comp;
133 comp = timf_msb * (1<<16) + timf_lsb - comp;
135 timf_msb = (comp>>16)&0xFF ;
136 timf_lsb = comp&0xFFFF;
138 u32 timf = 1384402 * (BW_INDEX_TO_KHZ(bw) / 1000);
140 dib3000mc_write_word(state, 23, timf >> 16);
141 dib3000mc_write_word(state, 24, timf & 0xffff);
146 static int dib3000mc_setup_pwm3_state(struct dib3000mc_state *state)
148 if (state->cfg->pwm3_inversion) {
149 dib3000mc_write_word(state, 51, (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0));
150 dib3000mc_write_word(state, 52, (0 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (2 << 0));
152 dib3000mc_write_word(state, 51, (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0));
153 dib3000mc_write_word(state, 52, (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0));
156 if (state->cfg->use_pwm3)
157 dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0));
159 dib3000mc_write_word(state, 245, 0);
161 dib3000mc_write_word(state, 1040, 0x3);
165 static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode)
168 u16 fifo_threshold = 1792;
172 u16 smo_reg = (0 << 6) | (0 << 5) | (0 << 3) | (1 << 1) | 0 |
173 (dib3000mc_read_word(state, 206) & 0x0010); /* keep the pid_parse bit */
175 dprintk("-I- Setting output mode for demod %p to %d\n",
176 &state->demod, mode);
179 case OUTMODE_HIGH_Z: // disable
182 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
185 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
188 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
191 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
194 P_smo_error_discard [1;6:6] = 0
195 P_smo_rs_discard [1;5:5] = 0
196 P_smo_pid_parse [1;4:4] = 0
197 P_smo_fifo_flush [1;3:3] = 0
198 P_smo_mode [2;2:1] = 11
199 P_smo_ovf_prot [1;0:0] = 0
201 smo_reg = (0 << 6) | (0 << 5) | (0 << 3) |(3 << 1) | 0;
202 fifo_threshold = 512;
205 case OUTMODE_DIVERSITY:
210 dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod);
215 if ((state->cfg->output_mpeg2_in_188_bytes))
216 smo_reg |= (1 << 5); // P_smo_rs_discard [1;5:5] = 1
218 outreg = dib3000mc_read_word(state, 244) & 0x07FF;
219 outreg |= (outmode << 11);
220 ret |= dib3000mc_write_word(state, 244, outreg);
221 ret |= dib3000mc_write_word(state, 206, smo_reg); /*smo_ mode*/
222 ret |= dib3000mc_write_word(state, 207, fifo_threshold); /* synchronous fread */
223 ret |= dib3000mc_write_word(state, 1040, elecout); /* P_out_cfg */
227 static int dib3000mc_set_bandwidth(struct dvb_frontend *demod, u8 bw)
229 struct dib3000mc_state *state = demod->demodulator_priv;
230 u16 bw_cfg[6] = { 0 };
231 u16 imp_bw_cfg[3] = { 0 };
234 /* settings here are for 27.7MHz */
236 case BANDWIDTH_8_MHZ:
237 bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20;
238 imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7;
241 case BANDWIDTH_7_MHZ:
242 bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7;
243 imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0;
246 case BANDWIDTH_6_MHZ:
247 bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5;
248 imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089;
251 case 255 /* BANDWIDTH_5_MHZ */:
252 bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500;
253 imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072;
256 default: return -EINVAL;
259 for (reg = 6; reg < 12; reg++)
260 dib3000mc_write_word(state, reg, bw_cfg[reg - 6]);
261 dib3000mc_write_word(state, 12, 0x0000);
262 dib3000mc_write_word(state, 13, 0x03e8);
263 dib3000mc_write_word(state, 14, 0x0000);
264 dib3000mc_write_word(state, 15, 0x03f2);
265 dib3000mc_write_word(state, 16, 0x0001);
266 dib3000mc_write_word(state, 17, 0xb0d0);
268 dib3000mc_write_word(state, 18, 0x0393);
269 dib3000mc_write_word(state, 19, 0x8700);
271 for (reg = 55; reg < 58; reg++)
272 dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]);
274 // Timing configuration
275 dib3000mc_set_timing(state, 0, bw, 0);
280 static u16 impulse_noise_val[29] =
283 0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, 0x3ffe, 0x7f3,
284 0x2d94, 0x76, 0x53d, 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, 0x3feb, 0x7d2,
285 0x365e, 0x76, 0x48c, 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0000, 0xd
288 static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft)
291 for (i = 58; i < 87; i++)
292 dib3000mc_write_word(state, i, impulse_noise_val[i-58]);
295 dib3000mc_write_word(state, 58, 0x3b);
296 dib3000mc_write_word(state, 84, 0x00);
297 dib3000mc_write_word(state, 85, 0x8200);
300 dib3000mc_write_word(state, 34, 0x1294);
301 dib3000mc_write_word(state, 35, 0x1ff8);
303 dib3000mc_write_word(state, 55, dib3000mc_read_word(state, 55) | (1 << 10));
306 static int dib3000mc_init(struct dvb_frontend *demod)
308 struct dib3000mc_state *state = demod->demodulator_priv;
309 struct dibx000_agc_config *agc = state->cfg->agc;
311 // Restart Configuration
312 dib3000mc_write_word(state, 1027, 0x8000);
313 dib3000mc_write_word(state, 1027, 0x0000);
315 // power up the demod + mobility configuration
316 dib3000mc_write_word(state, 140, 0x0000);
317 dib3000mc_write_word(state, 1031, 0);
319 if (state->cfg->mobile_mode) {
320 dib3000mc_write_word(state, 139, 0x0000);
321 dib3000mc_write_word(state, 141, 0x0000);
322 dib3000mc_write_word(state, 175, 0x0002);
323 dib3000mc_write_word(state, 1032, 0x0000);
325 dib3000mc_write_word(state, 139, 0x0001);
326 dib3000mc_write_word(state, 141, 0x0000);
327 dib3000mc_write_word(state, 175, 0x0000);
328 dib3000mc_write_word(state, 1032, 0x012C);
330 dib3000mc_write_word(state, 1033, 0);
333 dib3000mc_write_word(state, 1037, 12592);
335 // other configurations
338 dib3000mc_write_word(state, 33, (5 << 0));
339 dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0));
341 // Phase noise control
342 // P_fft_phacor_inh, P_fft_phacor_cpe, P_fft_powrange
343 dib3000mc_write_word(state, 99, (1 << 9) | (0x20 << 0));
345 if (state->cfg->phase_noise_mode == 0)
346 dib3000mc_write_word(state, 111, 0x00);
348 dib3000mc_write_word(state, 111, 0x02);
351 dib3000mc_write_word(state, 50, 0x8000);
354 dib3000mc_setup_pwm3_state(state);
356 // P_agc_counter_lock
357 dib3000mc_write_word(state, 53, 0x87);
358 // P_agc_counter_unlock
359 dib3000mc_write_word(state, 54, 0x87);
362 dib3000mc_write_word(state, 36, state->cfg->max_time);
363 dib3000mc_write_word(state, 37, agc->setup);
364 dib3000mc_write_word(state, 38, state->cfg->pwm3_value);
365 dib3000mc_write_word(state, 39, state->cfg->ln_adc_level);
368 dib3000mc_write_word(state, 40, 0x0179);
369 dib3000mc_write_word(state, 41, 0x03f0);
371 dib3000mc_write_word(state, 42, agc->agc1_max);
372 dib3000mc_write_word(state, 43, agc->agc1_min);
373 dib3000mc_write_word(state, 44, agc->agc2_max);
374 dib3000mc_write_word(state, 45, agc->agc2_min);
375 dib3000mc_write_word(state, 46, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
376 dib3000mc_write_word(state, 47, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
377 dib3000mc_write_word(state, 48, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
378 dib3000mc_write_word(state, 49, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
380 // Begin: TimeOut registers
382 dib3000mc_write_word(state, 110, 3277);
383 // P_timf_alpha = 6, P_corm_alpha = 6, P_corm_thres = 0x80
384 dib3000mc_write_word(state, 26, 0x6680);
386 dib3000mc_write_word(state, 1, 4);
388 dib3000mc_write_word(state, 2, 4);
390 dib3000mc_write_word(state, 3, 0x1000);
391 // P_search_maxtrial=1
392 dib3000mc_write_word(state, 5, 1);
394 dib3000mc_set_bandwidth(&state->demod, BANDWIDTH_8_MHZ);
397 dib3000mc_write_word(state, 4, 0x814);
399 dib3000mc_write_word(state, 21, (1 << 9) | 0x164);
400 dib3000mc_write_word(state, 22, 0x463d);
403 // P_cspu_regul, P_cspu_win_cut
404 dib3000mc_write_word(state, 120, 0x200f);
406 dib3000mc_write_word(state, 134, 0);
409 dib3000mc_write_word(state, 195, 0x10);
411 // diversity register: P_dvsy_sync_wait..
412 dib3000mc_write_word(state, 180, 0x2FF0);
414 // Impulse noise configuration
415 dib3000mc_set_impulse_noise(state, 0, 1);
417 // output mode set-up
418 dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
420 /* close the i2c-gate */
421 dib3000mc_write_word(state, 769, (1 << 7) );
426 static int dib3000mc_sleep(struct dvb_frontend *demod)
428 struct dib3000mc_state *state = demod->demodulator_priv;
430 dib3000mc_write_word(state, 1037, dib3000mc_read_word(state, 1037) | 0x0003);
431 dib3000mc_write_word(state, 1031, 0xFFFF);
432 dib3000mc_write_word(state, 1032, 0xFFFF);
433 dib3000mc_write_word(state, 1033, 0xFFF4); // **** Bin2
438 static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
440 u16 cfg[4] = { 0 },reg;
443 cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0;
446 cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0;
449 cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8;
452 for (reg = 129; reg < 133; reg++)
453 dib3000mc_write_word(state, reg, cfg[reg - 129]);
456 static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dibx000_ofdm_channel *chan, u16 seq)
460 dib3000mc_set_timing(state, chan->nfft, chan->Bw, 0);
463 // dib3000mc_write_word(state, 100, (11 << 6) + 6);
465 dib3000mc_write_word(state, 100, (16 << 6) + 9);
467 dib3000mc_write_word(state, 1027, 0x0800);
468 dib3000mc_write_word(state, 1027, 0x0000);
470 //Default cfg isi offset adp
471 dib3000mc_write_word(state, 26, 0x6680);
472 dib3000mc_write_word(state, 29, 0x1273);
473 dib3000mc_write_word(state, 33, 5);
474 dib3000mc_set_adp_cfg(state, 1);
475 dib3000mc_write_word(state, 133, 15564);
477 dib3000mc_write_word(state, 12 , 0x0);
478 dib3000mc_write_word(state, 13 , 0x3e8);
479 dib3000mc_write_word(state, 14 , 0x0);
480 dib3000mc_write_word(state, 15 , 0x3f2);
482 dib3000mc_write_word(state, 93,0);
483 dib3000mc_write_word(state, 94,0);
484 dib3000mc_write_word(state, 95,0);
485 dib3000mc_write_word(state, 96,0);
486 dib3000mc_write_word(state, 97,0);
487 dib3000mc_write_word(state, 98,0);
489 dib3000mc_set_impulse_noise(state, 0, chan->nfft);
491 tmp = ((chan->nfft & 0x1) << 7) | (chan->guard << 5) | (chan->nqam << 3) | chan->vit_alpha;
492 dib3000mc_write_word(state, 0, tmp);
494 dib3000mc_write_word(state, 5, seq);
496 tmp = (chan->vit_hrch << 4) | (chan->vit_select_hp);
497 if (!chan->vit_hrch || (chan->vit_hrch && chan->vit_select_hp))
498 tmp |= chan->vit_code_rate_hp << 1;
500 tmp |= chan->vit_code_rate_lp << 1;
501 dib3000mc_write_word(state, 181, tmp);
503 // diversity synchro delay
504 tmp = dib3000mc_read_word(state, 180) & 0x000f;
505 tmp |= ((chan->nfft == 0) ? 64 : 256) * ((1 << (chan->guard)) * 3 / 2) << 4; // add 50% SFN margin
506 dib3000mc_write_word(state, 180, tmp);
509 tmp = dib3000mc_read_word(state, 0);
510 dib3000mc_write_word(state, 0, tmp | (1 << 9));
511 dib3000mc_write_word(state, 0, tmp);
515 dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, chan->nfft);
518 static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dibx000_ofdm_channel *chan)
520 struct dib3000mc_state *state = demod->demodulator_priv;
523 struct dibx000_ofdm_channel fchan;
525 INIT_OFDM_CHANNEL(&fchan);
529 /* a channel for autosearch */
531 if (chan->nfft == -1 && chan->guard == -1) reg = 7;
532 if (chan->nfft == -1 && chan->guard != -1) reg = 2;
533 if (chan->nfft != -1 && chan->guard == -1) reg = 3;
535 fchan.nfft = 1; fchan.guard = 0; fchan.nqam = 2;
536 fchan.vit_alpha = 1; fchan.vit_code_rate_hp = 2; fchan.vit_code_rate_lp = 2;
537 fchan.vit_hrch = 0; fchan.vit_select_hp = 1;
539 dib3000mc_set_channel_cfg(state, &fchan, reg);
541 reg = dib3000mc_read_word(state, 0);
542 dib3000mc_write_word(state, 0, reg | (1 << 8));
543 dib3000mc_write_word(state, 0, reg);
548 static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod)
550 struct dib3000mc_state *state = demod->demodulator_priv;
551 u16 irq_pending = dib3000mc_read_word(state, 511);
553 if (irq_pending & 0x1) // failed
556 if (irq_pending & 0x2) // succeeded
559 return 0; // still pending
562 static int dib3000mc_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel *ch)
564 struct dib3000mc_state *state = demod->demodulator_priv;
566 // ** configure demod **
567 dib3000mc_set_channel_cfg(state, ch, 0);
570 dib3000mc_write_word(state, 29, 0x1073);
572 dib3000mc_set_adp_cfg(state, (u8)ch->nqam);
575 dib3000mc_write_word(state, 26, 38528);
576 dib3000mc_write_word(state, 33, 8);
578 dib3000mc_write_word(state, 26, 30336);
579 dib3000mc_write_word(state, 33, 6);
583 // dib3000mc_set_timing(state, ch->nfft, ch->Bw, 1);
588 static int dib3000mc_demod_output_mode(struct dvb_frontend *demod, int mode)
590 struct dib3000mc_state *state = demod->demodulator_priv;
591 return dib3000mc_set_output_mode(state, mode);
594 static int dib3000mc_i2c_enumeration(struct dvb_frontend *demod[], int no_of_demods, u8 default_addr)
596 struct dib3000mc_state *st;
600 static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
602 for (k = no_of_demods-1; k >= 0; k--) {
603 st = demod[k]->demodulator_priv;
605 /* designated i2c address */
606 new_addr = DIB3000MC_I2C_ADDRESS[k];
608 st->i2c_addr = new_addr;
609 if (dib3000mc_identify(st) != 0) {
610 st->i2c_addr = default_addr;
611 if (dib3000mc_identify(st) != 0) {
612 dprintk("-E- DiB3000P/MC #%d: not identified\n", k);
617 /* turn on div_out */
618 dib3000mc_demod_output_mode(demod[k], OUTMODE_MPEG2_PAR_CONT_CLK);
620 // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
621 ret |= dib3000mc_write_word(st, 1024, (new_addr << 3) | 0x1);
622 st->i2c_addr = new_addr;
625 for (k = 0; k < no_of_demods; k++) {
626 st = demod[k]->demodulator_priv;
628 ret |= dib3000mc_write_word(st, 1024, st->i2c_addr << 3);
630 /* turn off data output */
631 dib3000mc_demod_output_mode(demod[k],OUTMODE_HIGH_Z);
632 dib3000mc_write_word(st, 769, (1 << 7) );
638 struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating)
640 struct dib3000mc_state *st = demod->demodulator_priv;
641 return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating);
644 EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master);
646 static int dib3000mc_get_frontend(struct dvb_frontend* fe,
647 struct dvb_frontend_parameters *fep)
649 struct dib3000mc_state *state = fe->demodulator_priv;
650 u16 tps = dib3000mc_read_word(state,458);
652 fep->inversion = INVERSION_AUTO;
654 fep->u.ofdm.bandwidth = state->current_bandwidth;
656 switch ((tps >> 8) & 0x1) {
657 case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break;
658 case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break;
662 case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break;
663 case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break;
664 case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break;
665 case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break;
668 switch ((tps >> 13) & 0x3) {
669 case 0: fep->u.ofdm.constellation = QPSK; break;
670 case 1: fep->u.ofdm.constellation = QAM_16; break;
672 default: fep->u.ofdm.constellation = QAM_64; break;
675 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
676 /* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */
678 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
679 switch ((tps >> 5) & 0x7) {
680 case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break;
681 case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break;
682 case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break;
683 case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break;
685 default: fep->u.ofdm.code_rate_HP = FEC_7_8; break;
689 switch ((tps >> 2) & 0x7) {
690 case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break;
691 case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break;
692 case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break;
693 case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break;
695 default: fep->u.ofdm.code_rate_LP = FEC_7_8; break;
701 static int dib3000mc_set_frontend(struct dvb_frontend* fe,
702 struct dvb_frontend_parameters *fep)
704 struct dib3000mc_state *state = fe->demodulator_priv;
705 struct dibx000_ofdm_channel ch;
707 INIT_OFDM_CHANNEL(&ch);
710 state->current_bandwidth = fep->u.ofdm.bandwidth;
711 dib3000mc_set_bandwidth(fe, fep->u.ofdm.bandwidth);
713 if (fe->ops.tuner_ops.set_params) {
714 fe->ops.tuner_ops.set_params(fe, fep);
718 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
719 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ||
720 fep->u.ofdm.constellation == QAM_AUTO ||
721 fep->u.ofdm.code_rate_HP == FEC_AUTO) {
724 dib3000mc_autosearch_start(fe, &ch);
727 found = dib3000mc_autosearch_is_irq(fe);
728 } while (found == 0 && i--);
730 dprintk("autosearch returns: %d\n",found);
731 if (found == 0 || found == 1)
732 return 0; // no channel found
734 dib3000mc_get_frontend(fe, fep);
738 /* make this a config parameter */
739 dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
741 return dib3000mc_tune(fe, &ch);
744 static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat)
746 struct dib3000mc_state *state = fe->demodulator_priv;
747 u16 lock = dib3000mc_read_word(state, 509);
752 *stat |= FE_HAS_SIGNAL;
754 *stat |= FE_HAS_CARRIER;
756 *stat |= FE_HAS_VITERBI;
758 *stat |= FE_HAS_SYNC;
760 *stat |= FE_HAS_LOCK;
765 static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber)
767 struct dib3000mc_state *state = fe->demodulator_priv;
768 *ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501);
772 static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
774 struct dib3000mc_state *state = fe->demodulator_priv;
775 *unc = dib3000mc_read_word(state, 508);
779 static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
781 struct dib3000mc_state *state = fe->demodulator_priv;
782 u16 val = dib3000mc_read_word(state, 392);
783 *strength = 65535 - val;
787 static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
793 static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
795 tune->min_delay_ms = 1000;
799 static void dib3000mc_release(struct dvb_frontend *fe)
801 struct dib3000mc_state *state = fe->demodulator_priv;
802 dibx000_exit_i2c_master(&state->i2c_master);
806 int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff)
808 struct dib3000mc_state *state = fe->demodulator_priv;
809 dib3000mc_write_word(state, 212 + index, onoff ? (1 << 13) | pid : 0);
812 EXPORT_SYMBOL(dib3000mc_pid_control);
814 int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
816 struct dib3000mc_state *state = fe->demodulator_priv;
817 u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4);
819 return dib3000mc_write_word(state, 206, tmp);
821 EXPORT_SYMBOL(dib3000mc_pid_parse);
823 void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg)
825 struct dib3000mc_state *state = fe->demodulator_priv;
828 EXPORT_SYMBOL(dib3000mc_set_config);
830 static struct dvb_frontend_ops dib3000mc_ops;
832 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[])
834 struct dib3000mc_state *st;
837 if (no_of_demods < 1)
840 for (k = 0; k < no_of_demods; k++) {
841 st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
848 // st->gpio_val = cfg[k].gpio_val;
849 // st->gpio_dir = cfg[k].gpio_dir;
850 st->i2c_adap = i2c_adap;
852 demod[k] = &st->demod;
853 demod[k]->demodulator_priv = st;
854 memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
856 // INIT_COMPONENT_REGISTER_ACCESS(&st->register_access, 12, 16, dib7000p_register_read, dib7000p_register_write, st);
857 // demod[k]->register_access = &st->register_access;
861 if (dib3000mc_i2c_enumeration(demod,no_of_demods,default_addr) != 0)
864 st = demod[0]->demodulator_priv;
865 st->i2c_addr = default_addr;
866 if (dib3000mc_identify(st) != 0)
870 for (k = 0; k < num; k++) {
871 st = demod[k]->demodulator_priv;
872 dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
878 for (k = 0; k < num; k++) {
879 kfree(demod[k]->demodulator_priv);
885 EXPORT_SYMBOL(dib3000mc_attach);
887 static struct dvb_frontend_ops dib3000mc_ops = {
889 .name = "DiBcom 3000MC/P",
891 .frequency_min = 44250000,
892 .frequency_max = 867250000,
893 .frequency_stepsize = 62500,
894 .caps = FE_CAN_INVERSION_AUTO |
895 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
896 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
897 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
898 FE_CAN_TRANSMISSION_MODE_AUTO |
899 FE_CAN_GUARD_INTERVAL_AUTO |
901 FE_CAN_HIERARCHY_AUTO,
904 .release = dib3000mc_release,
906 .init = dib3000mc_init,
907 .sleep = dib3000mc_sleep,
909 .set_frontend = dib3000mc_set_frontend,
910 .get_tune_settings = dib3000mc_fe_get_tune_settings,
911 .get_frontend = dib3000mc_get_frontend,
913 .read_status = dib3000mc_read_status,
914 .read_ber = dib3000mc_read_ber,
915 .read_signal_strength = dib3000mc_read_signal_strength,
916 .read_snr = dib3000mc_read_snr,
917 .read_ucblocks = dib3000mc_read_unc_blocks,
920 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
921 MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator");
922 MODULE_LICENSE("GPL");