1
2
3
4
5
6
7
8
9
10
11#include <linux/kernel.h>
12#include <linux/i2c.h>
13
14#include "dvb_frontend.h"
15
16#include "dib7000m.h"
17
18static int debug;
19module_param(debug, int, 0644);
20MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
21
22#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000M: "); printk(args); printk("\n"); } } while (0)
23
24struct dib7000m_state {
25 struct dvb_frontend demod;
26 struct dib7000m_config cfg;
27
28 u8 i2c_addr;
29 struct i2c_adapter *i2c_adap;
30
31 struct dibx000_i2c_master i2c_master;
32
33
34 u8 reg_offs;
35
36 u16 wbd_ref;
37
38 u8 current_band;
39 fe_bandwidth_t current_bandwidth;
40 struct dibx000_agc_config *current_agc;
41 u32 timf;
42 u32 timf_default;
43 u32 internal_clk;
44
45 u8 div_force_off : 1;
46 u8 div_state : 1;
47 u16 div_sync_wait;
48
49 u16 revision;
50
51 u8 agc_state;
52};
53
54enum dib7000m_power_mode {
55 DIB7000M_POWER_ALL = 0,
56
57 DIB7000M_POWER_NO,
58 DIB7000M_POWER_INTERF_ANALOG_AGC,
59 DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD,
60 DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD,
61 DIB7000M_POWER_INTERFACE_ONLY,
62};
63
64static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg)
65{
66 u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
67 u8 rb[2];
68 struct i2c_msg msg[2] = {
69 { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 },
70 { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
71 };
72
73 if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
74 dprintk("i2c read error on %d",reg);
75
76 return (rb[0] << 8) | rb[1];
77}
78
79static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val)
80{
81 u8 b[4] = {
82 (reg >> 8) & 0xff, reg & 0xff,
83 (val >> 8) & 0xff, val & 0xff,
84 };
85 struct i2c_msg msg = {
86 .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
87 };
88 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
89}
90static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf)
91{
92 u16 l = 0, r, *n;
93 n = buf;
94 l = *n++;
95 while (l) {
96 r = *n++;
97
98 if (state->reg_offs && (r >= 112 && r <= 331))
99 r++;
100
101 do {
102 dib7000m_write_word(state, r, *n++);
103 r++;
104 } while (--l);
105 l = *n++;
106 }
107}
108
109static int dib7000m_set_output_mode(struct dib7000m_state *state, int mode)
110{
111 int ret = 0;
112 u16 outreg, fifo_threshold, smo_mode,
113 sram = 0x0005;
114
115 outreg = 0;
116 fifo_threshold = 1792;
117 smo_mode = (dib7000m_read_word(state, 294 + state->reg_offs) & 0x0010) | (1 << 1);
118
119 dprintk( "setting output mode for demod %p to %d", &state->demod, mode);
120
121 switch (mode) {
122 case OUTMODE_MPEG2_PAR_GATED_CLK:
123 outreg = (1 << 10);
124 break;
125 case OUTMODE_MPEG2_PAR_CONT_CLK:
126 outreg = (1 << 10) | (1 << 6);
127 break;
128 case OUTMODE_MPEG2_SERIAL:
129 outreg = (1 << 10) | (2 << 6) | (0 << 1);
130 break;
131 case OUTMODE_DIVERSITY:
132 if (state->cfg.hostbus_diversity)
133 outreg = (1 << 10) | (4 << 6);
134 else
135 sram |= 0x0c00;
136 break;
137 case OUTMODE_MPEG2_FIFO:
138 smo_mode |= (3 << 1);
139 fifo_threshold = 512;
140 outreg = (1 << 10) | (5 << 6);
141 break;
142 case OUTMODE_HIGH_Z:
143 outreg = 0;
144 break;
145 default:
146 dprintk( "Unhandled output_mode passed to be set for demod %p",&state->demod);
147 break;
148 }
149
150 if (state->cfg.output_mpeg2_in_188_bytes)
151 smo_mode |= (1 << 5) ;
152
153 ret |= dib7000m_write_word(state, 294 + state->reg_offs, smo_mode);
154 ret |= dib7000m_write_word(state, 295 + state->reg_offs, fifo_threshold);
155 ret |= dib7000m_write_word(state, 1795, outreg);
156 ret |= dib7000m_write_word(state, 1805, sram);
157
158 if (state->revision == 0x4003) {
159 u16 clk_cfg1 = dib7000m_read_word(state, 909) & 0xfffd;
160 if (mode == OUTMODE_DIVERSITY)
161 clk_cfg1 |= (1 << 1);
162 dib7000m_write_word(state, 909, clk_cfg1);
163 }
164 return ret;
165}
166
167static void dib7000m_set_power_mode(struct dib7000m_state *state, enum dib7000m_power_mode mode)
168{
169
170 u16 reg_903 = 0xffff, reg_904 = 0xffff, reg_905 = 0xffff, reg_906 = 0x3fff;
171 u8 offset = 0;
172
173
174 switch (mode) {
175
176 case DIB7000M_POWER_ALL:
177 reg_903 = 0x0000; reg_904 = 0x0000; reg_905 = 0x0000; reg_906 = 0x0000;
178 break;
179
180
181 case DIB7000M_POWER_INTERFACE_ONLY:
182 reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 2));
183 break;
184
185 case DIB7000M_POWER_INTERF_ANALOG_AGC:
186 reg_903 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10));
187 reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 2));
188 reg_906 &= ~((1 << 0));
189 break;
190
191 case DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD:
192 reg_903 = 0x0000; reg_904 = 0x801f; reg_905 = 0x0000; reg_906 = 0x0000;
193 break;
194
195 case DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD:
196 reg_903 = 0x0000; reg_904 = 0x8000; reg_905 = 0x010b; reg_906 = 0x0000;
197 break;
198 case DIB7000M_POWER_NO:
199 break;
200 }
201
202
203 if (!state->cfg.mobile_mode)
204 reg_904 |= (1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) | (1 << 1);
205
206
207 if (state->revision != 0x4000)
208 reg_906 <<= 1;
209
210 if (state->revision == 0x4003)
211 offset = 1;
212
213 dib7000m_write_word(state, 903 + offset, reg_903);
214 dib7000m_write_word(state, 904 + offset, reg_904);
215 dib7000m_write_word(state, 905 + offset, reg_905);
216 dib7000m_write_word(state, 906 + offset, reg_906);
217}
218
219static int dib7000m_set_adc_state(struct dib7000m_state *state, enum dibx000_adc_states no)
220{
221 int ret = 0;
222 u16 reg_913 = dib7000m_read_word(state, 913),
223 reg_914 = dib7000m_read_word(state, 914);
224
225 switch (no) {
226 case DIBX000_SLOW_ADC_ON:
227 reg_914 |= (1 << 1) | (1 << 0);
228 ret |= dib7000m_write_word(state, 914, reg_914);
229 reg_914 &= ~(1 << 1);
230 break;
231
232 case DIBX000_SLOW_ADC_OFF:
233 reg_914 |= (1 << 1) | (1 << 0);
234 break;
235
236 case DIBX000_ADC_ON:
237 if (state->revision == 0x4000) {
238
239 dib7000m_write_word(state, 913, 0);
240 dib7000m_write_word(state, 914, reg_914 & 0x3);
241
242 dib7000m_write_word(state, 913, (1 << 15));
243 dib7000m_write_word(state, 914, reg_914 & 0x3);
244 }
245
246 reg_913 &= 0x0fff;
247 reg_914 &= 0x0003;
248 break;
249
250 case DIBX000_ADC_OFF:
251 reg_913 |= (1 << 14) | (1 << 13) | (1 << 12);
252 reg_914 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
253 break;
254
255 case DIBX000_VBG_ENABLE:
256 reg_913 &= ~(1 << 15);
257 break;
258
259 case DIBX000_VBG_DISABLE:
260 reg_913 |= (1 << 15);
261 break;
262
263 default:
264 break;
265 }
266
267
268 ret |= dib7000m_write_word(state, 913, reg_913);
269 ret |= dib7000m_write_word(state, 914, reg_914);
270
271 return ret;
272}
273
274static int dib7000m_set_bandwidth(struct dib7000m_state *state, u32 bw)
275{
276 u32 timf;
277
278
279 state->current_bandwidth = bw;
280
281 if (state->timf == 0) {
282 dprintk( "using default timf");
283 timf = state->timf_default;
284 } else {
285 dprintk( "using updated timf");
286 timf = state->timf;
287 }
288
289 timf = timf * (bw / 50) / 160;
290
291 dib7000m_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
292 dib7000m_write_word(state, 24, (u16) ((timf ) & 0xffff));
293
294 return 0;
295}
296
297static int dib7000m_set_diversity_in(struct dvb_frontend *demod, int onoff)
298{
299 struct dib7000m_state *state = demod->demodulator_priv;
300
301 if (state->div_force_off) {
302 dprintk( "diversity combination deactivated - forced by COFDM parameters");
303 onoff = 0;
304 }
305 state->div_state = (u8)onoff;
306
307 if (onoff) {
308 dib7000m_write_word(state, 263 + state->reg_offs, 6);
309 dib7000m_write_word(state, 264 + state->reg_offs, 6);
310 dib7000m_write_word(state, 266 + state->reg_offs, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
311 } else {
312 dib7000m_write_word(state, 263 + state->reg_offs, 1);
313 dib7000m_write_word(state, 264 + state->reg_offs, 0);
314 dib7000m_write_word(state, 266 + state->reg_offs, 0);
315 }
316
317 return 0;
318}
319
320static int dib7000m_sad_calib(struct dib7000m_state *state)
321{
322
323
324
325 dib7000m_write_word(state, 929, (0 << 1) | (0 << 0));
326 dib7000m_write_word(state, 930, 776);
327
328
329 dib7000m_write_word(state, 929, (1 << 0));
330 dib7000m_write_word(state, 929, (0 << 0));
331
332 msleep(1);
333
334 return 0;
335}
336
337static void dib7000m_reset_pll_common(struct dib7000m_state *state, const struct dibx000_bandwidth_config *bw)
338{
339 dib7000m_write_word(state, 18, (u16) (((bw->internal*1000) >> 16) & 0xffff));
340 dib7000m_write_word(state, 19, (u16) ( (bw->internal*1000) & 0xffff));
341 dib7000m_write_word(state, 21, (u16) ( (bw->ifreq >> 16) & 0xffff));
342 dib7000m_write_word(state, 22, (u16) ( bw->ifreq & 0xffff));
343
344 dib7000m_write_word(state, 928, bw->sad_cfg);
345}
346
347static void dib7000m_reset_pll(struct dib7000m_state *state)
348{
349 const struct dibx000_bandwidth_config *bw = state->cfg.bw;
350 u16 reg_907,reg_910;
351
352
353 reg_907 = (bw->pll_bypass << 15) | (bw->modulo << 7) |
354 (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) |
355 (bw->enable_refdiv << 1) | (0 << 0);
356 reg_910 = (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset;
357
358
359
360 if (!state->cfg.quartz_direct) {
361 reg_910 |= (1 << 5);
362
363
364 if(state->cfg.input_clk_is_div_2)
365 reg_907 |= (16 << 9);
366 else
367 reg_907 |= (8 << 9);
368 } else {
369 reg_907 |= (bw->pll_ratio & 0x3f) << 9;
370 reg_910 |= (bw->pll_prediv << 5);
371 }
372
373 dib7000m_write_word(state, 910, reg_910);
374 dib7000m_write_word(state, 907, reg_907);
375 dib7000m_write_word(state, 908, 0x0006);
376
377 dib7000m_reset_pll_common(state, bw);
378}
379
380static void dib7000mc_reset_pll(struct dib7000m_state *state)
381{
382 const struct dibx000_bandwidth_config *bw = state->cfg.bw;
383 u16 clk_cfg1;
384
385
386 dib7000m_write_word(state, 907, (bw->pll_prediv << 8) | (bw->pll_ratio << 0));
387
388
389
390 clk_cfg1 = (0 << 14) | (3 << 12) |(0 << 11) |
391 (bw->IO_CLK_en_core << 10) | (bw->bypclk_div << 5) | (bw->enable_refdiv << 4) |
392 (1 << 3) | (bw->pll_range << 1) | (bw->pll_reset << 0);
393 dib7000m_write_word(state, 908, clk_cfg1);
394 clk_cfg1 = (clk_cfg1 & 0xfff7) | (bw->pll_bypass << 3);
395 dib7000m_write_word(state, 908, clk_cfg1);
396
397
398 dib7000m_write_word(state, 910, (1 << 12) | (2 << 10) | (bw->modulo << 8) | (bw->ADClkSrc << 7));
399
400 dib7000m_reset_pll_common(state, bw);
401}
402
403static int dib7000m_reset_gpio(struct dib7000m_state *st)
404{
405
406 dib7000m_write_word(st, 773, st->cfg.gpio_dir);
407 dib7000m_write_word(st, 774, st->cfg.gpio_val);
408
409
410
411 dib7000m_write_word(st, 775, st->cfg.gpio_pwm_pos);
412
413 dib7000m_write_word(st, 780, st->cfg.pwm_freq_div);
414 return 0;
415}
416
417static u16 dib7000m_defaults_common[] =
418
419{
420
421 3, 2,
422 0x0004,
423 0x1000,
424 0x0814,
425
426 12, 6,
427 0x001b,
428 0x7740,
429 0x005b,
430 0x8d80,
431 0x01c9,
432 0xc380,
433 0x0000,
434 0x0080,
435 0x0000,
436 0x0090,
437 0x0001,
438 0xd4c0,
439
440 1, 26,
441 0x6680,
442
443 1, 170,
444 0x0410,
445
446 8, 173,
447 0,
448 0,
449 0,
450 0,
451 0,
452 0,
453 0,
454 0,
455
456 1, 182,
457 8192,
458
459 2, 195,
460 0x0ccd,
461 0,
462
463 1, 205,
464 0x200f,
465
466 5, 214,
467 0x023d,
468 0x00a4,
469 0x00a4,
470 0x7ff0,
471 0x3ccc,
472
473 1, 226,
474 0,
475
476 1, 255,
477 0x800,
478
479 1, 263,
480 0x0001,
481
482 1, 281,
483 0x0010,
484
485 1, 294,
486 0x0062,
487
488 0
489};
490
491static u16 dib7000m_defaults[] =
492
493{
494
495 11, 76,
496 (1 << 13) - 825 - 117,
497 (1 << 13) - 837 - 117,
498 (1 << 13) - 811 - 117,
499 (1 << 13) - 766 - 117,
500 (1 << 13) - 737 - 117,
501 (1 << 13) - 693 - 117,
502 (1 << 13) - 648 - 117,
503 (1 << 13) - 619 - 117,
504 (1 << 13) - 575 - 117,
505 (1 << 13) - 531 - 117,
506 (1 << 13) - 501 - 117,
507
508
509 1, 912,
510 0x2c8a,
511
512 1, 1817,
513 1,
514
515 0,
516};
517
518static int dib7000m_demod_reset(struct dib7000m_state *state)
519{
520 dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
521
522
523 dib7000m_set_adc_state(state, DIBX000_VBG_ENABLE);
524
525
526 dib7000m_write_word(state, 898, 0xffff);
527 dib7000m_write_word(state, 899, 0xffff);
528 dib7000m_write_word(state, 900, 0xff0f);
529 dib7000m_write_word(state, 901, 0xfffc);
530
531 dib7000m_write_word(state, 898, 0);
532 dib7000m_write_word(state, 899, 0);
533 dib7000m_write_word(state, 900, 0);
534 dib7000m_write_word(state, 901, 0);
535
536 if (state->revision == 0x4000)
537 dib7000m_reset_pll(state);
538 else
539 dib7000mc_reset_pll(state);
540
541 if (dib7000m_reset_gpio(state) != 0)
542 dprintk( "GPIO reset was not successful.");
543
544 if (dib7000m_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
545 dprintk( "OUTPUT_MODE could not be reset.");
546
547
548 dib7000m_write_word(state, 1794, dib7000m_read_word(state, 1794) & ~(1 << 1) );
549
550 dib7000m_set_bandwidth(state, 8000);
551
552 dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON);
553 dib7000m_sad_calib(state);
554 dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
555
556 if (state->cfg.dvbt_mode)
557 dib7000m_write_word(state, 1796, 0x0);
558
559 if (state->cfg.mobile_mode)
560 dib7000m_write_word(state, 261 + state->reg_offs, 2);
561 else
562 dib7000m_write_word(state, 224 + state->reg_offs, 1);
563
564
565 if(state->cfg.tuner_is_baseband)
566 dib7000m_write_word(state, 36, 0x0755);
567 else
568 dib7000m_write_word(state, 36, 0x1f55);
569
570
571 if (state->revision == 0x4000)
572 dib7000m_write_word(state, 909, (3 << 10) | (1 << 6));
573 else
574 dib7000m_write_word(state, 909, (3 << 4) | 1);
575
576 dib7000m_write_tab(state, dib7000m_defaults_common);
577 dib7000m_write_tab(state, dib7000m_defaults);
578
579 dib7000m_set_power_mode(state, DIB7000M_POWER_INTERFACE_ONLY);
580
581 state->internal_clk = state->cfg.bw->internal;
582
583 return 0;
584}
585
586static void dib7000m_restart_agc(struct dib7000m_state *state)
587{
588
589 dib7000m_write_word(state, 898, 0x0c00);
590 dib7000m_write_word(state, 898, 0x0000);
591}
592
593static int dib7000m_agc_soft_split(struct dib7000m_state *state)
594{
595 u16 agc,split_offset;
596
597 if(!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
598 return 0;
599
600
601 agc = dib7000m_read_word(state, 390);
602
603 if (agc > state->current_agc->split.min_thres)
604 split_offset = state->current_agc->split.min;
605 else if (agc < state->current_agc->split.max_thres)
606 split_offset = state->current_agc->split.max;
607 else
608 split_offset = state->current_agc->split.max *
609 (agc - state->current_agc->split.min_thres) /
610 (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
611
612 dprintk( "AGC split_offset: %d",split_offset);
613
614
615 return dib7000m_write_word(state, 103, (dib7000m_read_word(state, 103) & 0xff00) | split_offset);
616}
617
618static int dib7000m_update_lna(struct dib7000m_state *state)
619{
620 u16 dyn_gain;
621
622 if (state->cfg.update_lna) {
623
624 dyn_gain = dib7000m_read_word(state, 390);
625
626 if (state->cfg.update_lna(&state->demod,dyn_gain)) {
627 dib7000m_restart_agc(state);
628 return 1;
629 }
630 }
631 return 0;
632}
633
634static int dib7000m_set_agc_config(struct dib7000m_state *state, u8 band)
635{
636 struct dibx000_agc_config *agc = NULL;
637 int i;
638 if (state->current_band == band && state->current_agc != NULL)
639 return 0;
640 state->current_band = band;
641
642 for (i = 0; i < state->cfg.agc_config_count; i++)
643 if (state->cfg.agc[i].band_caps & band) {
644 agc = &state->cfg.agc[i];
645 break;
646 }
647
648 if (agc == NULL) {
649 dprintk( "no valid AGC configuration found for band 0x%02x",band);
650 return -EINVAL;
651 }
652
653 state->current_agc = agc;
654
655
656 dib7000m_write_word(state, 72 , agc->setup);
657 dib7000m_write_word(state, 73 , agc->inv_gain);
658 dib7000m_write_word(state, 74 , agc->time_stabiliz);
659 dib7000m_write_word(state, 97 , (agc->alpha_level << 12) | agc->thlock);
660
661
662 dib7000m_write_word(state, 98, (agc->alpha_mant << 5) | agc->alpha_exp);
663 dib7000m_write_word(state, 99, (agc->beta_mant << 6) | agc->beta_exp);
664
665 dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d",
666 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
667
668
669 if (state->wbd_ref != 0)
670 dib7000m_write_word(state, 102, state->wbd_ref);
671 else
672 dib7000m_write_word(state, 102, agc->wbd_ref);
673
674 dib7000m_write_word(state, 103, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8) );
675 dib7000m_write_word(state, 104, agc->agc1_max);
676 dib7000m_write_word(state, 105, agc->agc1_min);
677 dib7000m_write_word(state, 106, agc->agc2_max);
678 dib7000m_write_word(state, 107, agc->agc2_min);
679 dib7000m_write_word(state, 108, (agc->agc1_pt1 << 8) | agc->agc1_pt2 );
680 dib7000m_write_word(state, 109, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
681 dib7000m_write_word(state, 110, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
682 dib7000m_write_word(state, 111, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
683
684 if (state->revision > 0x4000) {
685 dib7000m_write_word(state, 71, agc->agc1_pt3);
686
687
688 dib7000m_write_word(state, 929, (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2));
689 } else {
690
691 u16 b[9] = { 676, 696, 717, 737, 758, 778, 799, 819, 840 };
692 for (i = 0; i < 9; i++)
693 dib7000m_write_word(state, 88 + i, b[i]);
694 }
695 return 0;
696}
697
698static void dib7000m_update_timf(struct dib7000m_state *state)
699{
700 u32 timf = (dib7000m_read_word(state, 436) << 16) | dib7000m_read_word(state, 437);
701 state->timf = timf * 160 / (state->current_bandwidth / 50);
702 dib7000m_write_word(state, 23, (u16) (timf >> 16));
703 dib7000m_write_word(state, 24, (u16) (timf & 0xffff));
704 dprintk( "updated timf_frequency: %d (default: %d)",state->timf, state->timf_default);
705}
706
707static int dib7000m_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
708{
709 struct dib7000m_state *state = demod->demodulator_priv;
710 u16 cfg_72 = dib7000m_read_word(state, 72);
711 int ret = -1;
712 u8 *agc_state = &state->agc_state;
713 u8 agc_split;
714
715 switch (state->agc_state) {
716 case 0:
717
718 dib7000m_set_power_mode(state, DIB7000M_POWER_INTERF_ANALOG_AGC);
719 dib7000m_set_adc_state(state, DIBX000_ADC_ON);
720
721 if (dib7000m_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0)
722 return -1;
723
724 ret = 7;
725 (*agc_state)++;
726 break;
727
728 case 1:
729
730 if (state->cfg.agc_control)
731 state->cfg.agc_control(&state->demod, 1);
732
733 dib7000m_write_word(state, 75, 32768);
734 if (!state->current_agc->perform_agc_softsplit) {
735
736 dib7000m_write_word(state, 103, 1 << 8);
737 (*agc_state)++;
738 ret = 5;
739 } else {
740
741 (*agc_state) = 4;
742
743 ret = 7;
744 }
745
746 dib7000m_restart_agc(state);
747 break;
748
749 case 2:
750 dib7000m_write_word(state, 72, cfg_72 | (1 << 4));
751 dib7000m_write_word(state, 103, 2 << 9);
752 (*agc_state)++;
753 ret = 14;
754 break;
755
756 case 3:
757 agc_split = (u8)dib7000m_read_word(state, 392);
758 dib7000m_write_word(state, 75, dib7000m_read_word(state, 390));
759
760 dib7000m_write_word(state, 72, cfg_72 & ~(1 << 4));
761 dib7000m_write_word(state, 103, (state->current_agc->wbd_alpha << 9) | agc_split);
762
763 dib7000m_restart_agc(state);
764
765 dprintk( "SPLIT %p: %hd", demod, agc_split);
766
767 (*agc_state)++;
768 ret = 5;
769 break;
770
771 case 4:
772
773 ret = 7;
774
775 if (dib7000m_update_lna(state))
776
777 ret = 5;
778 else
779 (*agc_state)++;
780 break;
781
782 case 5:
783 dib7000m_agc_soft_split(state);
784
785 if (state->cfg.agc_control)
786 state->cfg.agc_control(&state->demod, 0);
787
788 (*agc_state)++;
789 break;
790
791 default:
792 break;
793 }
794 return ret;
795}
796
797static void dib7000m_set_channel(struct dib7000m_state *state, struct dvb_frontend_parameters *ch, u8 seq)
798{
799 u16 value, est[4];
800
801 dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
802
803
804 value = 0;
805 switch (ch->u.ofdm.transmission_mode) {
806 case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
807 case 255: value |= (2 << 7); break;
808 default:
809 case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
810 }
811 switch (ch->u.ofdm.guard_interval) {
812 case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
813 case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
814 case GUARD_INTERVAL_1_4: value |= (3 << 5); break;
815 default:
816 case GUARD_INTERVAL_1_8: value |= (2 << 5); break;
817 }
818 switch (ch->u.ofdm.constellation) {
819 case QPSK: value |= (0 << 3); break;
820 case QAM_16: value |= (1 << 3); break;
821 default:
822 case QAM_64: value |= (2 << 3); break;
823 }
824 switch (HIERARCHY_1) {
825 case HIERARCHY_2: value |= 2; break;
826 case HIERARCHY_4: value |= 4; break;
827 default:
828 case HIERARCHY_1: value |= 1; break;
829 }
830 dib7000m_write_word(state, 0, value);
831 dib7000m_write_word(state, 5, (seq << 4));
832
833
834 value = 0;
835 if (1 != 0)
836 value |= (1 << 6);
837 if (ch->u.ofdm.hierarchy_information == 1)
838 value |= (1 << 4);
839 if (1 == 1)
840 value |= 1;
841 switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
842 case FEC_2_3: value |= (2 << 1); break;
843 case FEC_3_4: value |= (3 << 1); break;
844 case FEC_5_6: value |= (5 << 1); break;
845 case FEC_7_8: value |= (7 << 1); break;
846 default:
847 case FEC_1_2: value |= (1 << 1); break;
848 }
849 dib7000m_write_word(state, 267 + state->reg_offs, value);
850
851
852
853
854 dib7000m_write_word(state, 26, (6 << 12) | (6 << 8) | 0x80);
855
856
857 dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (1 << 9) | (3 << 5) | (1 << 4) | (0x3));
858
859
860 dib7000m_write_word(state, 32, (0 << 4) | 0x3);
861
862
863 dib7000m_write_word(state, 33, (0 << 4) | 0x5);
864
865
866 switch (ch->u.ofdm.transmission_mode) {
867 case TRANSMISSION_MODE_8K: value = 256; break;
868 case 255: value = 128; break;
869 case TRANSMISSION_MODE_2K:
870 default: value = 64; break;
871 }
872 switch (ch->u.ofdm.guard_interval) {
873 case GUARD_INTERVAL_1_16: value *= 2; break;
874 case GUARD_INTERVAL_1_8: value *= 4; break;
875 case GUARD_INTERVAL_1_4: value *= 8; break;
876 default:
877 case GUARD_INTERVAL_1_32: value *= 1; break;
878 }
879 state->div_sync_wait = (value * 3) / 2 + 32;
880
881
882
883 if (1 == 1 || state->revision > 0x4000)
884 state->div_force_off = 0;
885 else
886 state->div_force_off = 1;
887 dib7000m_set_diversity_in(&state->demod, state->div_state);
888
889
890 switch (ch->u.ofdm.constellation) {
891 case QAM_64:
892 est[0] = 0x0148;
893 est[1] = 0xfff0;
894 est[2] = 0x00a4;
895 est[3] = 0xfff8;
896 break;
897 case QAM_16:
898 est[0] = 0x023d;
899 est[1] = 0xffdf;
900 est[2] = 0x00a4;
901 est[3] = 0xfff0;
902 break;
903 default:
904 est[0] = 0x099a;
905 est[1] = 0xffae;
906 est[2] = 0x0333;
907 est[3] = 0xfff8;
908 break;
909 }
910 for (value = 0; value < 4; value++)
911 dib7000m_write_word(state, 214 + value + state->reg_offs, est[value]);
912
913
914 dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD);
915}
916
917static int dib7000m_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
918{
919 struct dib7000m_state *state = demod->demodulator_priv;
920 struct dvb_frontend_parameters schan;
921 int ret = 0;
922 u32 value, factor;
923
924 schan = *ch;
925
926 schan.u.ofdm.constellation = QAM_64;
927 schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
928 schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
929 schan.u.ofdm.code_rate_HP = FEC_2_3;
930 schan.u.ofdm.code_rate_LP = FEC_3_4;
931 schan.u.ofdm.hierarchy_information = 0;
932
933 dib7000m_set_channel(state, &schan, 7);
934
935 factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth);
936 if (factor >= 5000)
937 factor = 1;
938 else
939 factor = 6;
940
941
942 value = 30 * state->internal_clk * factor;
943 ret |= dib7000m_write_word(state, 6, (u16) ((value >> 16) & 0xffff));
944 ret |= dib7000m_write_word(state, 7, (u16) (value & 0xffff));
945 value = 100 * state->internal_clk * factor;
946 ret |= dib7000m_write_word(state, 8, (u16) ((value >> 16) & 0xffff));
947 ret |= dib7000m_write_word(state, 9, (u16) (value & 0xffff));
948 value = 500 * state->internal_clk * factor;
949 ret |= dib7000m_write_word(state, 10, (u16) ((value >> 16) & 0xffff));
950 ret |= dib7000m_write_word(state, 11, (u16) (value & 0xffff));
951
952
953 value = dib7000m_read_word(state, 0);
954 ret |= dib7000m_write_word(state, 0, (u16) (value | (1 << 9)));
955
956
957 if (state->revision == 0x4000)
958 dib7000m_write_word(state, 1793, 0);
959 else
960 dib7000m_read_word(state, 537);
961
962 ret |= dib7000m_write_word(state, 0, (u16) value);
963
964 return ret;
965}
966
967static int dib7000m_autosearch_irq(struct dib7000m_state *state, u16 reg)
968{
969 u16 irq_pending = dib7000m_read_word(state, reg);
970
971 if (irq_pending & 0x1) {
972 dprintk( "autosearch failed");
973 return 1;
974 }
975
976 if (irq_pending & 0x2) {
977 dprintk( "autosearch succeeded");
978 return 2;
979 }
980 return 0;
981}
982
983static int dib7000m_autosearch_is_irq(struct dvb_frontend *demod)
984{
985 struct dib7000m_state *state = demod->demodulator_priv;
986 if (state->revision == 0x4000)
987 return dib7000m_autosearch_irq(state, 1793);
988 else
989 return dib7000m_autosearch_irq(state, 537);
990}
991
992static int dib7000m_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
993{
994 struct dib7000m_state *state = demod->demodulator_priv;
995 int ret = 0;
996 u16 value;
997
998
999 if (ch != NULL)
1000 dib7000m_set_channel(state, ch, 0);
1001 else
1002 return -EINVAL;
1003
1004
1005 ret |= dib7000m_write_word(state, 898, 0x4000);
1006 ret |= dib7000m_write_word(state, 898, 0x0000);
1007 msleep(45);
1008
1009 dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD);
1010
1011 ret |= dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3));
1012
1013
1014 if (state->timf == 0)
1015 msleep(200);
1016
1017
1018
1019 value = (6 << 8) | 0x80;
1020 switch (ch->u.ofdm.transmission_mode) {
1021 case TRANSMISSION_MODE_2K: value |= (7 << 12); break;
1022 case 255: value |= (8 << 12); break;
1023 default:
1024 case TRANSMISSION_MODE_8K: value |= (9 << 12); break;
1025 }
1026 ret |= dib7000m_write_word(state, 26, value);
1027
1028
1029 value = (0 << 4);
1030 switch (ch->u.ofdm.transmission_mode) {
1031 case TRANSMISSION_MODE_2K: value |= 0x6; break;
1032 case 255: value |= 0x7; break;
1033 default:
1034 case TRANSMISSION_MODE_8K: value |= 0x8; break;
1035 }
1036 ret |= dib7000m_write_word(state, 32, value);
1037
1038
1039 value = (0 << 4);
1040 switch (ch->u.ofdm.transmission_mode) {
1041 case TRANSMISSION_MODE_2K: value |= 0x6; break;
1042 case 255: value |= 0x7; break;
1043 default:
1044 case TRANSMISSION_MODE_8K: value |= 0x8; break;
1045 }
1046 ret |= dib7000m_write_word(state, 33, value);
1047
1048
1049 if ((dib7000m_read_word(state, 535) >> 6) & 0x1)
1050 dib7000m_update_timf(state);
1051
1052 dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1053 return ret;
1054}
1055
1056static int dib7000m_wakeup(struct dvb_frontend *demod)
1057{
1058 struct dib7000m_state *state = demod->demodulator_priv;
1059
1060 dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
1061
1062 if (dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
1063 dprintk( "could not start Slow ADC");
1064
1065 return 0;
1066}
1067
1068static int dib7000m_sleep(struct dvb_frontend *demod)
1069{
1070 struct dib7000m_state *st = demod->demodulator_priv;
1071 dib7000m_set_output_mode(st, OUTMODE_HIGH_Z);
1072 dib7000m_set_power_mode(st, DIB7000M_POWER_INTERFACE_ONLY);
1073 return dib7000m_set_adc_state(st, DIBX000_SLOW_ADC_OFF) |
1074 dib7000m_set_adc_state(st, DIBX000_ADC_OFF);
1075}
1076
1077static int dib7000m_identify(struct dib7000m_state *state)
1078{
1079 u16 value;
1080
1081 if ((value = dib7000m_read_word(state, 896)) != 0x01b3) {
1082 dprintk( "wrong Vendor ID (0x%x)",value);
1083 return -EREMOTEIO;
1084 }
1085
1086 state->revision = dib7000m_read_word(state, 897);
1087 if (state->revision != 0x4000 &&
1088 state->revision != 0x4001 &&
1089 state->revision != 0x4002 &&
1090 state->revision != 0x4003) {
1091 dprintk( "wrong Device ID (0x%x)",value);
1092 return -EREMOTEIO;
1093 }
1094
1095
1096 if (state->revision == 0x4000 && dib7000m_read_word(state, 769) == 0x4000) {
1097 dprintk( "this driver does not work with DiB7000PC");
1098 return -EREMOTEIO;
1099 }
1100
1101 switch (state->revision) {
1102 case 0x4000: dprintk( "found DiB7000MA/PA/MB/PB"); break;
1103 case 0x4001: state->reg_offs = 1; dprintk( "found DiB7000HC"); break;
1104 case 0x4002: state->reg_offs = 1; dprintk( "found DiB7000MC"); break;
1105 case 0x4003: state->reg_offs = 1; dprintk( "found DiB9000"); break;
1106 }
1107
1108 return 0;
1109}
1110
1111
1112static int dib7000m_get_frontend(struct dvb_frontend* fe,
1113 struct dvb_frontend_parameters *fep)
1114{
1115 struct dib7000m_state *state = fe->demodulator_priv;
1116 u16 tps = dib7000m_read_word(state,480);
1117
1118 fep->inversion = INVERSION_AUTO;
1119
1120 fep->u.ofdm.bandwidth = state->current_bandwidth;
1121
1122 switch ((tps >> 8) & 0x3) {
1123 case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break;
1124 case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break;
1125
1126 }
1127
1128 switch (tps & 0x3) {
1129 case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break;
1130 case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break;
1131 case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break;
1132 case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break;
1133 }
1134
1135 switch ((tps >> 14) & 0x3) {
1136 case 0: fep->u.ofdm.constellation = QPSK; break;
1137 case 1: fep->u.ofdm.constellation = QAM_16; break;
1138 case 2:
1139 default: fep->u.ofdm.constellation = QAM_64; break;
1140 }
1141
1142
1143
1144
1145 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
1146 switch ((tps >> 5) & 0x7) {
1147 case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break;
1148 case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break;
1149 case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break;
1150 case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break;
1151 case 7:
1152 default: fep->u.ofdm.code_rate_HP = FEC_7_8; break;
1153
1154 }
1155
1156 switch ((tps >> 2) & 0x7) {
1157 case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break;
1158 case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break;
1159 case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break;
1160 case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break;
1161 case 7:
1162 default: fep->u.ofdm.code_rate_LP = FEC_7_8; break;
1163 }
1164
1165
1166
1167 return 0;
1168}
1169
1170static int dib7000m_set_frontend(struct dvb_frontend* fe,
1171 struct dvb_frontend_parameters *fep)
1172{
1173 struct dib7000m_state *state = fe->demodulator_priv;
1174 int time, ret;
1175
1176 dib7000m_set_output_mode(state, OUTMODE_HIGH_Z);
1177
1178 state->current_bandwidth = fep->u.ofdm.bandwidth;
1179 dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->u.ofdm.bandwidth));
1180
1181 if (fe->ops.tuner_ops.set_params)
1182 fe->ops.tuner_ops.set_params(fe, fep);
1183
1184
1185 state->agc_state = 0;
1186 do {
1187 time = dib7000m_agc_startup(fe, fep);
1188 if (time != -1)
1189 msleep(time);
1190 } while (time != -1);
1191
1192 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
1193 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ||
1194 fep->u.ofdm.constellation == QAM_AUTO ||
1195 fep->u.ofdm.code_rate_HP == FEC_AUTO) {
1196 int i = 800, found;
1197
1198 dib7000m_autosearch_start(fe, fep);
1199 do {
1200 msleep(1);
1201 found = dib7000m_autosearch_is_irq(fe);
1202 } while (found == 0 && i--);
1203
1204 dprintk("autosearch returns: %d",found);
1205 if (found == 0 || found == 1)
1206 return 0;
1207
1208 dib7000m_get_frontend(fe, fep);
1209 }
1210
1211 ret = dib7000m_tune(fe, fep);
1212
1213
1214 dib7000m_set_output_mode(state, OUTMODE_MPEG2_FIFO);
1215 return ret;
1216}
1217
1218static int dib7000m_read_status(struct dvb_frontend *fe, fe_status_t *stat)
1219{
1220 struct dib7000m_state *state = fe->demodulator_priv;
1221 u16 lock = dib7000m_read_word(state, 535);
1222
1223 *stat = 0;
1224
1225 if (lock & 0x8000)
1226 *stat |= FE_HAS_SIGNAL;
1227 if (lock & 0x3000)
1228 *stat |= FE_HAS_CARRIER;
1229 if (lock & 0x0100)
1230 *stat |= FE_HAS_VITERBI;
1231 if (lock & 0x0010)
1232 *stat |= FE_HAS_SYNC;
1233 if (lock & 0x0008)
1234 *stat |= FE_HAS_LOCK;
1235
1236 return 0;
1237}
1238
1239static int dib7000m_read_ber(struct dvb_frontend *fe, u32 *ber)
1240{
1241 struct dib7000m_state *state = fe->demodulator_priv;
1242 *ber = (dib7000m_read_word(state, 526) << 16) | dib7000m_read_word(state, 527);
1243 return 0;
1244}
1245
1246static int dib7000m_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
1247{
1248 struct dib7000m_state *state = fe->demodulator_priv;
1249 *unc = dib7000m_read_word(state, 534);
1250 return 0;
1251}
1252
1253static int dib7000m_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1254{
1255 struct dib7000m_state *state = fe->demodulator_priv;
1256 u16 val = dib7000m_read_word(state, 390);
1257 *strength = 65535 - val;
1258 return 0;
1259}
1260
1261static int dib7000m_read_snr(struct dvb_frontend* fe, u16 *snr)
1262{
1263 *snr = 0x0000;
1264 return 0;
1265}
1266
1267static int dib7000m_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
1268{
1269 tune->min_delay_ms = 1000;
1270 return 0;
1271}
1272
1273static void dib7000m_release(struct dvb_frontend *demod)
1274{
1275 struct dib7000m_state *st = demod->demodulator_priv;
1276 dibx000_exit_i2c_master(&st->i2c_master);
1277 kfree(st);
1278}
1279
1280struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
1281{
1282 struct dib7000m_state *st = demod->demodulator_priv;
1283 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1284}
1285EXPORT_SYMBOL(dib7000m_get_i2c_master);
1286
1287#if 0
1288
1289int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods,
1290 u8 default_addr, struct dib7000m_config cfg[])
1291{
1292 struct dib7000m_state st = { .i2c_adap = i2c };
1293 int k = 0;
1294 u8 new_addr = 0;
1295
1296 for (k = no_of_demods-1; k >= 0; k--) {
1297 st.cfg = cfg[k];
1298
1299
1300 new_addr = (0x40 + k) << 1;
1301 st.i2c_addr = new_addr;
1302 if (dib7000m_identify(&st) != 0) {
1303 st.i2c_addr = default_addr;
1304 if (dib7000m_identify(&st) != 0) {
1305 dprintk("DiB7000M #%d: not identified", k);
1306 return -EIO;
1307 }
1308 }
1309
1310
1311 dib7000m_set_output_mode(&st, OUTMODE_DIVERSITY);
1312
1313 dib7000m_write_word(&st, 1796, 0x0);
1314
1315
1316 dib7000m_write_word(&st, 1794, (new_addr << 2) | 0x2);
1317
1318 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
1319 }
1320
1321 for (k = 0; k < no_of_demods; k++) {
1322 st.cfg = cfg[k];
1323 st.i2c_addr = (0x40 + k) << 1;
1324
1325
1326 dib7000m_write_word(&st,1794, st.i2c_addr << 2);
1327
1328
1329 dib7000m_set_output_mode(&st, OUTMODE_HIGH_Z);
1330 }
1331
1332 return 0;
1333}
1334EXPORT_SYMBOL(dib7000m_i2c_enumeration);
1335#endif
1336
1337static struct dvb_frontend_ops dib7000m_ops;
1338struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg)
1339{
1340 struct dvb_frontend *demod;
1341 struct dib7000m_state *st;
1342 st = kzalloc(sizeof(struct dib7000m_state), GFP_KERNEL);
1343 if (st == NULL)
1344 return NULL;
1345
1346 memcpy(&st->cfg, cfg, sizeof(struct dib7000m_config));
1347 st->i2c_adap = i2c_adap;
1348 st->i2c_addr = i2c_addr;
1349
1350 demod = &st->demod;
1351 demod->demodulator_priv = st;
1352 memcpy(&st->demod.ops, &dib7000m_ops, sizeof(struct dvb_frontend_ops));
1353
1354 st->timf_default = cfg->bw->timf;
1355
1356 if (dib7000m_identify(st) != 0)
1357 goto error;
1358
1359 if (st->revision == 0x4000)
1360 dibx000_init_i2c_master(&st->i2c_master, DIB7000, st->i2c_adap, st->i2c_addr);
1361 else
1362 dibx000_init_i2c_master(&st->i2c_master, DIB7000MC, st->i2c_adap, st->i2c_addr);
1363
1364 dib7000m_demod_reset(st);
1365
1366 return demod;
1367
1368error:
1369 kfree(st);
1370 return NULL;
1371}
1372EXPORT_SYMBOL(dib7000m_attach);
1373
1374static struct dvb_frontend_ops dib7000m_ops = {
1375 .info = {
1376 .name = "DiBcom 7000MA/MB/PA/PB/MC",
1377 .type = FE_OFDM,
1378 .frequency_min = 44250000,
1379 .frequency_max = 867250000,
1380 .frequency_stepsize = 62500,
1381 .caps = FE_CAN_INVERSION_AUTO |
1382 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1383 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1384 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1385 FE_CAN_TRANSMISSION_MODE_AUTO |
1386 FE_CAN_GUARD_INTERVAL_AUTO |
1387 FE_CAN_RECOVER |
1388 FE_CAN_HIERARCHY_AUTO,
1389 },
1390
1391 .release = dib7000m_release,
1392
1393 .init = dib7000m_wakeup,
1394 .sleep = dib7000m_sleep,
1395
1396 .set_frontend = dib7000m_set_frontend,
1397 .get_tune_settings = dib7000m_fe_get_tune_settings,
1398 .get_frontend = dib7000m_get_frontend,
1399
1400 .read_status = dib7000m_read_status,
1401 .read_ber = dib7000m_read_ber,
1402 .read_signal_strength = dib7000m_read_signal_strength,
1403 .read_snr = dib7000m_read_snr,
1404 .read_ucblocks = dib7000m_read_unc_blocks,
1405};
1406
1407MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
1408MODULE_DESCRIPTION("Driver for the DiBcom 7000MA/MB/PA/PB/MC COFDM demodulator");
1409MODULE_LICENSE("GPL");
1410