Committer: Michael Beasley <mike@snafu.setup>
[mikesnafu-overlay.git] / drivers / media / dvb / frontends / dib3000mc.c
blobfa851601e7d4af1baae5312cce3819380df2a523
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/i2c.h>
17 #include "dvb_frontend.h"
19 #include "dib3000mc.h"
21 static int debug;
22 module_param(debug, int, 0644);
23 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
25 static int buggy_sfn_workaround;
26 module_param(buggy_sfn_workaround, int, 0644);
27 MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
29 #define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); printk("\n"); } } while (0)
31 struct dib3000mc_state {
32 struct dvb_frontend demod;
33 struct dib3000mc_config *cfg;
35 u8 i2c_addr;
36 struct i2c_adapter *i2c_adap;
38 struct dibx000_i2c_master i2c_master;
40 u32 timf;
42 fe_bandwidth_t current_bandwidth;
44 u16 dev_id;
46 u8 sfn_workaround_active :1;
49 static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
51 u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
52 u8 rb[2];
53 struct i2c_msg msg[2] = {
54 { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 },
55 { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
58 if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
59 dprintk("i2c read error on %d\n",reg);
61 return (rb[0] << 8) | rb[1];
64 static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
66 u8 b[4] = {
67 (reg >> 8) & 0xff, reg & 0xff,
68 (val >> 8) & 0xff, val & 0xff,
70 struct i2c_msg msg = {
71 .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
73 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
76 static int dib3000mc_identify(struct dib3000mc_state *state)
78 u16 value;
79 if ((value = dib3000mc_read_word(state, 1025)) != 0x01b3) {
80 dprintk("-E- DiB3000MC/P: wrong Vendor ID (read=0x%x)\n",value);
81 return -EREMOTEIO;
84 value = dib3000mc_read_word(state, 1026);
85 if (value != 0x3001 && value != 0x3002) {
86 dprintk("-E- DiB3000MC/P: wrong Device ID (%x)\n",value);
87 return -EREMOTEIO;
89 state->dev_id = value;
91 dprintk("-I- found DiB3000MC/P: %x\n",state->dev_id);
93 return 0;
96 static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u32 bw, u8 update_offset)
98 u32 timf;
100 if (state->timf == 0) {
101 timf = 1384402; // default value for 8MHz
102 if (update_offset)
103 msleep(200); // first time we do an update
104 } else
105 timf = state->timf;
107 timf *= (bw / 1000);
109 if (update_offset) {
110 s16 tim_offs = dib3000mc_read_word(state, 416);
112 if (tim_offs & 0x2000)
113 tim_offs -= 0x4000;
115 if (nfft == TRANSMISSION_MODE_2K)
116 tim_offs *= 4;
118 timf += tim_offs;
119 state->timf = timf / (bw / 1000);
122 dprintk("timf: %d\n", timf);
124 dib3000mc_write_word(state, 23, (u16) (timf >> 16));
125 dib3000mc_write_word(state, 24, (u16) (timf ) & 0xffff);
127 return 0;
130 static int dib3000mc_setup_pwm_state(struct dib3000mc_state *state)
132 u16 reg_51, reg_52 = state->cfg->agc->setup & 0xfefb;
133 if (state->cfg->pwm3_inversion) {
134 reg_51 = (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
135 reg_52 |= (1 << 2);
136 } else {
137 reg_51 = (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
138 reg_52 |= (1 << 8);
140 dib3000mc_write_word(state, 51, reg_51);
141 dib3000mc_write_word(state, 52, reg_52);
143 if (state->cfg->use_pwm3)
144 dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0));
145 else
146 dib3000mc_write_word(state, 245, 0);
148 dib3000mc_write_word(state, 1040, 0x3);
149 return 0;
152 static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode)
154 int ret = 0;
155 u16 fifo_threshold = 1792;
156 u16 outreg = 0;
157 u16 outmode = 0;
158 u16 elecout = 1;
159 u16 smo_reg = dib3000mc_read_word(state, 206) & 0x0010; /* keep the pid_parse bit */
161 dprintk("-I- Setting output mode for demod %p to %d\n",
162 &state->demod, mode);
164 switch (mode) {
165 case OUTMODE_HIGH_Z: // disable
166 elecout = 0;
167 break;
168 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
169 outmode = 0;
170 break;
171 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
172 outmode = 1;
173 break;
174 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
175 outmode = 2;
176 break;
177 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
178 elecout = 3;
179 /*ADDR @ 206 :
180 P_smo_error_discard [1;6:6] = 0
181 P_smo_rs_discard [1;5:5] = 0
182 P_smo_pid_parse [1;4:4] = 0
183 P_smo_fifo_flush [1;3:3] = 0
184 P_smo_mode [2;2:1] = 11
185 P_smo_ovf_prot [1;0:0] = 0
187 smo_reg |= 3 << 1;
188 fifo_threshold = 512;
189 outmode = 5;
190 break;
191 case OUTMODE_DIVERSITY:
192 outmode = 4;
193 elecout = 1;
194 break;
195 default:
196 dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod);
197 outmode = 0;
198 break;
201 if ((state->cfg->output_mpeg2_in_188_bytes))
202 smo_reg |= (1 << 5); // P_smo_rs_discard [1;5:5] = 1
204 outreg = dib3000mc_read_word(state, 244) & 0x07FF;
205 outreg |= (outmode << 11);
206 ret |= dib3000mc_write_word(state, 244, outreg);
207 ret |= dib3000mc_write_word(state, 206, smo_reg); /*smo_ mode*/
208 ret |= dib3000mc_write_word(state, 207, fifo_threshold); /* synchronous fread */
209 ret |= dib3000mc_write_word(state, 1040, elecout); /* P_out_cfg */
210 return ret;
213 static int dib3000mc_set_bandwidth(struct dib3000mc_state *state, u32 bw)
215 u16 bw_cfg[6] = { 0 };
216 u16 imp_bw_cfg[3] = { 0 };
217 u16 reg;
219 /* settings here are for 27.7MHz */
220 switch (bw) {
221 case 8000:
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;
224 break;
226 case 7000:
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;
229 break;
231 case 6000:
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;
234 break;
236 case 5000:
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;
239 break;
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);
252 // P_sec_len
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, TRANSMISSION_MODE_2K, bw, 0);
262 return 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)
275 u16 i;
276 for (i = 58; i < 87; i++)
277 dib3000mc_write_word(state, i, impulse_noise_val[i-58]);
279 if (nfft == TRANSMISSION_MODE_8K) {
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);
287 if (mode == 1)
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);
309 } else {
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, 0x0000);
317 // P_clk_cfg
318 dib3000mc_write_word(state, 1037, 0x3130);
320 // other configurations
322 // P_ctrl_sfreq
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);
332 else
333 dib3000mc_write_word(state, 111, 0x02);
335 // P_agc_global
336 dib3000mc_write_word(state, 50, 0x8000);
338 // agc setup misc
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);
346 /* agc */
347 dib3000mc_write_word(state, 36, state->cfg->max_time);
348 dib3000mc_write_word(state, 37, (state->cfg->agc_command1 << 13) | (state->cfg->agc_command2 << 12) | (0x1d << 0));
349 dib3000mc_write_word(state, 38, state->cfg->pwm3_value);
350 dib3000mc_write_word(state, 39, state->cfg->ln_adc_level);
352 // set_agc_loop_Bw
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
366 // P_pha3_thres
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);
370 // lock_mask0
371 dib3000mc_write_word(state, 1, 4);
372 // lock_mask1
373 dib3000mc_write_word(state, 2, 4);
374 // lock_mask2
375 dib3000mc_write_word(state, 3, 0x1000);
376 // P_search_maxtrial=1
377 dib3000mc_write_word(state, 5, 1);
379 dib3000mc_set_bandwidth(state, 8000);
381 // div_lock_mask
382 dib3000mc_write_word(state, 4, 0x814);
384 dib3000mc_write_word(state, 21, (1 << 9) | 0x164);
385 dib3000mc_write_word(state, 22, 0x463d);
387 // Spurious rm cfg
388 // P_cspu_regul, P_cspu_win_cut
389 dib3000mc_write_word(state, 120, 0x200f);
390 // P_adp_selec_monit
391 dib3000mc_write_word(state, 134, 0);
393 // Fec cfg
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, TRANSMISSION_MODE_8K);
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) );
408 return 0;
411 static int dib3000mc_sleep(struct dvb_frontend *demod)
413 struct dib3000mc_state *state = demod->demodulator_priv;
415 dib3000mc_write_word(state, 1031, 0xFFFF);
416 dib3000mc_write_word(state, 1032, 0xFFFF);
417 dib3000mc_write_word(state, 1033, 0xFFF0);
419 return 0;
422 static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
424 u16 cfg[4] = { 0 },reg;
425 switch (qam) {
426 case QPSK:
427 cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0;
428 break;
429 case QAM_16:
430 cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0;
431 break;
432 case QAM_64:
433 cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8;
434 break;
436 for (reg = 129; reg < 133; reg++)
437 dib3000mc_write_word(state, reg, cfg[reg - 129]);
440 static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dvb_frontend_parameters *ch, u16 seq)
442 u16 value;
443 dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
444 dib3000mc_set_timing(state, ch->u.ofdm.transmission_mode, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth), 0);
446 // if (boost)
447 // dib3000mc_write_word(state, 100, (11 << 6) + 6);
448 // else
449 dib3000mc_write_word(state, 100, (16 << 6) + 9);
451 dib3000mc_write_word(state, 1027, 0x0800);
452 dib3000mc_write_word(state, 1027, 0x0000);
454 //Default cfg isi offset adp
455 dib3000mc_write_word(state, 26, 0x6680);
456 dib3000mc_write_word(state, 29, 0x1273);
457 dib3000mc_write_word(state, 33, 5);
458 dib3000mc_set_adp_cfg(state, QAM_16);
459 dib3000mc_write_word(state, 133, 15564);
461 dib3000mc_write_word(state, 12 , 0x0);
462 dib3000mc_write_word(state, 13 , 0x3e8);
463 dib3000mc_write_word(state, 14 , 0x0);
464 dib3000mc_write_word(state, 15 , 0x3f2);
466 dib3000mc_write_word(state, 93,0);
467 dib3000mc_write_word(state, 94,0);
468 dib3000mc_write_word(state, 95,0);
469 dib3000mc_write_word(state, 96,0);
470 dib3000mc_write_word(state, 97,0);
471 dib3000mc_write_word(state, 98,0);
473 dib3000mc_set_impulse_noise(state, 0, ch->u.ofdm.transmission_mode);
475 value = 0;
476 switch (ch->u.ofdm.transmission_mode) {
477 case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
478 default:
479 case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
481 switch (ch->u.ofdm.guard_interval) {
482 case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
483 case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
484 case GUARD_INTERVAL_1_4: value |= (3 << 5); break;
485 default:
486 case GUARD_INTERVAL_1_8: value |= (2 << 5); break;
488 switch (ch->u.ofdm.constellation) {
489 case QPSK: value |= (0 << 3); break;
490 case QAM_16: value |= (1 << 3); break;
491 default:
492 case QAM_64: value |= (2 << 3); break;
494 switch (HIERARCHY_1) {
495 case HIERARCHY_2: value |= 2; break;
496 case HIERARCHY_4: value |= 4; break;
497 default:
498 case HIERARCHY_1: value |= 1; break;
500 dib3000mc_write_word(state, 0, value);
501 dib3000mc_write_word(state, 5, (1 << 8) | ((seq & 0xf) << 4));
503 value = 0;
504 if (ch->u.ofdm.hierarchy_information == 1)
505 value |= (1 << 4);
506 if (1 == 1)
507 value |= 1;
508 switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
509 case FEC_2_3: value |= (2 << 1); break;
510 case FEC_3_4: value |= (3 << 1); break;
511 case FEC_5_6: value |= (5 << 1); break;
512 case FEC_7_8: value |= (7 << 1); break;
513 default:
514 case FEC_1_2: value |= (1 << 1); break;
516 dib3000mc_write_word(state, 181, value);
518 // diversity synchro delay add 50% SFN margin
519 switch (ch->u.ofdm.transmission_mode) {
520 case TRANSMISSION_MODE_8K: value = 256; break;
521 case TRANSMISSION_MODE_2K:
522 default: value = 64; break;
524 switch (ch->u.ofdm.guard_interval) {
525 case GUARD_INTERVAL_1_16: value *= 2; break;
526 case GUARD_INTERVAL_1_8: value *= 4; break;
527 case GUARD_INTERVAL_1_4: value *= 8; break;
528 default:
529 case GUARD_INTERVAL_1_32: value *= 1; break;
531 value <<= 4;
532 value |= dib3000mc_read_word(state, 180) & 0x000f;
533 dib3000mc_write_word(state, 180, value);
535 // restart demod
536 value = dib3000mc_read_word(state, 0);
537 dib3000mc_write_word(state, 0, value | (1 << 9));
538 dib3000mc_write_word(state, 0, value);
540 msleep(30);
542 dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, ch->u.ofdm.transmission_mode);
545 static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *chan)
547 struct dib3000mc_state *state = demod->demodulator_priv;
548 u16 reg;
549 // u32 val;
550 struct dvb_frontend_parameters schan;
552 schan = *chan;
554 /* TODO what is that ? */
556 /* a channel for autosearch */
557 schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
558 schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
559 schan.u.ofdm.constellation = QAM_64;
560 schan.u.ofdm.code_rate_HP = FEC_2_3;
561 schan.u.ofdm.code_rate_LP = FEC_2_3;
562 schan.u.ofdm.hierarchy_information = 0;
564 dib3000mc_set_channel_cfg(state, &schan, 11);
566 reg = dib3000mc_read_word(state, 0);
567 dib3000mc_write_word(state, 0, reg | (1 << 8));
568 dib3000mc_read_word(state, 511);
569 dib3000mc_write_word(state, 0, reg);
571 return 0;
574 static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod)
576 struct dib3000mc_state *state = demod->demodulator_priv;
577 u16 irq_pending = dib3000mc_read_word(state, 511);
579 if (irq_pending & 0x1) // failed
580 return 1;
582 if (irq_pending & 0x2) // succeeded
583 return 2;
585 return 0; // still pending
588 static int dib3000mc_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
590 struct dib3000mc_state *state = demod->demodulator_priv;
592 // ** configure demod **
593 dib3000mc_set_channel_cfg(state, ch, 0);
595 // activates isi
596 if (state->sfn_workaround_active) {
597 dprintk("SFN workaround is active\n");
598 dib3000mc_write_word(state, 29, 0x1273);
599 dib3000mc_write_word(state, 108, 0x4000); // P_pha3_force_pha_shift
600 } else {
601 dib3000mc_write_word(state, 29, 0x1073);
602 dib3000mc_write_word(state, 108, 0x0000); // P_pha3_force_pha_shift
605 dib3000mc_set_adp_cfg(state, (u8)ch->u.ofdm.constellation);
606 if (ch->u.ofdm.transmission_mode == TRANSMISSION_MODE_8K) {
607 dib3000mc_write_word(state, 26, 38528);
608 dib3000mc_write_word(state, 33, 8);
609 } else {
610 dib3000mc_write_word(state, 26, 30336);
611 dib3000mc_write_word(state, 33, 6);
614 if (dib3000mc_read_word(state, 509) & 0x80)
615 dib3000mc_set_timing(state, ch->u.ofdm.transmission_mode, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth), 1);
617 return 0;
620 struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating)
622 struct dib3000mc_state *st = demod->demodulator_priv;
623 return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating);
626 EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master);
628 static int dib3000mc_get_frontend(struct dvb_frontend* fe,
629 struct dvb_frontend_parameters *fep)
631 struct dib3000mc_state *state = fe->demodulator_priv;
632 u16 tps = dib3000mc_read_word(state,458);
634 fep->inversion = INVERSION_AUTO;
636 fep->u.ofdm.bandwidth = state->current_bandwidth;
638 switch ((tps >> 8) & 0x1) {
639 case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break;
640 case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break;
643 switch (tps & 0x3) {
644 case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break;
645 case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break;
646 case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break;
647 case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break;
650 switch ((tps >> 13) & 0x3) {
651 case 0: fep->u.ofdm.constellation = QPSK; break;
652 case 1: fep->u.ofdm.constellation = QAM_16; break;
653 case 2:
654 default: fep->u.ofdm.constellation = QAM_64; break;
657 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
658 /* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */
660 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
661 switch ((tps >> 5) & 0x7) {
662 case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break;
663 case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break;
664 case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break;
665 case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break;
666 case 7:
667 default: fep->u.ofdm.code_rate_HP = FEC_7_8; break;
671 switch ((tps >> 2) & 0x7) {
672 case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break;
673 case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break;
674 case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break;
675 case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break;
676 case 7:
677 default: fep->u.ofdm.code_rate_LP = FEC_7_8; break;
680 return 0;
683 static int dib3000mc_set_frontend(struct dvb_frontend* fe,
684 struct dvb_frontend_parameters *fep)
686 struct dib3000mc_state *state = fe->demodulator_priv;
687 int ret;
689 dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
691 state->current_bandwidth = fep->u.ofdm.bandwidth;
692 dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth));
694 /* maybe the parameter has been changed */
695 state->sfn_workaround_active = buggy_sfn_workaround;
697 if (fe->ops.tuner_ops.set_params) {
698 fe->ops.tuner_ops.set_params(fe, fep);
699 msleep(100);
702 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
703 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ||
704 fep->u.ofdm.constellation == QAM_AUTO ||
705 fep->u.ofdm.code_rate_HP == FEC_AUTO) {
706 int i = 1000, found;
708 dib3000mc_autosearch_start(fe, fep);
709 do {
710 msleep(1);
711 found = dib3000mc_autosearch_is_irq(fe);
712 } while (found == 0 && i--);
714 dprintk("autosearch returns: %d\n",found);
715 if (found == 0 || found == 1)
716 return 0; // no channel found
718 dib3000mc_get_frontend(fe, fep);
721 ret = dib3000mc_tune(fe, fep);
723 /* make this a config parameter */
724 dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
725 return ret;
728 static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat)
730 struct dib3000mc_state *state = fe->demodulator_priv;
731 u16 lock = dib3000mc_read_word(state, 509);
733 *stat = 0;
735 if (lock & 0x8000)
736 *stat |= FE_HAS_SIGNAL;
737 if (lock & 0x3000)
738 *stat |= FE_HAS_CARRIER;
739 if (lock & 0x0100)
740 *stat |= FE_HAS_VITERBI;
741 if (lock & 0x0010)
742 *stat |= FE_HAS_SYNC;
743 if (lock & 0x0008)
744 *stat |= FE_HAS_LOCK;
746 return 0;
749 static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber)
751 struct dib3000mc_state *state = fe->demodulator_priv;
752 *ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501);
753 return 0;
756 static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
758 struct dib3000mc_state *state = fe->demodulator_priv;
759 *unc = dib3000mc_read_word(state, 508);
760 return 0;
763 static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
765 struct dib3000mc_state *state = fe->demodulator_priv;
766 u16 val = dib3000mc_read_word(state, 392);
767 *strength = 65535 - val;
768 return 0;
771 static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
773 *snr = 0x0000;
774 return 0;
777 static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
779 tune->min_delay_ms = 1000;
780 return 0;
783 static void dib3000mc_release(struct dvb_frontend *fe)
785 struct dib3000mc_state *state = fe->demodulator_priv;
786 dibx000_exit_i2c_master(&state->i2c_master);
787 kfree(state);
790 int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff)
792 struct dib3000mc_state *state = fe->demodulator_priv;
793 dib3000mc_write_word(state, 212 + index, onoff ? (1 << 13) | pid : 0);
794 return 0;
796 EXPORT_SYMBOL(dib3000mc_pid_control);
798 int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
800 struct dib3000mc_state *state = fe->demodulator_priv;
801 u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4);
802 tmp |= (onoff << 4);
803 return dib3000mc_write_word(state, 206, tmp);
805 EXPORT_SYMBOL(dib3000mc_pid_parse);
807 void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg)
809 struct dib3000mc_state *state = fe->demodulator_priv;
810 state->cfg = cfg;
812 EXPORT_SYMBOL(dib3000mc_set_config);
814 int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[])
816 struct dib3000mc_state st = { .i2c_adap = i2c };
817 int k;
818 u8 new_addr;
820 static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
822 for (k = no_of_demods-1; k >= 0; k--) {
823 st.cfg = &cfg[k];
825 /* designated i2c address */
826 new_addr = DIB3000MC_I2C_ADDRESS[k];
827 st.i2c_addr = new_addr;
828 if (dib3000mc_identify(&st) != 0) {
829 st.i2c_addr = default_addr;
830 if (dib3000mc_identify(&st) != 0) {
831 dprintk("-E- DiB3000P/MC #%d: not identified\n", k);
832 return -ENODEV;
836 dib3000mc_set_output_mode(&st, OUTMODE_MPEG2_PAR_CONT_CLK);
838 // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
839 dib3000mc_write_word(&st, 1024, (new_addr << 3) | 0x1);
840 st.i2c_addr = new_addr;
843 for (k = 0; k < no_of_demods; k++) {
844 st.cfg = &cfg[k];
845 st.i2c_addr = DIB3000MC_I2C_ADDRESS[k];
847 dib3000mc_write_word(&st, 1024, st.i2c_addr << 3);
849 /* turn off data output */
850 dib3000mc_set_output_mode(&st, OUTMODE_HIGH_Z);
852 return 0;
854 EXPORT_SYMBOL(dib3000mc_i2c_enumeration);
856 static struct dvb_frontend_ops dib3000mc_ops;
858 struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
860 struct dvb_frontend *demod;
861 struct dib3000mc_state *st;
862 st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
863 if (st == NULL)
864 return NULL;
866 st->cfg = cfg;
867 st->i2c_adap = i2c_adap;
868 st->i2c_addr = i2c_addr;
870 demod = &st->demod;
871 demod->demodulator_priv = st;
872 memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
874 if (dib3000mc_identify(st) != 0)
875 goto error;
877 dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
879 dib3000mc_write_word(st, 1037, 0x3130);
881 return demod;
883 error:
884 kfree(st);
885 return NULL;
887 EXPORT_SYMBOL(dib3000mc_attach);
889 static struct dvb_frontend_ops dib3000mc_ops = {
890 .info = {
891 .name = "DiBcom 3000MC/P",
892 .type = FE_OFDM,
893 .frequency_min = 44250000,
894 .frequency_max = 867250000,
895 .frequency_stepsize = 62500,
896 .caps = FE_CAN_INVERSION_AUTO |
897 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
898 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
899 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
900 FE_CAN_TRANSMISSION_MODE_AUTO |
901 FE_CAN_GUARD_INTERVAL_AUTO |
902 FE_CAN_RECOVER |
903 FE_CAN_HIERARCHY_AUTO,
906 .release = dib3000mc_release,
908 .init = dib3000mc_init,
909 .sleep = dib3000mc_sleep,
911 .set_frontend = dib3000mc_set_frontend,
912 .get_tune_settings = dib3000mc_fe_get_tune_settings,
913 .get_frontend = dib3000mc_get_frontend,
915 .read_status = dib3000mc_read_status,
916 .read_ber = dib3000mc_read_ber,
917 .read_signal_strength = dib3000mc_read_signal_strength,
918 .read_snr = dib3000mc_read_snr,
919 .read_ucblocks = dib3000mc_read_unc_blocks,
922 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
923 MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator");
924 MODULE_LICENSE("GPL");