1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
24
25#include <linux/kernel.h>
26#include <linux/slab.h>
27#include <linux/i2c.h>
28#include <linux/mutex.h>
29
30#include <media/dvb_frontend.h>
31
32#include "dib0070.h"
33#include "dibx000_common.h"
34
35static int debug;
36module_param(debug, int, 0644);
37MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
38
39#define dprintk(fmt, arg...) do { \
40 if (debug) \
41 printk(KERN_DEBUG pr_fmt("%s: " fmt), \
42 __func__, ##arg); \
43} while (0)
44
45#define DIB0070_P1D 0x00
46#define DIB0070_P1F 0x01
47#define DIB0070_P1G 0x03
48#define DIB0070S_P1A 0x02
49
50struct dib0070_state {
51 struct i2c_adapter *i2c;
52 struct dvb_frontend *fe;
53 const struct dib0070_config *cfg;
54 u16 wbd_ff_offset;
55 u8 revision;
56
57 enum frontend_tune_state tune_state;
58 u32 current_rf;
59
60
61 s8 step;
62 u16 adc_diff;
63
64 s8 captrim;
65 s8 fcaptrim;
66 u16 lo4;
67
68 const struct dib0070_tuning *current_tune_table_index;
69 const struct dib0070_lna_match *lna_match;
70
71 u8 wbd_gain_current;
72 u16 wbd_offset_3_3[2];
73
74
75 struct i2c_msg msg[2];
76 u8 i2c_write_buffer[3];
77 u8 i2c_read_buffer[2];
78 struct mutex i2c_buffer_lock;
79};
80
81static u16 dib0070_read_reg(struct dib0070_state *state, u8 reg)
82{
83 u16 ret;
84
85 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
86 dprintk("could not acquire lock\n");
87 return 0;
88 }
89
90 state->i2c_write_buffer[0] = reg;
91
92 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
93 state->msg[0].addr = state->cfg->i2c_address;
94 state->msg[0].flags = 0;
95 state->msg[0].buf = state->i2c_write_buffer;
96 state->msg[0].len = 1;
97 state->msg[1].addr = state->cfg->i2c_address;
98 state->msg[1].flags = I2C_M_RD;
99 state->msg[1].buf = state->i2c_read_buffer;
100 state->msg[1].len = 2;
101
102 if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
103 pr_warn("DiB0070 I2C read failed\n");
104 ret = 0;
105 } else
106 ret = (state->i2c_read_buffer[0] << 8)
107 | state->i2c_read_buffer[1];
108
109 mutex_unlock(&state->i2c_buffer_lock);
110 return ret;
111}
112
113static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
114{
115 int ret;
116
117 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
118 dprintk("could not acquire lock\n");
119 return -EINVAL;
120 }
121 state->i2c_write_buffer[0] = reg;
122 state->i2c_write_buffer[1] = val >> 8;
123 state->i2c_write_buffer[2] = val & 0xff;
124
125 memset(state->msg, 0, sizeof(struct i2c_msg));
126 state->msg[0].addr = state->cfg->i2c_address;
127 state->msg[0].flags = 0;
128 state->msg[0].buf = state->i2c_write_buffer;
129 state->msg[0].len = 3;
130
131 if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
132 pr_warn("DiB0070 I2C write failed\n");
133 ret = -EREMOTEIO;
134 } else
135 ret = 0;
136
137 mutex_unlock(&state->i2c_buffer_lock);
138 return ret;
139}
140
141#define HARD_RESET(state) do { \
142 state->cfg->sleep(state->fe, 0); \
143 if (state->cfg->reset) { \
144 state->cfg->reset(state->fe,1); msleep(10); \
145 state->cfg->reset(state->fe,0); msleep(10); \
146 } \
147} while (0)
148
149static int dib0070_set_bandwidth(struct dvb_frontend *fe)
150 {
151 struct dib0070_state *state = fe->tuner_priv;
152 u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff;
153
154 if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 7000)
155 tmp |= (0 << 14);
156 else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 6000)
157 tmp |= (1 << 14);
158 else if (state->fe->dtv_property_cache.bandwidth_hz/1000 > 5000)
159 tmp |= (2 << 14);
160 else
161 tmp |= (3 << 14);
162
163 dib0070_write_reg(state, 0x02, tmp);
164
165
166 if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) {
167 u16 value = dib0070_read_reg(state, 0x17);
168
169 dib0070_write_reg(state, 0x17, value & 0xfffc);
170 tmp = dib0070_read_reg(state, 0x01) & 0x01ff;
171 dib0070_write_reg(state, 0x01, tmp | (60 << 9));
172
173 dib0070_write_reg(state, 0x17, value);
174 }
175 return 0;
176}
177
178static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state *tune_state)
179{
180 int8_t step_sign;
181 u16 adc;
182 int ret = 0;
183
184 if (*tune_state == CT_TUNER_STEP_0) {
185 dib0070_write_reg(state, 0x0f, 0xed10);
186 dib0070_write_reg(state, 0x17, 0x0034);
187
188 dib0070_write_reg(state, 0x18, 0x0032);
189 state->step = state->captrim = state->fcaptrim = 64;
190 state->adc_diff = 3000;
191 ret = 20;
192
193 *tune_state = CT_TUNER_STEP_1;
194 } else if (*tune_state == CT_TUNER_STEP_1) {
195 state->step /= 2;
196 dib0070_write_reg(state, 0x14, state->lo4 | state->captrim);
197 ret = 15;
198
199 *tune_state = CT_TUNER_STEP_2;
200 } else if (*tune_state == CT_TUNER_STEP_2) {
201
202 adc = dib0070_read_reg(state, 0x19);
203
204 dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV\n", state->captrim, adc, (u32) adc*(u32)1800/(u32)1024);
205
206 if (adc >= 400) {
207 adc -= 400;
208 step_sign = -1;
209 } else {
210 adc = 400 - adc;
211 step_sign = 1;
212 }
213
214 if (adc < state->adc_diff) {
215 dprintk("CAPTRIM=%hd is closer to target (%hd/%hd)\n", state->captrim, adc, state->adc_diff);
216 state->adc_diff = adc;
217 state->fcaptrim = state->captrim;
218 }
219 state->captrim += (step_sign * state->step);
220
221 if (state->step >= 1)
222 *tune_state = CT_TUNER_STEP_1;
223 else
224 *tune_state = CT_TUNER_STEP_3;
225
226 } else if (*tune_state == CT_TUNER_STEP_3) {
227 dib0070_write_reg(state, 0x14, state->lo4 | state->fcaptrim);
228 dib0070_write_reg(state, 0x18, 0x07ff);
229 *tune_state = CT_TUNER_STEP_4;
230 }
231
232 return ret;
233}
234
235static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt)
236{
237 struct dib0070_state *state = fe->tuner_priv;
238 u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0);
239
240 dprintk("CTRL_LO5: 0x%x\n", lo5);
241 return dib0070_write_reg(state, 0x15, lo5);
242}
243
244void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open)
245{
246 struct dib0070_state *state = fe->tuner_priv;
247
248 if (open) {
249 dib0070_write_reg(state, 0x1b, 0xff00);
250 dib0070_write_reg(state, 0x1a, 0x0000);
251 } else {
252 dib0070_write_reg(state, 0x1b, 0x4112);
253 if (state->cfg->vga_filter != 0) {
254 dib0070_write_reg(state, 0x1a, state->cfg->vga_filter);
255 dprintk("vga filter register is set to %x\n", state->cfg->vga_filter);
256 } else
257 dib0070_write_reg(state, 0x1a, 0x0009);
258 }
259}
260
261EXPORT_SYMBOL(dib0070_ctrl_agc_filter);
262struct dib0070_tuning {
263 u32 max_freq;
264 u8 switch_trim;
265 u8 vco_band;
266 u8 hfdiv;
267 u8 vco_multi;
268 u8 presc;
269 u8 wbdmux;
270 u16 tuner_enable;
271};
272
273struct dib0070_lna_match {
274 u32 max_freq;
275 u8 lna_band;
276};
277
278static const struct dib0070_tuning dib0070s_tuning_table[] = {
279 { 570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800 },
280 { 700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800 },
281 { 863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800 },
282 { 1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 },
283 { 1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 },
284 { 2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400 },
285 { 0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000 },
286};
287
288static const struct dib0070_tuning dib0070_tuning_table[] = {
289 { 115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000 },
290 { 179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000 },
291 { 189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000 },
292 { 250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000 },
293 { 569999, 2, 1, 5, 6, 2, 2, 0x4000 | 0x0800 },
294 { 699999, 2, 0, 1, 4, 2, 2, 0x4000 | 0x0800 },
295 { 863999, 2, 1, 1, 4, 2, 2, 0x4000 | 0x0800 },
296 { 0xffffffff, 0, 1, 0, 2, 2, 4, 0x2000 | 0x0400 },
297};
298
299static const struct dib0070_lna_match dib0070_lna_flip_chip[] = {
300 { 180000, 0 },
301 { 188000, 1 },
302 { 196400, 2 },
303 { 250000, 3 },
304 { 550000, 0 },
305 { 590000, 1 },
306 { 666000, 3 },
307 { 864000, 5 },
308 { 1500000, 0 },
309 { 1600000, 1 },
310 { 2000000, 3 },
311 { 0xffffffff, 7 },
312};
313
314static const struct dib0070_lna_match dib0070_lna[] = {
315 { 180000, 0 },
316 { 188000, 1 },
317 { 196400, 2 },
318 { 250000, 3 },
319 { 550000, 2 },
320 { 650000, 3 },
321 { 750000, 5 },
322 { 850000, 6 },
323 { 864000, 7 },
324 { 1500000, 0 },
325 { 1600000, 1 },
326 { 2000000, 3 },
327 { 0xffffffff, 7 },
328};
329
330#define LPF 100
331static int dib0070_tune_digital(struct dvb_frontend *fe)
332{
333 struct dib0070_state *state = fe->tuner_priv;
334
335 const struct dib0070_tuning *tune;
336 const struct dib0070_lna_match *lna_match;
337
338 enum frontend_tune_state *tune_state = &state->tune_state;
339 int ret = 10;
340
341 u8 band = (u8)BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency/1000);
342 u32 freq = fe->dtv_property_cache.frequency/1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf);
343
344#ifdef CONFIG_SYS_ISDBT
345 if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1)
346 if (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2)
347 && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
348 || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
349 && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == (state->fe->dtv_property_cache.isdbt_sb_segment_count / 2)))
350 || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
351 && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))))
352 freq += 850;
353#endif
354 if (state->current_rf != freq) {
355
356 switch (state->revision) {
357 case DIB0070S_P1A:
358 tune = dib0070s_tuning_table;
359 lna_match = dib0070_lna;
360 break;
361 default:
362 tune = dib0070_tuning_table;
363 if (state->cfg->flip_chip)
364 lna_match = dib0070_lna_flip_chip;
365 else
366 lna_match = dib0070_lna;
367 break;
368 }
369 while (freq > tune->max_freq)
370 tune++;
371 while (freq > lna_match->max_freq)
372 lna_match++;
373
374 state->current_tune_table_index = tune;
375 state->lna_match = lna_match;
376 }
377
378 if (*tune_state == CT_TUNER_START) {
379 dprintk("Tuning for Band: %hd (%d kHz)\n", band, freq);
380 if (state->current_rf != freq) {
381 u8 REFDIV;
382 u32 FBDiv, Rest, FREF, VCOF_kHz;
383 u8 Den;
384
385 state->current_rf = freq;
386 state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7);
387
388
389 dib0070_write_reg(state, 0x17, 0x30);
390
391
392 VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2;
393
394 switch (band) {
395 case BAND_VHF:
396 REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000);
397 break;
398 case BAND_FM:
399 REFDIV = (u8) ((state->cfg->clock_khz) / 1000);
400 break;
401 default:
402 REFDIV = (u8) (state->cfg->clock_khz / 10000);
403 break;
404 }
405 FREF = state->cfg->clock_khz / REFDIV;
406
407
408
409 switch (state->revision) {
410 case DIB0070S_P1A:
411 FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF);
412 Rest = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF;
413 break;
414
415 case DIB0070_P1G:
416 case DIB0070_P1F:
417 default:
418 FBDiv = (freq / (FREF / 2));
419 Rest = 2 * freq - FBDiv * FREF;
420 break;
421 }
422
423 if (Rest < LPF)
424 Rest = 0;
425 else if (Rest < 2 * LPF)
426 Rest = 2 * LPF;
427 else if (Rest > (FREF - LPF)) {
428 Rest = 0;
429 FBDiv += 1;
430 } else if (Rest > (FREF - 2 * LPF))
431 Rest = FREF - 2 * LPF;
432 Rest = (Rest * 6528) / (FREF / 10);
433
434 Den = 1;
435 if (Rest > 0) {
436 state->lo4 |= (1 << 14) | (1 << 12);
437 Den = 255;
438 }
439
440
441 dib0070_write_reg(state, 0x11, (u16)FBDiv);
442 dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV);
443 dib0070_write_reg(state, 0x13, (u16) Rest);
444
445 if (state->revision == DIB0070S_P1A) {
446
447 if (band == BAND_SBAND) {
448 dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
449 dib0070_write_reg(state, 0x1d, 0xFFFF);
450 } else
451 dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1);
452 }
453
454 dib0070_write_reg(state, 0x20,
455 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable);
456
457 dprintk("REFDIV: %hd, FREF: %d\n", REFDIV, FREF);
458 dprintk("FBDIV: %d, Rest: %d\n", FBDiv, Rest);
459 dprintk("Num: %hd, Den: %hd, SD: %hd\n", (u16) Rest, Den, (state->lo4 >> 12) & 0x1);
460 dprintk("HFDIV code: %hd\n", state->current_tune_table_index->hfdiv);
461 dprintk("VCO = %hd\n", state->current_tune_table_index->vco_band);
462 dprintk("VCOF: ((%hd*%d) << 1))\n", state->current_tune_table_index->vco_multi, freq);
463
464 *tune_state = CT_TUNER_STEP_0;
465 } else {
466 ret = 50;
467 *tune_state = CT_TUNER_STEP_5;
468 }
469 } else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) {
470
471 ret = dib0070_captrim(state, tune_state);
472
473 } else if (*tune_state == CT_TUNER_STEP_4) {
474 const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
475 if (tmp != NULL) {
476 while (freq/1000 > tmp->freq)
477 tmp++;
478 dib0070_write_reg(state, 0x0f,
479 (0 << 15) | (1 << 14) | (3 << 12)
480 | (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7)
481 | (state->current_tune_table_index->wbdmux << 0));
482 state->wbd_gain_current = tmp->wbd_gain_val;
483 } else {
484 dib0070_write_reg(state, 0x0f,
485 (0 << 15) | (1 << 14) | (3 << 12)
486 | (6 << 9) | (0 << 8) | (1 << 7)
487 | (state->current_tune_table_index->wbdmux << 0));
488 state->wbd_gain_current = 6;
489 }
490
491 dib0070_write_reg(state, 0x06, 0x3fff);
492 dib0070_write_reg(state, 0x07,
493 (state->current_tune_table_index->switch_trim << 11) | (7 << 8) | (state->lna_match->lna_band << 3) | (3 << 0));
494 dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127));
495 dib0070_write_reg(state, 0x0d, 0x0d80);
496
497
498 dib0070_write_reg(state, 0x18, 0x07ff);
499 dib0070_write_reg(state, 0x17, 0x0033);
500
501
502 *tune_state = CT_TUNER_STEP_5;
503 } else if (*tune_state == CT_TUNER_STEP_5) {
504 dib0070_set_bandwidth(fe);
505 *tune_state = CT_TUNER_STOP;
506 } else {
507 ret = FE_CALLBACK_TIME_NEVER;
508 }
509 return ret;
510}
511
512
513static int dib0070_tune(struct dvb_frontend *fe)
514{
515 struct dib0070_state *state = fe->tuner_priv;
516 uint32_t ret;
517
518 state->tune_state = CT_TUNER_START;
519
520 do {
521 ret = dib0070_tune_digital(fe);
522 if (ret != FE_CALLBACK_TIME_NEVER)
523 msleep(ret/10);
524 else
525 break;
526 } while (state->tune_state != CT_TUNER_STOP);
527
528 return 0;
529}
530
531static int dib0070_wakeup(struct dvb_frontend *fe)
532{
533 struct dib0070_state *state = fe->tuner_priv;
534 if (state->cfg->sleep)
535 state->cfg->sleep(fe, 0);
536 return 0;
537}
538
539static int dib0070_sleep(struct dvb_frontend *fe)
540{
541 struct dib0070_state *state = fe->tuner_priv;
542 if (state->cfg->sleep)
543 state->cfg->sleep(fe, 1);
544 return 0;
545}
546
547u8 dib0070_get_rf_output(struct dvb_frontend *fe)
548{
549 struct dib0070_state *state = fe->tuner_priv;
550 return (dib0070_read_reg(state, 0x07) >> 11) & 0x3;
551}
552EXPORT_SYMBOL(dib0070_get_rf_output);
553
554int dib0070_set_rf_output(struct dvb_frontend *fe, u8 no)
555{
556 struct dib0070_state *state = fe->tuner_priv;
557 u16 rxrf2 = dib0070_read_reg(state, 0x07) & 0xfe7ff;
558 if (no > 3)
559 no = 3;
560 if (no < 1)
561 no = 1;
562 return dib0070_write_reg(state, 0x07, rxrf2 | (no << 11));
563}
564EXPORT_SYMBOL(dib0070_set_rf_output);
565
566static const u16 dib0070_p1f_defaults[] =
567
568{
569 7, 0x02,
570 0x0008,
571 0x0000,
572 0x0000,
573 0x0000,
574 0x0000,
575 0x0002,
576 0x0100,
577
578 3, 0x0d,
579 0x0d80,
580 0x0001,
581 0x0000,
582
583 4, 0x11,
584 0x0000,
585 0x0103,
586 0x0000,
587 0x0000,
588
589 3, 0x16,
590 0x0004 | 0x0040,
591 0x0030,
592 0x07ff,
593
594 6, 0x1b,
595 0x4112,
596 0xff00,
597 0xc07f,
598 0x0000,
599 0x0180,
600 0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001,
601
602 0,
603};
604
605static u16 dib0070_read_wbd_offset(struct dib0070_state *state, u8 gain)
606{
607 u16 tuner_en = dib0070_read_reg(state, 0x20);
608 u16 offset;
609
610 dib0070_write_reg(state, 0x18, 0x07ff);
611 dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001);
612 dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0));
613 msleep(9);
614 offset = dib0070_read_reg(state, 0x19);
615 dib0070_write_reg(state, 0x20, tuner_en);
616 return offset;
617}
618
619static void dib0070_wbd_offset_calibration(struct dib0070_state *state)
620{
621 u8 gain;
622 for (gain = 6; gain < 8; gain++) {
623 state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2);
624 dprintk("Gain: %d, WBDOffset (3.3V) = %hd\n", gain, state->wbd_offset_3_3[gain-6]);
625 }
626}
627
628u16 dib0070_wbd_offset(struct dvb_frontend *fe)
629{
630 struct dib0070_state *state = fe->tuner_priv;
631 const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
632 u32 freq = fe->dtv_property_cache.frequency/1000;
633
634 if (tmp != NULL) {
635 while (freq/1000 > tmp->freq)
636 tmp++;
637 state->wbd_gain_current = tmp->wbd_gain_val;
638 } else
639 state->wbd_gain_current = 6;
640
641 return state->wbd_offset_3_3[state->wbd_gain_current - 6];
642}
643EXPORT_SYMBOL(dib0070_wbd_offset);
644
645#define pgm_read_word(w) (*w)
646static int dib0070_reset(struct dvb_frontend *fe)
647{
648 struct dib0070_state *state = fe->tuner_priv;
649 u16 l, r, *n;
650
651 HARD_RESET(state);
652
653
654#ifndef FORCE_SBAND_TUNER
655 if ((dib0070_read_reg(state, 0x22) >> 9) & 0x1)
656 state->revision = (dib0070_read_reg(state, 0x1f) >> 8) & 0xff;
657 else
658#else
659#warning forcing SBAND
660#endif
661 state->revision = DIB0070S_P1A;
662
663
664 dprintk("Revision: %x\n", state->revision);
665
666 if (state->revision == DIB0070_P1D) {
667 dprintk("Error: this driver is not to be used meant for P1D or earlier\n");
668 return -EINVAL;
669 }
670
671 n = (u16 *) dib0070_p1f_defaults;
672 l = pgm_read_word(n++);
673 while (l) {
674 r = pgm_read_word(n++);
675 do {
676 dib0070_write_reg(state, (u8)r, pgm_read_word(n++));
677 r++;
678 } while (--l);
679 l = pgm_read_word(n++);
680 }
681
682 if (state->cfg->force_crystal_mode != 0)
683 r = state->cfg->force_crystal_mode;
684 else if (state->cfg->clock_khz >= 24000)
685 r = 1;
686 else
687 r = 2;
688
689
690 r |= state->cfg->osc_buffer_state << 3;
691
692 dib0070_write_reg(state, 0x10, r);
693 dib0070_write_reg(state, 0x1f, (1 << 8) | ((state->cfg->clock_pad_drive & 0xf) << 5));
694
695 if (state->cfg->invert_iq) {
696 r = dib0070_read_reg(state, 0x02) & 0xffdf;
697 dib0070_write_reg(state, 0x02, r | (1 << 5));
698 }
699
700 if (state->revision == DIB0070S_P1A)
701 dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
702 else
703 dib0070_set_ctrl_lo5(fe, 5, 4, state->cfg->charge_pump,
704 state->cfg->enable_third_order_filter);
705
706 dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8);
707
708 dib0070_wbd_offset_calibration(state);
709
710 return 0;
711}
712
713static int dib0070_get_frequency(struct dvb_frontend *fe, u32 *frequency)
714{
715 struct dib0070_state *state = fe->tuner_priv;
716
717 *frequency = 1000 * state->current_rf;
718 return 0;
719}
720
721static void dib0070_release(struct dvb_frontend *fe)
722{
723 kfree(fe->tuner_priv);
724 fe->tuner_priv = NULL;
725}
726
727static const struct dvb_tuner_ops dib0070_ops = {
728 .info = {
729 .name = "DiBcom DiB0070",
730 .frequency_min = 45000000,
731 .frequency_max = 860000000,
732 .frequency_step = 1000,
733 },
734 .release = dib0070_release,
735
736 .init = dib0070_wakeup,
737 .sleep = dib0070_sleep,
738 .set_params = dib0070_tune,
739
740 .get_frequency = dib0070_get_frequency,
741
742};
743
744struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
745{
746 struct dib0070_state *state = kzalloc(sizeof(struct dib0070_state), GFP_KERNEL);
747 if (state == NULL)
748 return NULL;
749
750 state->cfg = cfg;
751 state->i2c = i2c;
752 state->fe = fe;
753 mutex_init(&state->i2c_buffer_lock);
754 fe->tuner_priv = state;
755
756 if (dib0070_reset(fe) != 0)
757 goto free_mem;
758
759 pr_info("DiB0070: successfully identified\n");
760 memcpy(&fe->ops.tuner_ops, &dib0070_ops, sizeof(struct dvb_tuner_ops));
761
762 fe->tuner_priv = state;
763 return fe;
764
765free_mem:
766 kfree(state);
767 fe->tuner_priv = NULL;
768 return NULL;
769}
770EXPORT_SYMBOL(dib0070_attach);
771
772MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
773MODULE_DESCRIPTION("Driver for the DiBcom 0070 base-band RF Tuner");
774MODULE_LICENSE("GPL");
775