1
2
3
4
5
6
7
8
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(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(state->i2c_adap, msg, 2) != 2)
75 dprintk("i2c read error on %d\n",reg);
76
77 word = (b[2] << 8) | b[3];
78 kfree(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(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(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
103 kfree(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, 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, 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;
134 if (update_offset)
135 msleep(200);
136 } else
137 timf = state->timf;
138
139 timf *= (bw / 1000);
140
141 if (update_offset) {
142 s16 tim_offs = dib3000mc_read_word(state, 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, 23, (u16) (timf >> 16));
157 dib3000mc_write_word(state, 24, (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, 51, reg_51);
173 dib3000mc_write_word(state, 52, reg_52);
174
175 if (state->cfg->use_pwm3)
176 dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0));
177 else
178 dib3000mc_write_word(state, 245, 0);
179
180 dib3000mc_write_word(state, 1040, 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, 206) & 0x0010;
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:
198 elecout = 0;
199 break;
200 case OUTMODE_MPEG2_PAR_GATED_CLK:
201 outmode = 0;
202 break;
203 case OUTMODE_MPEG2_PAR_CONT_CLK:
204 outmode = 1;
205 break;
206 case OUTMODE_MPEG2_SERIAL:
207 outmode = 2;
208 break;
209 case OUTMODE_MPEG2_FIFO:
210 elecout = 3;
211
212
213
214
215
216
217
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);
235
236 outreg = dib3000mc_read_word(state, 244) & 0x07FF;
237 outreg |= (outmode << 11);
238 ret |= dib3000mc_write_word(state, 244, outreg);
239 ret |= dib3000mc_write_word(state, 206, smo_reg);
240 ret |= dib3000mc_write_word(state, 207, fifo_threshold);
241 ret |= dib3000mc_write_word(state, 1040, elecout);
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
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, bw_cfg[reg - 6]);
278 dib3000mc_write_word(state, 12, 0x0000);
279 dib3000mc_write_word(state, 13, 0x03e8);
280 dib3000mc_write_word(state, 14, 0x0000);
281 dib3000mc_write_word(state, 15, 0x03f2);
282 dib3000mc_write_word(state, 16, 0x0001);
283 dib3000mc_write_word(state, 17, 0xb0d0);
284
285 dib3000mc_write_word(state, 18, 0x0393);
286 dib3000mc_write_word(state, 19, 0x8700);
287
288 for (reg = 55; reg < 58; reg++)
289 dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]);
290
291
292 dib3000mc_set_timing(state, TRANSMISSION_MODE_2K, bw, 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, i, impulse_noise_val[i-58]);
310
311 if (nfft == TRANSMISSION_MODE_8K) {
312 dib3000mc_write_word(state, 58, 0x3b);
313 dib3000mc_write_word(state, 84, 0x00);
314 dib3000mc_write_word(state, 85, 0x8200);
315 }
316
317 dib3000mc_write_word(state, 34, 0x1294);
318 dib3000mc_write_word(state, 35, 0x1ff8);
319 if (mode == 1)
320 dib3000mc_write_word(state, 55, dib3000mc_read_word(state, 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
329 dib3000mc_write_word(state, 1027, 0x8000);
330 dib3000mc_write_word(state, 1027, 0x0000);
331
332
333 dib3000mc_write_word(state, 140, 0x0000);
334 dib3000mc_write_word(state, 1031, 0);
335
336 if (state->cfg->mobile_mode) {
337 dib3000mc_write_word(state, 139, 0x0000);
338 dib3000mc_write_word(state, 141, 0x0000);
339 dib3000mc_write_word(state, 175, 0x0002);
340 dib3000mc_write_word(state, 1032, 0x0000);
341 } else {
342 dib3000mc_write_word(state, 139, 0x0001);
343 dib3000mc_write_word(state, 141, 0x0000);
344 dib3000mc_write_word(state, 175, 0x0000);
345 dib3000mc_write_word(state, 1032, 0x012C);
346 }
347 dib3000mc_write_word(state, 1033, 0x0000);
348
349
350 dib3000mc_write_word(state, 1037, 0x3130);
351
352
353
354
355 dib3000mc_write_word(state, 33, (5 << 0));
356 dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0));
357
358
359
360 dib3000mc_write_word(state, 99, (1 << 9) | (0x20 << 0));
361
362 if (state->cfg->phase_noise_mode == 0)
363 dib3000mc_write_word(state, 111, 0x00);
364 else
365 dib3000mc_write_word(state, 111, 0x02);
366
367
368 dib3000mc_write_word(state, 50, 0x8000);
369
370
371 dib3000mc_setup_pwm_state(state);
372
373
374 dib3000mc_write_word(state, 53, 0x87);
375
376 dib3000mc_write_word(state, 54, 0x87);
377
378
379 dib3000mc_write_word(state, 36, state->cfg->max_time);
380 dib3000mc_write_word(state, 37, (state->cfg->agc_command1 << 13) | (state->cfg->agc_command2 << 12) | (0x1d << 0));
381 dib3000mc_write_word(state, 38, state->cfg->pwm3_value);
382 dib3000mc_write_word(state, 39, state->cfg->ln_adc_level);
383
384
385 dib3000mc_write_word(state, 40, 0x0179);
386 dib3000mc_write_word(state, 41, 0x03f0);
387
388 dib3000mc_write_word(state, 42, agc->agc1_max);
389 dib3000mc_write_word(state, 43, agc->agc1_min);
390 dib3000mc_write_word(state, 44, agc->agc2_max);
391 dib3000mc_write_word(state, 45, agc->agc2_min);
392 dib3000mc_write_word(state, 46, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
393 dib3000mc_write_word(state, 47, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
394 dib3000mc_write_word(state, 48, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
395 dib3000mc_write_word(state, 49, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
396
397
398
399 dib3000mc_write_word(state, 110, 3277);
400
401 dib3000mc_write_word(state, 26, 0x6680);
402
403 dib3000mc_write_word(state, 1, 4);
404
405 dib3000mc_write_word(state, 2, 4);
406
407 dib3000mc_write_word(state, 3, 0x1000);
408
409 dib3000mc_write_word(state, 5, 1);
410
411 dib3000mc_set_bandwidth(state, 8000);
412
413
414 dib3000mc_write_word(state, 4, 0x814);
415
416 dib3000mc_write_word(state, 21, (1 << 9) | 0x164);
417 dib3000mc_write_word(state, 22, 0x463d);
418
419
420
421 dib3000mc_write_word(state, 120, 0x200f);
422
423 dib3000mc_write_word(state, 134, 0);
424
425
426 dib3000mc_write_word(state, 195, 0x10);
427
428
429 dib3000mc_write_word(state, 180, 0x2FF0);
430
431
432 dib3000mc_set_impulse_noise(state, 0, TRANSMISSION_MODE_8K);
433
434
435 dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
436
437
438 dib3000mc_write_word(state, 769, (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, 1031, 0xFFFF);
448 dib3000mc_write_word(state, 1032, 0xFFFF);
449 dib3000mc_write_word(state, 1033, 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, 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, ch->transmission_mode, bw, 0);
480
481#if 1
482 dib3000mc_write_word(state, 100, (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, 1027, 0x0800);
491 dib3000mc_write_word(state, 1027, 0x0000);
492
493
494 dib3000mc_write_word(state, 26, 0x6680);
495 dib3000mc_write_word(state, 29, 0x1273);
496 dib3000mc_write_word(state, 33, 5);
497 dib3000mc_set_adp_cfg(state, QAM_16);
498 dib3000mc_write_word(state, 133, 15564);
499
500 dib3000mc_write_word(state, 12 , 0x0);
501 dib3000mc_write_word(state, 13 , 0x3e8);
502 dib3000mc_write_word(state, 14 , 0x0);
503 dib3000mc_write_word(state, 15 , 0x3f2);
504
505 dib3000mc_write_word(state, 93,0);
506 dib3000mc_write_word(state, 94,0);
507 dib3000mc_write_word(state, 95,0);
508 dib3000mc_write_word(state, 96,0);
509 dib3000mc_write_word(state, 97,0);
510 dib3000mc_write_word(state, 98,0);
511
512 dib3000mc_set_impulse_noise(state, 0, 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, 0, value);
540 dib3000mc_write_word(state, 5, (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, 181, value);
556
557
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, 180) & 0x000f;
572 dib3000mc_write_word(state, 180, value);
573
574
575 value = dib3000mc_read_word(state, 0);
576 dib3000mc_write_word(state, 0, value | (1 << 9));
577 dib3000mc_write_word(state, 0, value);
578
579 msleep(30);
580
581 dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, 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
590 struct dtv_frontend_properties schan;
591
592 schan = *chan;
593
594
595
596
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, &schan, 11);
605
606 reg = dib3000mc_read_word(state, 0);
607 dib3000mc_write_word(state, 0, reg | (1 << 8));
608 dib3000mc_read_word(state, 511);
609 dib3000mc_write_word(state, 0, 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, 511);
618
619 if (irq_pending & 0x1)
620 return 1;
621
622 if (irq_pending & 0x2)
623 return 2;
624
625 return 0;
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
634 dib3000mc_set_channel_cfg(state, ch, 0);
635
636
637 if (state->sfn_workaround_active) {
638 dprintk("SFN workaround is active\n");
639 dib3000mc_write_word(state, 29, 0x1273);
640 dib3000mc_write_word(state, 108, 0x4000);
641 } else {
642 dib3000mc_write_word(state, 29, 0x1073);
643 dib3000mc_write_word(state, 108, 0x0000);
644 }
645
646 dib3000mc_set_adp_cfg(state, (u8)ch->modulation);
647 if (ch->transmission_mode == TRANSMISSION_MODE_8K) {
648 dib3000mc_write_word(state, 26, 38528);
649 dib3000mc_write_word(state, 33, 8);
650 } else {
651 dib3000mc_write_word(state, 26, 30336);
652 dib3000mc_write_word(state, 33, 6);
653 }
654
655 if (dib3000mc_read_word(state, 509) & 0x80)
656 dib3000mc_set_timing(state, ch->transmission_mode,
657 BANDWIDTH_TO_KHZ(ch->bandwidth_hz), 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(&st->i2c_master, 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,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
700
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
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(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(fe);
751 do {
752 msleep(1);
753 found = dib3000mc_autosearch_is_irq(fe);
754 } while (found == 0 && i--);
755
756 dprintk("autosearch returns: %d\n",found);
757 if (found == 0 || found == 1)
758 return 0;
759
760 dib3000mc_get_frontend(fe, fep);
761 }
762
763 ret = dib3000mc_tune(fe);
764
765
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, 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, 500) << 16) | dib3000mc_read_word(state, 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, 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, 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(&state->i2c_master);
829 kfree(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, 212 + index, 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, 206) & ~(1 << 4);
844 tmp |= (onoff << 4);
845 return dib3000mc_write_word(state, 206, 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 u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
863
864 dmcst = kzalloc(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
874 new_addr = DIB3000MC_I2C_ADDRESS[k];
875 dmcst->i2c_addr = new_addr;
876 if (dib3000mc_identify(dmcst) != 0) {
877 dmcst->i2c_addr = default_addr;
878 if (dib3000mc_identify(dmcst) != 0) {
879 dprintk("-E- DiB3000P/MC #%d: not identified\n", k);
880 kfree(dmcst);
881 return -ENODEV;
882 }
883 }
884
885 dib3000mc_set_output_mode(dmcst, OUTMODE_MPEG2_PAR_CONT_CLK);
886
887
888 dib3000mc_write_word(dmcst, 1024, (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(dmcst, 1024, dmcst->i2c_addr << 3);
897
898
899 dib3000mc_set_output_mode(dmcst, OUTMODE_HIGH_Z);
900 }
901
902 kfree(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(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(st) != 0)
926 goto error;
927
928 dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
929
930 dib3000mc_write_word(st, 1037, 0x3130);
931
932 return demod;
933
934error:
935 kfree(st);
936 return NULL;
937}
938EXPORT_SYMBOL(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