GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / media / dvb / frontends / dib3000mc.c
blob088e7fadbe3db11d01828606ed478096086c5c51
1 /*
2 * Driver for DiBcom DiB3000MC/P-demodulator.
4 * Copyright (C) 2004-7 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/slab.h>
16 #include <linux/i2c.h>
18 #include "dvb_frontend.h"
20 #include "dib3000mc.h"
22 static int debug;
23 module_param(debug, int, 0644);
24 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
26 static int buggy_sfn_workaround;
27 module_param(buggy_sfn_workaround, int, 0644);
28 MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
30 #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); printk("\n"); } } while (0)
32 struct dib3000mc_state {
33 struct dvb_frontend demod;
34 struct dib3000mc_config *cfg;
36 u8 i2c_addr;
37 struct i2c_adapter *i2c_adap;
39 struct dibx000_i2c_master i2c_master;
41 u32 timf;
43 fe_bandwidth_t current_bandwidth;
45 u16 dev_id;
47 u8 sfn_workaround_active :1;
50 static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
52 u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
53 u8 rb[2];
54 struct i2c_msg msg[2] = {
55 { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 },
56 { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
59 if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
60 dprintk("i2c read error on %d\n",reg);
62 return (rb[0] << 8) | rb[1];
65 static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
67 u8 b[4] = {
68 (reg >> 8) & 0xff, reg & 0xff,
69 (val >> 8) & 0xff, val & 0xff,
71 struct i2c_msg msg = {
72 .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
74 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
77 static int dib3000mc_identify(struct dib3000mc_state *state)
79 u16 value;
80 if ((value = dib3000mc_read_word(state, 1025)) != 0x01b3) {
81 dprintk("-E- DiB3000MC/P: wrong Vendor ID (read=0x%x)\n",value);
82 return -EREMOTEIO;
85 value = dib3000mc_read_word(state, 1026);
86 if (value != 0x3001 && value != 0x3002) {
87 dprintk("-E- DiB3000MC/P: wrong Device ID (%x)\n",value);
88 return -EREMOTEIO;
90 state->dev_id = value;
92 dprintk("-I- found DiB3000MC/P: %x\n",state->dev_id);
94 return 0;
97 static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u32 bw, u8 update_offset)
99 u32 timf;
101 if (state->timf == 0) {
102 timf = 1384402; // default value for 8MHz
103 if (update_offset)
104 msleep(200); // first time we do an update
105 } else
106 timf = state->timf;
108 timf *= (bw / 1000);
110 if (update_offset) {
111 s16 tim_offs = dib3000mc_read_word(state, 416);
113 if (tim_offs & 0x2000)
114 tim_offs -= 0x4000;
116 if (nfft == TRANSMISSION_MODE_2K)
117 tim_offs *= 4;
119 timf += tim_offs;
120 state->timf = timf / (bw / 1000);
123 dprintk("timf: %d\n", timf);
125 dib3000mc_write_word(state, 23, (u16) (timf >> 16));
126 dib3000mc_write_word(state, 24, (u16) (timf ) & 0xffff);
128 return 0;
131 static int dib3000mc_setup_pwm_state(struct dib3000mc_state *state)
133 u16 reg_51, reg_52 = state->cfg->agc->setup & 0xfefb;
134 if (state->cfg->pwm3_inversion) {
135 reg_51 = (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
136 reg_52 |= (1 << 2);
137 } else {
138 reg_51 = (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
139 reg_52 |= (1 << 8);
141 dib3000mc_write_word(state, 51, reg_51);
142 dib3000mc_write_word(state, 52, reg_52);
144 if (state->cfg->use_pwm3)
145 dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0));
146 else
147 dib3000mc_write_word(state, 245, 0);
149 dib3000mc_write_word(state, 1040, 0x3);
150 return 0;
153 static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode)
155 int ret = 0;
156 u16 fifo_threshold = 1792;
157 u16 outreg = 0;
158 u16 outmode = 0;
159 u16 elecout = 1;
160 u16 smo_reg = dib3000mc_read_word(state, 206) & 0x0010; /* keep the pid_parse bit */
162 dprintk("-I- Setting output mode for demod %p to %d\n",
163 &state->demod, mode);
165 switch (mode) {
166 case OUTMODE_HIGH_Z: // disable
167 elecout = 0;
168 break;
169 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
170 outmode = 0;
171 break;
172 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
173 outmode = 1;
174 break;
175 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
176 outmode = 2;
177 break;
178 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
179 elecout = 3;
180 /*ADDR @ 206 :
181 P_smo_error_discard [1;6:6] = 0
182 P_smo_rs_discard [1;5:5] = 0
183 P_smo_pid_parse [1;4:4] = 0
184 P_smo_fifo_flush [1;3:3] = 0
185 P_smo_mode [2;2:1] = 11
186 P_smo_ovf_prot [1;0:0] = 0
188 smo_reg |= 3 << 1;
189 fifo_threshold = 512;
190 outmode = 5;
191 break;
192 case OUTMODE_DIVERSITY:
193 outmode = 4;
194 elecout = 1;
195 break;
196 default:
197 dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod);
198 outmode = 0;
199 break;
202 if ((state->cfg->output_mpeg2_in_188_bytes))
203 smo_reg |= (1 << 5); // P_smo_rs_discard [1;5:5] = 1
205 outreg = dib3000mc_read_word(state, 244) & 0x07FF;
206 outreg |= (outmode << 11);
207 ret |= dib3000mc_write_word(state, 244, outreg);
208 ret |= dib3000mc_write_word(state, 206, smo_reg); /*smo_ mode*/
209 ret |= dib3000mc_write_word(state, 207, fifo_threshold); /* synchronous fread */
210 ret |= dib3000mc_write_word(state, 1040, elecout); /* P_out_cfg */
211 return ret;
214 static int dib3000mc_set_bandwidth(struct dib3000mc_state *state, u32 bw)
216 u16 bw_cfg[6] = { 0 };
217 u16 imp_bw_cfg[3] = { 0 };
218 u16 reg;
220 /* settings here are for 27.7MHz */
221 switch (bw) {
222 case 8000:
223 bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20;
224 imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7;
225 break;
227 case 7000:
228 bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7;
229 imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0;
230 break;
232 case 6000:
233 bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5;
234 imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089;
235 break;
237 case 5000:
238 bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500;
239 imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072;
240 break;
242 default: return -EINVAL;
245 for (reg = 6; reg < 12; reg++)
246 dib3000mc_write_word(state, reg, bw_cfg[reg - 6]);
247 dib3000mc_write_word(state, 12, 0x0000);
248 dib3000mc_write_word(state, 13, 0x03e8);
249 dib3000mc_write_word(state, 14, 0x0000);
250 dib3000mc_write_word(state, 15, 0x03f2);
251 dib3000mc_write_word(state, 16, 0x0001);
252 dib3000mc_write_word(state, 17, 0xb0d0);
253 // P_sec_len
254 dib3000mc_write_word(state, 18, 0x0393);
255 dib3000mc_write_word(state, 19, 0x8700);
257 for (reg = 55; reg < 58; reg++)
258 dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]);
260 // Timing configuration
261 dib3000mc_set_timing(state, TRANSMISSION_MODE_2K, bw, 0);
263 return 0;
266 static u16 impulse_noise_val[29] =
269 0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, 0x3ffe, 0x7f3,
270 0x2d94, 0x76, 0x53d, 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, 0x3feb, 0x7d2,
271 0x365e, 0x76, 0x48c, 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0000, 0xd
274 static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft)
276 u16 i;
277 for (i = 58; i < 87; i++)
278 dib3000mc_write_word(state, i, impulse_noise_val[i-58]);
280 if (nfft == TRANSMISSION_MODE_8K) {
281 dib3000mc_write_word(state, 58, 0x3b);
282 dib3000mc_write_word(state, 84, 0x00);
283 dib3000mc_write_word(state, 85, 0x8200);
286 dib3000mc_write_word(state, 34, 0x1294);
287 dib3000mc_write_word(state, 35, 0x1ff8);
288 if (mode == 1)
289 dib3000mc_write_word(state, 55, dib3000mc_read_word(state, 55) | (1 << 10));
292 static int dib3000mc_init(struct dvb_frontend *demod)
294 struct dib3000mc_state *state = demod->demodulator_priv;
295 struct dibx000_agc_config *agc = state->cfg->agc;
297 // Restart Configuration
298 dib3000mc_write_word(state, 1027, 0x8000);
299 dib3000mc_write_word(state, 1027, 0x0000);
301 // power up the demod + mobility configuration
302 dib3000mc_write_word(state, 140, 0x0000);
303 dib3000mc_write_word(state, 1031, 0);
305 if (state->cfg->mobile_mode) {
306 dib3000mc_write_word(state, 139, 0x0000);
307 dib3000mc_write_word(state, 141, 0x0000);
308 dib3000mc_write_word(state, 175, 0x0002);
309 dib3000mc_write_word(state, 1032, 0x0000);
310 } else {
311 dib3000mc_write_word(state, 139, 0x0001);
312 dib3000mc_write_word(state, 141, 0x0000);
313 dib3000mc_write_word(state, 175, 0x0000);
314 dib3000mc_write_word(state, 1032, 0x012C);
316 dib3000mc_write_word(state, 1033, 0x0000);
318 // P_clk_cfg
319 dib3000mc_write_word(state, 1037, 0x3130);
321 // other configurations
323 // P_ctrl_sfreq
324 dib3000mc_write_word(state, 33, (5 << 0));
325 dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0));
327 // Phase noise control
328 // P_fft_phacor_inh, P_fft_phacor_cpe, P_fft_powrange
329 dib3000mc_write_word(state, 99, (1 << 9) | (0x20 << 0));
331 if (state->cfg->phase_noise_mode == 0)
332 dib3000mc_write_word(state, 111, 0x00);
333 else
334 dib3000mc_write_word(state, 111, 0x02);
336 // P_agc_global
337 dib3000mc_write_word(state, 50, 0x8000);
339 // agc setup misc
340 dib3000mc_setup_pwm_state(state);
342 // P_agc_counter_lock
343 dib3000mc_write_word(state, 53, 0x87);
344 // P_agc_counter_unlock
345 dib3000mc_write_word(state, 54, 0x87);
347 /* agc */
348 dib3000mc_write_word(state, 36, state->cfg->max_time);
349 dib3000mc_write_word(state, 37, (state->cfg->agc_command1 << 13) | (state->cfg->agc_command2 << 12) | (0x1d << 0));
350 dib3000mc_write_word(state, 38, state->cfg->pwm3_value);
351 dib3000mc_write_word(state, 39, state->cfg->ln_adc_level);
353 // set_agc_loop_Bw
354 dib3000mc_write_word(state, 40, 0x0179);
355 dib3000mc_write_word(state, 41, 0x03f0);
357 dib3000mc_write_word(state, 42, agc->agc1_max);
358 dib3000mc_write_word(state, 43, agc->agc1_min);
359 dib3000mc_write_word(state, 44, agc->agc2_max);
360 dib3000mc_write_word(state, 45, agc->agc2_min);
361 dib3000mc_write_word(state, 46, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
362 dib3000mc_write_word(state, 47, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
363 dib3000mc_write_word(state, 48, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
364 dib3000mc_write_word(state, 49, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
366 // Begin: TimeOut registers
367 // P_pha3_thres
368 dib3000mc_write_word(state, 110, 3277);
369 // P_timf_alpha = 6, P_corm_alpha = 6, P_corm_thres = 0x80
370 dib3000mc_write_word(state, 26, 0x6680);
371 // lock_mask0
372 dib3000mc_write_word(state, 1, 4);
373 // lock_mask1
374 dib3000mc_write_word(state, 2, 4);
375 // lock_mask2
376 dib3000mc_write_word(state, 3, 0x1000);
377 // P_search_maxtrial=1
378 dib3000mc_write_word(state, 5, 1);
380 dib3000mc_set_bandwidth(state, 8000);
382 // div_lock_mask
383 dib3000mc_write_word(state, 4, 0x814);
385 dib3000mc_write_word(state, 21, (1 << 9) | 0x164);
386 dib3000mc_write_word(state, 22, 0x463d);
388 // Spurious rm cfg
389 // P_cspu_regul, P_cspu_win_cut
390 dib3000mc_write_word(state, 120, 0x200f);
391 // P_adp_selec_monit
392 dib3000mc_write_word(state, 134, 0);
394 // Fec cfg
395 dib3000mc_write_word(state, 195, 0x10);
397 // diversity register: P_dvsy_sync_wait..
398 dib3000mc_write_word(state, 180, 0x2FF0);
400 // Impulse noise configuration
401 dib3000mc_set_impulse_noise(state, 0, TRANSMISSION_MODE_8K);
403 // output mode set-up
404 dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
406 /* close the i2c-gate */
407 dib3000mc_write_word(state, 769, (1 << 7) );
409 return 0;
412 static int dib3000mc_sleep(struct dvb_frontend *demod)
414 struct dib3000mc_state *state = demod->demodulator_priv;
416 dib3000mc_write_word(state, 1031, 0xFFFF);
417 dib3000mc_write_word(state, 1032, 0xFFFF);
418 dib3000mc_write_word(state, 1033, 0xFFF0);
420 return 0;
423 static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
425 u16 cfg[4] = { 0 },reg;
426 switch (qam) {
427 case QPSK:
428 cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0;
429 break;
430 case QAM_16:
431 cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0;
432 break;
433 case QAM_64:
434 cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8;
435 break;
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 dvb_frontend_parameters *ch, u16 seq)
443 u16 value;
444 dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
445 dib3000mc_set_timing(state, ch->u.ofdm.transmission_mode, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth), 0);
447 // if (boost)
448 // dib3000mc_write_word(state, 100, (11 << 6) + 6);
449 // else
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, QAM_16);
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, ch->u.ofdm.transmission_mode);
476 value = 0;
477 switch (ch->u.ofdm.transmission_mode) {
478 case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
479 default:
480 case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
482 switch (ch->u.ofdm.guard_interval) {
483 case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
484 case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
485 case GUARD_INTERVAL_1_4: value |= (3 << 5); break;
486 default:
487 case GUARD_INTERVAL_1_8: value |= (2 << 5); break;
489 switch (ch->u.ofdm.constellation) {
490 case QPSK: value |= (0 << 3); break;
491 case QAM_16: value |= (1 << 3); break;
492 default:
493 case QAM_64: value |= (2 << 3); break;
495 switch (HIERARCHY_1) {
496 case HIERARCHY_2: value |= 2; break;
497 case HIERARCHY_4: value |= 4; break;
498 default:
499 case HIERARCHY_1: value |= 1; break;
501 dib3000mc_write_word(state, 0, value);
502 dib3000mc_write_word(state, 5, (1 << 8) | ((seq & 0xf) << 4));
504 value = 0;
505 if (ch->u.ofdm.hierarchy_information == 1)
506 value |= (1 << 4);
507 if (1 == 1)
508 value |= 1;
509 switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
510 case FEC_2_3: value |= (2 << 1); break;
511 case FEC_3_4: value |= (3 << 1); break;
512 case FEC_5_6: value |= (5 << 1); break;
513 case FEC_7_8: value |= (7 << 1); break;
514 default:
515 case FEC_1_2: value |= (1 << 1); break;
517 dib3000mc_write_word(state, 181, value);
519 // diversity synchro delay add 50% SFN margin
520 switch (ch->u.ofdm.transmission_mode) {
521 case TRANSMISSION_MODE_8K: value = 256; break;
522 case TRANSMISSION_MODE_2K:
523 default: value = 64; break;
525 switch (ch->u.ofdm.guard_interval) {
526 case GUARD_INTERVAL_1_16: value *= 2; break;
527 case GUARD_INTERVAL_1_8: value *= 4; break;
528 case GUARD_INTERVAL_1_4: value *= 8; break;
529 default:
530 case GUARD_INTERVAL_1_32: value *= 1; break;
532 value <<= 4;
533 value |= dib3000mc_read_word(state, 180) & 0x000f;
534 dib3000mc_write_word(state, 180, value);
536 // restart demod
537 value = dib3000mc_read_word(state, 0);
538 dib3000mc_write_word(state, 0, value | (1 << 9));
539 dib3000mc_write_word(state, 0, value);
541 msleep(30);
543 dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, ch->u.ofdm.transmission_mode);
546 static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *chan)
548 struct dib3000mc_state *state = demod->demodulator_priv;
549 u16 reg;
550 // u32 val;
551 struct dvb_frontend_parameters schan;
553 schan = *chan;
555 /* TODO what is that ? */
557 /* a channel for autosearch */
558 schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
559 schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
560 schan.u.ofdm.constellation = QAM_64;
561 schan.u.ofdm.code_rate_HP = FEC_2_3;
562 schan.u.ofdm.code_rate_LP = FEC_2_3;
563 schan.u.ofdm.hierarchy_information = 0;
565 dib3000mc_set_channel_cfg(state, &schan, 11);
567 reg = dib3000mc_read_word(state, 0);
568 dib3000mc_write_word(state, 0, reg | (1 << 8));
569 dib3000mc_read_word(state, 511);
570 dib3000mc_write_word(state, 0, reg);
572 return 0;
575 static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod)
577 struct dib3000mc_state *state = demod->demodulator_priv;
578 u16 irq_pending = dib3000mc_read_word(state, 511);
580 if (irq_pending & 0x1) // failed
581 return 1;
583 if (irq_pending & 0x2) // succeeded
584 return 2;
586 return 0; // still pending
589 static int dib3000mc_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
591 struct dib3000mc_state *state = demod->demodulator_priv;
593 // ** configure demod **
594 dib3000mc_set_channel_cfg(state, ch, 0);
596 // activates isi
597 if (state->sfn_workaround_active) {
598 dprintk("SFN workaround is active\n");
599 dib3000mc_write_word(state, 29, 0x1273);
600 dib3000mc_write_word(state, 108, 0x4000); // P_pha3_force_pha_shift
601 } else {
602 dib3000mc_write_word(state, 29, 0x1073);
603 dib3000mc_write_word(state, 108, 0x0000); // P_pha3_force_pha_shift
606 dib3000mc_set_adp_cfg(state, (u8)ch->u.ofdm.constellation);
607 if (ch->u.ofdm.transmission_mode == TRANSMISSION_MODE_8K) {
608 dib3000mc_write_word(state, 26, 38528);
609 dib3000mc_write_word(state, 33, 8);
610 } else {
611 dib3000mc_write_word(state, 26, 30336);
612 dib3000mc_write_word(state, 33, 6);
615 if (dib3000mc_read_word(state, 509) & 0x80)
616 dib3000mc_set_timing(state, ch->u.ofdm.transmission_mode, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth), 1);
618 return 0;
621 struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating)
623 struct dib3000mc_state *st = demod->demodulator_priv;
624 return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating);
627 EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master);
629 static int dib3000mc_get_frontend(struct dvb_frontend* fe,
630 struct dvb_frontend_parameters *fep)
632 struct dib3000mc_state *state = fe->demodulator_priv;
633 u16 tps = dib3000mc_read_word(state,458);
635 fep->inversion = INVERSION_AUTO;
637 fep->u.ofdm.bandwidth = state->current_bandwidth;
639 switch ((tps >> 8) & 0x1) {
640 case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break;
641 case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break;
644 switch (tps & 0x3) {
645 case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break;
646 case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break;
647 case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break;
648 case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break;
651 switch ((tps >> 13) & 0x3) {
652 case 0: fep->u.ofdm.constellation = QPSK; break;
653 case 1: fep->u.ofdm.constellation = QAM_16; break;
654 case 2:
655 default: fep->u.ofdm.constellation = QAM_64; break;
658 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
659 /* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */
661 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
662 switch ((tps >> 5) & 0x7) {
663 case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break;
664 case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break;
665 case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break;
666 case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break;
667 case 7:
668 default: fep->u.ofdm.code_rate_HP = FEC_7_8; break;
672 switch ((tps >> 2) & 0x7) {
673 case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break;
674 case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break;
675 case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break;
676 case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break;
677 case 7:
678 default: fep->u.ofdm.code_rate_LP = FEC_7_8; break;
681 return 0;
684 static int dib3000mc_set_frontend(struct dvb_frontend* fe,
685 struct dvb_frontend_parameters *fep)
687 struct dib3000mc_state *state = fe->demodulator_priv;
688 int ret;
690 dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
692 state->current_bandwidth = fep->u.ofdm.bandwidth;
693 dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth));
695 /* maybe the parameter has been changed */
696 state->sfn_workaround_active = buggy_sfn_workaround;
698 if (fe->ops.tuner_ops.set_params) {
699 fe->ops.tuner_ops.set_params(fe, fep);
700 msleep(100);
703 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
704 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ||
705 fep->u.ofdm.constellation == QAM_AUTO ||
706 fep->u.ofdm.code_rate_HP == FEC_AUTO) {
707 int i = 1000, found;
709 dib3000mc_autosearch_start(fe, fep);
710 do {
711 msleep(1);
712 found = dib3000mc_autosearch_is_irq(fe);
713 } while (found == 0 && i--);
715 dprintk("autosearch returns: %d\n",found);
716 if (found == 0 || found == 1)
717 return 0; // no channel found
719 dib3000mc_get_frontend(fe, fep);
722 ret = dib3000mc_tune(fe, fep);
724 /* make this a config parameter */
725 dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
726 return ret;
729 static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat)
731 struct dib3000mc_state *state = fe->demodulator_priv;
732 u16 lock = dib3000mc_read_word(state, 509);
734 *stat = 0;
736 if (lock & 0x8000)
737 *stat |= FE_HAS_SIGNAL;
738 if (lock & 0x3000)
739 *stat |= FE_HAS_CARRIER;
740 if (lock & 0x0100)
741 *stat |= FE_HAS_VITERBI;
742 if (lock & 0x0010)
743 *stat |= FE_HAS_SYNC;
744 if (lock & 0x0008)
745 *stat |= FE_HAS_LOCK;
747 return 0;
750 static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber)
752 struct dib3000mc_state *state = fe->demodulator_priv;
753 *ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501);
754 return 0;
757 static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
759 struct dib3000mc_state *state = fe->demodulator_priv;
760 *unc = dib3000mc_read_word(state, 508);
761 return 0;
764 static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
766 struct dib3000mc_state *state = fe->demodulator_priv;
767 u16 val = dib3000mc_read_word(state, 392);
768 *strength = 65535 - val;
769 return 0;
772 static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
774 *snr = 0x0000;
775 return 0;
778 static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
780 tune->min_delay_ms = 1000;
781 return 0;
784 static void dib3000mc_release(struct dvb_frontend *fe)
786 struct dib3000mc_state *state = fe->demodulator_priv;
787 dibx000_exit_i2c_master(&state->i2c_master);
788 kfree(state);
791 int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff)
793 struct dib3000mc_state *state = fe->demodulator_priv;
794 dib3000mc_write_word(state, 212 + index, onoff ? (1 << 13) | pid : 0);
795 return 0;
797 EXPORT_SYMBOL(dib3000mc_pid_control);
799 int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
801 struct dib3000mc_state *state = fe->demodulator_priv;
802 u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4);
803 tmp |= (onoff << 4);
804 return dib3000mc_write_word(state, 206, tmp);
806 EXPORT_SYMBOL(dib3000mc_pid_parse);
808 void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg)
810 struct dib3000mc_state *state = fe->demodulator_priv;
811 state->cfg = cfg;
813 EXPORT_SYMBOL(dib3000mc_set_config);
815 int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[])
817 struct dib3000mc_state *dmcst;
818 int k;
819 u8 new_addr;
821 static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
823 dmcst = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
824 if (dmcst == NULL)
825 return -ENOMEM;
827 dmcst->i2c_adap = i2c;
829 for (k = no_of_demods-1; k >= 0; k--) {
830 dmcst->cfg = &cfg[k];
832 /* designated i2c address */
833 new_addr = DIB3000MC_I2C_ADDRESS[k];
834 dmcst->i2c_addr = new_addr;
835 if (dib3000mc_identify(dmcst) != 0) {
836 dmcst->i2c_addr = default_addr;
837 if (dib3000mc_identify(dmcst) != 0) {
838 dprintk("-E- DiB3000P/MC #%d: not identified\n", k);
839 kfree(dmcst);
840 return -ENODEV;
844 dib3000mc_set_output_mode(dmcst, OUTMODE_MPEG2_PAR_CONT_CLK);
846 // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
847 dib3000mc_write_word(dmcst, 1024, (new_addr << 3) | 0x1);
848 dmcst->i2c_addr = new_addr;
851 for (k = 0; k < no_of_demods; k++) {
852 dmcst->cfg = &cfg[k];
853 dmcst->i2c_addr = DIB3000MC_I2C_ADDRESS[k];
855 dib3000mc_write_word(dmcst, 1024, dmcst->i2c_addr << 3);
857 /* turn off data output */
858 dib3000mc_set_output_mode(dmcst, OUTMODE_HIGH_Z);
861 kfree(dmcst);
862 return 0;
864 EXPORT_SYMBOL(dib3000mc_i2c_enumeration);
866 static struct dvb_frontend_ops dib3000mc_ops;
868 struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
870 struct dvb_frontend *demod;
871 struct dib3000mc_state *st;
872 st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
873 if (st == NULL)
874 return NULL;
876 st->cfg = cfg;
877 st->i2c_adap = i2c_adap;
878 st->i2c_addr = i2c_addr;
880 demod = &st->demod;
881 demod->demodulator_priv = st;
882 memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
884 if (dib3000mc_identify(st) != 0)
885 goto error;
887 dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
889 dib3000mc_write_word(st, 1037, 0x3130);
891 return demod;
893 error:
894 kfree(st);
895 return NULL;
897 EXPORT_SYMBOL(dib3000mc_attach);
899 static struct dvb_frontend_ops dib3000mc_ops = {
900 .info = {
901 .name = "DiBcom 3000MC/P",
902 .type = FE_OFDM,
903 .frequency_min = 44250000,
904 .frequency_max = 867250000,
905 .frequency_stepsize = 62500,
906 .caps = FE_CAN_INVERSION_AUTO |
907 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
908 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
909 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
910 FE_CAN_TRANSMISSION_MODE_AUTO |
911 FE_CAN_GUARD_INTERVAL_AUTO |
912 FE_CAN_RECOVER |
913 FE_CAN_HIERARCHY_AUTO,
916 .release = dib3000mc_release,
918 .init = dib3000mc_init,
919 .sleep = dib3000mc_sleep,
921 .set_frontend = dib3000mc_set_frontend,
922 .get_tune_settings = dib3000mc_fe_get_tune_settings,
923 .get_frontend = dib3000mc_get_frontend,
925 .read_status = dib3000mc_read_status,
926 .read_ber = dib3000mc_read_ber,
927 .read_signal_strength = dib3000mc_read_signal_strength,
928 .read_snr = dib3000mc_read_snr,
929 .read_ucblocks = dib3000mc_read_unc_blocks,
932 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
933 MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator");
934 MODULE_LICENSE("GPL");