Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial
[deliverable/linux.git] / drivers / media / dvb-frontends / dib3000mc.c
CommitLineData
1da177e4 1/*
b7571f8d 2 * Driver for DiBcom DiB3000MC/P-demodulator.
1da177e4 3 *
b6884a17 4 * Copyright (C) 2004-7 DiBcom (http://www.dibcom.fr/)
1da177e4
LT
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 *
b7571f8d 7 * This code is partially based on the previous dib3000mc.c .
1da177e4 8 *
b7571f8d 9 * This program is free software; you can redistribute it and/or
1da177e4
LT
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation, version 2.
1da177e4 12 */
b7571f8d 13
1da177e4 14#include <linux/kernel.h>
5a0e3ad6 15#include <linux/slab.h>
b7571f8d 16#include <linux/i2c.h>
b7571f8d
PB
17
18#include "dvb_frontend.h"
19
20#include "dib3000mc.h"
21
1da177e4
LT
22static int debug;
23module_param(debug, int, 0644);
b7571f8d 24MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
1da177e4 25
8f6956c7
MD
26static int buggy_sfn_workaround;
27module_param(buggy_sfn_workaround, int, 0644);
8d99996b 28MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
8f6956c7 29
b6884a17 30#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); printk("\n"); } } while (0)
b7571f8d
PB
31
32struct dib3000mc_state {
33 struct dvb_frontend demod;
34 struct dib3000mc_config *cfg;
35
36 u8 i2c_addr;
37 struct i2c_adapter *i2c_adap;
38
39 struct dibx000_i2c_master i2c_master;
40
01b4bf31
PB
41 u32 timf;
42
88ab898f 43 u32 current_bandwidth;
b7571f8d
PB
44
45 u16 dev_id;
8f6956c7
MD
46
47 u8 sfn_workaround_active :1;
b7571f8d
PB
48};
49
50static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
51{
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 },
57 };
58
59 if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
60 dprintk("i2c read error on %d\n",reg);
61
62 return (rb[0] << 8) | rb[1];
63}
64
65static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
66{
67 u8 b[4] = {
68 (reg >> 8) & 0xff, reg & 0xff,
69 (val >> 8) & 0xff, val & 0xff,
70 };
71 struct i2c_msg msg = {
72 .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
73 };
74 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
75}
76
b7571f8d 77static int dib3000mc_identify(struct dib3000mc_state *state)
1da177e4 78{
b7571f8d
PB
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;
83 }
1da177e4 84
b7571f8d
PB
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;
1da177e4 89 }
b7571f8d
PB
90 state->dev_id = value;
91
92 dprintk("-I- found DiB3000MC/P: %x\n",state->dev_id);
93
94 return 0;
95}
96
b6884a17 97static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u32 bw, u8 update_offset)
b7571f8d 98{
01b4bf31 99 u32 timf;
b7571f8d 100
01b4bf31
PB
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
1da177e4 105 } else
01b4bf31 106 timf = state->timf;
1da177e4 107
b6884a17 108 timf *= (bw / 1000);
1da177e4 109
01b4bf31
PB
110 if (update_offset) {
111 s16 tim_offs = dib3000mc_read_word(state, 416);
112
113 if (tim_offs & 0x2000)
114 tim_offs -= 0x4000;
115
b6884a17 116 if (nfft == TRANSMISSION_MODE_2K)
01b4bf31
PB
117 tim_offs *= 4;
118
119 timf += tim_offs;
b6884a17 120 state->timf = timf / (bw / 1000);
01b4bf31 121 }
b7571f8d 122
01b4bf31 123 dprintk("timf: %d\n", timf);
1da177e4 124
b6884a17
PB
125 dib3000mc_write_word(state, 23, (u16) (timf >> 16));
126 dib3000mc_write_word(state, 24, (u16) (timf ) & 0xffff);
1da177e4 127
1da177e4
LT
128 return 0;
129}
130
01b4bf31 131static int dib3000mc_setup_pwm_state(struct dib3000mc_state *state)
1da177e4 132{
01b4bf31 133 u16 reg_51, reg_52 = state->cfg->agc->setup & 0xfefb;
c7a092e3 134 if (state->cfg->pwm3_inversion) {
01b4bf31
PB
135 reg_51 = (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
136 reg_52 |= (1 << 2);
1da177e4 137 } else {
01b4bf31
PB
138 reg_51 = (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
139 reg_52 |= (1 << 8);
1da177e4 140 }
01b4bf31
PB
141 dib3000mc_write_word(state, 51, reg_51);
142 dib3000mc_write_word(state, 52, reg_52);
b7571f8d 143
c7a092e3 144 if (state->cfg->use_pwm3)
b7571f8d
PB
145 dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0));
146 else
147 dib3000mc_write_word(state, 245, 0);
148
f9e2e0e8 149 dib3000mc_write_word(state, 1040, 0x3);
1da177e4
LT
150 return 0;
151}
152
b7571f8d 153static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode)
1da177e4 154{
b7571f8d
PB
155 int ret = 0;
156 u16 fifo_threshold = 1792;
157 u16 outreg = 0;
158 u16 outmode = 0;
159 u16 elecout = 1;
fb6065bb 160 u16 smo_reg = dib3000mc_read_word(state, 206) & 0x0010; /* keep the pid_parse bit */
b7571f8d
PB
161
162 dprintk("-I- Setting output mode for demod %p to %d\n",
163 &state->demod, mode);
164
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
187 */
fb6065bb 188 smo_reg |= 3 << 1;
b7571f8d
PB
189 fifo_threshold = 512;
190 outmode = 5;
191 break;
192 case OUTMODE_DIVERSITY:
193 outmode = 4;
194 elecout = 1;
1da177e4
LT
195 break;
196 default:
b7571f8d
PB
197 dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod);
198 outmode = 0;
1da177e4
LT
199 break;
200 }
b7571f8d
PB
201
202 if ((state->cfg->output_mpeg2_in_188_bytes))
559463bb 203 smo_reg |= (1 << 5); // P_smo_rs_discard [1;5:5] = 1
b7571f8d
PB
204
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;
1da177e4
LT
212}
213
b6884a17 214static int dib3000mc_set_bandwidth(struct dib3000mc_state *state, u32 bw)
1da177e4 215{
b7571f8d
PB
216 u16 bw_cfg[6] = { 0 };
217 u16 imp_bw_cfg[3] = { 0 };
218 u16 reg;
1da177e4 219
b7571f8d
PB
220/* settings here are for 27.7MHz */
221 switch (bw) {
b6884a17 222 case 8000:
b7571f8d
PB
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;
1da177e4 226
b6884a17 227 case 7000:
b7571f8d
PB
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;
1da177e4 231
b6884a17 232 case 6000:
b7571f8d
PB
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;
1da177e4 235 break;
b7571f8d 236
b6884a17 237 case 5000:
b7571f8d
PB
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;
1da177e4 240 break;
b7571f8d
PB
241
242 default: return -EINVAL;
1da177e4
LT
243 }
244
b7571f8d
PB
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);
1da177e4 256
b7571f8d
PB
257 for (reg = 55; reg < 58; reg++)
258 dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]);
1da177e4 259
b7571f8d 260 // Timing configuration
b6884a17 261 dib3000mc_set_timing(state, TRANSMISSION_MODE_2K, bw, 0);
1da177e4 262
b7571f8d
PB
263 return 0;
264}
1da177e4 265
b7571f8d 266static u16 impulse_noise_val[29] =
1da177e4 267
b7571f8d
PB
268{
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
272};
1da177e4 273
b7571f8d
PB
274static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft)
275{
276 u16 i;
277 for (i = 58; i < 87; i++)
278 dib3000mc_write_word(state, i, impulse_noise_val[i-58]);
279
b6884a17 280 if (nfft == TRANSMISSION_MODE_8K) {
b7571f8d
PB
281 dib3000mc_write_word(state, 58, 0x3b);
282 dib3000mc_write_word(state, 84, 0x00);
283 dib3000mc_write_word(state, 85, 0x8200);
1da177e4
LT
284 }
285
b7571f8d
PB
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));
290}
291
292static int dib3000mc_init(struct dvb_frontend *demod)
293{
294 struct dib3000mc_state *state = demod->demodulator_priv;
295 struct dibx000_agc_config *agc = state->cfg->agc;
296
297 // Restart Configuration
298 dib3000mc_write_word(state, 1027, 0x8000);
299 dib3000mc_write_word(state, 1027, 0x0000);
300
301 // power up the demod + mobility configuration
302 dib3000mc_write_word(state, 140, 0x0000);
303 dib3000mc_write_word(state, 1031, 0);
304
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);
1da177e4 310 } else {
b7571f8d
PB
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);
1da177e4 315 }
303cbeaa 316 dib3000mc_write_word(state, 1033, 0x0000);
1da177e4 317
b7571f8d 318 // P_clk_cfg
303cbeaa 319 dib3000mc_write_word(state, 1037, 0x3130);
1da177e4 320
b7571f8d 321 // other configurations
1da177e4 322
b7571f8d
PB
323 // P_ctrl_sfreq
324 dib3000mc_write_word(state, 33, (5 << 0));
325 dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0));
1da177e4 326
b7571f8d
PB
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));
1da177e4 330
b7571f8d
PB
331 if (state->cfg->phase_noise_mode == 0)
332 dib3000mc_write_word(state, 111, 0x00);
333 else
334 dib3000mc_write_word(state, 111, 0x02);
335
336 // P_agc_global
337 dib3000mc_write_word(state, 50, 0x8000);
338
339 // agc setup misc
01b4bf31 340 dib3000mc_setup_pwm_state(state);
b7571f8d
PB
341
342 // P_agc_counter_lock
343 dib3000mc_write_word(state, 53, 0x87);
344 // P_agc_counter_unlock
345 dib3000mc_write_word(state, 54, 0x87);
346
347 /* agc */
348 dib3000mc_write_word(state, 36, state->cfg->max_time);
5570dd02 349 dib3000mc_write_word(state, 37, (state->cfg->agc_command1 << 13) | (state->cfg->agc_command2 << 12) | (0x1d << 0));
b7571f8d
PB
350 dib3000mc_write_word(state, 38, state->cfg->pwm3_value);
351 dib3000mc_write_word(state, 39, state->cfg->ln_adc_level);
352
353 // set_agc_loop_Bw
354 dib3000mc_write_word(state, 40, 0x0179);
355 dib3000mc_write_word(state, 41, 0x03f0);
356
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);
365
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);
379
b6884a17 380 dib3000mc_set_bandwidth(state, 8000);
b7571f8d
PB
381
382 // div_lock_mask
383 dib3000mc_write_word(state, 4, 0x814);
384
385 dib3000mc_write_word(state, 21, (1 << 9) | 0x164);
386 dib3000mc_write_word(state, 22, 0x463d);
387
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);
393
394 // Fec cfg
395 dib3000mc_write_word(state, 195, 0x10);
396
397 // diversity register: P_dvsy_sync_wait..
398 dib3000mc_write_word(state, 180, 0x2FF0);
399
400 // Impulse noise configuration
b6884a17 401 dib3000mc_set_impulse_noise(state, 0, TRANSMISSION_MODE_8K);
b7571f8d
PB
402
403 // output mode set-up
404 dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
405
406 /* close the i2c-gate */
407 dib3000mc_write_word(state, 769, (1 << 7) );
1da177e4 408
b7571f8d
PB
409 return 0;
410}
1da177e4 411
b7571f8d
PB
412static int dib3000mc_sleep(struct dvb_frontend *demod)
413{
414 struct dib3000mc_state *state = demod->demodulator_priv;
1da177e4 415
b7571f8d
PB
416 dib3000mc_write_word(state, 1031, 0xFFFF);
417 dib3000mc_write_word(state, 1032, 0xFFFF);
303cbeaa 418 dib3000mc_write_word(state, 1033, 0xFFF0);
1da177e4 419
c7a092e3 420 return 0;
b7571f8d 421}
1da177e4 422
b7571f8d
PB
423static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
424{
425 u16 cfg[4] = { 0 },reg;
426 switch (qam) {
b6884a17 427 case QPSK:
b7571f8d
PB
428 cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0;
429 break;
b6884a17 430 case QAM_16:
b7571f8d
PB
431 cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0;
432 break;
b6884a17 433 case QAM_64:
b7571f8d
PB
434 cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8;
435 break;
1da177e4 436 }
b7571f8d
PB
437 for (reg = 129; reg < 133; reg++)
438 dib3000mc_write_word(state, reg, cfg[reg - 129]);
1da177e4
LT
439}
440
c1f814f4
MCC
441static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state,
442 struct dtv_frontend_properties *ch, u16 seq)
1da177e4 443{
b6884a17 444 u16 value;
c1f814f4
MCC
445 u32 bw = BANDWIDTH_TO_KHZ(ch->bandwidth_hz);
446
447 dib3000mc_set_bandwidth(state, bw);
448 dib3000mc_set_timing(state, ch->transmission_mode, bw, 0);
1da177e4 449
c7a092e3
MCC
450#if 1
451 dib3000mc_write_word(state, 100, (16 << 6) + 9);
452#else
453 if (boost)
454 dib3000mc_write_word(state, 100, (11 << 6) + 6);
455 else
b7571f8d 456 dib3000mc_write_word(state, 100, (16 << 6) + 9);
c7a092e3 457#endif
1da177e4 458
b7571f8d
PB
459 dib3000mc_write_word(state, 1027, 0x0800);
460 dib3000mc_write_word(state, 1027, 0x0000);
1da177e4 461
b7571f8d
PB
462 //Default cfg isi offset adp
463 dib3000mc_write_word(state, 26, 0x6680);
464 dib3000mc_write_word(state, 29, 0x1273);
465 dib3000mc_write_word(state, 33, 5);
b6884a17 466 dib3000mc_set_adp_cfg(state, QAM_16);
b7571f8d 467 dib3000mc_write_word(state, 133, 15564);
1da177e4 468
b7571f8d
PB
469 dib3000mc_write_word(state, 12 , 0x0);
470 dib3000mc_write_word(state, 13 , 0x3e8);
471 dib3000mc_write_word(state, 14 , 0x0);
472 dib3000mc_write_word(state, 15 , 0x3f2);
1da177e4 473
b7571f8d
PB
474 dib3000mc_write_word(state, 93,0);
475 dib3000mc_write_word(state, 94,0);
476 dib3000mc_write_word(state, 95,0);
477 dib3000mc_write_word(state, 96,0);
478 dib3000mc_write_word(state, 97,0);
479 dib3000mc_write_word(state, 98,0);
1da177e4 480
c1f814f4 481 dib3000mc_set_impulse_noise(state, 0, ch->transmission_mode);
e4d6c1f7 482
b6884a17 483 value = 0;
c1f814f4 484 switch (ch->transmission_mode) {
b6884a17
PB
485 case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
486 default:
487 case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
488 }
c1f814f4 489 switch (ch->guard_interval) {
b6884a17
PB
490 case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
491 case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
492 case GUARD_INTERVAL_1_4: value |= (3 << 5); break;
493 default:
494 case GUARD_INTERVAL_1_8: value |= (2 << 5); break;
495 }
c1f814f4 496 switch (ch->modulation) {
b6884a17
PB
497 case QPSK: value |= (0 << 3); break;
498 case QAM_16: value |= (1 << 3); break;
499 default:
500 case QAM_64: value |= (2 << 3); break;
501 }
502 switch (HIERARCHY_1) {
503 case HIERARCHY_2: value |= 2; break;
504 case HIERARCHY_4: value |= 4; break;
505 default:
506 case HIERARCHY_1: value |= 1; break;
507 }
508 dib3000mc_write_word(state, 0, value);
e3ab2fdd 509 dib3000mc_write_word(state, 5, (1 << 8) | ((seq & 0xf) << 4));
1da177e4 510
b6884a17 511 value = 0;
c1f814f4 512 if (ch->hierarchy == 1)
b6884a17
PB
513 value |= (1 << 4);
514 if (1 == 1)
515 value |= 1;
c1f814f4 516 switch ((ch->hierarchy == 0 || 1 == 1) ? ch->code_rate_HP : ch->code_rate_LP) {
b6884a17
PB
517 case FEC_2_3: value |= (2 << 1); break;
518 case FEC_3_4: value |= (3 << 1); break;
519 case FEC_5_6: value |= (5 << 1); break;
520 case FEC_7_8: value |= (7 << 1); break;
521 default:
522 case FEC_1_2: value |= (1 << 1); break;
523 }
524 dib3000mc_write_word(state, 181, value);
1da177e4 525
b6884a17 526 // diversity synchro delay add 50% SFN margin
c1f814f4 527 switch (ch->transmission_mode) {
b6884a17
PB
528 case TRANSMISSION_MODE_8K: value = 256; break;
529 case TRANSMISSION_MODE_2K:
530 default: value = 64; break;
531 }
c1f814f4 532 switch (ch->guard_interval) {
b6884a17
PB
533 case GUARD_INTERVAL_1_16: value *= 2; break;
534 case GUARD_INTERVAL_1_8: value *= 4; break;
535 case GUARD_INTERVAL_1_4: value *= 8; break;
536 default:
537 case GUARD_INTERVAL_1_32: value *= 1; break;
538 }
539 value <<= 4;
540 value |= dib3000mc_read_word(state, 180) & 0x000f;
541 dib3000mc_write_word(state, 180, value);
1da177e4 542
b7571f8d 543 // restart demod
b6884a17
PB
544 value = dib3000mc_read_word(state, 0);
545 dib3000mc_write_word(state, 0, value | (1 << 9));
546 dib3000mc_write_word(state, 0, value);
1da177e4 547
b7571f8d 548 msleep(30);
1da177e4 549
c1f814f4 550 dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, ch->transmission_mode);
b7571f8d 551}
1da177e4 552
c1f814f4 553static int dib3000mc_autosearch_start(struct dvb_frontend *demod)
b7571f8d 554{
c1f814f4 555 struct dtv_frontend_properties *chan = &demod->dtv_property_cache;
b7571f8d
PB
556 struct dib3000mc_state *state = demod->demodulator_priv;
557 u16 reg;
558// u32 val;
c1f814f4 559 struct dtv_frontend_properties schan;
1da177e4 560
b6884a17 561 schan = *chan;
1da177e4 562
b6884a17 563 /* TODO what is that ? */
1da177e4 564
b7571f8d 565 /* a channel for autosearch */
c1f814f4
MCC
566 schan.transmission_mode = TRANSMISSION_MODE_8K;
567 schan.guard_interval = GUARD_INTERVAL_1_32;
568 schan.modulation = QAM_64;
569 schan.code_rate_HP = FEC_2_3;
570 schan.code_rate_LP = FEC_2_3;
571 schan.hierarchy = 0;
1da177e4 572
b6884a17 573 dib3000mc_set_channel_cfg(state, &schan, 11);
1da177e4 574
b7571f8d
PB
575 reg = dib3000mc_read_word(state, 0);
576 dib3000mc_write_word(state, 0, reg | (1 << 8));
01b4bf31 577 dib3000mc_read_word(state, 511);
b7571f8d 578 dib3000mc_write_word(state, 0, reg);
1da177e4 579
b7571f8d
PB
580 return 0;
581}
1da177e4 582
b7571f8d
PB
583static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod)
584{
585 struct dib3000mc_state *state = demod->demodulator_priv;
586 u16 irq_pending = dib3000mc_read_word(state, 511);
1da177e4 587
b7571f8d
PB
588 if (irq_pending & 0x1) // failed
589 return 1;
1da177e4 590
b7571f8d
PB
591 if (irq_pending & 0x2) // succeeded
592 return 2;
a16bf5d5 593
b7571f8d 594 return 0; // still pending
1da177e4 595}
b7571f8d 596
c1f814f4 597static int dib3000mc_tune(struct dvb_frontend *demod)
1da177e4 598{
c1f814f4 599 struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
b7571f8d 600 struct dib3000mc_state *state = demod->demodulator_priv;
1da177e4 601
b7571f8d
PB
602 // ** configure demod **
603 dib3000mc_set_channel_cfg(state, ch, 0);
604
605 // activates isi
8f6956c7
MD
606 if (state->sfn_workaround_active) {
607 dprintk("SFN workaround is active\n");
608 dib3000mc_write_word(state, 29, 0x1273);
609 dib3000mc_write_word(state, 108, 0x4000); // P_pha3_force_pha_shift
610 } else {
611 dib3000mc_write_word(state, 29, 0x1073);
612 dib3000mc_write_word(state, 108, 0x0000); // P_pha3_force_pha_shift
613 }
1da177e4 614
c1f814f4
MCC
615 dib3000mc_set_adp_cfg(state, (u8)ch->modulation);
616 if (ch->transmission_mode == TRANSMISSION_MODE_8K) {
b7571f8d
PB
617 dib3000mc_write_word(state, 26, 38528);
618 dib3000mc_write_word(state, 33, 8);
619 } else {
620 dib3000mc_write_word(state, 26, 30336);
621 dib3000mc_write_word(state, 33, 6);
622 }
623
01b4bf31 624 if (dib3000mc_read_word(state, 509) & 0x80)
c1f814f4
MCC
625 dib3000mc_set_timing(state, ch->transmission_mode,
626 BANDWIDTH_TO_KHZ(ch->bandwidth_hz), 1);
1da177e4
LT
627
628 return 0;
629}
630
b7571f8d 631struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating)
1da177e4 632{
b7571f8d
PB
633 struct dib3000mc_state *st = demod->demodulator_priv;
634 return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating);
1da177e4
LT
635}
636
b7571f8d
PB
637EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master);
638
7c61d80a 639static int dib3000mc_get_frontend(struct dvb_frontend* fe)
1da177e4 640{
7c61d80a 641 struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
b7571f8d
PB
642 struct dib3000mc_state *state = fe->demodulator_priv;
643 u16 tps = dib3000mc_read_word(state,458);
1da177e4 644
b7571f8d
PB
645 fep->inversion = INVERSION_AUTO;
646
c1f814f4 647 fep->bandwidth_hz = state->current_bandwidth;
b7571f8d
PB
648
649 switch ((tps >> 8) & 0x1) {
c1f814f4
MCC
650 case 0: fep->transmission_mode = TRANSMISSION_MODE_2K; break;
651 case 1: fep->transmission_mode = TRANSMISSION_MODE_8K; break;
b7571f8d
PB
652 }
653
654 switch (tps & 0x3) {
c1f814f4
MCC
655 case 0: fep->guard_interval = GUARD_INTERVAL_1_32; break;
656 case 1: fep->guard_interval = GUARD_INTERVAL_1_16; break;
657 case 2: fep->guard_interval = GUARD_INTERVAL_1_8; break;
658 case 3: fep->guard_interval = GUARD_INTERVAL_1_4; break;
b7571f8d
PB
659 }
660
661 switch ((tps >> 13) & 0x3) {
c1f814f4
MCC
662 case 0: fep->modulation = QPSK; break;
663 case 1: fep->modulation = QAM_16; break;
b7571f8d 664 case 2:
c1f814f4 665 default: fep->modulation = QAM_64; break;
b7571f8d
PB
666 }
667
668 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
669 /* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */
670
c1f814f4 671 fep->hierarchy = HIERARCHY_NONE;
b7571f8d 672 switch ((tps >> 5) & 0x7) {
c1f814f4
MCC
673 case 1: fep->code_rate_HP = FEC_1_2; break;
674 case 2: fep->code_rate_HP = FEC_2_3; break;
675 case 3: fep->code_rate_HP = FEC_3_4; break;
676 case 5: fep->code_rate_HP = FEC_5_6; break;
b7571f8d 677 case 7:
c1f814f4 678 default: fep->code_rate_HP = FEC_7_8; break;
b7571f8d
PB
679
680 }
681
682 switch ((tps >> 2) & 0x7) {
c1f814f4
MCC
683 case 1: fep->code_rate_LP = FEC_1_2; break;
684 case 2: fep->code_rate_LP = FEC_2_3; break;
685 case 3: fep->code_rate_LP = FEC_3_4; break;
686 case 5: fep->code_rate_LP = FEC_5_6; break;
b7571f8d 687 case 7:
c1f814f4 688 default: fep->code_rate_LP = FEC_7_8; break;
b7571f8d 689 }
1da177e4 690
1da177e4
LT
691 return 0;
692}
693
c1f814f4 694static int dib3000mc_set_frontend(struct dvb_frontend *fe)
1da177e4 695{
7c61d80a 696 struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
b7571f8d 697 struct dib3000mc_state *state = fe->demodulator_priv;
c1f814f4 698 int ret;
853ea132
SM
699
700 dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
b7571f8d 701
c1f814f4
MCC
702 state->current_bandwidth = fep->bandwidth_hz;
703 dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->bandwidth_hz));
b7571f8d 704
8f6956c7
MD
705 /* maybe the parameter has been changed */
706 state->sfn_workaround_active = buggy_sfn_workaround;
707
b7571f8d 708 if (fe->ops.tuner_ops.set_params) {
14d24d14 709 fe->ops.tuner_ops.set_params(fe);
b7571f8d
PB
710 msleep(100);
711 }
712
c1f814f4
MCC
713 if (fep->transmission_mode == TRANSMISSION_MODE_AUTO ||
714 fep->guard_interval == GUARD_INTERVAL_AUTO ||
715 fep->modulation == QAM_AUTO ||
716 fep->code_rate_HP == FEC_AUTO) {
3a0311c6 717 int i = 1000, found;
b7571f8d 718
c1f814f4 719 dib3000mc_autosearch_start(fe);
b7571f8d
PB
720 do {
721 msleep(1);
722 found = dib3000mc_autosearch_is_irq(fe);
723 } while (found == 0 && i--);
724
725 dprintk("autosearch returns: %d\n",found);
726 if (found == 0 || found == 1)
727 return 0; // no channel found
728
7c61d80a 729 dib3000mc_get_frontend(fe);
b7571f8d
PB
730 }
731
c1f814f4 732 ret = dib3000mc_tune(fe);
853ea132 733
b7571f8d
PB
734 /* make this a config parameter */
735 dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
c1f814f4 736 return ret;
1da177e4
LT
737}
738
0df289a2 739static int dib3000mc_read_status(struct dvb_frontend *fe, enum fe_status *stat)
1da177e4 740{
b7571f8d
PB
741 struct dib3000mc_state *state = fe->demodulator_priv;
742 u16 lock = dib3000mc_read_word(state, 509);
743
744 *stat = 0;
745
746 if (lock & 0x8000)
747 *stat |= FE_HAS_SIGNAL;
748 if (lock & 0x3000)
749 *stat |= FE_HAS_CARRIER;
750 if (lock & 0x0100)
751 *stat |= FE_HAS_VITERBI;
752 if (lock & 0x0010)
753 *stat |= FE_HAS_SYNC;
754 if (lock & 0x0008)
755 *stat |= FE_HAS_LOCK;
756
1da177e4
LT
757 return 0;
758}
759
b7571f8d 760static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber)
1da177e4 761{
b7571f8d
PB
762 struct dib3000mc_state *state = fe->demodulator_priv;
763 *ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501);
764 return 0;
1da177e4
LT
765}
766
b7571f8d 767static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
1da177e4 768{
b7571f8d
PB
769 struct dib3000mc_state *state = fe->demodulator_priv;
770 *unc = dib3000mc_read_word(state, 508);
771 return 0;
1da177e4
LT
772}
773
b7571f8d 774static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1da177e4 775{
b7571f8d
PB
776 struct dib3000mc_state *state = fe->demodulator_priv;
777 u16 val = dib3000mc_read_word(state, 392);
778 *strength = 65535 - val;
779 return 0;
1da177e4
LT
780}
781
b7571f8d 782static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
1da177e4 783{
b7571f8d 784 *snr = 0x0000;
1da177e4
LT
785 return 0;
786}
787
b7571f8d 788static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
1da177e4 789{
b7571f8d 790 tune->min_delay_ms = 1000;
1da177e4
LT
791 return 0;
792}
793
b7571f8d 794static void dib3000mc_release(struct dvb_frontend *fe)
1da177e4 795{
b7571f8d
PB
796 struct dib3000mc_state *state = fe->demodulator_priv;
797 dibx000_exit_i2c_master(&state->i2c_master);
798 kfree(state);
1da177e4
LT
799}
800
b7571f8d 801int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff)
1da177e4 802{
b7571f8d
PB
803 struct dib3000mc_state *state = fe->demodulator_priv;
804 dib3000mc_write_word(state, 212 + index, onoff ? (1 << 13) | pid : 0);
1da177e4
LT
805 return 0;
806}
b7571f8d 807EXPORT_SYMBOL(dib3000mc_pid_control);
1da177e4 808
b7571f8d 809int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
1da177e4 810{
b7571f8d
PB
811 struct dib3000mc_state *state = fe->demodulator_priv;
812 u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4);
813 tmp |= (onoff << 4);
814 return dib3000mc_write_word(state, 206, tmp);
1da177e4 815}
b7571f8d 816EXPORT_SYMBOL(dib3000mc_pid_parse);
1da177e4 817
b7571f8d 818void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg)
e4d6c1f7 819{
b7571f8d
PB
820 struct dib3000mc_state *state = fe->demodulator_priv;
821 state->cfg = cfg;
e4d6c1f7 822}
b7571f8d 823EXPORT_SYMBOL(dib3000mc_set_config);
1da177e4 824
136cafbf 825int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[])
1da177e4 826{
0de8e353 827 struct dib3000mc_state *dmcst;
136cafbf
PB
828 int k;
829 u8 new_addr;
1da177e4 830
136cafbf 831 static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
1da177e4 832
0de8e353
RD
833 dmcst = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
834 if (dmcst == NULL)
febe2ea1 835 return -ENOMEM;
0de8e353
RD
836
837 dmcst->i2c_adap = i2c;
838
136cafbf 839 for (k = no_of_demods-1; k >= 0; k--) {
0de8e353 840 dmcst->cfg = &cfg[k];
1da177e4 841
136cafbf
PB
842 /* designated i2c address */
843 new_addr = DIB3000MC_I2C_ADDRESS[k];
0de8e353
RD
844 dmcst->i2c_addr = new_addr;
845 if (dib3000mc_identify(dmcst) != 0) {
846 dmcst->i2c_addr = default_addr;
847 if (dib3000mc_identify(dmcst) != 0) {
136cafbf 848 dprintk("-E- DiB3000P/MC #%d: not identified\n", k);
0de8e353 849 kfree(dmcst);
136cafbf
PB
850 return -ENODEV;
851 }
852 }
1da177e4 853
0de8e353 854 dib3000mc_set_output_mode(dmcst, OUTMODE_MPEG2_PAR_CONT_CLK);
1da177e4 855
136cafbf 856 // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
0de8e353
RD
857 dib3000mc_write_word(dmcst, 1024, (new_addr << 3) | 0x1);
858 dmcst->i2c_addr = new_addr;
b7571f8d 859 }
1da177e4 860
136cafbf 861 for (k = 0; k < no_of_demods; k++) {
0de8e353
RD
862 dmcst->cfg = &cfg[k];
863 dmcst->i2c_addr = DIB3000MC_I2C_ADDRESS[k];
1da177e4 864
0de8e353 865 dib3000mc_write_word(dmcst, 1024, dmcst->i2c_addr << 3);
1da177e4 866
136cafbf 867 /* turn off data output */
0de8e353 868 dib3000mc_set_output_mode(dmcst, OUTMODE_HIGH_Z);
136cafbf 869 }
0de8e353
RD
870
871 kfree(dmcst);
b7571f8d 872 return 0;
136cafbf
PB
873}
874EXPORT_SYMBOL(dib3000mc_i2c_enumeration);
875
876static struct dvb_frontend_ops dib3000mc_ops;
877
878struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
879{
880 struct dvb_frontend *demod;
881 struct dib3000mc_state *st;
882 st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
883 if (st == NULL)
884 return NULL;
885
886 st->cfg = cfg;
887 st->i2c_adap = i2c_adap;
6958effe 888 st->i2c_addr = i2c_addr;
136cafbf
PB
889
890 demod = &st->demod;
891 demod->demodulator_priv = st;
892 memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
893
894 if (dib3000mc_identify(st) != 0)
895 goto error;
896
897 dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
898
303cbeaa
PB
899 dib3000mc_write_word(st, 1037, 0x3130);
900
136cafbf 901 return demod;
1da177e4
LT
902
903error:
136cafbf
PB
904 kfree(st);
905 return NULL;
1da177e4 906}
e4d6c1f7 907EXPORT_SYMBOL(dib3000mc_attach);
1da177e4
LT
908
909static struct dvb_frontend_ops dib3000mc_ops = {
c1f814f4 910 .delsys = { SYS_DVBT },
1da177e4 911 .info = {
b7571f8d 912 .name = "DiBcom 3000MC/P",
b7571f8d
PB
913 .frequency_min = 44250000,
914 .frequency_max = 867250000,
915 .frequency_stepsize = 62500,
1da177e4 916 .caps = FE_CAN_INVERSION_AUTO |
b7571f8d
PB
917 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
918 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
919 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
920 FE_CAN_TRANSMISSION_MODE_AUTO |
921 FE_CAN_GUARD_INTERVAL_AUTO |
922 FE_CAN_RECOVER |
923 FE_CAN_HIERARCHY_AUTO,
1da177e4
LT
924 },
925
b7571f8d 926 .release = dib3000mc_release,
1da177e4 927
b7571f8d
PB
928 .init = dib3000mc_init,
929 .sleep = dib3000mc_sleep,
1da177e4 930
c1f814f4 931 .set_frontend = dib3000mc_set_frontend,
b7571f8d 932 .get_tune_settings = dib3000mc_fe_get_tune_settings,
c1f814f4 933 .get_frontend = dib3000mc_get_frontend,
1da177e4 934
b7571f8d
PB
935 .read_status = dib3000mc_read_status,
936 .read_ber = dib3000mc_read_ber,
1da177e4 937 .read_signal_strength = dib3000mc_read_signal_strength,
b7571f8d
PB
938 .read_snr = dib3000mc_read_snr,
939 .read_ucblocks = dib3000mc_read_unc_blocks,
1da177e4
LT
940};
941
b7571f8d
PB
942MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
943MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator");
1da177e4 944MODULE_LICENSE("GPL");
This page took 0.956182 seconds and 5 git commands to generate.