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