]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/media/dvb/frontends/dib3000mc.c
V4L/DVB (5962): Fix line-break in err output
[mirror_ubuntu-bionic-kernel.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>
b7571f8d 15#include <linux/i2c.h>
b7571f8d
PB
16
17#include "dvb_frontend.h"
18
19#include "dib3000mc.h"
20
1da177e4
LT
21static int debug;
22module_param(debug, int, 0644);
b7571f8d 23MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
1da177e4 24
8f6956c7
MD
25static int buggy_sfn_workaround;
26module_param(buggy_sfn_workaround, int, 0644);
27MODULE_PARM_DESC(debug, "Enable work-around for buggy SFNs (default: 0)");
28
b6884a17 29#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); printk("\n"); } } while (0)
b7571f8d
PB
30
31struct dib3000mc_state {
32 struct dvb_frontend demod;
33 struct dib3000mc_config *cfg;
34
35 u8 i2c_addr;
36 struct i2c_adapter *i2c_adap;
37
38 struct dibx000_i2c_master i2c_master;
39
01b4bf31
PB
40 u32 timf;
41
b7571f8d
PB
42 fe_bandwidth_t current_bandwidth;
43
44 u16 dev_id;
8f6956c7
MD
45
46 u8 sfn_workaround_active :1;
b7571f8d
PB
47};
48
49static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
50{
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 },
56 };
57
58 if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
59 dprintk("i2c read error on %d\n",reg);
60
61 return (rb[0] << 8) | rb[1];
62}
63
64static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
65{
66 u8 b[4] = {
67 (reg >> 8) & 0xff, reg & 0xff,
68 (val >> 8) & 0xff, val & 0xff,
69 };
70 struct i2c_msg msg = {
71 .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
72 };
73 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
74}
75
b7571f8d 76static int dib3000mc_identify(struct dib3000mc_state *state)
1da177e4 77{
b7571f8d
PB
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;
82 }
1da177e4 83
b7571f8d
PB
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;
1da177e4 88 }
b7571f8d
PB
89 state->dev_id = value;
90
91 dprintk("-I- found DiB3000MC/P: %x\n",state->dev_id);
92
93 return 0;
94}
95
b6884a17 96static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u32 bw, u8 update_offset)
b7571f8d 97{
01b4bf31 98 u32 timf;
b7571f8d 99
01b4bf31
PB
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
1da177e4 104 } else
01b4bf31 105 timf = state->timf;
1da177e4 106
b6884a17 107 timf *= (bw / 1000);
1da177e4 108
01b4bf31
PB
109 if (update_offset) {
110 s16 tim_offs = dib3000mc_read_word(state, 416);
111
112 if (tim_offs & 0x2000)
113 tim_offs -= 0x4000;
114
b6884a17 115 if (nfft == TRANSMISSION_MODE_2K)
01b4bf31
PB
116 tim_offs *= 4;
117
118 timf += tim_offs;
b6884a17 119 state->timf = timf / (bw / 1000);
01b4bf31 120 }
b7571f8d 121
01b4bf31 122 dprintk("timf: %d\n", timf);
1da177e4 123
b6884a17
PB
124 dib3000mc_write_word(state, 23, (u16) (timf >> 16));
125 dib3000mc_write_word(state, 24, (u16) (timf ) & 0xffff);
1da177e4 126
1da177e4
LT
127 return 0;
128}
129
01b4bf31 130static int dib3000mc_setup_pwm_state(struct dib3000mc_state *state)
1da177e4 131{
01b4bf31 132 u16 reg_51, reg_52 = state->cfg->agc->setup & 0xfefb;
b7571f8d 133 if (state->cfg->pwm3_inversion) {
01b4bf31
PB
134 reg_51 = (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
135 reg_52 |= (1 << 2);
1da177e4 136 } else {
01b4bf31
PB
137 reg_51 = (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
138 reg_52 |= (1 << 8);
1da177e4 139 }
01b4bf31
PB
140 dib3000mc_write_word(state, 51, reg_51);
141 dib3000mc_write_word(state, 52, reg_52);
b7571f8d
PB
142
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);
147
148 dib3000mc_write_word(state, 1040, 0x3);
1da177e4
LT
149 return 0;
150}
151
b7571f8d 152static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode)
1da177e4 153{
b7571f8d
PB
154 int ret = 0;
155 u16 fifo_threshold = 1792;
156 u16 outreg = 0;
157 u16 outmode = 0;
158 u16 elecout = 1;
fb6065bb 159 u16 smo_reg = dib3000mc_read_word(state, 206) & 0x0010; /* keep the pid_parse bit */
b7571f8d
PB
160
161 dprintk("-I- Setting output mode for demod %p to %d\n",
162 &state->demod, mode);
163
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
186 */
fb6065bb 187 smo_reg |= 3 << 1;
b7571f8d
PB
188 fifo_threshold = 512;
189 outmode = 5;
190 break;
191 case OUTMODE_DIVERSITY:
192 outmode = 4;
193 elecout = 1;
1da177e4
LT
194 break;
195 default:
b7571f8d
PB
196 dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod);
197 outmode = 0;
1da177e4
LT
198 break;
199 }
b7571f8d
PB
200
201 if ((state->cfg->output_mpeg2_in_188_bytes))
559463bb 202 smo_reg |= (1 << 5); // P_smo_rs_discard [1;5:5] = 1
b7571f8d
PB
203
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;
1da177e4
LT
211}
212
b6884a17 213static int dib3000mc_set_bandwidth(struct dib3000mc_state *state, u32 bw)
1da177e4 214{
b7571f8d
PB
215 u16 bw_cfg[6] = { 0 };
216 u16 imp_bw_cfg[3] = { 0 };
217 u16 reg;
1da177e4 218
b7571f8d
PB
219/* settings here are for 27.7MHz */
220 switch (bw) {
b6884a17 221 case 8000:
b7571f8d
PB
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;
1da177e4 225
b6884a17 226 case 7000:
b7571f8d
PB
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;
1da177e4 230
b6884a17 231 case 6000:
b7571f8d
PB
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;
1da177e4 234 break;
b7571f8d 235
b6884a17 236 case 5000:
b7571f8d
PB
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;
1da177e4 239 break;
b7571f8d
PB
240
241 default: return -EINVAL;
1da177e4
LT
242 }
243
b7571f8d
PB
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);
1da177e4 255
b7571f8d
PB
256 for (reg = 55; reg < 58; reg++)
257 dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]);
1da177e4 258
b7571f8d 259 // Timing configuration
b6884a17 260 dib3000mc_set_timing(state, TRANSMISSION_MODE_2K, bw, 0);
1da177e4 261
b7571f8d
PB
262 return 0;
263}
1da177e4 264
b7571f8d 265static u16 impulse_noise_val[29] =
1da177e4 266
b7571f8d
PB
267{
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
271};
1da177e4 272
b7571f8d
PB
273static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft)
274{
275 u16 i;
276 for (i = 58; i < 87; i++)
277 dib3000mc_write_word(state, i, impulse_noise_val[i-58]);
278
b6884a17 279 if (nfft == TRANSMISSION_MODE_8K) {
b7571f8d
PB
280 dib3000mc_write_word(state, 58, 0x3b);
281 dib3000mc_write_word(state, 84, 0x00);
282 dib3000mc_write_word(state, 85, 0x8200);
1da177e4
LT
283 }
284
b7571f8d
PB
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));
289}
290
291static int dib3000mc_init(struct dvb_frontend *demod)
292{
293 struct dib3000mc_state *state = demod->demodulator_priv;
294 struct dibx000_agc_config *agc = state->cfg->agc;
295
296 // Restart Configuration
297 dib3000mc_write_word(state, 1027, 0x8000);
298 dib3000mc_write_word(state, 1027, 0x0000);
299
300 // power up the demod + mobility configuration
301 dib3000mc_write_word(state, 140, 0x0000);
302 dib3000mc_write_word(state, 1031, 0);
303
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);
1da177e4 309 } else {
b7571f8d
PB
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);
1da177e4 314 }
303cbeaa 315 dib3000mc_write_word(state, 1033, 0x0000);
1da177e4 316
b7571f8d 317 // P_clk_cfg
303cbeaa 318 dib3000mc_write_word(state, 1037, 0x3130);
1da177e4 319
b7571f8d 320 // other configurations
1da177e4 321
b7571f8d
PB
322 // P_ctrl_sfreq
323 dib3000mc_write_word(state, 33, (5 << 0));
324 dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0));
1da177e4 325
b7571f8d
PB
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));
1da177e4 329
b7571f8d
PB
330 if (state->cfg->phase_noise_mode == 0)
331 dib3000mc_write_word(state, 111, 0x00);
332 else
333 dib3000mc_write_word(state, 111, 0x02);
334
335 // P_agc_global
336 dib3000mc_write_word(state, 50, 0x8000);
337
338 // agc setup misc
01b4bf31 339 dib3000mc_setup_pwm_state(state);
b7571f8d
PB
340
341 // P_agc_counter_lock
342 dib3000mc_write_word(state, 53, 0x87);
343 // P_agc_counter_unlock
344 dib3000mc_write_word(state, 54, 0x87);
345
346 /* agc */
347 dib3000mc_write_word(state, 36, state->cfg->max_time);
5570dd02 348 dib3000mc_write_word(state, 37, (state->cfg->agc_command1 << 13) | (state->cfg->agc_command2 << 12) | (0x1d << 0));
b7571f8d
PB
349 dib3000mc_write_word(state, 38, state->cfg->pwm3_value);
350 dib3000mc_write_word(state, 39, state->cfg->ln_adc_level);
351
352 // set_agc_loop_Bw
353 dib3000mc_write_word(state, 40, 0x0179);
354 dib3000mc_write_word(state, 41, 0x03f0);
355
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);
364
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);
378
b6884a17 379 dib3000mc_set_bandwidth(state, 8000);
b7571f8d
PB
380
381 // div_lock_mask
382 dib3000mc_write_word(state, 4, 0x814);
383
384 dib3000mc_write_word(state, 21, (1 << 9) | 0x164);
385 dib3000mc_write_word(state, 22, 0x463d);
386
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);
392
393 // Fec cfg
394 dib3000mc_write_word(state, 195, 0x10);
395
396 // diversity register: P_dvsy_sync_wait..
397 dib3000mc_write_word(state, 180, 0x2FF0);
398
399 // Impulse noise configuration
b6884a17 400 dib3000mc_set_impulse_noise(state, 0, TRANSMISSION_MODE_8K);
b7571f8d
PB
401
402 // output mode set-up
403 dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
404
405 /* close the i2c-gate */
406 dib3000mc_write_word(state, 769, (1 << 7) );
1da177e4 407
b7571f8d
PB
408 return 0;
409}
1da177e4 410
b7571f8d
PB
411static int dib3000mc_sleep(struct dvb_frontend *demod)
412{
413 struct dib3000mc_state *state = demod->demodulator_priv;
1da177e4 414
b7571f8d
PB
415 dib3000mc_write_word(state, 1031, 0xFFFF);
416 dib3000mc_write_word(state, 1032, 0xFFFF);
303cbeaa 417 dib3000mc_write_word(state, 1033, 0xFFF0);
1da177e4 418
b7571f8d
PB
419 return 0;
420}
1da177e4 421
b7571f8d
PB
422static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
423{
424 u16 cfg[4] = { 0 },reg;
425 switch (qam) {
b6884a17 426 case QPSK:
b7571f8d
PB
427 cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0;
428 break;
b6884a17 429 case QAM_16:
b7571f8d
PB
430 cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0;
431 break;
b6884a17 432 case QAM_64:
b7571f8d
PB
433 cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8;
434 break;
1da177e4 435 }
b7571f8d
PB
436 for (reg = 129; reg < 133; reg++)
437 dib3000mc_write_word(state, reg, cfg[reg - 129]);
1da177e4
LT
438}
439
b6884a17 440static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dvb_frontend_parameters *ch, u16 seq)
1da177e4 441{
b6884a17
PB
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);
1da177e4 445
b7571f8d
PB
446// if (boost)
447// dib3000mc_write_word(state, 100, (11 << 6) + 6);
448// else
449 dib3000mc_write_word(state, 100, (16 << 6) + 9);
1da177e4 450
b7571f8d
PB
451 dib3000mc_write_word(state, 1027, 0x0800);
452 dib3000mc_write_word(state, 1027, 0x0000);
1da177e4 453
b7571f8d
PB
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);
b6884a17 458 dib3000mc_set_adp_cfg(state, QAM_16);
b7571f8d 459 dib3000mc_write_word(state, 133, 15564);
1da177e4 460
b7571f8d
PB
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);
1da177e4 465
b7571f8d
PB
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);
1da177e4 472
b6884a17 473 dib3000mc_set_impulse_noise(state, 0, ch->u.ofdm.transmission_mode);
e4d6c1f7 474
b6884a17
PB
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;
480 }
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;
487 }
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;
493 }
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;
499 }
500 dib3000mc_write_word(state, 0, value);
e3ab2fdd 501 dib3000mc_write_word(state, 5, (1 << 8) | ((seq & 0xf) << 4));
1da177e4 502
b6884a17
PB
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;
515 }
516 dib3000mc_write_word(state, 181, value);
1da177e4 517
b6884a17
PB
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;
523 }
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;
530 }
531 value <<= 4;
532 value |= dib3000mc_read_word(state, 180) & 0x000f;
533 dib3000mc_write_word(state, 180, value);
1da177e4 534
b7571f8d 535 // restart demod
b6884a17
PB
536 value = dib3000mc_read_word(state, 0);
537 dib3000mc_write_word(state, 0, value | (1 << 9));
538 dib3000mc_write_word(state, 0, value);
1da177e4 539
b7571f8d 540 msleep(30);
1da177e4 541
b6884a17 542 dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, ch->u.ofdm.transmission_mode);
b7571f8d 543}
1da177e4 544
b6884a17 545static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *chan)
b7571f8d
PB
546{
547 struct dib3000mc_state *state = demod->demodulator_priv;
548 u16 reg;
549// u32 val;
b6884a17 550 struct dvb_frontend_parameters schan;
1da177e4 551
b6884a17 552 schan = *chan;
1da177e4 553
b6884a17 554 /* TODO what is that ? */
1da177e4 555
b7571f8d 556 /* a channel for autosearch */
b6884a17
PB
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;
1da177e4 563
b6884a17 564 dib3000mc_set_channel_cfg(state, &schan, 11);
1da177e4 565
b7571f8d
PB
566 reg = dib3000mc_read_word(state, 0);
567 dib3000mc_write_word(state, 0, reg | (1 << 8));
01b4bf31 568 dib3000mc_read_word(state, 511);
b7571f8d 569 dib3000mc_write_word(state, 0, reg);
1da177e4 570
b7571f8d
PB
571 return 0;
572}
1da177e4 573
b7571f8d
PB
574static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod)
575{
576 struct dib3000mc_state *state = demod->demodulator_priv;
577 u16 irq_pending = dib3000mc_read_word(state, 511);
1da177e4 578
b7571f8d
PB
579 if (irq_pending & 0x1) // failed
580 return 1;
1da177e4 581
b7571f8d
PB
582 if (irq_pending & 0x2) // succeeded
583 return 2;
a16bf5d5 584
b7571f8d 585 return 0; // still pending
1da177e4 586}
b7571f8d 587
b6884a17 588static int dib3000mc_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
1da177e4 589{
b7571f8d 590 struct dib3000mc_state *state = demod->demodulator_priv;
1da177e4 591
b7571f8d
PB
592 // ** configure demod **
593 dib3000mc_set_channel_cfg(state, ch, 0);
594
595 // activates isi
8f6956c7
MD
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
603 }
1da177e4 604
01373a5c 605 dib3000mc_set_adp_cfg(state, (u8)ch->u.ofdm.constellation);
b6884a17 606 if (ch->u.ofdm.transmission_mode == TRANSMISSION_MODE_8K) {
b7571f8d
PB
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);
612 }
613
01b4bf31 614 if (dib3000mc_read_word(state, 509) & 0x80)
b6884a17 615 dib3000mc_set_timing(state, ch->u.ofdm.transmission_mode, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth), 1);
1da177e4
LT
616
617 return 0;
618}
619
b7571f8d 620struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating)
1da177e4 621{
b7571f8d
PB
622 struct dib3000mc_state *st = demod->demodulator_priv;
623 return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating);
1da177e4
LT
624}
625
b7571f8d
PB
626EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master);
627
628static int dib3000mc_get_frontend(struct dvb_frontend* fe,
629 struct dvb_frontend_parameters *fep)
1da177e4 630{
b7571f8d
PB
631 struct dib3000mc_state *state = fe->demodulator_priv;
632 u16 tps = dib3000mc_read_word(state,458);
1da177e4 633
b7571f8d
PB
634 fep->inversion = INVERSION_AUTO;
635
636 fep->u.ofdm.bandwidth = state->current_bandwidth;
637
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;
641 }
642
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;
648 }
649
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;
655 }
656
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 */
659
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;
668
669 }
670
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;
678 }
1da177e4 679
1da177e4
LT
680 return 0;
681}
682
b7571f8d
PB
683static int dib3000mc_set_frontend(struct dvb_frontend* fe,
684 struct dvb_frontend_parameters *fep)
1da177e4 685{
b7571f8d 686 struct dib3000mc_state *state = fe->demodulator_priv;
b7571f8d 687
b7571f8d 688 state->current_bandwidth = fep->u.ofdm.bandwidth;
b6884a17 689 dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth));
b7571f8d 690
8f6956c7
MD
691 /* maybe the parameter has been changed */
692 state->sfn_workaround_active = buggy_sfn_workaround;
693
b7571f8d
PB
694 if (fe->ops.tuner_ops.set_params) {
695 fe->ops.tuner_ops.set_params(fe, fep);
696 msleep(100);
697 }
698
699 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
700 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ||
701 fep->u.ofdm.constellation == QAM_AUTO ||
702 fep->u.ofdm.code_rate_HP == FEC_AUTO) {
703 int i = 100, found;
704
b6884a17 705 dib3000mc_autosearch_start(fe, fep);
b7571f8d
PB
706 do {
707 msleep(1);
708 found = dib3000mc_autosearch_is_irq(fe);
709 } while (found == 0 && i--);
710
711 dprintk("autosearch returns: %d\n",found);
712 if (found == 0 || found == 1)
713 return 0; // no channel found
714
715 dib3000mc_get_frontend(fe, fep);
b7571f8d
PB
716 }
717
718 /* make this a config parameter */
719 dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
720
b6884a17 721 return dib3000mc_tune(fe, fep);
1da177e4
LT
722}
723
b7571f8d 724static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat)
1da177e4 725{
b7571f8d
PB
726 struct dib3000mc_state *state = fe->demodulator_priv;
727 u16 lock = dib3000mc_read_word(state, 509);
728
729 *stat = 0;
730
731 if (lock & 0x8000)
732 *stat |= FE_HAS_SIGNAL;
733 if (lock & 0x3000)
734 *stat |= FE_HAS_CARRIER;
735 if (lock & 0x0100)
736 *stat |= FE_HAS_VITERBI;
737 if (lock & 0x0010)
738 *stat |= FE_HAS_SYNC;
739 if (lock & 0x0008)
740 *stat |= FE_HAS_LOCK;
741
1da177e4
LT
742 return 0;
743}
744
b7571f8d 745static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber)
1da177e4 746{
b7571f8d
PB
747 struct dib3000mc_state *state = fe->demodulator_priv;
748 *ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501);
749 return 0;
1da177e4
LT
750}
751
b7571f8d 752static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
1da177e4 753{
b7571f8d
PB
754 struct dib3000mc_state *state = fe->demodulator_priv;
755 *unc = dib3000mc_read_word(state, 508);
756 return 0;
1da177e4
LT
757}
758
b7571f8d 759static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1da177e4 760{
b7571f8d
PB
761 struct dib3000mc_state *state = fe->demodulator_priv;
762 u16 val = dib3000mc_read_word(state, 392);
763 *strength = 65535 - val;
764 return 0;
1da177e4
LT
765}
766
b7571f8d 767static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
1da177e4 768{
b7571f8d 769 *snr = 0x0000;
1da177e4
LT
770 return 0;
771}
772
b7571f8d 773static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
1da177e4 774{
b7571f8d 775 tune->min_delay_ms = 1000;
1da177e4
LT
776 return 0;
777}
778
b7571f8d 779static void dib3000mc_release(struct dvb_frontend *fe)
1da177e4 780{
b7571f8d
PB
781 struct dib3000mc_state *state = fe->demodulator_priv;
782 dibx000_exit_i2c_master(&state->i2c_master);
783 kfree(state);
1da177e4
LT
784}
785
b7571f8d 786int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff)
1da177e4 787{
b7571f8d
PB
788 struct dib3000mc_state *state = fe->demodulator_priv;
789 dib3000mc_write_word(state, 212 + index, onoff ? (1 << 13) | pid : 0);
1da177e4
LT
790 return 0;
791}
b7571f8d 792EXPORT_SYMBOL(dib3000mc_pid_control);
1da177e4 793
b7571f8d 794int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
1da177e4 795{
b7571f8d
PB
796 struct dib3000mc_state *state = fe->demodulator_priv;
797 u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4);
798 tmp |= (onoff << 4);
799 return dib3000mc_write_word(state, 206, tmp);
1da177e4 800}
b7571f8d 801EXPORT_SYMBOL(dib3000mc_pid_parse);
1da177e4 802
b7571f8d 803void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg)
e4d6c1f7 804{
b7571f8d
PB
805 struct dib3000mc_state *state = fe->demodulator_priv;
806 state->cfg = cfg;
e4d6c1f7 807}
b7571f8d 808EXPORT_SYMBOL(dib3000mc_set_config);
1da177e4 809
136cafbf 810int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[])
1da177e4 811{
136cafbf
PB
812 struct dib3000mc_state st = { .i2c_adap = i2c };
813 int k;
814 u8 new_addr;
1da177e4 815
136cafbf 816 static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
1da177e4 817
136cafbf
PB
818 for (k = no_of_demods-1; k >= 0; k--) {
819 st.cfg = &cfg[k];
1da177e4 820
136cafbf
PB
821 /* designated i2c address */
822 new_addr = DIB3000MC_I2C_ADDRESS[k];
823 st.i2c_addr = new_addr;
824 if (dib3000mc_identify(&st) != 0) {
825 st.i2c_addr = default_addr;
826 if (dib3000mc_identify(&st) != 0) {
827 dprintk("-E- DiB3000P/MC #%d: not identified\n", k);
828 return -ENODEV;
829 }
830 }
1da177e4 831
136cafbf 832 dib3000mc_set_output_mode(&st, OUTMODE_MPEG2_PAR_CONT_CLK);
1da177e4 833
136cafbf
PB
834 // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
835 dib3000mc_write_word(&st, 1024, (new_addr << 3) | 0x1);
836 st.i2c_addr = new_addr;
b7571f8d 837 }
1da177e4 838
136cafbf
PB
839 for (k = 0; k < no_of_demods; k++) {
840 st.cfg = &cfg[k];
841 st.i2c_addr = DIB3000MC_I2C_ADDRESS[k];
1da177e4 842
136cafbf 843 dib3000mc_write_word(&st, 1024, st.i2c_addr << 3);
1da177e4 844
136cafbf
PB
845 /* turn off data output */
846 dib3000mc_set_output_mode(&st, OUTMODE_HIGH_Z);
847 }
b7571f8d 848 return 0;
136cafbf
PB
849}
850EXPORT_SYMBOL(dib3000mc_i2c_enumeration);
851
852static struct dvb_frontend_ops dib3000mc_ops;
853
854struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
855{
856 struct dvb_frontend *demod;
857 struct dib3000mc_state *st;
858 st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
859 if (st == NULL)
860 return NULL;
861
862 st->cfg = cfg;
863 st->i2c_adap = i2c_adap;
6958effe 864 st->i2c_addr = i2c_addr;
136cafbf
PB
865
866 demod = &st->demod;
867 demod->demodulator_priv = st;
868 memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
869
870 if (dib3000mc_identify(st) != 0)
871 goto error;
872
873 dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
874
303cbeaa
PB
875 dib3000mc_write_word(st, 1037, 0x3130);
876
136cafbf 877 return demod;
1da177e4
LT
878
879error:
136cafbf
PB
880 kfree(st);
881 return NULL;
1da177e4 882}
e4d6c1f7 883EXPORT_SYMBOL(dib3000mc_attach);
1da177e4
LT
884
885static struct dvb_frontend_ops dib3000mc_ops = {
1da177e4 886 .info = {
b7571f8d
PB
887 .name = "DiBcom 3000MC/P",
888 .type = FE_OFDM,
889 .frequency_min = 44250000,
890 .frequency_max = 867250000,
891 .frequency_stepsize = 62500,
1da177e4 892 .caps = FE_CAN_INVERSION_AUTO |
b7571f8d
PB
893 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
894 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
895 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
896 FE_CAN_TRANSMISSION_MODE_AUTO |
897 FE_CAN_GUARD_INTERVAL_AUTO |
898 FE_CAN_RECOVER |
899 FE_CAN_HIERARCHY_AUTO,
1da177e4
LT
900 },
901
b7571f8d 902 .release = dib3000mc_release,
1da177e4 903
b7571f8d
PB
904 .init = dib3000mc_init,
905 .sleep = dib3000mc_sleep,
1da177e4 906
b7571f8d
PB
907 .set_frontend = dib3000mc_set_frontend,
908 .get_tune_settings = dib3000mc_fe_get_tune_settings,
909 .get_frontend = dib3000mc_get_frontend,
1da177e4 910
b7571f8d
PB
911 .read_status = dib3000mc_read_status,
912 .read_ber = dib3000mc_read_ber,
1da177e4 913 .read_signal_strength = dib3000mc_read_signal_strength,
b7571f8d
PB
914 .read_snr = dib3000mc_read_snr,
915 .read_ucblocks = dib3000mc_read_unc_blocks,
1da177e4
LT
916};
917
b7571f8d
PB
918MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
919MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator");
1da177e4 920MODULE_LICENSE("GPL");