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

source code of linux/drivers/media/dvb-frontends/dib3000mc.c