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