]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/blame_incremental - drivers/media/dvb-frontends/dib3000mc.c
Merge remote-tracking branches 'asoc/topic/ac97', 'asoc/topic/ac97-mfd', 'asoc/topic...
[mirror_ubuntu-focal-kernel.git] / drivers / media / dvb-frontends / dib3000mc.c
... / ...
CommitLineData
1/*
2 * Driver for DiBcom DiB3000MC/P-demodulator.
3 *
4 * Copyright (C) 2004-7 DiBcom (http://www.dibcom.fr/)
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
6 *
7 * This code is partially based on the previous dib3000mc.c .
8 *
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.
12 */
13
14#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15
16#include <linux/kernel.h>
17#include <linux/slab.h>
18#include <linux/i2c.h>
19
20#include "dvb_frontend.h"
21
22#include "dib3000mc.h"
23
24static int debug;
25module_param(debug, int, 0644);
26MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
27
28static int buggy_sfn_workaround;
29module_param(buggy_sfn_workaround, int, 0644);
30MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
31
32#define dprintk(fmt, arg...) do { \
33 if (debug) \
34 printk(KERN_DEBUG pr_fmt("%s: " fmt), \
35 __func__, ##arg); \
36} while (0)
37
38struct dib3000mc_state {
39 struct dvb_frontend demod;
40 struct dib3000mc_config *cfg;
41
42 u8 i2c_addr;
43 struct i2c_adapter *i2c_adap;
44
45 struct dibx000_i2c_master i2c_master;
46
47 u32 timf;
48
49 u32 current_bandwidth;
50
51 u16 dev_id;
52
53 u8 sfn_workaround_active :1;
54};
55
56static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
57{
58 struct i2c_msg msg[2] = {
59 { .addr = state->i2c_addr >> 1, .flags = 0, .len = 2 },
60 { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .len = 2 },
61 };
62 u16 word;
63 u8 *b;
64
65 b = kmalloc(4, GFP_KERNEL);
66 if (!b)
67 return 0;
68
69 b[0] = (reg >> 8) | 0x80;
70 b[1] = reg;
71 b[2] = 0;
72 b[3] = 0;
73
74 msg[0].buf = b;
75 msg[1].buf = b + 2;
76
77 if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
78 dprintk("i2c read error on %d\n",reg);
79
80 word = (b[2] << 8) | b[3];
81 kfree(b);
82
83 return word;
84}
85
86static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
87{
88 struct i2c_msg msg = {
89 .addr = state->i2c_addr >> 1, .flags = 0, .len = 4
90 };
91 int rc;
92 u8 *b;
93
94 b = kmalloc(4, GFP_KERNEL);
95 if (!b)
96 return -ENOMEM;
97
98 b[0] = reg >> 8;
99 b[1] = reg;
100 b[2] = val >> 8;
101 b[3] = val;
102
103 msg.buf = b;
104
105 rc = i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
106 kfree(b);
107
108 return rc;
109}
110
111static int dib3000mc_identify(struct dib3000mc_state *state)
112{
113 u16 value;
114 if ((value = dib3000mc_read_word(state, 1025)) != 0x01b3) {
115 dprintk("-E- DiB3000MC/P: wrong Vendor ID (read=0x%x)\n",value);
116 return -EREMOTEIO;
117 }
118
119 value = dib3000mc_read_word(state, 1026);
120 if (value != 0x3001 && value != 0x3002) {
121 dprintk("-E- DiB3000MC/P: wrong Device ID (%x)\n",value);
122 return -EREMOTEIO;
123 }
124 state->dev_id = value;
125
126 dprintk("-I- found DiB3000MC/P: %x\n",state->dev_id);
127
128 return 0;
129}
130
131static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u32 bw, u8 update_offset)
132{
133 u32 timf;
134
135 if (state->timf == 0) {
136 timf = 1384402; // default value for 8MHz
137 if (update_offset)
138 msleep(200); // first time we do an update
139 } else
140 timf = state->timf;
141
142 timf *= (bw / 1000);
143
144 if (update_offset) {
145 s16 tim_offs = dib3000mc_read_word(state, 416);
146
147 if (tim_offs & 0x2000)
148 tim_offs -= 0x4000;
149
150 if (nfft == TRANSMISSION_MODE_2K)
151 tim_offs *= 4;
152
153 timf += tim_offs;
154 state->timf = timf / (bw / 1000);
155 }
156
157 dprintk("timf: %d\n", timf);
158
159 dib3000mc_write_word(state, 23, (u16) (timf >> 16));
160 dib3000mc_write_word(state, 24, (u16) (timf ) & 0xffff);
161
162 return 0;
163}
164
165static int dib3000mc_setup_pwm_state(struct dib3000mc_state *state)
166{
167 u16 reg_51, reg_52 = state->cfg->agc->setup & 0xfefb;
168 if (state->cfg->pwm3_inversion) {
169 reg_51 = (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
170 reg_52 |= (1 << 2);
171 } else {
172 reg_51 = (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
173 reg_52 |= (1 << 8);
174 }
175 dib3000mc_write_word(state, 51, reg_51);
176 dib3000mc_write_word(state, 52, reg_52);
177
178 if (state->cfg->use_pwm3)
179 dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0));
180 else
181 dib3000mc_write_word(state, 245, 0);
182
183 dib3000mc_write_word(state, 1040, 0x3);
184 return 0;
185}
186
187static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode)
188{
189 int ret = 0;
190 u16 fifo_threshold = 1792;
191 u16 outreg = 0;
192 u16 outmode = 0;
193 u16 elecout = 1;
194 u16 smo_reg = dib3000mc_read_word(state, 206) & 0x0010; /* keep the pid_parse bit */
195
196 dprintk("-I- Setting output mode for demod %p to %d\n",
197 &state->demod, mode);
198
199 switch (mode) {
200 case OUTMODE_HIGH_Z: // disable
201 elecout = 0;
202 break;
203 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
204 outmode = 0;
205 break;
206 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
207 outmode = 1;
208 break;
209 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
210 outmode = 2;
211 break;
212 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
213 elecout = 3;
214 /*ADDR @ 206 :
215 P_smo_error_discard [1;6:6] = 0
216 P_smo_rs_discard [1;5:5] = 0
217 P_smo_pid_parse [1;4:4] = 0
218 P_smo_fifo_flush [1;3:3] = 0
219 P_smo_mode [2;2:1] = 11
220 P_smo_ovf_prot [1;0:0] = 0
221 */
222 smo_reg |= 3 << 1;
223 fifo_threshold = 512;
224 outmode = 5;
225 break;
226 case OUTMODE_DIVERSITY:
227 outmode = 4;
228 elecout = 1;
229 break;
230 default:
231 dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod);
232 outmode = 0;
233 break;
234 }
235
236 if ((state->cfg->output_mpeg2_in_188_bytes))
237 smo_reg |= (1 << 5); // P_smo_rs_discard [1;5:5] = 1
238
239 outreg = dib3000mc_read_word(state, 244) & 0x07FF;
240 outreg |= (outmode << 11);
241 ret |= dib3000mc_write_word(state, 244, outreg);
242 ret |= dib3000mc_write_word(state, 206, smo_reg); /*smo_ mode*/
243 ret |= dib3000mc_write_word(state, 207, fifo_threshold); /* synchronous fread */
244 ret |= dib3000mc_write_word(state, 1040, elecout); /* P_out_cfg */
245 return ret;
246}
247
248static int dib3000mc_set_bandwidth(struct dib3000mc_state *state, u32 bw)
249{
250 u16 bw_cfg[6] = { 0 };
251 u16 imp_bw_cfg[3] = { 0 };
252 u16 reg;
253
254/* settings here are for 27.7MHz */
255 switch (bw) {
256 case 8000:
257 bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20;
258 imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7;
259 break;
260
261 case 7000:
262 bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7;
263 imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0;
264 break;
265
266 case 6000:
267 bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5;
268 imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089;
269 break;
270
271 case 5000:
272 bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500;
273 imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072;
274 break;
275
276 default: return -EINVAL;
277 }
278
279 for (reg = 6; reg < 12; reg++)
280 dib3000mc_write_word(state, reg, bw_cfg[reg - 6]);
281 dib3000mc_write_word(state, 12, 0x0000);
282 dib3000mc_write_word(state, 13, 0x03e8);
283 dib3000mc_write_word(state, 14, 0x0000);
284 dib3000mc_write_word(state, 15, 0x03f2);
285 dib3000mc_write_word(state, 16, 0x0001);
286 dib3000mc_write_word(state, 17, 0xb0d0);
287 // P_sec_len
288 dib3000mc_write_word(state, 18, 0x0393);
289 dib3000mc_write_word(state, 19, 0x8700);
290
291 for (reg = 55; reg < 58; reg++)
292 dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]);
293
294 // Timing configuration
295 dib3000mc_set_timing(state, TRANSMISSION_MODE_2K, bw, 0);
296
297 return 0;
298}
299
300static u16 impulse_noise_val[29] =
301
302{
303 0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, 0x3ffe, 0x7f3,
304 0x2d94, 0x76, 0x53d, 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, 0x3feb, 0x7d2,
305 0x365e, 0x76, 0x48c, 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0000, 0xd
306};
307
308static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft)
309{
310 u16 i;
311 for (i = 58; i < 87; i++)
312 dib3000mc_write_word(state, i, impulse_noise_val[i-58]);
313
314 if (nfft == TRANSMISSION_MODE_8K) {
315 dib3000mc_write_word(state, 58, 0x3b);
316 dib3000mc_write_word(state, 84, 0x00);
317 dib3000mc_write_word(state, 85, 0x8200);
318 }
319
320 dib3000mc_write_word(state, 34, 0x1294);
321 dib3000mc_write_word(state, 35, 0x1ff8);
322 if (mode == 1)
323 dib3000mc_write_word(state, 55, dib3000mc_read_word(state, 55) | (1 << 10));
324}
325
326static int dib3000mc_init(struct dvb_frontend *demod)
327{
328 struct dib3000mc_state *state = demod->demodulator_priv;
329 struct dibx000_agc_config *agc = state->cfg->agc;
330
331 // Restart Configuration
332 dib3000mc_write_word(state, 1027, 0x8000);
333 dib3000mc_write_word(state, 1027, 0x0000);
334
335 // power up the demod + mobility configuration
336 dib3000mc_write_word(state, 140, 0x0000);
337 dib3000mc_write_word(state, 1031, 0);
338
339 if (state->cfg->mobile_mode) {
340 dib3000mc_write_word(state, 139, 0x0000);
341 dib3000mc_write_word(state, 141, 0x0000);
342 dib3000mc_write_word(state, 175, 0x0002);
343 dib3000mc_write_word(state, 1032, 0x0000);
344 } else {
345 dib3000mc_write_word(state, 139, 0x0001);
346 dib3000mc_write_word(state, 141, 0x0000);
347 dib3000mc_write_word(state, 175, 0x0000);
348 dib3000mc_write_word(state, 1032, 0x012C);
349 }
350 dib3000mc_write_word(state, 1033, 0x0000);
351
352 // P_clk_cfg
353 dib3000mc_write_word(state, 1037, 0x3130);
354
355 // other configurations
356
357 // P_ctrl_sfreq
358 dib3000mc_write_word(state, 33, (5 << 0));
359 dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0));
360
361 // Phase noise control
362 // P_fft_phacor_inh, P_fft_phacor_cpe, P_fft_powrange
363 dib3000mc_write_word(state, 99, (1 << 9) | (0x20 << 0));
364
365 if (state->cfg->phase_noise_mode == 0)
366 dib3000mc_write_word(state, 111, 0x00);
367 else
368 dib3000mc_write_word(state, 111, 0x02);
369
370 // P_agc_global
371 dib3000mc_write_word(state, 50, 0x8000);
372
373 // agc setup misc
374 dib3000mc_setup_pwm_state(state);
375
376 // P_agc_counter_lock
377 dib3000mc_write_word(state, 53, 0x87);
378 // P_agc_counter_unlock
379 dib3000mc_write_word(state, 54, 0x87);
380
381 /* agc */
382 dib3000mc_write_word(state, 36, state->cfg->max_time);
383 dib3000mc_write_word(state, 37, (state->cfg->agc_command1 << 13) | (state->cfg->agc_command2 << 12) | (0x1d << 0));
384 dib3000mc_write_word(state, 38, state->cfg->pwm3_value);
385 dib3000mc_write_word(state, 39, state->cfg->ln_adc_level);
386
387 // set_agc_loop_Bw
388 dib3000mc_write_word(state, 40, 0x0179);
389 dib3000mc_write_word(state, 41, 0x03f0);
390
391 dib3000mc_write_word(state, 42, agc->agc1_max);
392 dib3000mc_write_word(state, 43, agc->agc1_min);
393 dib3000mc_write_word(state, 44, agc->agc2_max);
394 dib3000mc_write_word(state, 45, agc->agc2_min);
395 dib3000mc_write_word(state, 46, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
396 dib3000mc_write_word(state, 47, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
397 dib3000mc_write_word(state, 48, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
398 dib3000mc_write_word(state, 49, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
399
400// Begin: TimeOut registers
401 // P_pha3_thres
402 dib3000mc_write_word(state, 110, 3277);
403 // P_timf_alpha = 6, P_corm_alpha = 6, P_corm_thres = 0x80
404 dib3000mc_write_word(state, 26, 0x6680);
405 // lock_mask0
406 dib3000mc_write_word(state, 1, 4);
407 // lock_mask1
408 dib3000mc_write_word(state, 2, 4);
409 // lock_mask2
410 dib3000mc_write_word(state, 3, 0x1000);
411 // P_search_maxtrial=1
412 dib3000mc_write_word(state, 5, 1);
413
414 dib3000mc_set_bandwidth(state, 8000);
415
416 // div_lock_mask
417 dib3000mc_write_word(state, 4, 0x814);
418
419 dib3000mc_write_word(state, 21, (1 << 9) | 0x164);
420 dib3000mc_write_word(state, 22, 0x463d);
421
422 // Spurious rm cfg
423 // P_cspu_regul, P_cspu_win_cut
424 dib3000mc_write_word(state, 120, 0x200f);
425 // P_adp_selec_monit
426 dib3000mc_write_word(state, 134, 0);
427
428 // Fec cfg
429 dib3000mc_write_word(state, 195, 0x10);
430
431 // diversity register: P_dvsy_sync_wait..
432 dib3000mc_write_word(state, 180, 0x2FF0);
433
434 // Impulse noise configuration
435 dib3000mc_set_impulse_noise(state, 0, TRANSMISSION_MODE_8K);
436
437 // output mode set-up
438 dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
439
440 /* close the i2c-gate */
441 dib3000mc_write_word(state, 769, (1 << 7) );
442
443 return 0;
444}
445
446static int dib3000mc_sleep(struct dvb_frontend *demod)
447{
448 struct dib3000mc_state *state = demod->demodulator_priv;
449
450 dib3000mc_write_word(state, 1031, 0xFFFF);
451 dib3000mc_write_word(state, 1032, 0xFFFF);
452 dib3000mc_write_word(state, 1033, 0xFFF0);
453
454 return 0;
455}
456
457static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
458{
459 u16 cfg[4] = { 0 },reg;
460 switch (qam) {
461 case QPSK:
462 cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0;
463 break;
464 case QAM_16:
465 cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0;
466 break;
467 case QAM_64:
468 cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8;
469 break;
470 }
471 for (reg = 129; reg < 133; reg++)
472 dib3000mc_write_word(state, reg, cfg[reg - 129]);
473}
474
475static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state,
476 struct dtv_frontend_properties *ch, u16 seq)
477{
478 u16 value;
479 u32 bw = BANDWIDTH_TO_KHZ(ch->bandwidth_hz);
480
481 dib3000mc_set_bandwidth(state, bw);
482 dib3000mc_set_timing(state, ch->transmission_mode, bw, 0);
483
484#if 1
485 dib3000mc_write_word(state, 100, (16 << 6) + 9);
486#else
487 if (boost)
488 dib3000mc_write_word(state, 100, (11 << 6) + 6);
489 else
490 dib3000mc_write_word(state, 100, (16 << 6) + 9);
491#endif
492
493 dib3000mc_write_word(state, 1027, 0x0800);
494 dib3000mc_write_word(state, 1027, 0x0000);
495
496 //Default cfg isi offset adp
497 dib3000mc_write_word(state, 26, 0x6680);
498 dib3000mc_write_word(state, 29, 0x1273);
499 dib3000mc_write_word(state, 33, 5);
500 dib3000mc_set_adp_cfg(state, QAM_16);
501 dib3000mc_write_word(state, 133, 15564);
502
503 dib3000mc_write_word(state, 12 , 0x0);
504 dib3000mc_write_word(state, 13 , 0x3e8);
505 dib3000mc_write_word(state, 14 , 0x0);
506 dib3000mc_write_word(state, 15 , 0x3f2);
507
508 dib3000mc_write_word(state, 93,0);
509 dib3000mc_write_word(state, 94,0);
510 dib3000mc_write_word(state, 95,0);
511 dib3000mc_write_word(state, 96,0);
512 dib3000mc_write_word(state, 97,0);
513 dib3000mc_write_word(state, 98,0);
514
515 dib3000mc_set_impulse_noise(state, 0, ch->transmission_mode);
516
517 value = 0;
518 switch (ch->transmission_mode) {
519 case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
520 default:
521 case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
522 }
523 switch (ch->guard_interval) {
524 case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
525 case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
526 case GUARD_INTERVAL_1_4: value |= (3 << 5); break;
527 default:
528 case GUARD_INTERVAL_1_8: value |= (2 << 5); break;
529 }
530 switch (ch->modulation) {
531 case QPSK: value |= (0 << 3); break;
532 case QAM_16: value |= (1 << 3); break;
533 default:
534 case QAM_64: value |= (2 << 3); break;
535 }
536 switch (HIERARCHY_1) {
537 case HIERARCHY_2: value |= 2; break;
538 case HIERARCHY_4: value |= 4; break;
539 default:
540 case HIERARCHY_1: value |= 1; break;
541 }
542 dib3000mc_write_word(state, 0, value);
543 dib3000mc_write_word(state, 5, (1 << 8) | ((seq & 0xf) << 4));
544
545 value = 0;
546 if (ch->hierarchy == 1)
547 value |= (1 << 4);
548 if (1 == 1)
549 value |= 1;
550 switch ((ch->hierarchy == 0 || 1 == 1) ? ch->code_rate_HP : ch->code_rate_LP) {
551 case FEC_2_3: value |= (2 << 1); break;
552 case FEC_3_4: value |= (3 << 1); break;
553 case FEC_5_6: value |= (5 << 1); break;
554 case FEC_7_8: value |= (7 << 1); break;
555 default:
556 case FEC_1_2: value |= (1 << 1); break;
557 }
558 dib3000mc_write_word(state, 181, value);
559
560 // diversity synchro delay add 50% SFN margin
561 switch (ch->transmission_mode) {
562 case TRANSMISSION_MODE_8K: value = 256; break;
563 case TRANSMISSION_MODE_2K:
564 default: value = 64; break;
565 }
566 switch (ch->guard_interval) {
567 case GUARD_INTERVAL_1_16: value *= 2; break;
568 case GUARD_INTERVAL_1_8: value *= 4; break;
569 case GUARD_INTERVAL_1_4: value *= 8; break;
570 default:
571 case GUARD_INTERVAL_1_32: value *= 1; break;
572 }
573 value <<= 4;
574 value |= dib3000mc_read_word(state, 180) & 0x000f;
575 dib3000mc_write_word(state, 180, value);
576
577 // restart demod
578 value = dib3000mc_read_word(state, 0);
579 dib3000mc_write_word(state, 0, value | (1 << 9));
580 dib3000mc_write_word(state, 0, value);
581
582 msleep(30);
583
584 dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, ch->transmission_mode);
585}
586
587static int dib3000mc_autosearch_start(struct dvb_frontend *demod)
588{
589 struct dtv_frontend_properties *chan = &demod->dtv_property_cache;
590 struct dib3000mc_state *state = demod->demodulator_priv;
591 u16 reg;
592// u32 val;
593 struct dtv_frontend_properties schan;
594
595 schan = *chan;
596
597 /* TODO what is that ? */
598
599 /* a channel for autosearch */
600 schan.transmission_mode = TRANSMISSION_MODE_8K;
601 schan.guard_interval = GUARD_INTERVAL_1_32;
602 schan.modulation = QAM_64;
603 schan.code_rate_HP = FEC_2_3;
604 schan.code_rate_LP = FEC_2_3;
605 schan.hierarchy = 0;
606
607 dib3000mc_set_channel_cfg(state, &schan, 11);
608
609 reg = dib3000mc_read_word(state, 0);
610 dib3000mc_write_word(state, 0, reg | (1 << 8));
611 dib3000mc_read_word(state, 511);
612 dib3000mc_write_word(state, 0, reg);
613
614 return 0;
615}
616
617static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod)
618{
619 struct dib3000mc_state *state = demod->demodulator_priv;
620 u16 irq_pending = dib3000mc_read_word(state, 511);
621
622 if (irq_pending & 0x1) // failed
623 return 1;
624
625 if (irq_pending & 0x2) // succeeded
626 return 2;
627
628 return 0; // still pending
629}
630
631static int dib3000mc_tune(struct dvb_frontend *demod)
632{
633 struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
634 struct dib3000mc_state *state = demod->demodulator_priv;
635
636 // ** configure demod **
637 dib3000mc_set_channel_cfg(state, ch, 0);
638
639 // activates isi
640 if (state->sfn_workaround_active) {
641 dprintk("SFN workaround is active\n");
642 dib3000mc_write_word(state, 29, 0x1273);
643 dib3000mc_write_word(state, 108, 0x4000); // P_pha3_force_pha_shift
644 } else {
645 dib3000mc_write_word(state, 29, 0x1073);
646 dib3000mc_write_word(state, 108, 0x0000); // P_pha3_force_pha_shift
647 }
648
649 dib3000mc_set_adp_cfg(state, (u8)ch->modulation);
650 if (ch->transmission_mode == TRANSMISSION_MODE_8K) {
651 dib3000mc_write_word(state, 26, 38528);
652 dib3000mc_write_word(state, 33, 8);
653 } else {
654 dib3000mc_write_word(state, 26, 30336);
655 dib3000mc_write_word(state, 33, 6);
656 }
657
658 if (dib3000mc_read_word(state, 509) & 0x80)
659 dib3000mc_set_timing(state, ch->transmission_mode,
660 BANDWIDTH_TO_KHZ(ch->bandwidth_hz), 1);
661
662 return 0;
663}
664
665struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating)
666{
667 struct dib3000mc_state *st = demod->demodulator_priv;
668 return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating);
669}
670
671EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master);
672
673static int dib3000mc_get_frontend(struct dvb_frontend* fe,
674 struct dtv_frontend_properties *fep)
675{
676 struct dib3000mc_state *state = fe->demodulator_priv;
677 u16 tps = dib3000mc_read_word(state,458);
678
679 fep->inversion = INVERSION_AUTO;
680
681 fep->bandwidth_hz = state->current_bandwidth;
682
683 switch ((tps >> 8) & 0x1) {
684 case 0: fep->transmission_mode = TRANSMISSION_MODE_2K; break;
685 case 1: fep->transmission_mode = TRANSMISSION_MODE_8K; break;
686 }
687
688 switch (tps & 0x3) {
689 case 0: fep->guard_interval = GUARD_INTERVAL_1_32; break;
690 case 1: fep->guard_interval = GUARD_INTERVAL_1_16; break;
691 case 2: fep->guard_interval = GUARD_INTERVAL_1_8; break;
692 case 3: fep->guard_interval = GUARD_INTERVAL_1_4; break;
693 }
694
695 switch ((tps >> 13) & 0x3) {
696 case 0: fep->modulation = QPSK; break;
697 case 1: fep->modulation = QAM_16; break;
698 case 2:
699 default: fep->modulation = QAM_64; break;
700 }
701
702 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
703 /* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */
704
705 fep->hierarchy = HIERARCHY_NONE;
706 switch ((tps >> 5) & 0x7) {
707 case 1: fep->code_rate_HP = FEC_1_2; break;
708 case 2: fep->code_rate_HP = FEC_2_3; break;
709 case 3: fep->code_rate_HP = FEC_3_4; break;
710 case 5: fep->code_rate_HP = FEC_5_6; break;
711 case 7:
712 default: fep->code_rate_HP = FEC_7_8; break;
713
714 }
715
716 switch ((tps >> 2) & 0x7) {
717 case 1: fep->code_rate_LP = FEC_1_2; break;
718 case 2: fep->code_rate_LP = FEC_2_3; break;
719 case 3: fep->code_rate_LP = FEC_3_4; break;
720 case 5: fep->code_rate_LP = FEC_5_6; break;
721 case 7:
722 default: fep->code_rate_LP = FEC_7_8; break;
723 }
724
725 return 0;
726}
727
728static int dib3000mc_set_frontend(struct dvb_frontend *fe)
729{
730 struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
731 struct dib3000mc_state *state = fe->demodulator_priv;
732 int ret;
733
734 dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
735
736 state->current_bandwidth = fep->bandwidth_hz;
737 dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->bandwidth_hz));
738
739 /* maybe the parameter has been changed */
740 state->sfn_workaround_active = buggy_sfn_workaround;
741
742 if (fe->ops.tuner_ops.set_params) {
743 fe->ops.tuner_ops.set_params(fe);
744 msleep(100);
745 }
746
747 if (fep->transmission_mode == TRANSMISSION_MODE_AUTO ||
748 fep->guard_interval == GUARD_INTERVAL_AUTO ||
749 fep->modulation == QAM_AUTO ||
750 fep->code_rate_HP == FEC_AUTO) {
751 int i = 1000, found;
752
753 dib3000mc_autosearch_start(fe);
754 do {
755 msleep(1);
756 found = dib3000mc_autosearch_is_irq(fe);
757 } while (found == 0 && i--);
758
759 dprintk("autosearch returns: %d\n",found);
760 if (found == 0 || found == 1)
761 return 0; // no channel found
762
763 dib3000mc_get_frontend(fe, fep);
764 }
765
766 ret = dib3000mc_tune(fe);
767
768 /* make this a config parameter */
769 dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
770 return ret;
771}
772
773static int dib3000mc_read_status(struct dvb_frontend *fe, enum fe_status *stat)
774{
775 struct dib3000mc_state *state = fe->demodulator_priv;
776 u16 lock = dib3000mc_read_word(state, 509);
777
778 *stat = 0;
779
780 if (lock & 0x8000)
781 *stat |= FE_HAS_SIGNAL;
782 if (lock & 0x3000)
783 *stat |= FE_HAS_CARRIER;
784 if (lock & 0x0100)
785 *stat |= FE_HAS_VITERBI;
786 if (lock & 0x0010)
787 *stat |= FE_HAS_SYNC;
788 if (lock & 0x0008)
789 *stat |= FE_HAS_LOCK;
790
791 return 0;
792}
793
794static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber)
795{
796 struct dib3000mc_state *state = fe->demodulator_priv;
797 *ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501);
798 return 0;
799}
800
801static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
802{
803 struct dib3000mc_state *state = fe->demodulator_priv;
804 *unc = dib3000mc_read_word(state, 508);
805 return 0;
806}
807
808static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
809{
810 struct dib3000mc_state *state = fe->demodulator_priv;
811 u16 val = dib3000mc_read_word(state, 392);
812 *strength = 65535 - val;
813 return 0;
814}
815
816static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
817{
818 *snr = 0x0000;
819 return 0;
820}
821
822static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
823{
824 tune->min_delay_ms = 1000;
825 return 0;
826}
827
828static void dib3000mc_release(struct dvb_frontend *fe)
829{
830 struct dib3000mc_state *state = fe->demodulator_priv;
831 dibx000_exit_i2c_master(&state->i2c_master);
832 kfree(state);
833}
834
835int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff)
836{
837 struct dib3000mc_state *state = fe->demodulator_priv;
838 dib3000mc_write_word(state, 212 + index, onoff ? (1 << 13) | pid : 0);
839 return 0;
840}
841EXPORT_SYMBOL(dib3000mc_pid_control);
842
843int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
844{
845 struct dib3000mc_state *state = fe->demodulator_priv;
846 u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4);
847 tmp |= (onoff << 4);
848 return dib3000mc_write_word(state, 206, tmp);
849}
850EXPORT_SYMBOL(dib3000mc_pid_parse);
851
852void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg)
853{
854 struct dib3000mc_state *state = fe->demodulator_priv;
855 state->cfg = cfg;
856}
857EXPORT_SYMBOL(dib3000mc_set_config);
858
859int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[])
860{
861 struct dib3000mc_state *dmcst;
862 int k;
863 u8 new_addr;
864
865 static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
866
867 dmcst = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
868 if (dmcst == NULL)
869 return -ENOMEM;
870
871 dmcst->i2c_adap = i2c;
872
873 for (k = no_of_demods-1; k >= 0; k--) {
874 dmcst->cfg = &cfg[k];
875
876 /* designated i2c address */
877 new_addr = DIB3000MC_I2C_ADDRESS[k];
878 dmcst->i2c_addr = new_addr;
879 if (dib3000mc_identify(dmcst) != 0) {
880 dmcst->i2c_addr = default_addr;
881 if (dib3000mc_identify(dmcst) != 0) {
882 dprintk("-E- DiB3000P/MC #%d: not identified\n", k);
883 kfree(dmcst);
884 return -ENODEV;
885 }
886 }
887
888 dib3000mc_set_output_mode(dmcst, OUTMODE_MPEG2_PAR_CONT_CLK);
889
890 // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
891 dib3000mc_write_word(dmcst, 1024, (new_addr << 3) | 0x1);
892 dmcst->i2c_addr = new_addr;
893 }
894
895 for (k = 0; k < no_of_demods; k++) {
896 dmcst->cfg = &cfg[k];
897 dmcst->i2c_addr = DIB3000MC_I2C_ADDRESS[k];
898
899 dib3000mc_write_word(dmcst, 1024, dmcst->i2c_addr << 3);
900
901 /* turn off data output */
902 dib3000mc_set_output_mode(dmcst, OUTMODE_HIGH_Z);
903 }
904
905 kfree(dmcst);
906 return 0;
907}
908EXPORT_SYMBOL(dib3000mc_i2c_enumeration);
909
910static const struct dvb_frontend_ops dib3000mc_ops;
911
912struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
913{
914 struct dvb_frontend *demod;
915 struct dib3000mc_state *st;
916 st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
917 if (st == NULL)
918 return NULL;
919
920 st->cfg = cfg;
921 st->i2c_adap = i2c_adap;
922 st->i2c_addr = i2c_addr;
923
924 demod = &st->demod;
925 demod->demodulator_priv = st;
926 memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
927
928 if (dib3000mc_identify(st) != 0)
929 goto error;
930
931 dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
932
933 dib3000mc_write_word(st, 1037, 0x3130);
934
935 return demod;
936
937error:
938 kfree(st);
939 return NULL;
940}
941EXPORT_SYMBOL(dib3000mc_attach);
942
943static const struct dvb_frontend_ops dib3000mc_ops = {
944 .delsys = { SYS_DVBT },
945 .info = {
946 .name = "DiBcom 3000MC/P",
947 .frequency_min = 44250000,
948 .frequency_max = 867250000,
949 .frequency_stepsize = 62500,
950 .caps = FE_CAN_INVERSION_AUTO |
951 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
952 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
953 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
954 FE_CAN_TRANSMISSION_MODE_AUTO |
955 FE_CAN_GUARD_INTERVAL_AUTO |
956 FE_CAN_RECOVER |
957 FE_CAN_HIERARCHY_AUTO,
958 },
959
960 .release = dib3000mc_release,
961
962 .init = dib3000mc_init,
963 .sleep = dib3000mc_sleep,
964
965 .set_frontend = dib3000mc_set_frontend,
966 .get_tune_settings = dib3000mc_fe_get_tune_settings,
967 .get_frontend = dib3000mc_get_frontend,
968
969 .read_status = dib3000mc_read_status,
970 .read_ber = dib3000mc_read_ber,
971 .read_signal_strength = dib3000mc_read_signal_strength,
972 .read_snr = dib3000mc_read_snr,
973 .read_ucblocks = dib3000mc_read_unc_blocks,
974};
975
976MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
977MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator");
978MODULE_LICENSE("GPL");