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
= dib3000mc_read_word(state
, 206) & 0x0010; /* keep the pid_parse bit */
174 dprintk("-I- Setting output mode for demod %p to %d\n",
175 &state
->demod
, mode
);
178 case OUTMODE_HIGH_Z
: // disable
181 case OUTMODE_MPEG2_PAR_GATED_CLK
: // STBs with parallel gated clock
184 case OUTMODE_MPEG2_PAR_CONT_CLK
: // STBs with parallel continues clock
187 case OUTMODE_MPEG2_SERIAL
: // STBs with serial input
190 case OUTMODE_MPEG2_FIFO
: // e.g. USB feeding
193 P_smo_error_discard [1;6:6] = 0
194 P_smo_rs_discard [1;5:5] = 0
195 P_smo_pid_parse [1;4:4] = 0
196 P_smo_fifo_flush [1;3:3] = 0
197 P_smo_mode [2;2:1] = 11
198 P_smo_ovf_prot [1;0:0] = 0
201 fifo_threshold
= 512;
204 case OUTMODE_DIVERSITY
:
209 dprintk("Unhandled output_mode passed to be set for demod %p\n",&state
->demod
);
214 if ((state
->cfg
->output_mpeg2_in_188_bytes
))
215 smo_reg
|= (1 << 5); // P_smo_rs_discard [1;5:5] = 1
217 outreg
= dib3000mc_read_word(state
, 244) & 0x07FF;
218 outreg
|= (outmode
<< 11);
219 ret
|= dib3000mc_write_word(state
, 244, outreg
);
220 ret
|= dib3000mc_write_word(state
, 206, smo_reg
); /*smo_ mode*/
221 ret
|= dib3000mc_write_word(state
, 207, fifo_threshold
); /* synchronous fread */
222 ret
|= dib3000mc_write_word(state
, 1040, elecout
); /* P_out_cfg */
226 static int dib3000mc_set_bandwidth(struct dvb_frontend
*demod
, u8 bw
)
228 struct dib3000mc_state
*state
= demod
->demodulator_priv
;
229 u16 bw_cfg
[6] = { 0 };
230 u16 imp_bw_cfg
[3] = { 0 };
233 /* settings here are for 27.7MHz */
235 case BANDWIDTH_8_MHZ
:
236 bw_cfg
[0] = 0x0019; bw_cfg
[1] = 0x5c30; bw_cfg
[2] = 0x0054; bw_cfg
[3] = 0x88a0; bw_cfg
[4] = 0x01a6; bw_cfg
[5] = 0xab20;
237 imp_bw_cfg
[0] = 0x04db; imp_bw_cfg
[1] = 0x00db; imp_bw_cfg
[2] = 0x00b7;
240 case BANDWIDTH_7_MHZ
:
241 bw_cfg
[0] = 0x001c; bw_cfg
[1] = 0xfba5; bw_cfg
[2] = 0x0060; bw_cfg
[3] = 0x9c25; bw_cfg
[4] = 0x01e3; bw_cfg
[5] = 0x0cb7;
242 imp_bw_cfg
[0] = 0x04c0; imp_bw_cfg
[1] = 0x00c0; imp_bw_cfg
[2] = 0x00a0;
245 case BANDWIDTH_6_MHZ
:
246 bw_cfg
[0] = 0x0021; bw_cfg
[1] = 0xd040; bw_cfg
[2] = 0x0070; bw_cfg
[3] = 0xb62b; bw_cfg
[4] = 0x0233; bw_cfg
[5] = 0x8ed5;
247 imp_bw_cfg
[0] = 0x04a5; imp_bw_cfg
[1] = 0x00a5; imp_bw_cfg
[2] = 0x0089;
250 case 255 /* BANDWIDTH_5_MHZ */:
251 bw_cfg
[0] = 0x0028; bw_cfg
[1] = 0x9380; bw_cfg
[2] = 0x0087; bw_cfg
[3] = 0x4100; bw_cfg
[4] = 0x02a4; bw_cfg
[5] = 0x4500;
252 imp_bw_cfg
[0] = 0x0489; imp_bw_cfg
[1] = 0x0089; imp_bw_cfg
[2] = 0x0072;
255 default: return -EINVAL
;
258 for (reg
= 6; reg
< 12; reg
++)
259 dib3000mc_write_word(state
, reg
, bw_cfg
[reg
- 6]);
260 dib3000mc_write_word(state
, 12, 0x0000);
261 dib3000mc_write_word(state
, 13, 0x03e8);
262 dib3000mc_write_word(state
, 14, 0x0000);
263 dib3000mc_write_word(state
, 15, 0x03f2);
264 dib3000mc_write_word(state
, 16, 0x0001);
265 dib3000mc_write_word(state
, 17, 0xb0d0);
267 dib3000mc_write_word(state
, 18, 0x0393);
268 dib3000mc_write_word(state
, 19, 0x8700);
270 for (reg
= 55; reg
< 58; reg
++)
271 dib3000mc_write_word(state
, reg
, imp_bw_cfg
[reg
- 55]);
273 // Timing configuration
274 dib3000mc_set_timing(state
, 0, bw
, 0);
279 static u16 impulse_noise_val
[29] =
282 0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, 0x3ffe, 0x7f3,
283 0x2d94, 0x76, 0x53d, 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, 0x3feb, 0x7d2,
284 0x365e, 0x76, 0x48c, 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0000, 0xd
287 static void dib3000mc_set_impulse_noise(struct dib3000mc_state
*state
, u8 mode
, s16 nfft
)
290 for (i
= 58; i
< 87; i
++)
291 dib3000mc_write_word(state
, i
, impulse_noise_val
[i
-58]);
294 dib3000mc_write_word(state
, 58, 0x3b);
295 dib3000mc_write_word(state
, 84, 0x00);
296 dib3000mc_write_word(state
, 85, 0x8200);
299 dib3000mc_write_word(state
, 34, 0x1294);
300 dib3000mc_write_word(state
, 35, 0x1ff8);
302 dib3000mc_write_word(state
, 55, dib3000mc_read_word(state
, 55) | (1 << 10));
305 static int dib3000mc_init(struct dvb_frontend
*demod
)
307 struct dib3000mc_state
*state
= demod
->demodulator_priv
;
308 struct dibx000_agc_config
*agc
= state
->cfg
->agc
;
310 // Restart Configuration
311 dib3000mc_write_word(state
, 1027, 0x8000);
312 dib3000mc_write_word(state
, 1027, 0x0000);
314 // power up the demod + mobility configuration
315 dib3000mc_write_word(state
, 140, 0x0000);
316 dib3000mc_write_word(state
, 1031, 0);
318 if (state
->cfg
->mobile_mode
) {
319 dib3000mc_write_word(state
, 139, 0x0000);
320 dib3000mc_write_word(state
, 141, 0x0000);
321 dib3000mc_write_word(state
, 175, 0x0002);
322 dib3000mc_write_word(state
, 1032, 0x0000);
324 dib3000mc_write_word(state
, 139, 0x0001);
325 dib3000mc_write_word(state
, 141, 0x0000);
326 dib3000mc_write_word(state
, 175, 0x0000);
327 dib3000mc_write_word(state
, 1032, 0x012C);
329 dib3000mc_write_word(state
, 1033, 0);
332 dib3000mc_write_word(state
, 1037, 12592);
334 // other configurations
337 dib3000mc_write_word(state
, 33, (5 << 0));
338 dib3000mc_write_word(state
, 88, (1 << 10) | (0x10 << 0));
340 // Phase noise control
341 // P_fft_phacor_inh, P_fft_phacor_cpe, P_fft_powrange
342 dib3000mc_write_word(state
, 99, (1 << 9) | (0x20 << 0));
344 if (state
->cfg
->phase_noise_mode
== 0)
345 dib3000mc_write_word(state
, 111, 0x00);
347 dib3000mc_write_word(state
, 111, 0x02);
350 dib3000mc_write_word(state
, 50, 0x8000);
353 dib3000mc_setup_pwm3_state(state
);
355 // P_agc_counter_lock
356 dib3000mc_write_word(state
, 53, 0x87);
357 // P_agc_counter_unlock
358 dib3000mc_write_word(state
, 54, 0x87);
361 dib3000mc_write_word(state
, 36, state
->cfg
->max_time
);
362 dib3000mc_write_word(state
, 37, agc
->setup
);
363 dib3000mc_write_word(state
, 38, state
->cfg
->pwm3_value
);
364 dib3000mc_write_word(state
, 39, state
->cfg
->ln_adc_level
);
367 dib3000mc_write_word(state
, 40, 0x0179);
368 dib3000mc_write_word(state
, 41, 0x03f0);
370 dib3000mc_write_word(state
, 42, agc
->agc1_max
);
371 dib3000mc_write_word(state
, 43, agc
->agc1_min
);
372 dib3000mc_write_word(state
, 44, agc
->agc2_max
);
373 dib3000mc_write_word(state
, 45, agc
->agc2_min
);
374 dib3000mc_write_word(state
, 46, (agc
->agc1_pt1
<< 8) | agc
->agc1_pt2
);
375 dib3000mc_write_word(state
, 47, (agc
->agc1_slope1
<< 8) | agc
->agc1_slope2
);
376 dib3000mc_write_word(state
, 48, (agc
->agc2_pt1
<< 8) | agc
->agc2_pt2
);
377 dib3000mc_write_word(state
, 49, (agc
->agc2_slope1
<< 8) | agc
->agc2_slope2
);
379 // Begin: TimeOut registers
381 dib3000mc_write_word(state
, 110, 3277);
382 // P_timf_alpha = 6, P_corm_alpha = 6, P_corm_thres = 0x80
383 dib3000mc_write_word(state
, 26, 0x6680);
385 dib3000mc_write_word(state
, 1, 4);
387 dib3000mc_write_word(state
, 2, 4);
389 dib3000mc_write_word(state
, 3, 0x1000);
390 // P_search_maxtrial=1
391 dib3000mc_write_word(state
, 5, 1);
393 dib3000mc_set_bandwidth(&state
->demod
, BANDWIDTH_8_MHZ
);
396 dib3000mc_write_word(state
, 4, 0x814);
398 dib3000mc_write_word(state
, 21, (1 << 9) | 0x164);
399 dib3000mc_write_word(state
, 22, 0x463d);
402 // P_cspu_regul, P_cspu_win_cut
403 dib3000mc_write_word(state
, 120, 0x200f);
405 dib3000mc_write_word(state
, 134, 0);
408 dib3000mc_write_word(state
, 195, 0x10);
410 // diversity register: P_dvsy_sync_wait..
411 dib3000mc_write_word(state
, 180, 0x2FF0);
413 // Impulse noise configuration
414 dib3000mc_set_impulse_noise(state
, 0, 1);
416 // output mode set-up
417 dib3000mc_set_output_mode(state
, OUTMODE_HIGH_Z
);
419 /* close the i2c-gate */
420 dib3000mc_write_word(state
, 769, (1 << 7) );
425 static int dib3000mc_sleep(struct dvb_frontend
*demod
)
427 struct dib3000mc_state
*state
= demod
->demodulator_priv
;
429 dib3000mc_write_word(state
, 1037, dib3000mc_read_word(state
, 1037) | 0x0003);
430 dib3000mc_write_word(state
, 1031, 0xFFFF);
431 dib3000mc_write_word(state
, 1032, 0xFFFF);
432 dib3000mc_write_word(state
, 1033, 0xFFF4); // **** Bin2
437 static void dib3000mc_set_adp_cfg(struct dib3000mc_state
*state
, s16 qam
)
439 u16 cfg
[4] = { 0 },reg
;
442 cfg
[0] = 0x099a; cfg
[1] = 0x7fae; cfg
[2] = 0x0333; cfg
[3] = 0x7ff0;
445 cfg
[0] = 0x023d; cfg
[1] = 0x7fdf; cfg
[2] = 0x00a4; cfg
[3] = 0x7ff0;
448 cfg
[0] = 0x0148; cfg
[1] = 0x7ff0; cfg
[2] = 0x00a4; cfg
[3] = 0x7ff8;
451 for (reg
= 129; reg
< 133; reg
++)
452 dib3000mc_write_word(state
, reg
, cfg
[reg
- 129]);
455 static void dib3000mc_set_channel_cfg(struct dib3000mc_state
*state
, struct dibx000_ofdm_channel
*chan
, u16 seq
)
459 dib3000mc_set_timing(state
, chan
->nfft
, chan
->Bw
, 0);
462 // dib3000mc_write_word(state, 100, (11 << 6) + 6);
464 dib3000mc_write_word(state
, 100, (16 << 6) + 9);
466 dib3000mc_write_word(state
, 1027, 0x0800);
467 dib3000mc_write_word(state
, 1027, 0x0000);
469 //Default cfg isi offset adp
470 dib3000mc_write_word(state
, 26, 0x6680);
471 dib3000mc_write_word(state
, 29, 0x1273);
472 dib3000mc_write_word(state
, 33, 5);
473 dib3000mc_set_adp_cfg(state
, 1);
474 dib3000mc_write_word(state
, 133, 15564);
476 dib3000mc_write_word(state
, 12 , 0x0);
477 dib3000mc_write_word(state
, 13 , 0x3e8);
478 dib3000mc_write_word(state
, 14 , 0x0);
479 dib3000mc_write_word(state
, 15 , 0x3f2);
481 dib3000mc_write_word(state
, 93,0);
482 dib3000mc_write_word(state
, 94,0);
483 dib3000mc_write_word(state
, 95,0);
484 dib3000mc_write_word(state
, 96,0);
485 dib3000mc_write_word(state
, 97,0);
486 dib3000mc_write_word(state
, 98,0);
488 dib3000mc_set_impulse_noise(state
, 0, chan
->nfft
);
490 tmp
= ((chan
->nfft
& 0x1) << 7) | (chan
->guard
<< 5) | (chan
->nqam
<< 3) | chan
->vit_alpha
;
491 dib3000mc_write_word(state
, 0, tmp
);
493 dib3000mc_write_word(state
, 5, seq
);
495 tmp
= (chan
->vit_hrch
<< 4) | (chan
->vit_select_hp
);
496 if (!chan
->vit_hrch
|| (chan
->vit_hrch
&& chan
->vit_select_hp
))
497 tmp
|= chan
->vit_code_rate_hp
<< 1;
499 tmp
|= chan
->vit_code_rate_lp
<< 1;
500 dib3000mc_write_word(state
, 181, tmp
);
502 // diversity synchro delay
503 tmp
= dib3000mc_read_word(state
, 180) & 0x000f;
504 tmp
|= ((chan
->nfft
== 0) ? 64 : 256) * ((1 << (chan
->guard
)) * 3 / 2) << 4; // add 50% SFN margin
505 dib3000mc_write_word(state
, 180, tmp
);
508 tmp
= dib3000mc_read_word(state
, 0);
509 dib3000mc_write_word(state
, 0, tmp
| (1 << 9));
510 dib3000mc_write_word(state
, 0, tmp
);
514 dib3000mc_set_impulse_noise(state
, state
->cfg
->impulse_noise_mode
, chan
->nfft
);
517 static int dib3000mc_autosearch_start(struct dvb_frontend
*demod
, struct dibx000_ofdm_channel
*chan
)
519 struct dib3000mc_state
*state
= demod
->demodulator_priv
;
522 struct dibx000_ofdm_channel fchan
;
524 INIT_OFDM_CHANNEL(&fchan
);
528 /* a channel for autosearch */
530 if (chan
->nfft
== -1 && chan
->guard
== -1) reg
= 7;
531 if (chan
->nfft
== -1 && chan
->guard
!= -1) reg
= 2;
532 if (chan
->nfft
!= -1 && chan
->guard
== -1) reg
= 3;
534 fchan
.nfft
= 1; fchan
.guard
= 0; fchan
.nqam
= 2;
535 fchan
.vit_alpha
= 1; fchan
.vit_code_rate_hp
= 2; fchan
.vit_code_rate_lp
= 2;
536 fchan
.vit_hrch
= 0; fchan
.vit_select_hp
= 1;
538 dib3000mc_set_channel_cfg(state
, &fchan
, reg
);
540 reg
= dib3000mc_read_word(state
, 0);
541 dib3000mc_write_word(state
, 0, reg
| (1 << 8));
542 dib3000mc_write_word(state
, 0, reg
);
547 static int dib3000mc_autosearch_is_irq(struct dvb_frontend
*demod
)
549 struct dib3000mc_state
*state
= demod
->demodulator_priv
;
550 u16 irq_pending
= dib3000mc_read_word(state
, 511);
552 if (irq_pending
& 0x1) // failed
555 if (irq_pending
& 0x2) // succeeded
558 return 0; // still pending
561 static int dib3000mc_tune(struct dvb_frontend
*demod
, struct dibx000_ofdm_channel
*ch
)
563 struct dib3000mc_state
*state
= demod
->demodulator_priv
;
565 // ** configure demod **
566 dib3000mc_set_channel_cfg(state
, ch
, 0);
569 dib3000mc_write_word(state
, 29, 0x1073);
571 dib3000mc_set_adp_cfg(state
, (u8
)ch
->nqam
);
574 dib3000mc_write_word(state
, 26, 38528);
575 dib3000mc_write_word(state
, 33, 8);
577 dib3000mc_write_word(state
, 26, 30336);
578 dib3000mc_write_word(state
, 33, 6);
582 // dib3000mc_set_timing(state, ch->nfft, ch->Bw, 1);
587 static int dib3000mc_demod_output_mode(struct dvb_frontend
*demod
, int mode
)
589 struct dib3000mc_state
*state
= demod
->demodulator_priv
;
590 return dib3000mc_set_output_mode(state
, mode
);
593 static int dib3000mc_i2c_enumeration(struct dvb_frontend
*demod
[], int no_of_demods
, u8 default_addr
)
595 struct dib3000mc_state
*st
;
599 static u8 DIB3000MC_I2C_ADDRESS
[] = {20,22,24,26};
601 for (k
= no_of_demods
-1; k
>= 0; k
--) {
602 st
= demod
[k
]->demodulator_priv
;
604 /* designated i2c address */
605 new_addr
= DIB3000MC_I2C_ADDRESS
[k
];
607 st
->i2c_addr
= new_addr
;
608 if (dib3000mc_identify(st
) != 0) {
609 st
->i2c_addr
= default_addr
;
610 if (dib3000mc_identify(st
) != 0) {
611 dprintk("-E- DiB3000P/MC #%d: not identified\n", k
);
616 /* turn on div_out */
617 dib3000mc_demod_output_mode(demod
[k
], OUTMODE_MPEG2_PAR_CONT_CLK
);
619 // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
620 ret
|= dib3000mc_write_word(st
, 1024, (new_addr
<< 3) | 0x1);
621 st
->i2c_addr
= new_addr
;
624 for (k
= 0; k
< no_of_demods
; k
++) {
625 st
= demod
[k
]->demodulator_priv
;
627 ret
|= dib3000mc_write_word(st
, 1024, st
->i2c_addr
<< 3);
629 /* turn off data output */
630 dib3000mc_demod_output_mode(demod
[k
],OUTMODE_HIGH_Z
);
631 dib3000mc_write_word(st
, 769, (1 << 7) );
637 struct i2c_adapter
* dib3000mc_get_tuner_i2c_master(struct dvb_frontend
*demod
, int gating
)
639 struct dib3000mc_state
*st
= demod
->demodulator_priv
;
640 return dibx000_get_i2c_adapter(&st
->i2c_master
, DIBX000_I2C_INTERFACE_TUNER
, gating
);
643 EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master
);
645 static int dib3000mc_get_frontend(struct dvb_frontend
* fe
,
646 struct dvb_frontend_parameters
*fep
)
648 struct dib3000mc_state
*state
= fe
->demodulator_priv
;
649 u16 tps
= dib3000mc_read_word(state
,458);
651 fep
->inversion
= INVERSION_AUTO
;
653 fep
->u
.ofdm
.bandwidth
= state
->current_bandwidth
;
655 switch ((tps
>> 8) & 0x1) {
656 case 0: fep
->u
.ofdm
.transmission_mode
= TRANSMISSION_MODE_2K
; break;
657 case 1: fep
->u
.ofdm
.transmission_mode
= TRANSMISSION_MODE_8K
; break;
661 case 0: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_32
; break;
662 case 1: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_16
; break;
663 case 2: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_8
; break;
664 case 3: fep
->u
.ofdm
.guard_interval
= GUARD_INTERVAL_1_4
; break;
667 switch ((tps
>> 13) & 0x3) {
668 case 0: fep
->u
.ofdm
.constellation
= QPSK
; break;
669 case 1: fep
->u
.ofdm
.constellation
= QAM_16
; break;
671 default: fep
->u
.ofdm
.constellation
= QAM_64
; break;
674 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
675 /* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */
677 fep
->u
.ofdm
.hierarchy_information
= HIERARCHY_NONE
;
678 switch ((tps
>> 5) & 0x7) {
679 case 1: fep
->u
.ofdm
.code_rate_HP
= FEC_1_2
; break;
680 case 2: fep
->u
.ofdm
.code_rate_HP
= FEC_2_3
; break;
681 case 3: fep
->u
.ofdm
.code_rate_HP
= FEC_3_4
; break;
682 case 5: fep
->u
.ofdm
.code_rate_HP
= FEC_5_6
; break;
684 default: fep
->u
.ofdm
.code_rate_HP
= FEC_7_8
; break;
688 switch ((tps
>> 2) & 0x7) {
689 case 1: fep
->u
.ofdm
.code_rate_LP
= FEC_1_2
; break;
690 case 2: fep
->u
.ofdm
.code_rate_LP
= FEC_2_3
; break;
691 case 3: fep
->u
.ofdm
.code_rate_LP
= FEC_3_4
; break;
692 case 5: fep
->u
.ofdm
.code_rate_LP
= FEC_5_6
; break;
694 default: fep
->u
.ofdm
.code_rate_LP
= FEC_7_8
; break;
700 static int dib3000mc_set_frontend(struct dvb_frontend
* fe
,
701 struct dvb_frontend_parameters
*fep
)
703 struct dib3000mc_state
*state
= fe
->demodulator_priv
;
704 struct dibx000_ofdm_channel ch
;
706 INIT_OFDM_CHANNEL(&ch
);
709 state
->current_bandwidth
= fep
->u
.ofdm
.bandwidth
;
710 dib3000mc_set_bandwidth(fe
, fep
->u
.ofdm
.bandwidth
);
712 if (fe
->ops
.tuner_ops
.set_params
) {
713 fe
->ops
.tuner_ops
.set_params(fe
, fep
);
717 if (fep
->u
.ofdm
.transmission_mode
== TRANSMISSION_MODE_AUTO
||
718 fep
->u
.ofdm
.guard_interval
== GUARD_INTERVAL_AUTO
||
719 fep
->u
.ofdm
.constellation
== QAM_AUTO
||
720 fep
->u
.ofdm
.code_rate_HP
== FEC_AUTO
) {
723 dib3000mc_autosearch_start(fe
, &ch
);
726 found
= dib3000mc_autosearch_is_irq(fe
);
727 } while (found
== 0 && i
--);
729 dprintk("autosearch returns: %d\n",found
);
730 if (found
== 0 || found
== 1)
731 return 0; // no channel found
733 dib3000mc_get_frontend(fe
, fep
);
737 /* make this a config parameter */
738 dib3000mc_set_output_mode(state
, OUTMODE_MPEG2_FIFO
);
740 return dib3000mc_tune(fe
, &ch
);
743 static int dib3000mc_read_status(struct dvb_frontend
*fe
, fe_status_t
*stat
)
745 struct dib3000mc_state
*state
= fe
->demodulator_priv
;
746 u16 lock
= dib3000mc_read_word(state
, 509);
751 *stat
|= FE_HAS_SIGNAL
;
753 *stat
|= FE_HAS_CARRIER
;
755 *stat
|= FE_HAS_VITERBI
;
757 *stat
|= FE_HAS_SYNC
;
759 *stat
|= FE_HAS_LOCK
;
764 static int dib3000mc_read_ber(struct dvb_frontend
*fe
, u32
*ber
)
766 struct dib3000mc_state
*state
= fe
->demodulator_priv
;
767 *ber
= (dib3000mc_read_word(state
, 500) << 16) | dib3000mc_read_word(state
, 501);
771 static int dib3000mc_read_unc_blocks(struct dvb_frontend
*fe
, u32
*unc
)
773 struct dib3000mc_state
*state
= fe
->demodulator_priv
;
774 *unc
= dib3000mc_read_word(state
, 508);
778 static int dib3000mc_read_signal_strength(struct dvb_frontend
*fe
, u16
*strength
)
780 struct dib3000mc_state
*state
= fe
->demodulator_priv
;
781 u16 val
= dib3000mc_read_word(state
, 392);
782 *strength
= 65535 - val
;
786 static int dib3000mc_read_snr(struct dvb_frontend
* fe
, u16
*snr
)
792 static int dib3000mc_fe_get_tune_settings(struct dvb_frontend
* fe
, struct dvb_frontend_tune_settings
*tune
)
794 tune
->min_delay_ms
= 1000;
798 static void dib3000mc_release(struct dvb_frontend
*fe
)
800 struct dib3000mc_state
*state
= fe
->demodulator_priv
;
801 dibx000_exit_i2c_master(&state
->i2c_master
);
805 int dib3000mc_pid_control(struct dvb_frontend
*fe
, int index
, int pid
,int onoff
)
807 struct dib3000mc_state
*state
= fe
->demodulator_priv
;
808 dib3000mc_write_word(state
, 212 + index
, onoff
? (1 << 13) | pid
: 0);
811 EXPORT_SYMBOL(dib3000mc_pid_control
);
813 int dib3000mc_pid_parse(struct dvb_frontend
*fe
, int onoff
)
815 struct dib3000mc_state
*state
= fe
->demodulator_priv
;
816 u16 tmp
= dib3000mc_read_word(state
, 206) & ~(1 << 4);
818 return dib3000mc_write_word(state
, 206, tmp
);
820 EXPORT_SYMBOL(dib3000mc_pid_parse
);
822 void dib3000mc_set_config(struct dvb_frontend
*fe
, struct dib3000mc_config
*cfg
)
824 struct dib3000mc_state
*state
= fe
->demodulator_priv
;
827 EXPORT_SYMBOL(dib3000mc_set_config
);
829 static struct dvb_frontend_ops dib3000mc_ops
;
831 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
[])
833 struct dib3000mc_state
*st
;
836 if (no_of_demods
< 1)
839 for (k
= 0; k
< no_of_demods
; k
++) {
840 st
= kzalloc(sizeof(struct dib3000mc_state
), GFP_KERNEL
);
847 // st->gpio_val = cfg[k].gpio_val;
848 // st->gpio_dir = cfg[k].gpio_dir;
849 st
->i2c_adap
= i2c_adap
;
851 demod
[k
] = &st
->demod
;
852 demod
[k
]->demodulator_priv
= st
;
853 memcpy(&st
->demod
.ops
, &dib3000mc_ops
, sizeof(struct dvb_frontend_ops
));
855 // INIT_COMPONENT_REGISTER_ACCESS(&st->register_access, 12, 16, dib7000p_register_read, dib7000p_register_write, st);
856 // demod[k]->register_access = &st->register_access;
860 if (dib3000mc_i2c_enumeration(demod
,no_of_demods
,default_addr
) != 0)
863 st
= demod
[0]->demodulator_priv
;
864 st
->i2c_addr
= default_addr
;
865 if (dib3000mc_identify(st
) != 0)
869 for (k
= 0; k
< num
; k
++) {
870 st
= demod
[k
]->demodulator_priv
;
871 dibx000_init_i2c_master(&st
->i2c_master
, DIB3000MC
, st
->i2c_adap
, st
->i2c_addr
);
877 for (k
= 0; k
< num
; k
++) {
878 kfree(demod
[k
]->demodulator_priv
);
884 EXPORT_SYMBOL(dib3000mc_attach
);
886 static struct dvb_frontend_ops dib3000mc_ops
= {
888 .name
= "DiBcom 3000MC/P",
890 .frequency_min
= 44250000,
891 .frequency_max
= 867250000,
892 .frequency_stepsize
= 62500,
893 .caps
= FE_CAN_INVERSION_AUTO
|
894 FE_CAN_FEC_1_2
| FE_CAN_FEC_2_3
| FE_CAN_FEC_3_4
|
895 FE_CAN_FEC_5_6
| FE_CAN_FEC_7_8
| FE_CAN_FEC_AUTO
|
896 FE_CAN_QPSK
| FE_CAN_QAM_16
| FE_CAN_QAM_64
| FE_CAN_QAM_AUTO
|
897 FE_CAN_TRANSMISSION_MODE_AUTO
|
898 FE_CAN_GUARD_INTERVAL_AUTO
|
900 FE_CAN_HIERARCHY_AUTO
,
903 .release
= dib3000mc_release
,
905 .init
= dib3000mc_init
,
906 .sleep
= dib3000mc_sleep
,
908 .set_frontend
= dib3000mc_set_frontend
,
909 .get_tune_settings
= dib3000mc_fe_get_tune_settings
,
910 .get_frontend
= dib3000mc_get_frontend
,
912 .read_status
= dib3000mc_read_status
,
913 .read_ber
= dib3000mc_read_ber
,
914 .read_signal_strength
= dib3000mc_read_signal_strength
,
915 .read_snr
= dib3000mc_read_snr
,
916 .read_ucblocks
= dib3000mc_read_unc_blocks
,
919 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
920 MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator");
921 MODULE_LICENSE("GPL");