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 "dvb_frontend.h"
31
32#include "dib0090.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 CONFIG_SYS_DVBT
46#define CONFIG_SYS_ISDBT
47#define CONFIG_BAND_CBAND
48#define CONFIG_BAND_VHF
49#define CONFIG_BAND_UHF
50#define CONFIG_DIB0090_USE_PWM_AGC
51
52#define EN_LNA0 0x8000
53#define EN_LNA1 0x4000
54#define EN_LNA2 0x2000
55#define EN_LNA3 0x1000
56#define EN_MIX0 0x0800
57#define EN_MIX1 0x0400
58#define EN_MIX2 0x0200
59#define EN_MIX3 0x0100
60#define EN_IQADC 0x0040
61#define EN_PLL 0x0020
62#define EN_TX 0x0010
63#define EN_BB 0x0008
64#define EN_LO 0x0004
65#define EN_BIAS 0x0001
66
67#define EN_IQANA 0x0002
68#define EN_DIGCLK 0x0080
69#define EN_CRYSTAL 0x0002
70
71#define EN_UHF 0x22E9
72#define EN_VHF 0x44E9
73#define EN_LBD 0x11E9
74#define EN_SBD 0x44E9
75#define EN_CAB 0x88E9
76
77
78#define DC_CAL 0x1
79#define WBD_CAL 0x2
80#define TEMP_CAL 0x4
81#define CAPTRIM_CAL 0x8
82
83#define KROSUS_PLL_LOCKED 0x800
84#define KROSUS 0x2
85
86
87#define SOC 0x02
88#define SOC_7090_P1G_11R1 0x82
89#define SOC_7090_P1G_21R1 0x8a
90#define SOC_8090_P1G_11R1 0x86
91#define SOC_8090_P1G_21R1 0x8e
92
93
94#define P1A_B 0x0
95#define P1C 0x1
96#define P1D_E_F 0x3
97#define P1G 0x7
98#define P1G_21R2 0xf
99
100#define MP001 0x1
101#define MP005 0x4
102#define MP008 0x6
103#define MP009 0x7
104
105#define pgm_read_word(w) (*w)
106
107struct dc_calibration;
108
109struct dib0090_tuning {
110 u32 max_freq;
111 u8 switch_trim;
112 u8 lna_tune;
113 u16 lna_bias;
114 u16 v2i;
115 u16 mix;
116 u16 load;
117 u16 tuner_enable;
118};
119
120struct dib0090_pll {
121 u32 max_freq;
122 u8 vco_band;
123 u8 hfdiv_code;
124 u8 hfdiv;
125 u8 topresc;
126};
127
128struct dib0090_identity {
129 u8 version;
130 u8 product;
131 u8 p1g;
132 u8 in_soc;
133};
134
135struct dib0090_state {
136 struct i2c_adapter *i2c;
137 struct dvb_frontend *fe;
138 const struct dib0090_config *config;
139
140 u8 current_band;
141 enum frontend_tune_state tune_state;
142 u32 current_rf;
143
144 u16 wbd_offset;
145 s16 wbd_target;
146
147 s16 rf_gain_limit;
148 s16 current_gain;
149 u8 agc_step;
150
151 u16 gain[2];
152
153 const u16 *rf_ramp;
154 const u16 *bb_ramp;
155
156
157 u16 bb_1_def;
158 u16 rf_lt_def;
159 u16 gain_reg[4];
160
161
162 s8 step;
163 s16 adc_diff;
164 s16 min_adc_diff;
165
166 s8 captrim;
167 s8 fcaptrim;
168
169 const struct dc_calibration *dc;
170 u16 bb6, bb7;
171
172 const struct dib0090_tuning *current_tune_table_index;
173 const struct dib0090_pll *current_pll_table_index;
174
175 u8 tuner_is_tuned;
176 u8 agc_freeze;
177
178 struct dib0090_identity identity;
179
180 u32 rf_request;
181 u8 current_standard;
182
183 u8 calibrate;
184 u32 rest;
185 u16 bias;
186 s16 temperature;
187
188 u8 wbd_calibration_gain;
189 const struct dib0090_wbd_slope *current_wbd_table;
190 u16 wbdmux;
191
192
193 struct i2c_msg msg[2];
194 u8 i2c_write_buffer[3];
195 u8 i2c_read_buffer[2];
196 struct mutex i2c_buffer_lock;
197};
198
199struct dib0090_fw_state {
200 struct i2c_adapter *i2c;
201 struct dvb_frontend *fe;
202 struct dib0090_identity identity;
203 const struct dib0090_config *config;
204
205
206 struct i2c_msg msg;
207 u8 i2c_write_buffer[2];
208 u8 i2c_read_buffer[2];
209 struct mutex i2c_buffer_lock;
210};
211
212static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg)
213{
214 u16 ret;
215
216 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
217 dprintk("could not acquire lock\n");
218 return 0;
219 }
220
221 state->i2c_write_buffer[0] = reg;
222
223 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
224 state->msg[0].addr = state->config->i2c_address;
225 state->msg[0].flags = 0;
226 state->msg[0].buf = state->i2c_write_buffer;
227 state->msg[0].len = 1;
228 state->msg[1].addr = state->config->i2c_address;
229 state->msg[1].flags = I2C_M_RD;
230 state->msg[1].buf = state->i2c_read_buffer;
231 state->msg[1].len = 2;
232
233 if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
234 pr_warn("DiB0090 I2C read failed\n");
235 ret = 0;
236 } else
237 ret = (state->i2c_read_buffer[0] << 8)
238 | state->i2c_read_buffer[1];
239
240 mutex_unlock(&state->i2c_buffer_lock);
241 return ret;
242}
243
244static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
245{
246 int ret;
247
248 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
249 dprintk("could not acquire lock\n");
250 return -EINVAL;
251 }
252
253 state->i2c_write_buffer[0] = reg & 0xff;
254 state->i2c_write_buffer[1] = val >> 8;
255 state->i2c_write_buffer[2] = val & 0xff;
256
257 memset(state->msg, 0, sizeof(struct i2c_msg));
258 state->msg[0].addr = state->config->i2c_address;
259 state->msg[0].flags = 0;
260 state->msg[0].buf = state->i2c_write_buffer;
261 state->msg[0].len = 3;
262
263 if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
264 pr_warn("DiB0090 I2C write failed\n");
265 ret = -EREMOTEIO;
266 } else
267 ret = 0;
268
269 mutex_unlock(&state->i2c_buffer_lock);
270 return ret;
271}
272
273static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg)
274{
275 u16 ret;
276
277 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
278 dprintk("could not acquire lock\n");
279 return 0;
280 }
281
282 state->i2c_write_buffer[0] = reg;
283
284 memset(&state->msg, 0, sizeof(struct i2c_msg));
285 state->msg.addr = reg;
286 state->msg.flags = I2C_M_RD;
287 state->msg.buf = state->i2c_read_buffer;
288 state->msg.len = 2;
289 if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
290 pr_warn("DiB0090 I2C read failed\n");
291 ret = 0;
292 } else
293 ret = (state->i2c_read_buffer[0] << 8)
294 | state->i2c_read_buffer[1];
295
296 mutex_unlock(&state->i2c_buffer_lock);
297 return ret;
298}
299
300static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val)
301{
302 int ret;
303
304 if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
305 dprintk("could not acquire lock\n");
306 return -EINVAL;
307 }
308
309 state->i2c_write_buffer[0] = val >> 8;
310 state->i2c_write_buffer[1] = val & 0xff;
311
312 memset(&state->msg, 0, sizeof(struct i2c_msg));
313 state->msg.addr = reg;
314 state->msg.flags = 0;
315 state->msg.buf = state->i2c_write_buffer;
316 state->msg.len = 2;
317 if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
318 pr_warn("DiB0090 I2C write failed\n");
319 ret = -EREMOTEIO;
320 } else
321 ret = 0;
322
323 mutex_unlock(&state->i2c_buffer_lock);
324 return ret;
325}
326
327#define HARD_RESET(state) do { if (cfg->reset) { if (cfg->sleep) cfg->sleep(fe, 0); msleep(10); cfg->reset(fe, 1); msleep(10); cfg->reset(fe, 0); msleep(10); } } while (0)
328#define ADC_TARGET -220
329#define GAIN_ALPHA 5
330#define WBD_ALPHA 6
331#define LPF 100
332static void dib0090_write_regs(struct dib0090_state *state, u8 r, const u16 * b, u8 c)
333{
334 do {
335 dib0090_write_reg(state, r++, *b++);
336 } while (--c);
337}
338
339static int dib0090_identify(struct dvb_frontend *fe)
340{
341 struct dib0090_state *state = fe->tuner_priv;
342 u16 v;
343 struct dib0090_identity *identity = &state->identity;
344
345 v = dib0090_read_reg(state, 0x1a);
346
347 identity->p1g = 0;
348 identity->in_soc = 0;
349
350 dprintk("Tuner identification (Version = 0x%04x)\n", v);
351
352
353 v &= ~KROSUS_PLL_LOCKED;
354
355 identity->version = v & 0xff;
356 identity->product = (v >> 8) & 0xf;
357
358 if (identity->product != KROSUS)
359 goto identification_error;
360
361 if ((identity->version & 0x3) == SOC) {
362 identity->in_soc = 1;
363 switch (identity->version) {
364 case SOC_8090_P1G_11R1:
365 dprintk("SOC 8090 P1-G11R1 Has been detected\n");
366 identity->p1g = 1;
367 break;
368 case SOC_8090_P1G_21R1:
369 dprintk("SOC 8090 P1-G21R1 Has been detected\n");
370 identity->p1g = 1;
371 break;
372 case SOC_7090_P1G_11R1:
373 dprintk("SOC 7090 P1-G11R1 Has been detected\n");
374 identity->p1g = 1;
375 break;
376 case SOC_7090_P1G_21R1:
377 dprintk("SOC 7090 P1-G21R1 Has been detected\n");
378 identity->p1g = 1;
379 break;
380 default:
381 goto identification_error;
382 }
383 } else {
384 switch ((identity->version >> 5) & 0x7) {
385 case MP001:
386 dprintk("MP001 : 9090/8096\n");
387 break;
388 case MP005:
389 dprintk("MP005 : Single Sband\n");
390 break;
391 case MP008:
392 dprintk("MP008 : diversity VHF-UHF-LBAND\n");
393 break;
394 case MP009:
395 dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND\n");
396 break;
397 default:
398 goto identification_error;
399 }
400
401 switch (identity->version & 0x1f) {
402 case P1G_21R2:
403 dprintk("P1G_21R2 detected\n");
404 identity->p1g = 1;
405 break;
406 case P1G:
407 dprintk("P1G detected\n");
408 identity->p1g = 1;
409 break;
410 case P1D_E_F:
411 dprintk("P1D/E/F detected\n");
412 break;
413 case P1C:
414 dprintk("P1C detected\n");
415 break;
416 case P1A_B:
417 dprintk("P1-A/B detected: driver is deactivated - not available\n");
418 goto identification_error;
419 break;
420 default:
421 goto identification_error;
422 }
423 }
424
425 return 0;
426
427identification_error:
428 return -EIO;
429}
430
431static int dib0090_fw_identify(struct dvb_frontend *fe)
432{
433 struct dib0090_fw_state *state = fe->tuner_priv;
434 struct dib0090_identity *identity = &state->identity;
435
436 u16 v = dib0090_fw_read_reg(state, 0x1a);
437 identity->p1g = 0;
438 identity->in_soc = 0;
439
440 dprintk("FE: Tuner identification (Version = 0x%04x)\n", v);
441
442
443 v &= ~KROSUS_PLL_LOCKED;
444
445 identity->version = v & 0xff;
446 identity->product = (v >> 8) & 0xf;
447
448 if (identity->product != KROSUS)
449 goto identification_error;
450
451 if ((identity->version & 0x3) == SOC) {
452 identity->in_soc = 1;
453 switch (identity->version) {
454 case SOC_8090_P1G_11R1:
455 dprintk("SOC 8090 P1-G11R1 Has been detected\n");
456 identity->p1g = 1;
457 break;
458 case SOC_8090_P1G_21R1:
459 dprintk("SOC 8090 P1-G21R1 Has been detected\n");
460 identity->p1g = 1;
461 break;
462 case SOC_7090_P1G_11R1:
463 dprintk("SOC 7090 P1-G11R1 Has been detected\n");
464 identity->p1g = 1;
465 break;
466 case SOC_7090_P1G_21R1:
467 dprintk("SOC 7090 P1-G21R1 Has been detected\n");
468 identity->p1g = 1;
469 break;
470 default:
471 goto identification_error;
472 }
473 } else {
474 switch ((identity->version >> 5) & 0x7) {
475 case MP001:
476 dprintk("MP001 : 9090/8096\n");
477 break;
478 case MP005:
479 dprintk("MP005 : Single Sband\n");
480 break;
481 case MP008:
482 dprintk("MP008 : diversity VHF-UHF-LBAND\n");
483 break;
484 case MP009:
485 dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND\n");
486 break;
487 default:
488 goto identification_error;
489 }
490
491 switch (identity->version & 0x1f) {
492 case P1G_21R2:
493 dprintk("P1G_21R2 detected\n");
494 identity->p1g = 1;
495 break;
496 case P1G:
497 dprintk("P1G detected\n");
498 identity->p1g = 1;
499 break;
500 case P1D_E_F:
501 dprintk("P1D/E/F detected\n");
502 break;
503 case P1C:
504 dprintk("P1C detected\n");
505 break;
506 case P1A_B:
507 dprintk("P1-A/B detected: driver is deactivated - not available\n");
508 goto identification_error;
509 break;
510 default:
511 goto identification_error;
512 }
513 }
514
515 return 0;
516
517identification_error:
518 return -EIO;
519}
520
521static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
522{
523 struct dib0090_state *state = fe->tuner_priv;
524 u16 PllCfg, i, v;
525
526 HARD_RESET(state);
527 dib0090_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
528 if (cfg->in_soc)
529 return;
530
531 dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL);
532
533 dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0);
534 if (cfg->clkoutdrive != 0)
535 dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
536 | (cfg->clkoutdrive << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
537 else
538 dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
539 | (7 << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
540
541
542 PllCfg = dib0090_read_reg(state, 0x21);
543
544
545 if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && (!cfg->in_soc)
546 && !cfg->io.pll_bypass) {
547
548
549 PllCfg |= (1 << 15);
550 dib0090_write_reg(state, 0x21, PllCfg);
551
552
553 PllCfg &= ~(1 << 13);
554 dib0090_write_reg(state, 0x21, PllCfg);
555
556
557 PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv);
558 dib0090_write_reg(state, 0x21, PllCfg);
559
560
561 PllCfg |= (1 << 13);
562 dib0090_write_reg(state, 0x21, PllCfg);
563
564
565 i = 100;
566 do {
567 v = !!(dib0090_read_reg(state, 0x1a) & 0x800);
568 if (v)
569 break;
570 } while (--i);
571
572 if (i == 0) {
573 dprintk("Pll: Unable to lock Pll\n");
574 return;
575 }
576
577
578 PllCfg &= ~(1 << 15);
579 dib0090_write_reg(state, 0x21, PllCfg);
580 }
581
582 if (cfg->io.pll_bypass) {
583 PllCfg |= (cfg->io.pll_bypass << 15);
584 dib0090_write_reg(state, 0x21, PllCfg);
585 }
586}
587
588static int dib0090_fw_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
589{
590 struct dib0090_fw_state *state = fe->tuner_priv;
591 u16 PllCfg;
592 u16 v;
593 int i;
594
595 dprintk("fw reset digital\n");
596 HARD_RESET(state);
597
598 dib0090_fw_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
599 dib0090_fw_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL);
600
601 dib0090_fw_write_reg(state, 0x20,
602 ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (cfg->data_tx_drv << 4) | cfg->ls_cfg_pad_drv);
603
604 v = (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 9) | (0 << 8) | (cfg->clkouttobamse << 4) | (0 << 2) | (0);
605 if (cfg->clkoutdrive != 0)
606 v |= cfg->clkoutdrive << 5;
607 else
608 v |= 7 << 5;
609
610 v |= 2 << 10;
611 dib0090_fw_write_reg(state, 0x23, v);
612
613
614 PllCfg = dib0090_fw_read_reg(state, 0x21);
615
616
617 if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && !cfg->io.pll_bypass) {
618
619
620 PllCfg |= (1 << 15);
621 dib0090_fw_write_reg(state, 0x21, PllCfg);
622
623
624 PllCfg &= ~(1 << 13);
625 dib0090_fw_write_reg(state, 0x21, PllCfg);
626
627
628 PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv);
629 dib0090_fw_write_reg(state, 0x21, PllCfg);
630
631
632 PllCfg |= (1 << 13);
633 dib0090_fw_write_reg(state, 0x21, PllCfg);
634
635
636 i = 100;
637 do {
638 v = !!(dib0090_fw_read_reg(state, 0x1a) & 0x800);
639 if (v)
640 break;
641 } while (--i);
642
643 if (i == 0) {
644 dprintk("Pll: Unable to lock Pll\n");
645 return -EIO;
646 }
647
648
649 PllCfg &= ~(1 << 15);
650 dib0090_fw_write_reg(state, 0x21, PllCfg);
651 }
652
653 if (cfg->io.pll_bypass) {
654 PllCfg |= (cfg->io.pll_bypass << 15);
655 dib0090_fw_write_reg(state, 0x21, PllCfg);
656 }
657
658 return dib0090_fw_identify(fe);
659}
660
661static int dib0090_wakeup(struct dvb_frontend *fe)
662{
663 struct dib0090_state *state = fe->tuner_priv;
664 if (state->config->sleep)
665 state->config->sleep(fe, 0);
666
667
668 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
669 return 0;
670}
671
672static int dib0090_sleep(struct dvb_frontend *fe)
673{
674 struct dib0090_state *state = fe->tuner_priv;
675 if (state->config->sleep)
676 state->config->sleep(fe, 1);
677 return 0;
678}
679
680void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
681{
682 struct dib0090_state *state = fe->tuner_priv;
683 if (fast)
684 dib0090_write_reg(state, 0x04, 0);
685 else
686 dib0090_write_reg(state, 0x04, 1);
687}
688
689EXPORT_SYMBOL(dib0090_dcc_freq);
690
691static const u16 bb_ramp_pwm_normal_socs[] = {
692 550,
693 (1<<9) | 8,
694 440,
695 (4 << 9) | 0,
696 (0 << 9) | 208,
697 (4 << 9) | 208,
698 (0 << 9) | 440,
699};
700
701static const u16 rf_ramp_pwm_cband_7090p[] = {
702 280,
703 18,
704 504,
705 (29 << 10) | 364,
706 (0 << 10) | 504,
707 (60 << 10) | 228,
708 (0 << 10) | 364,
709 (34 << 10) | 109,
710 (0 << 10) | 228,
711 (37 << 10) | 0,
712 (0 << 10) | 109,
713};
714
715static const u16 rf_ramp_pwm_cband_7090e_sensitivity[] = {
716 186,
717 40,
718 746,
719 (10 << 10) | 345,
720 (0 << 10) | 746,
721 (0 << 10) | 0,
722 (0 << 10) | 0,
723 (28 << 10) | 200,
724 (0 << 10) | 345,
725 (20 << 10) | 0,
726 (0 << 10) | 200,
727};
728
729static const u16 rf_ramp_pwm_cband_7090e_aci[] = {
730 86,
731 40,
732 345,
733 (0 << 10) | 0,
734 (0 << 10) | 0,
735 (0 << 10) | 0,
736 (0 << 10) | 0,
737 (28 << 10) | 200,
738 (0 << 10) | 345,
739 (20 << 10) | 0,
740 (0 << 10) | 200,
741};
742
743static const u16 rf_ramp_pwm_cband_8090[] = {
744 345,
745 29,
746 1000,
747 (35 << 10) | 772,
748 (0 << 10) | 1000,
749 (58 << 10) | 496,
750 (0 << 10) | 772,
751 (27 << 10) | 200,
752 (0 << 10) | 496,
753 (40 << 10) | 0,
754 (0 << 10) | 200,
755};
756
757static const u16 rf_ramp_pwm_uhf_7090[] = {
758 407,
759 13,
760 529,
761 (23 << 10) | 0,
762 (0 << 10) | 176,
763 (63 << 10) | 400,
764 (0 << 10) | 529,
765 (48 << 10) | 316,
766 (0 << 10) | 400,
767 (29 << 10) | 176,
768 (0 << 10) | 316,
769};
770
771static const u16 rf_ramp_pwm_uhf_8090[] = {
772 388,
773 26,
774 1008,
775 (11 << 10) | 0,
776 (0 << 10) | 369,
777 (41 << 10) | 809,
778 (0 << 10) | 1008,
779 (27 << 10) | 659,
780 (0 << 10) | 809,
781 (14 << 10) | 369,
782 (0 << 10) | 659,
783};
784
785
786static const u16 bb_ramp_pwm_normal[] = {
787 500,
788 8,
789 400,
790 (2 << 9) | 0,
791 (0 << 9) | 168,
792 (2 << 9) | 168,
793 (0 << 9) | 400,
794};
795
796#if 0
797
798static const u16 bb_ramp_pwm_boost[] = {
799 550,
800 8,
801 440,
802 (2 << 9) | 0,
803 (0 << 9) | 208,
804 (2 << 9) | 208,
805 (0 << 9) | 440,
806};
807#endif
808
809static const u16 rf_ramp_pwm_cband[] = {
810 314,
811 33,
812 1023,
813 (8 << 10) | 743,
814 (0 << 10) | 1023,
815 (15 << 10) | 469,
816 (0 << 10) | 742,
817 (9 << 10) | 234,
818 (0 << 10) | 468,
819 (9 << 10) | 0,
820 (0 << 10) | 233,
821};
822
823static const u16 rf_ramp_pwm_vhf[] = {
824 398,
825 24,
826 954,
827 (7 << 10) | 0,
828 (0 << 10) | 290,
829 (16 << 10) | 699,
830 (0 << 10) | 954,
831 (17 << 10) | 580,
832 (0 << 10) | 699,
833 (7 << 10) | 290,
834 (0 << 10) | 580,
835};
836
837static const u16 rf_ramp_pwm_uhf[] = {
838 398,
839 24,
840 954,
841 (7 << 10) | 0,
842 (0 << 10) | 290,
843 (16 << 10) | 699,
844 (0 << 10) | 954,
845 (17 << 10) | 580,
846 (0 << 10) | 699,
847 (7 << 10) | 290,
848 (0 << 10) | 580,
849};
850
851#if 0
852
853static const u16 rf_ramp_pwm_sband[] = {
854 253,
855 38,
856 961,
857 (4 << 10) | 0,
858 (0 << 10) | 508,
859 (9 << 10) | 508,
860 (0 << 10) | 961,
861 (0 << 10) | 0,
862 (0 << 10) | 0,
863 (0 << 10) | 0,
864 (0 << 10) | 0,
865};
866#endif
867
868struct slope {
869 s16 range;
870 s16 slope;
871};
872static u16 slopes_to_scale(const struct slope *slopes, u8 num, s16 val)
873{
874 u8 i;
875 u16 rest;
876 u16 ret = 0;
877 for (i = 0; i < num; i++) {
878 if (val > slopes[i].range)
879 rest = slopes[i].range;
880 else
881 rest = val;
882 ret += (rest * slopes[i].slope) / slopes[i].range;
883 val -= rest;
884 }
885 return ret;
886}
887
888static const struct slope dib0090_wbd_slopes[3] = {
889 {66, 120},
890 {600, 170},
891 {170, 250},
892};
893
894static s16 dib0090_wbd_to_db(struct dib0090_state *state, u16 wbd)
895{
896 wbd &= 0x3ff;
897 if (wbd < state->wbd_offset)
898 wbd = 0;
899 else
900 wbd -= state->wbd_offset;
901
902 return -640 + (s16) slopes_to_scale(dib0090_wbd_slopes, ARRAY_SIZE(dib0090_wbd_slopes), wbd);
903}
904
905static void dib0090_wbd_target(struct dib0090_state *state, u32 rf)
906{
907 u16 offset = 250;
908
909
910
911 if (state->current_band == BAND_VHF)
912 offset = 650;
913#ifndef FIRMWARE_FIREFLY
914 if (state->current_band == BAND_VHF)
915 offset = state->config->wbd_vhf_offset;
916 if (state->current_band == BAND_CBAND)
917 offset = state->config->wbd_cband_offset;
918#endif
919
920 state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + offset);
921 dprintk("wbd-target: %d dB\n", (u32) state->wbd_target);
922}
923
924static const int gain_reg_addr[4] = {
925 0x08, 0x0a, 0x0f, 0x01
926};
927
928static void dib0090_gain_apply(struct dib0090_state *state, s16 gain_delta, s16 top_delta, u8 force)
929{
930 u16 rf, bb, ref;
931 u16 i, v, gain_reg[4] = { 0 }, gain;
932 const u16 *g;
933
934 if (top_delta < -511)
935 top_delta = -511;
936 if (top_delta > 511)
937 top_delta = 511;
938
939 if (force) {
940 top_delta *= (1 << WBD_ALPHA);
941 gain_delta *= (1 << GAIN_ALPHA);
942 }
943
944 if (top_delta >= ((s16) (state->rf_ramp[0] << WBD_ALPHA) - state->rf_gain_limit))
945 state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
946 else
947 state->rf_gain_limit += top_delta;
948
949 if (state->rf_gain_limit < 0)
950 state->rf_gain_limit = 0;
951
952
953 gain = ((state->rf_gain_limit >> WBD_ALPHA) + state->bb_ramp[0]) << GAIN_ALPHA;
954 if (gain_delta >= ((s16) gain - state->current_gain))
955 state->current_gain = gain;
956 else
957 state->current_gain += gain_delta;
958
959 if (state->current_gain < 0)
960 state->current_gain = 0;
961
962
963 gain = state->current_gain >> GAIN_ALPHA;
964
965
966 if (gain > (state->rf_gain_limit >> WBD_ALPHA)) {
967 rf = state->rf_gain_limit >> WBD_ALPHA;
968 bb = gain - rf;
969 if (bb > state->bb_ramp[0])
970 bb = state->bb_ramp[0];
971 } else {
972 rf = gain;
973 bb = 0;
974 }
975
976 state->gain[0] = rf;
977 state->gain[1] = bb;
978
979
980
981 g = state->rf_ramp + 1;
982 ref = rf;
983 for (i = 0; i < 7; i++) {
984 if (g[0] == 0 || ref < (g[1] - g[0]))
985 v = 0;
986 else if (ref >= g[1])
987 v = g[2];
988 else
989 v = ((ref - (g[1] - g[0])) * g[2]) / g[0];
990
991 if (i == 0)
992 gain_reg[0] = v;
993 else if (i == 1)
994 gain_reg[0] |= v << 7;
995 else if (i == 2)
996 gain_reg[1] = v;
997 else if (i == 3)
998 gain_reg[1] |= v << 7;
999 else if (i == 4)
1000 gain_reg[2] = v | state->rf_lt_def;
1001 else if (i == 5)
1002 gain_reg[3] = v << 3;
1003 else if (i == 6)
1004 gain_reg[3] |= v << 8;
1005
1006 g += 3;
1007
1008
1009 if (i == 4) {
1010 g = state->bb_ramp + 1;
1011 ref = bb;
1012 }
1013 }
1014 gain_reg[3] |= state->bb_1_def;
1015 gain_reg[3] |= ((bb % 10) * 100) / 125;
1016
1017#ifdef DEBUG_AGC
1018 dprintk("GA CALC: DB: %3d(rf) + %3d(bb) = %3d gain_reg[0]=%04x gain_reg[1]=%04x gain_reg[2]=%04x gain_reg[0]=%04x\n", rf, bb, rf + bb,
1019 gain_reg[0], gain_reg[1], gain_reg[2], gain_reg[3]);
1020#endif
1021
1022
1023 for (i = 0; i < 4; i++) {
1024 v = gain_reg[i];
1025 if (force || state->gain_reg[i] != v) {
1026 state->gain_reg[i] = v;
1027 dib0090_write_reg(state, gain_reg_addr[i], v);
1028 }
1029 }
1030}
1031
1032static void dib0090_set_boost(struct dib0090_state *state, int onoff)
1033{
1034 state->bb_1_def &= 0xdfff;
1035 state->bb_1_def |= onoff << 13;
1036}
1037
1038static void dib0090_set_rframp(struct dib0090_state *state, const u16 * cfg)
1039{
1040 state->rf_ramp = cfg;
1041}
1042
1043static void dib0090_set_rframp_pwm(struct dib0090_state *state, const u16 * cfg)
1044{
1045 state->rf_ramp = cfg;
1046
1047 dib0090_write_reg(state, 0x2a, 0xffff);
1048
1049 dprintk("total RF gain: %ddB, step: %d\n", (u32) cfg[0], dib0090_read_reg(state, 0x2a));
1050
1051 dib0090_write_regs(state, 0x2c, cfg + 3, 6);
1052 dib0090_write_regs(state, 0x3e, cfg + 9, 2);
1053}
1054
1055static void dib0090_set_bbramp(struct dib0090_state *state, const u16 * cfg)
1056{
1057 state->bb_ramp = cfg;
1058 dib0090_set_boost(state, cfg[0] > 500);
1059}
1060
1061static void dib0090_set_bbramp_pwm(struct dib0090_state *state, const u16 * cfg)
1062{
1063 state->bb_ramp = cfg;
1064
1065 dib0090_set_boost(state, cfg[0] > 500);
1066
1067 dib0090_write_reg(state, 0x33, 0xffff);
1068 dprintk("total BB gain: %ddB, step: %d\n", (u32) cfg[0], dib0090_read_reg(state, 0x33));
1069 dib0090_write_regs(state, 0x35, cfg + 3, 4);
1070}
1071
1072void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
1073{
1074 struct dib0090_state *state = fe->tuner_priv;
1075 u16 *bb_ramp = (u16 *)&bb_ramp_pwm_normal;
1076 u16 *rf_ramp = NULL;
1077 u8 en_pwm_rf_mux = 1;
1078
1079
1080 if (state->config->use_pwm_agc) {
1081 if (state->current_band == BAND_CBAND) {
1082 if (state->identity.in_soc) {
1083 bb_ramp = (u16 *)&bb_ramp_pwm_normal_socs;
1084 if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
1085 rf_ramp = (u16 *)&rf_ramp_pwm_cband_8090;
1086 else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1) {
1087 if (state->config->is_dib7090e) {
1088 if (state->rf_ramp == NULL)
1089 rf_ramp = (u16 *)&rf_ramp_pwm_cband_7090e_sensitivity;
1090 else
1091 rf_ramp = (u16 *)state->rf_ramp;
1092 } else
1093 rf_ramp = (u16 *)&rf_ramp_pwm_cband_7090p;
1094 }
1095 } else
1096 rf_ramp = (u16 *)&rf_ramp_pwm_cband;
1097 } else
1098
1099 if (state->current_band == BAND_VHF) {
1100 if (state->identity.in_soc) {
1101 bb_ramp = (u16 *)&bb_ramp_pwm_normal_socs;
1102
1103 } else
1104 rf_ramp = (u16 *)&rf_ramp_pwm_vhf;
1105 } else if (state->current_band == BAND_UHF) {
1106 if (state->identity.in_soc) {
1107 bb_ramp = (u16 *)&bb_ramp_pwm_normal_socs;
1108 if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
1109 rf_ramp = (u16 *)&rf_ramp_pwm_uhf_8090;
1110 else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
1111 rf_ramp = (u16 *)&rf_ramp_pwm_uhf_7090;
1112 } else
1113 rf_ramp = (u16 *)&rf_ramp_pwm_uhf;
1114 }
1115 if (rf_ramp)
1116 dib0090_set_rframp_pwm(state, rf_ramp);
1117 dib0090_set_bbramp_pwm(state, bb_ramp);
1118
1119
1120 if (state->rf_ramp)
1121 dprintk("ramp RF gain = %d BAND = %s version = %d\n",
1122 state->rf_ramp[0],
1123 (state->current_band == BAND_CBAND) ? "CBAND" : "NOT CBAND",
1124 state->identity.version & 0x1f);
1125
1126 if (rf_ramp && ((state->rf_ramp && state->rf_ramp[0] == 0) ||
1127 (state->current_band == BAND_CBAND &&
1128 (state->identity.version & 0x1f) <= P1D_E_F))) {
1129 dprintk("DE-Engage mux for direct gain reg control\n");
1130 en_pwm_rf_mux = 0;
1131 } else
1132 dprintk("Engage mux for PWM control\n");
1133
1134 dib0090_write_reg(state, 0x32, (en_pwm_rf_mux << 12) | (en_pwm_rf_mux << 11));
1135
1136
1137 if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
1138 dib0090_write_reg(state, 0x04, 3);
1139 else
1140 dib0090_write_reg(state, 0x04, 1);
1141 dib0090_write_reg(state, 0x39, (1 << 10));
1142 }
1143}
1144EXPORT_SYMBOL(dib0090_pwm_gain_reset);
1145
1146void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff)
1147{
1148 struct dib0090_state *state = fe->tuner_priv;
1149 if (DC_servo_cutoff < 4)
1150 dib0090_write_reg(state, 0x04, DC_servo_cutoff);
1151}
1152EXPORT_SYMBOL(dib0090_set_dc_servo);
1153
1154static u32 dib0090_get_slow_adc_val(struct dib0090_state *state)
1155{
1156 u16 adc_val = dib0090_read_reg(state, 0x1d);
1157 if (state->identity.in_soc)
1158 adc_val >>= 2;
1159 return adc_val;
1160}
1161
1162int dib0090_gain_control(struct dvb_frontend *fe)
1163{
1164 struct dib0090_state *state = fe->tuner_priv;
1165 enum frontend_tune_state *tune_state = &state->tune_state;
1166 int ret = 10;
1167
1168 u16 wbd_val = 0;
1169 u8 apply_gain_immediatly = 1;
1170 s16 wbd_error = 0, adc_error = 0;
1171
1172 if (*tune_state == CT_AGC_START) {
1173 state->agc_freeze = 0;
1174 dib0090_write_reg(state, 0x04, 0x0);
1175
1176#ifdef CONFIG_BAND_SBAND
1177 if (state->current_band == BAND_SBAND) {
1178 dib0090_set_rframp(state, rf_ramp_sband);
1179 dib0090_set_bbramp(state, bb_ramp_boost);
1180 } else
1181#endif
1182#ifdef CONFIG_BAND_VHF
1183 if (state->current_band == BAND_VHF && !state->identity.p1g) {
1184 dib0090_set_rframp(state, rf_ramp_pwm_vhf);
1185 dib0090_set_bbramp(state, bb_ramp_pwm_normal);
1186 } else
1187#endif
1188#ifdef CONFIG_BAND_CBAND
1189 if (state->current_band == BAND_CBAND && !state->identity.p1g) {
1190 dib0090_set_rframp(state, rf_ramp_pwm_cband);
1191 dib0090_set_bbramp(state, bb_ramp_pwm_normal);
1192 } else
1193#endif
1194 if ((state->current_band == BAND_CBAND || state->current_band == BAND_VHF) && state->identity.p1g) {
1195 dib0090_set_rframp(state, rf_ramp_pwm_cband_7090p);
1196 dib0090_set_bbramp(state, bb_ramp_pwm_normal_socs);
1197 } else {
1198 dib0090_set_rframp(state, rf_ramp_pwm_uhf);
1199 dib0090_set_bbramp(state, bb_ramp_pwm_normal);
1200 }
1201
1202 dib0090_write_reg(state, 0x32, 0);
1203 dib0090_write_reg(state, 0x39, 0);
1204
1205 dib0090_wbd_target(state, state->current_rf);
1206
1207 state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
1208 state->current_gain = ((state->rf_ramp[0] + state->bb_ramp[0]) / 2) << GAIN_ALPHA;
1209
1210 *tune_state = CT_AGC_STEP_0;
1211 } else if (!state->agc_freeze) {
1212 s16 wbd = 0, i, cnt;
1213
1214 int adc;
1215 wbd_val = dib0090_get_slow_adc_val(state);
1216
1217 if (*tune_state == CT_AGC_STEP_0)
1218 cnt = 5;
1219 else
1220 cnt = 1;
1221
1222 for (i = 0; i < cnt; i++) {
1223 wbd_val = dib0090_get_slow_adc_val(state);
1224 wbd += dib0090_wbd_to_db(state, wbd_val);
1225 }
1226 wbd /= cnt;
1227 wbd_error = state->wbd_target - wbd;
1228
1229 if (*tune_state == CT_AGC_STEP_0) {
1230 if (wbd_error < 0 && state->rf_gain_limit > 0 && !state->identity.p1g) {
1231#ifdef CONFIG_BAND_CBAND
1232
1233 u8 ltg2 = (state->rf_lt_def >> 10) & 0x7;
1234 if (state->current_band == BAND_CBAND && ltg2) {
1235 ltg2 >>= 1;
1236 state->rf_lt_def &= ltg2 << 10;
1237 }
1238#endif
1239 } else {
1240 state->agc_step = 0;
1241 *tune_state = CT_AGC_STEP_1;
1242 }
1243 } else {
1244
1245 adc = state->config->get_adc_power(fe);
1246 adc = (adc * ((s32) 355774) + (((s32) 1) << 20)) >> 21;
1247
1248 adc_error = (s16) (((s32) ADC_TARGET) - adc);
1249#ifdef CONFIG_STANDARD_DAB
1250 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB)
1251 adc_error -= 10;
1252#endif
1253#ifdef CONFIG_STANDARD_DVBT
1254 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DVBT &&
1255 (state->fe->dtv_property_cache.modulation == QAM_64 || state->fe->dtv_property_cache.modulation == QAM_16))
1256 adc_error += 60;
1257#endif
1258#ifdef CONFIG_SYS_ISDBT
1259 if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) && (((state->fe->dtv_property_cache.layer[0].segment_count >
1260 0)
1261 &&
1262 ((state->fe->dtv_property_cache.layer[0].modulation ==
1263 QAM_64)
1264 || (state->fe->dtv_property_cache.
1265 layer[0].modulation == QAM_16)))
1266 ||
1267 ((state->fe->dtv_property_cache.layer[1].segment_count >
1268 0)
1269 &&
1270 ((state->fe->dtv_property_cache.layer[1].modulation ==
1271 QAM_64)
1272 || (state->fe->dtv_property_cache.
1273 layer[1].modulation == QAM_16)))
1274 ||
1275 ((state->fe->dtv_property_cache.layer[2].segment_count >
1276 0)
1277 &&
1278 ((state->fe->dtv_property_cache.layer[2].modulation ==
1279 QAM_64)
1280 || (state->fe->dtv_property_cache.
1281 layer[2].modulation == QAM_16)))
1282 )
1283 )
1284 adc_error += 60;
1285#endif
1286
1287 if (*tune_state == CT_AGC_STEP_1) {
1288 if (ABS(adc_error) < 50 || state->agc_step++ > 5) {
1289
1290#ifdef CONFIG_STANDARD_DAB
1291 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) {
1292 dib0090_write_reg(state, 0x02, (1 << 15) | (15 << 11) | (31 << 6) | (63));
1293 dib0090_write_reg(state, 0x04, 0x0);
1294 } else
1295#endif
1296 {
1297 dib0090_write_reg(state, 0x02, (1 << 15) | (3 << 11) | (6 << 6) | (32));
1298 dib0090_write_reg(state, 0x04, 0x01);
1299 }
1300
1301 *tune_state = CT_AGC_STOP;
1302 }
1303 } else {
1304
1305 ret = 100;
1306 apply_gain_immediatly = 0;
1307 }
1308 }
1309#ifdef DEBUG_AGC
1310 dprintk
1311 ("tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm",
1312 (u32) *tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val,
1313 (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA));
1314#endif
1315 }
1316
1317
1318 if (!state->agc_freeze)
1319 dib0090_gain_apply(state, adc_error, wbd_error, apply_gain_immediatly);
1320 return ret;
1321}
1322
1323EXPORT_SYMBOL(dib0090_gain_control);
1324
1325void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt)
1326{
1327 struct dib0090_state *state = fe->tuner_priv;
1328 if (rf)
1329 *rf = state->gain[0];
1330 if (bb)
1331 *bb = state->gain[1];
1332 if (rf_gain_limit)
1333 *rf_gain_limit = state->rf_gain_limit;
1334 if (rflt)
1335 *rflt = (state->rf_lt_def >> 10) & 0x7;
1336}
1337
1338EXPORT_SYMBOL(dib0090_get_current_gain);
1339
1340u16 dib0090_get_wbd_target(struct dvb_frontend *fe)
1341{
1342 struct dib0090_state *state = fe->tuner_priv;
1343 u32 f_MHz = state->fe->dtv_property_cache.frequency / 1000000;
1344 s32 current_temp = state->temperature;
1345 s32 wbd_thot, wbd_tcold;
1346 const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1347
1348 while (f_MHz > wbd->max_freq)
1349 wbd++;
1350
1351 dprintk("using wbd-table-entry with max freq %d\n", wbd->max_freq);
1352
1353 if (current_temp < 0)
1354 current_temp = 0;
1355 if (current_temp > 128)
1356 current_temp = 128;
1357
1358 state->wbdmux &= ~(7 << 13);
1359 if (wbd->wbd_gain != 0)
1360 state->wbdmux |= (wbd->wbd_gain << 13);
1361 else
1362 state->wbdmux |= (4 << 13);
1363
1364 dib0090_write_reg(state, 0x10, state->wbdmux);
1365
1366 wbd_thot = wbd->offset_hot - (((u32) wbd->slope_hot * f_MHz) >> 6);
1367 wbd_tcold = wbd->offset_cold - (((u32) wbd->slope_cold * f_MHz) >> 6);
1368
1369 wbd_tcold += ((wbd_thot - wbd_tcold) * current_temp) >> 7;
1370
1371 state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + wbd_tcold);
1372 dprintk("wbd-target: %d dB\n", (u32) state->wbd_target);
1373 dprintk("wbd offset applied is %d\n", wbd_tcold);
1374
1375 return state->wbd_offset + wbd_tcold;
1376}
1377EXPORT_SYMBOL(dib0090_get_wbd_target);
1378
1379u16 dib0090_get_wbd_offset(struct dvb_frontend *fe)
1380{
1381 struct dib0090_state *state = fe->tuner_priv;
1382 return state->wbd_offset;
1383}
1384EXPORT_SYMBOL(dib0090_get_wbd_offset);
1385
1386int dib0090_set_switch(struct dvb_frontend *fe, u8 sw1, u8 sw2, u8 sw3)
1387{
1388 struct dib0090_state *state = fe->tuner_priv;
1389
1390 dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xfff8)
1391 | ((sw3 & 1) << 2) | ((sw2 & 1) << 1) | (sw1 & 1));
1392
1393 return 0;
1394}
1395EXPORT_SYMBOL(dib0090_set_switch);
1396
1397int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff)
1398{
1399 struct dib0090_state *state = fe->tuner_priv;
1400
1401 dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x7fff)
1402 | ((onoff & 1) << 15));
1403 return 0;
1404}
1405EXPORT_SYMBOL(dib0090_set_vga);
1406
1407int dib0090_update_rframp_7090(struct dvb_frontend *fe, u8 cfg_sensitivity)
1408{
1409 struct dib0090_state *state = fe->tuner_priv;
1410
1411 if ((!state->identity.p1g) || (!state->identity.in_soc)
1412 || ((state->identity.version != SOC_7090_P1G_21R1)
1413 && (state->identity.version != SOC_7090_P1G_11R1))) {
1414 dprintk("%s() function can only be used for dib7090P\n", __func__);
1415 return -ENODEV;
1416 }
1417
1418 if (cfg_sensitivity)
1419 state->rf_ramp = (const u16 *)&rf_ramp_pwm_cband_7090e_sensitivity;
1420 else
1421 state->rf_ramp = (const u16 *)&rf_ramp_pwm_cband_7090e_aci;
1422 dib0090_pwm_gain_reset(fe);
1423
1424 return 0;
1425}
1426EXPORT_SYMBOL(dib0090_update_rframp_7090);
1427
1428static const u16 dib0090_defaults[] = {
1429
1430 25, 0x01,
1431 0x0000,
1432 0x99a0,
1433 0x6008,
1434 0x0000,
1435 0x8bcb,
1436 0x0000,
1437 0x0405,
1438 0x0000,
1439 0x0000,
1440 0x0000,
1441 0xb802,
1442 0x0300,
1443 0x2d12,
1444 0xbac0,
1445 0x7c00,
1446 0xdbb9,
1447 0x0954,
1448 0x0743,
1449 0x8000,
1450 0x0001,
1451 0x0040,
1452 0x0100,
1453 0x0000,
1454 0xe910,
1455 0x149e,
1456
1457 1, 0x1c,
1458 0xff2d,
1459
1460 1, 0x39,
1461 0x0000,
1462
1463 2, 0x1e,
1464 0x07FF,
1465 0x0007,
1466
1467 1, 0x24,
1468 EN_UHF | EN_CRYSTAL,
1469
1470 2, 0x3c,
1471 0x3ff,
1472 0x111,
1473 0
1474};
1475
1476static const u16 dib0090_p1g_additionnal_defaults[] = {
1477 1, 0x05,
1478 0xabcd,
1479
1480 1, 0x11,
1481 0x00b4,
1482
1483 1, 0x1c,
1484 0xfffd,
1485
1486 1, 0x40,
1487 0x108,
1488 0
1489};
1490
1491static void dib0090_set_default_config(struct dib0090_state *state, const u16 * n)
1492{
1493 u16 l, r;
1494
1495 l = pgm_read_word(n++);
1496 while (l) {
1497 r = pgm_read_word(n++);
1498 do {
1499 dib0090_write_reg(state, r, pgm_read_word(n++));
1500 r++;
1501 } while (--l);
1502 l = pgm_read_word(n++);
1503 }
1504}
1505
1506#define CAP_VALUE_MIN (u8) 9
1507#define CAP_VALUE_MAX (u8) 40
1508#define HR_MIN (u8) 25
1509#define HR_MAX (u8) 40
1510#define POLY_MIN (u8) 0
1511#define POLY_MAX (u8) 8
1512
1513static void dib0090_set_EFUSE(struct dib0090_state *state)
1514{
1515 u8 c, h, n;
1516 u16 e2, e4;
1517 u16 cal;
1518
1519 e2 = dib0090_read_reg(state, 0x26);
1520 e4 = dib0090_read_reg(state, 0x28);
1521
1522 if ((state->identity.version == P1D_E_F) ||
1523 (state->identity.version == P1G) || (e2 == 0xffff)) {
1524
1525 dib0090_write_reg(state, 0x22, 0x10);
1526 cal = (dib0090_read_reg(state, 0x22) >> 6) & 0x3ff;
1527
1528 if ((cal < 670) || (cal == 1023))
1529 cal = 850;
1530 n = 165 - ((cal * 10)>>6) ;
1531 e2 = e4 = (3<<12) | (34<<6) | (n);
1532 }
1533
1534 if (e2 != e4)
1535 e2 &= e4;
1536
1537 if (e2 != 0xffff) {
1538 c = e2 & 0x3f;
1539 n = (e2 >> 12) & 0xf;
1540 h = (e2 >> 6) & 0x3f;
1541
1542 if ((c >= CAP_VALUE_MAX) || (c <= CAP_VALUE_MIN))
1543 c = 32;
1544 else
1545 c += 14;
1546 if ((h >= HR_MAX) || (h <= HR_MIN))
1547 h = 34;
1548 if ((n >= POLY_MAX) || (n <= POLY_MIN))
1549 n = 3;
1550
1551 dib0090_write_reg(state, 0x13, (h << 10));
1552 e2 = (n << 11) | ((h >> 2)<<6) | c;
1553 dib0090_write_reg(state, 0x2, e2);
1554 }
1555}
1556
1557static int dib0090_reset(struct dvb_frontend *fe)
1558{
1559 struct dib0090_state *state = fe->tuner_priv;
1560
1561 dib0090_reset_digital(fe, state->config);
1562 if (dib0090_identify(fe) < 0)
1563 return -EIO;
1564
1565#ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT
1566 if (!(state->identity.version & 0x1))
1567 return 0;
1568#endif
1569
1570 if (!state->identity.in_soc) {
1571 if ((dib0090_read_reg(state, 0x1a) >> 5) & 0x2)
1572 dib0090_write_reg(state, 0x1b, (EN_IQADC | EN_BB | EN_BIAS | EN_DIGCLK | EN_PLL | EN_CRYSTAL));
1573 else
1574 dib0090_write_reg(state, 0x1b, (EN_DIGCLK | EN_PLL | EN_CRYSTAL));
1575 }
1576
1577 dib0090_set_default_config(state, dib0090_defaults);
1578
1579 if (state->identity.in_soc)
1580 dib0090_write_reg(state, 0x18, 0x2910);
1581
1582 if (state->identity.p1g)
1583 dib0090_set_default_config(state, dib0090_p1g_additionnal_defaults);
1584
1585
1586 if (((state->identity.version & 0x1f) >= P1D_E_F) || (state->identity.in_soc))
1587 dib0090_set_EFUSE(state);
1588
1589
1590 if (state->config->force_crystal_mode != 0)
1591 dib0090_write_reg(state, 0x14,
1592 state->config->force_crystal_mode & 3);
1593 else if (state->config->io.clock_khz >= 24000)
1594 dib0090_write_reg(state, 0x14, 1);
1595 else
1596 dib0090_write_reg(state, 0x14, 2);
1597 dprintk("Pll lock : %d\n", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1);
1598
1599 state->calibrate = DC_CAL | WBD_CAL | TEMP_CAL;
1600
1601 return 0;
1602}
1603
1604#define steps(u) (((u) > 15) ? ((u)-16) : (u))
1605#define INTERN_WAIT 10
1606static int dib0090_get_offset(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1607{
1608 int ret = INTERN_WAIT * 10;
1609
1610 switch (*tune_state) {
1611 case CT_TUNER_STEP_2:
1612
1613 dib0090_write_reg(state, 0x1f, 0x7);
1614 *tune_state = CT_TUNER_STEP_3;
1615 break;
1616
1617 case CT_TUNER_STEP_3:
1618 state->adc_diff = dib0090_read_reg(state, 0x1d);
1619
1620
1621 dib0090_write_reg(state, 0x1f, 0x4);
1622 *tune_state = CT_TUNER_STEP_4;
1623 break;
1624
1625 case CT_TUNER_STEP_4:
1626 state->adc_diff -= dib0090_read_reg(state, 0x1d);
1627 *tune_state = CT_TUNER_STEP_5;
1628 ret = 0;
1629 break;
1630
1631 default:
1632 break;
1633 }
1634
1635 return ret;
1636}
1637
1638struct dc_calibration {
1639 u8 addr;
1640 u8 offset;
1641 u8 pga:1;
1642 u16 bb1;
1643 u8 i:1;
1644};
1645
1646static const struct dc_calibration dc_table[] = {
1647
1648 {0x06, 5, 1, (1 << 13) | (0 << 8) | (26 << 3), 1},
1649 {0x07, 11, 1, (1 << 13) | (0 << 8) | (26 << 3), 0},
1650
1651 {0x06, 0, 0, (1 << 13) | (29 << 8) | (26 << 3), 1},
1652 {0x06, 10, 0, (1 << 13) | (29 << 8) | (26 << 3), 0},
1653 {0},
1654};
1655
1656static const struct dc_calibration dc_p1g_table[] = {
1657
1658
1659 {0x06, 5, 1, (1 << 13) | (0 << 8) | (15 << 3), 1},
1660 {0x07, 11, 1, (1 << 13) | (0 << 8) | (15 << 3), 0},
1661
1662 {0x06, 0, 0, (1 << 13) | (29 << 8) | (15 << 3), 1},
1663 {0x06, 10, 0, (1 << 13) | (29 << 8) | (15 << 3), 0},
1664 {0},
1665};
1666
1667static void dib0090_set_trim(struct dib0090_state *state)
1668{
1669 u16 *val;
1670
1671 if (state->dc->addr == 0x07)
1672 val = &state->bb7;
1673 else
1674 val = &state->bb6;
1675
1676 *val &= ~(0x1f << state->dc->offset);
1677 *val |= state->step << state->dc->offset;
1678
1679 dib0090_write_reg(state, state->dc->addr, *val);
1680}
1681
1682static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1683{
1684 int ret = 0;
1685 u16 reg;
1686
1687 switch (*tune_state) {
1688 case CT_TUNER_START:
1689 dprintk("Start DC offset calibration");
1690
1691
1692 state->bb6 = 0;
1693 state->bb7 = 0x040d;
1694
1695
1696 reg = dib0090_read_reg(state, 0x24) & 0x0ffb;
1697 dib0090_write_reg(state, 0x24, reg);
1698
1699 state->wbdmux = dib0090_read_reg(state, 0x10);
1700 dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x7 << 3) | 0x3);
1701 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
1702
1703 state->dc = dc_table;
1704
1705 if (state->identity.p1g)
1706 state->dc = dc_p1g_table;
1707
1708
1709 case CT_TUNER_STEP_0:
1710 dprintk("Start/continue DC calibration for %s path\n",
1711 (state->dc->i == 1) ? "I" : "Q");
1712 dib0090_write_reg(state, 0x01, state->dc->bb1);
1713 dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7));
1714
1715 state->step = 0;
1716 state->min_adc_diff = 1023;
1717 *tune_state = CT_TUNER_STEP_1;
1718 ret = 50;
1719 break;
1720
1721 case CT_TUNER_STEP_1:
1722 dib0090_set_trim(state);
1723 *tune_state = CT_TUNER_STEP_2;
1724 break;
1725
1726 case CT_TUNER_STEP_2:
1727 case CT_TUNER_STEP_3:
1728 case CT_TUNER_STEP_4:
1729 ret = dib0090_get_offset(state, tune_state);
1730 break;
1731
1732 case CT_TUNER_STEP_5:
1733 dprintk("adc_diff = %d, current step= %d\n", (u32) state->adc_diff, state->step);
1734 if (state->step == 0 && state->adc_diff < 0) {
1735 state->min_adc_diff = -1023;
1736 dprintk("Change of sign of the minimum adc diff\n");
1737 }
1738
1739 dprintk("adc_diff = %d, min_adc_diff = %d current_step = %d\n", state->adc_diff, state->min_adc_diff, state->step);
1740
1741
1742 if (state->step == 0) {
1743 if (state->dc->pga && state->adc_diff < 0)
1744 state->step = 0x10;
1745 if (state->dc->pga == 0 && state->adc_diff > 0)
1746 state->step = 0x10;
1747 }
1748
1749
1750 if ((state->adc_diff & 0x8000) == (state->min_adc_diff & 0x8000) && steps(state->step) < 15) {
1751
1752 state->step++;
1753 state->min_adc_diff = state->adc_diff;
1754 *tune_state = CT_TUNER_STEP_1;
1755 } else {
1756
1757 if (ABS(state->adc_diff) > ABS(state->min_adc_diff)) {
1758 dprintk("Since adc_diff N = %d > adc_diff step N-1 = %d, Come back one step\n", state->adc_diff, state->min_adc_diff);
1759 state->step--;
1760 }
1761
1762 dib0090_set_trim(state);
1763 dprintk("BB Offset Cal, BBreg=%hd,Offset=%hd,Value Set=%hd\n", state->dc->addr, state->adc_diff, state->step);
1764
1765 state->dc++;
1766 if (state->dc->addr == 0)
1767 *tune_state = CT_TUNER_STEP_6;
1768 else
1769 *tune_state = CT_TUNER_STEP_0;
1770
1771 }
1772 break;
1773
1774 case CT_TUNER_STEP_6:
1775 dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008);
1776 dib0090_write_reg(state, 0x1f, 0x7);
1777 *tune_state = CT_TUNER_START;
1778 state->calibrate &= ~DC_CAL;
1779 default:
1780 break;
1781 }
1782 return ret;
1783}
1784
1785static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1786{
1787 u8 wbd_gain;
1788 const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1789
1790 switch (*tune_state) {
1791 case CT_TUNER_START:
1792 while (state->current_rf / 1000 > wbd->max_freq)
1793 wbd++;
1794 if (wbd->wbd_gain != 0)
1795 wbd_gain = wbd->wbd_gain;
1796 else {
1797 wbd_gain = 4;
1798#if defined(CONFIG_BAND_LBAND) || defined(CONFIG_BAND_SBAND)
1799 if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND))
1800 wbd_gain = 2;
1801#endif
1802 }
1803
1804 if (wbd_gain == state->wbd_calibration_gain) {
1805 *tune_state = CT_TUNER_START;
1806 state->calibrate &= ~WBD_CAL;
1807 return 0;
1808 }
1809
1810 dib0090_write_reg(state, 0x10, 0x1b81 | (1 << 10) | (wbd_gain << 13) | (1 << 3));
1811
1812 dib0090_write_reg(state, 0x24, ((EN_UHF & 0x0fff) | (1 << 1)));
1813 *tune_state = CT_TUNER_STEP_0;
1814 state->wbd_calibration_gain = wbd_gain;
1815 return 90;
1816
1817 case CT_TUNER_STEP_0:
1818 state->wbd_offset = dib0090_get_slow_adc_val(state);
1819 dprintk("WBD calibration offset = %d\n", state->wbd_offset);
1820 *tune_state = CT_TUNER_START;
1821 state->calibrate &= ~WBD_CAL;
1822 break;
1823
1824 default:
1825 break;
1826 }
1827 return 0;
1828}
1829
1830static void dib0090_set_bandwidth(struct dib0090_state *state)
1831{
1832 u16 tmp;
1833
1834 if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 5000)
1835 tmp = (3 << 14);
1836 else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 6000)
1837 tmp = (2 << 14);
1838 else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 7000)
1839 tmp = (1 << 14);
1840 else
1841 tmp = (0 << 14);
1842
1843 state->bb_1_def &= 0x3fff;
1844 state->bb_1_def |= tmp;
1845
1846 dib0090_write_reg(state, 0x01, state->bb_1_def);
1847
1848 dib0090_write_reg(state, 0x03, 0x6008);
1849 dib0090_write_reg(state, 0x04, 0x1);
1850 if (state->identity.in_soc) {
1851 dib0090_write_reg(state, 0x05, 0x9bcf);
1852 } else {
1853 dib0090_write_reg(state, 0x02, (5 << 11) | (8 << 6) | (22 & 0x3f));
1854 dib0090_write_reg(state, 0x05, 0xabcd);
1855 }
1856}
1857
1858static const struct dib0090_pll dib0090_pll_table[] = {
1859#ifdef CONFIG_BAND_CBAND
1860 {56000, 0, 9, 48, 6},
1861 {70000, 1, 9, 48, 6},
1862 {87000, 0, 8, 32, 4},
1863 {105000, 1, 8, 32, 4},
1864 {115000, 0, 7, 24, 6},
1865 {140000, 1, 7, 24, 6},
1866 {170000, 0, 6, 16, 4},
1867#endif
1868#ifdef CONFIG_BAND_VHF
1869 {200000, 1, 6, 16, 4},
1870 {230000, 0, 5, 12, 6},
1871 {280000, 1, 5, 12, 6},
1872 {340000, 0, 4, 8, 4},
1873 {380000, 1, 4, 8, 4},
1874 {450000, 0, 3, 6, 6},
1875#endif
1876#ifdef CONFIG_BAND_UHF
1877 {580000, 1, 3, 6, 6},
1878 {700000, 0, 2, 4, 4},
1879 {860000, 1, 2, 4, 4},
1880#endif
1881#ifdef CONFIG_BAND_LBAND
1882 {1800000, 1, 0, 2, 4},
1883#endif
1884#ifdef CONFIG_BAND_SBAND
1885 {2900000, 0, 14, 1, 4},
1886#endif
1887};
1888
1889static const struct dib0090_tuning dib0090_tuning_table_fm_vhf_on_cband[] = {
1890
1891#ifdef CONFIG_BAND_CBAND
1892 {184000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1893 {227000, 4, 3, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1894 {380000, 4, 7, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1895#endif
1896#ifdef CONFIG_BAND_UHF
1897 {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1898 {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1899 {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1900 {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1901 {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1902 {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1903#endif
1904#ifdef CONFIG_BAND_LBAND
1905 {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1906 {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1907 {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1908#endif
1909#ifdef CONFIG_BAND_SBAND
1910 {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1911 {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1912#endif
1913};
1914
1915static const struct dib0090_tuning dib0090_tuning_table[] = {
1916
1917#ifdef CONFIG_BAND_CBAND
1918 {170000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1919#endif
1920#ifdef CONFIG_BAND_VHF
1921 {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1922 {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1923 {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1924#endif
1925#ifdef CONFIG_BAND_UHF
1926 {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1927 {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1928 {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1929 {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1930 {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1931 {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1932#endif
1933#ifdef CONFIG_BAND_LBAND
1934 {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1935 {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1936 {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1937#endif
1938#ifdef CONFIG_BAND_SBAND
1939 {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1940 {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1941#endif
1942};
1943
1944static const struct dib0090_tuning dib0090_p1g_tuning_table[] = {
1945#ifdef CONFIG_BAND_CBAND
1946 {170000, 4, 1, 0x820f, 0x300, 0x2d22, 0x82cb, EN_CAB},
1947#endif
1948#ifdef CONFIG_BAND_VHF
1949 {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1950 {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1951 {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1952#endif
1953#ifdef CONFIG_BAND_UHF
1954 {510000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1955 {540000, 2, 1, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1956 {600000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1957 {630000, 2, 4, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1958 {680000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1959 {720000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1960 {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1961#endif
1962#ifdef CONFIG_BAND_LBAND
1963 {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1964 {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1965 {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1966#endif
1967#ifdef CONFIG_BAND_SBAND
1968 {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1969 {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1970#endif
1971};
1972
1973static const struct dib0090_pll dib0090_p1g_pll_table[] = {
1974#ifdef CONFIG_BAND_CBAND
1975 {57000, 0, 11, 48, 6},
1976 {70000, 1, 11, 48, 6},
1977 {86000, 0, 10, 32, 4},
1978 {105000, 1, 10, 32, 4},
1979 {115000, 0, 9, 24, 6},
1980 {140000, 1, 9, 24, 6},
1981 {170000, 0, 8, 16, 4},
1982#endif
1983#ifdef CONFIG_BAND_VHF
1984 {200000, 1, 8, 16, 4},
1985 {230000, 0, 7, 12, 6},
1986 {280000, 1, 7, 12, 6},
1987 {340000, 0, 6, 8, 4},
1988 {380000, 1, 6, 8, 4},
1989 {455000, 0, 5, 6, 6},
1990#endif
1991#ifdef CONFIG_BAND_UHF
1992 {580000, 1, 5, 6, 6},
1993 {680000, 0, 4, 4, 4},
1994 {860000, 1, 4, 4, 4},
1995#endif
1996#ifdef CONFIG_BAND_LBAND
1997 {1800000, 1, 2, 2, 4},
1998#endif
1999#ifdef CONFIG_BAND_SBAND
2000 {2900000, 0, 1, 1, 6},
2001#endif
2002};
2003
2004static const struct dib0090_tuning dib0090_p1g_tuning_table_fm_vhf_on_cband[] = {
2005#ifdef CONFIG_BAND_CBAND
2006 {184000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
2007 {227000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
2008 {380000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
2009#endif
2010#ifdef CONFIG_BAND_UHF
2011 {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2012 {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2013 {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2014 {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2015 {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2016 {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2017#endif
2018#ifdef CONFIG_BAND_LBAND
2019 {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
2020 {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
2021 {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
2022#endif
2023#ifdef CONFIG_BAND_SBAND
2024 {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
2025 {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
2026#endif
2027};
2028
2029static const struct dib0090_tuning dib0090_tuning_table_cband_7090[] = {
2030#ifdef CONFIG_BAND_CBAND
2031 {300000, 4, 3, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2032 {380000, 4, 10, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2033 {570000, 4, 10, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2034 {858000, 4, 5, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2035#endif
2036};
2037
2038static const struct dib0090_tuning dib0090_tuning_table_cband_7090e_sensitivity[] = {
2039#ifdef CONFIG_BAND_CBAND
2040 { 300000, 0 , 3, 0x8105, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
2041 { 380000, 0 , 10, 0x810F, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
2042 { 600000, 0 , 10, 0x815E, 0x280, 0x2d12, 0xb84e, EN_CAB },
2043 { 660000, 0 , 5, 0x85E3, 0x280, 0x2d12, 0xb84e, EN_CAB },
2044 { 720000, 0 , 5, 0x852E, 0x280, 0x2d12, 0xb84e, EN_CAB },
2045 { 860000, 0 , 4, 0x85E5, 0x280, 0x2d12, 0xb84e, EN_CAB },
2046#endif
2047};
2048
2049int dib0090_update_tuning_table_7090(struct dvb_frontend *fe,
2050 u8 cfg_sensitivity)
2051{
2052 struct dib0090_state *state = fe->tuner_priv;
2053 const struct dib0090_tuning *tune =
2054 dib0090_tuning_table_cband_7090e_sensitivity;
2055 static const struct dib0090_tuning dib0090_tuning_table_cband_7090e_aci[] = {
2056 { 300000, 0 , 3, 0x8165, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
2057 { 650000, 0 , 4, 0x815B, 0x280, 0x2d12, 0xb84e, EN_CAB },
2058 { 860000, 0 , 5, 0x84EF, 0x280, 0x2d12, 0xb84e, EN_CAB },
2059 };
2060
2061 if ((!state->identity.p1g) || (!state->identity.in_soc)
2062 || ((state->identity.version != SOC_7090_P1G_21R1)
2063 && (state->identity.version != SOC_7090_P1G_11R1))) {
2064 dprintk("%s() function can only be used for dib7090\n", __func__);
2065 return -ENODEV;
2066 }
2067
2068 if (cfg_sensitivity)
2069 tune = dib0090_tuning_table_cband_7090e_sensitivity;
2070 else
2071 tune = dib0090_tuning_table_cband_7090e_aci;
2072
2073 while (state->rf_request > tune->max_freq)
2074 tune++;
2075
2076 dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x8000)
2077 | (tune->lna_bias & 0x7fff));
2078 dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xf83f)
2079 | ((tune->lna_tune << 6) & 0x07c0));
2080 return 0;
2081}
2082EXPORT_SYMBOL(dib0090_update_tuning_table_7090);
2083
2084static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tune_state *tune_state)
2085{
2086 int ret = 0;
2087 u16 lo4 = 0xe900;
2088
2089 s16 adc_target;
2090 u16 adc;
2091 s8 step_sign;
2092 u8 force_soft_search = 0;
2093
2094 if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
2095 force_soft_search = 1;
2096
2097 if (*tune_state == CT_TUNER_START) {
2098 dprintk("Start Captrim search : %s\n",
2099 (force_soft_search == 1) ? "FORCE SOFT SEARCH" : "AUTO");
2100 dib0090_write_reg(state, 0x10, 0x2B1);
2101 dib0090_write_reg(state, 0x1e, 0x0032);
2102
2103 if (!state->tuner_is_tuned) {
2104
2105 if (!state->identity.p1g || force_soft_search)
2106 state->step = state->captrim = state->fcaptrim = 64;
2107
2108 state->current_rf = state->rf_request;
2109 } else {
2110 if (!state->identity.p1g || force_soft_search) {
2111
2112 state->step = 4;
2113 state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f;
2114 }
2115 }
2116 state->adc_diff = 3000;
2117 *tune_state = CT_TUNER_STEP_0;
2118
2119 } else if (*tune_state == CT_TUNER_STEP_0) {
2120 if (state->identity.p1g && !force_soft_search) {
2121 u8 ratio = 31;
2122
2123 dib0090_write_reg(state, 0x40, (3 << 7) | (ratio << 2) | (1 << 1) | 1);
2124 dib0090_read_reg(state, 0x40);
2125 ret = 50;
2126 } else {
2127 state->step /= 2;
2128 dib0090_write_reg(state, 0x18, lo4 | state->captrim);
2129
2130 if (state->identity.in_soc)
2131 ret = 25;
2132 }
2133 *tune_state = CT_TUNER_STEP_1;
2134
2135 } else if (*tune_state == CT_TUNER_STEP_1) {
2136 if (state->identity.p1g && !force_soft_search) {
2137 dib0090_write_reg(state, 0x40, 0x18c | (0 << 1) | 0);
2138 dib0090_read_reg(state, 0x40);
2139
2140 state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7F;
2141 dprintk("***Final Captrim= 0x%x\n", state->fcaptrim);
2142 *tune_state = CT_TUNER_STEP_3;
2143
2144 } else {
2145
2146 adc = dib0090_get_slow_adc_val(state);
2147 dprintk("CAPTRIM=%d; ADC = %d (ADC) & %dmV\n", (u32) state->captrim, (u32) adc, (u32) (adc) * (u32) 1800 / (u32) 1024);
2148
2149 if (state->rest == 0 || state->identity.in_soc) {
2150 adc_target = 200;
2151 } else
2152 adc_target = 400;
2153
2154 if (adc >= adc_target) {
2155 adc -= adc_target;
2156 step_sign = -1;
2157 } else {
2158 adc = adc_target - adc;
2159 step_sign = 1;
2160 }
2161
2162 if (adc < state->adc_diff) {
2163 dprintk("CAPTRIM=%d is closer to target (%d/%d)\n", (u32) state->captrim, (u32) adc, (u32) state->adc_diff);
2164 state->adc_diff = adc;
2165 state->fcaptrim = state->captrim;
2166 }
2167
2168 state->captrim += step_sign * state->step;
2169 if (state->step >= 1)
2170 *tune_state = CT_TUNER_STEP_0;
2171 else
2172 *tune_state = CT_TUNER_STEP_2;
2173
2174 ret = 25;
2175 }
2176 } else if (*tune_state == CT_TUNER_STEP_2) {
2177
2178 dib0090_write_reg(state, 0x18, lo4 | state->fcaptrim);
2179
2180 *tune_state = CT_TUNER_STEP_3;
2181
2182 } else if (*tune_state == CT_TUNER_STEP_3) {
2183 state->calibrate &= ~CAPTRIM_CAL;
2184 *tune_state = CT_TUNER_STEP_0;
2185 }
2186
2187 return ret;
2188}
2189
2190static int dib0090_get_temperature(struct dib0090_state *state, enum frontend_tune_state *tune_state)
2191{
2192 int ret = 15;
2193 s16 val;
2194
2195 switch (*tune_state) {
2196 case CT_TUNER_START:
2197 state->wbdmux = dib0090_read_reg(state, 0x10);
2198 dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x8 << 3));
2199
2200 state->bias = dib0090_read_reg(state, 0x13);
2201 dib0090_write_reg(state, 0x13, state->bias | (0x3 << 8));
2202
2203 *tune_state = CT_TUNER_STEP_0;
2204
2205 break;
2206
2207 case CT_TUNER_STEP_0:
2208 state->adc_diff = dib0090_get_slow_adc_val(state);
2209 dib0090_write_reg(state, 0x13, (state->bias & ~(0x3 << 8)) | (0x2 << 8));
2210 *tune_state = CT_TUNER_STEP_1;
2211 break;
2212
2213 case CT_TUNER_STEP_1:
2214 val = dib0090_get_slow_adc_val(state);
2215 state->temperature = ((s16) ((val - state->adc_diff) * 180) >> 8) + 55;
2216
2217 dprintk("temperature: %d C\n", state->temperature - 30);
2218
2219 *tune_state = CT_TUNER_STEP_2;
2220 break;
2221
2222 case CT_TUNER_STEP_2:
2223 dib0090_write_reg(state, 0x13, state->bias);
2224 dib0090_write_reg(state, 0x10, state->wbdmux);
2225
2226 *tune_state = CT_TUNER_START;
2227 state->calibrate &= ~TEMP_CAL;
2228 if (state->config->analog_output == 0)
2229 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
2230
2231 break;
2232
2233 default:
2234 ret = 0;
2235 break;
2236 }
2237 return ret;
2238}
2239
2240#define WBD 0x781
2241static int dib0090_tune(struct dvb_frontend *fe)
2242{
2243 struct dib0090_state *state = fe->tuner_priv;
2244 const struct dib0090_tuning *tune = state->current_tune_table_index;
2245 const struct dib0090_pll *pll = state->current_pll_table_index;
2246 enum frontend_tune_state *tune_state = &state->tune_state;
2247
2248 u16 lo5, lo6, Den, tmp;
2249 u32 FBDiv, Rest, FREF, VCOF_kHz = 0;
2250 int ret = 10;
2251 u8 c, i;
2252
2253
2254
2255
2256
2257
2258
2259 if (*tune_state == CT_TUNER_START) {
2260
2261 if (state->calibrate & (DC_CAL | TEMP_CAL | WBD_CAL))
2262 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
2263 else
2264
2265 if (state->config->analog_output == 0)
2266 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
2267 }
2268
2269 if (state->calibrate & DC_CAL)
2270 return dib0090_dc_offset_calibration(state, tune_state);
2271 else if (state->calibrate & WBD_CAL) {
2272 if (state->current_rf == 0)
2273 state->current_rf = state->fe->dtv_property_cache.frequency / 1000;
2274 return dib0090_wbd_calibration(state, tune_state);
2275 } else if (state->calibrate & TEMP_CAL)
2276 return dib0090_get_temperature(state, tune_state);
2277 else if (state->calibrate & CAPTRIM_CAL)
2278 return dib0090_captrim_search(state, tune_state);
2279
2280 if (*tune_state == CT_TUNER_START) {
2281
2282 if (state->config->use_pwm_agc && state->identity.in_soc) {
2283 tmp = dib0090_read_reg(state, 0x39);
2284 if ((tmp >> 10) & 0x1)
2285 dib0090_write_reg(state, 0x39, tmp & ~(1 << 10));
2286 }
2287
2288 state->current_band = (u8) BAND_OF_FREQUENCY(state->fe->dtv_property_cache.frequency / 1000);
2289 state->rf_request =
2290 state->fe->dtv_property_cache.frequency / 1000 + (state->current_band ==
2291 BAND_UHF ? state->config->freq_offset_khz_uhf : state->config->
2292 freq_offset_khz_vhf);
2293
2294
2295 if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1
2296 && state->fe->dtv_property_cache.isdbt_partial_reception == 0)) {
2297 const struct dib0090_low_if_offset_table *LUT_offset = state->config->low_if;
2298 u8 found_offset = 0;
2299 u32 margin_khz = 100;
2300
2301 if (LUT_offset != NULL) {
2302 while (LUT_offset->RF_freq != 0xffff) {
2303 if (((state->rf_request > (LUT_offset->RF_freq - margin_khz))
2304 && (state->rf_request < (LUT_offset->RF_freq + margin_khz)))
2305 && LUT_offset->std == state->fe->dtv_property_cache.delivery_system) {
2306 state->rf_request += LUT_offset->offset_khz;
2307 found_offset = 1;
2308 break;
2309 }
2310 LUT_offset++;
2311 }
2312 }
2313
2314 if (found_offset == 0)
2315 state->rf_request += 400;
2316 }
2317 if (state->current_rf != state->rf_request || (state->current_standard != state->fe->dtv_property_cache.delivery_system)) {
2318 state->tuner_is_tuned = 0;
2319 state->current_rf = 0;
2320 state->current_standard = 0;
2321
2322 tune = dib0090_tuning_table;
2323 if (state->identity.p1g)
2324 tune = dib0090_p1g_tuning_table;
2325
2326 tmp = (state->identity.version >> 5) & 0x7;
2327
2328 if (state->identity.in_soc) {
2329 if (state->config->force_cband_input) {
2330 if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF
2331 || state->current_band & BAND_UHF) {
2332 state->current_band = BAND_CBAND;
2333 if (state->config->is_dib7090e)
2334 tune = dib0090_tuning_table_cband_7090e_sensitivity;
2335 else
2336 tune = dib0090_tuning_table_cband_7090;
2337 }
2338 } else {
2339 if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF) {
2340 state->current_band = BAND_CBAND;
2341 if (state->config->is_dib7090e)
2342 tune = dib0090_tuning_table_cband_7090e_sensitivity;
2343 else
2344 tune = dib0090_tuning_table_cband_7090;
2345 }
2346 }
2347 } else
2348 if (tmp == 0x4 || tmp == 0x7) {
2349
2350 if (state->current_band == BAND_FM || state->current_band == BAND_CBAND || state->current_band == BAND_VHF) {
2351 state->current_band = BAND_CBAND;
2352
2353 tune = dib0090_tuning_table_fm_vhf_on_cband;
2354 if (state->identity.p1g)
2355 tune = dib0090_p1g_tuning_table_fm_vhf_on_cband;
2356 }
2357 }
2358
2359 pll = dib0090_pll_table;
2360 if (state->identity.p1g)
2361 pll = dib0090_p1g_pll_table;
2362
2363
2364 while (state->rf_request > tune->max_freq)
2365 tune++;
2366 while (state->rf_request > pll->max_freq)
2367 pll++;
2368
2369 state->current_tune_table_index = tune;
2370 state->current_pll_table_index = pll;
2371
2372 dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim));
2373
2374 VCOF_kHz = (pll->hfdiv * state->rf_request) * 2;
2375
2376 FREF = state->config->io.clock_khz;
2377 if (state->config->fref_clock_ratio != 0)
2378 FREF /= state->config->fref_clock_ratio;
2379
2380 FBDiv = (VCOF_kHz / pll->topresc / FREF);
2381 Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF;
2382
2383 if (Rest < LPF)
2384 Rest = 0;
2385 else if (Rest < 2 * LPF)
2386 Rest = 2 * LPF;
2387 else if (Rest > (FREF - LPF)) {
2388 Rest = 0;
2389 FBDiv += 1;
2390 } else if (Rest > (FREF - 2 * LPF))
2391 Rest = FREF - 2 * LPF;
2392 Rest = (Rest * 6528) / (FREF / 10);
2393 state->rest = Rest;
2394
2395
2396
2397
2398
2399 if (Rest == 0) {
2400 if (pll->vco_band)
2401 lo5 = 0x049f;
2402 else
2403 lo5 = 0x041f;
2404 } else {
2405 if (pll->vco_band)
2406 lo5 = 0x049e;
2407 else if (state->config->analog_output)
2408 lo5 = 0x041d;
2409 else
2410 lo5 = 0x041c;
2411 }
2412
2413 if (state->identity.p1g) {
2414 if (state->identity.in_soc) {
2415 if (state->identity.version == SOC_8090_P1G_11R1)
2416 lo5 = 0x46f;
2417 else
2418 lo5 = 0x42f;
2419 } else
2420 lo5 = 0x42c;
2421 }
2422
2423 lo5 |= (pll->hfdiv_code << 11) | (pll->vco_band << 7);
2424
2425 if (!state->config->io.pll_int_loop_filt) {
2426 if (state->identity.in_soc)
2427 lo6 = 0xff98;
2428 else if (state->identity.p1g || (Rest == 0))
2429 lo6 = 0xfff8;
2430 else
2431 lo6 = 0xff28;
2432 } else
2433 lo6 = (state->config->io.pll_int_loop_filt << 3);
2434
2435 Den = 1;
2436
2437 if (Rest > 0) {
2438 lo6 |= (1 << 2) | 2;
2439 Den = 255;
2440 }
2441 dib0090_write_reg(state, 0x15, (u16) FBDiv);
2442 if (state->config->fref_clock_ratio != 0)
2443 dib0090_write_reg(state, 0x16, (Den << 8) | state->config->fref_clock_ratio);
2444 else
2445 dib0090_write_reg(state, 0x16, (Den << 8) | 1);
2446 dib0090_write_reg(state, 0x17, (u16) Rest);
2447 dib0090_write_reg(state, 0x19, lo5);
2448 dib0090_write_reg(state, 0x1c, lo6);
2449
2450 lo6 = tune->tuner_enable;
2451 if (state->config->analog_output)
2452 lo6 = (lo6 & 0xff9f) | 0x2;
2453
2454 dib0090_write_reg(state, 0x24, lo6 | EN_LO | state->config->use_pwm_agc * EN_CRYSTAL);
2455
2456 }
2457
2458 state->current_rf = state->rf_request;
2459 state->current_standard = state->fe->dtv_property_cache.delivery_system;
2460
2461 ret = 20;
2462 state->calibrate = CAPTRIM_CAL;
2463 }
2464
2465 else if (*tune_state == CT_TUNER_STEP_0) {
2466 const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
2467
2468 while (state->current_rf / 1000 > wbd->max_freq)
2469 wbd++;
2470
2471 dib0090_write_reg(state, 0x1e, 0x07ff);
2472 dprintk("Final Captrim: %d\n", (u32) state->fcaptrim);
2473 dprintk("HFDIV code: %d\n", (u32) pll->hfdiv_code);
2474 dprintk("VCO = %d\n", (u32) pll->vco_band);
2475 dprintk("VCOF in kHz: %d ((%d*%d) << 1))\n", (u32) ((pll->hfdiv * state->rf_request) * 2), (u32) pll->hfdiv, (u32) state->rf_request);
2476 dprintk("REFDIV: %d, FREF: %d\n", (u32) 1, (u32) state->config->io.clock_khz);
2477 dprintk("FBDIV: %d, Rest: %d\n", (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17));
2478 dprintk("Num: %d, Den: %d, SD: %d\n", (u32) dib0090_read_reg(state, 0x17), (u32) (dib0090_read_reg(state, 0x16) >> 8),
2479 (u32) dib0090_read_reg(state, 0x1c) & 0x3);
2480
2481#define WBD 0x781
2482 c = 4;
2483 i = 3;
2484
2485 if (wbd->wbd_gain != 0)
2486 c = wbd->wbd_gain;
2487
2488 state->wbdmux = (c << 13) | (i << 11) | (WBD | (state->config->use_pwm_agc << 1));
2489 dib0090_write_reg(state, 0x10, state->wbdmux);
2490
2491 if ((tune->tuner_enable == EN_CAB) && state->identity.p1g) {
2492 dprintk("P1G : The cable band is selected and lna_tune = %d\n", tune->lna_tune);
2493 dib0090_write_reg(state, 0x09, tune->lna_bias);
2494 dib0090_write_reg(state, 0x0b, 0xb800 | (tune->lna_tune << 6) | (tune->switch_trim));
2495 } else
2496 dib0090_write_reg(state, 0x09, (tune->lna_tune << 5) | tune->lna_bias);
2497
2498 dib0090_write_reg(state, 0x0c, tune->v2i);
2499 dib0090_write_reg(state, 0x0d, tune->mix);
2500 dib0090_write_reg(state, 0x0e, tune->load);
2501 *tune_state = CT_TUNER_STEP_1;
2502
2503 } else if (*tune_state == CT_TUNER_STEP_1) {
2504
2505 state->rf_lt_def = 0x7c00;
2506
2507 dib0090_set_bandwidth(state);
2508 state->tuner_is_tuned = 1;
2509
2510 state->calibrate |= WBD_CAL;
2511 state->calibrate |= TEMP_CAL;
2512 *tune_state = CT_TUNER_STOP;
2513 } else
2514 ret = FE_CALLBACK_TIME_NEVER;
2515 return ret;
2516}
2517
2518static void dib0090_release(struct dvb_frontend *fe)
2519{
2520 kfree(fe->tuner_priv);
2521 fe->tuner_priv = NULL;
2522}
2523
2524enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe)
2525{
2526 struct dib0090_state *state = fe->tuner_priv;
2527
2528 return state->tune_state;
2529}
2530
2531EXPORT_SYMBOL(dib0090_get_tune_state);
2532
2533int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
2534{
2535 struct dib0090_state *state = fe->tuner_priv;
2536
2537 state->tune_state = tune_state;
2538 return 0;
2539}
2540
2541EXPORT_SYMBOL(dib0090_set_tune_state);
2542
2543static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency)
2544{
2545 struct dib0090_state *state = fe->tuner_priv;
2546
2547 *frequency = 1000 * state->current_rf;
2548 return 0;
2549}
2550
2551static int dib0090_set_params(struct dvb_frontend *fe)
2552{
2553 struct dib0090_state *state = fe->tuner_priv;
2554 u32 ret;
2555
2556 state->tune_state = CT_TUNER_START;
2557
2558 do {
2559 ret = dib0090_tune(fe);
2560 if (ret == FE_CALLBACK_TIME_NEVER)
2561 break;
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571 ret = 10 * (ret + 99)/100;
2572 usleep_range(ret * 1000, (ret + 1) * 1000);
2573 } while (state->tune_state != CT_TUNER_STOP);
2574
2575 return 0;
2576}
2577
2578static const struct dvb_tuner_ops dib0090_ops = {
2579 .info = {
2580 .name = "DiBcom DiB0090",
2581 .frequency_min = 45000000,
2582 .frequency_max = 860000000,
2583 .frequency_step = 1000,
2584 },
2585 .release = dib0090_release,
2586
2587 .init = dib0090_wakeup,
2588 .sleep = dib0090_sleep,
2589 .set_params = dib0090_set_params,
2590 .get_frequency = dib0090_get_frequency,
2591};
2592
2593static const struct dvb_tuner_ops dib0090_fw_ops = {
2594 .info = {
2595 .name = "DiBcom DiB0090",
2596 .frequency_min = 45000000,
2597 .frequency_max = 860000000,
2598 .frequency_step = 1000,
2599 },
2600 .release = dib0090_release,
2601
2602 .init = NULL,
2603 .sleep = NULL,
2604 .set_params = NULL,
2605 .get_frequency = NULL,
2606};
2607
2608static const struct dib0090_wbd_slope dib0090_wbd_table_default[] = {
2609 {470, 0, 250, 0, 100, 4},
2610 {860, 51, 866, 21, 375, 4},
2611 {1700, 0, 800, 0, 850, 4},
2612 {2900, 0, 250, 0, 100, 6},
2613 {0xFFFF, 0, 0, 0, 0, 0},
2614};
2615
2616struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
2617{
2618 struct dib0090_state *st = kzalloc(sizeof(struct dib0090_state), GFP_KERNEL);
2619 if (st == NULL)
2620 return NULL;
2621
2622 st->config = config;
2623 st->i2c = i2c;
2624 st->fe = fe;
2625 mutex_init(&st->i2c_buffer_lock);
2626 fe->tuner_priv = st;
2627
2628 if (config->wbd == NULL)
2629 st->current_wbd_table = dib0090_wbd_table_default;
2630 else
2631 st->current_wbd_table = config->wbd;
2632
2633 if (dib0090_reset(fe) != 0)
2634 goto free_mem;
2635
2636 pr_info("DiB0090: successfully identified\n");
2637 memcpy(&fe->ops.tuner_ops, &dib0090_ops, sizeof(struct dvb_tuner_ops));
2638
2639 return fe;
2640 free_mem:
2641 kfree(st);
2642 fe->tuner_priv = NULL;
2643 return NULL;
2644}
2645
2646EXPORT_SYMBOL(dib0090_register);
2647
2648struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
2649{
2650 struct dib0090_fw_state *st = kzalloc(sizeof(struct dib0090_fw_state), GFP_KERNEL);
2651 if (st == NULL)
2652 return NULL;
2653
2654 st->config = config;
2655 st->i2c = i2c;
2656 st->fe = fe;
2657 mutex_init(&st->i2c_buffer_lock);
2658 fe->tuner_priv = st;
2659
2660 if (dib0090_fw_reset_digital(fe, st->config) != 0)
2661 goto free_mem;
2662
2663 dprintk("DiB0090 FW: successfully identified\n");
2664 memcpy(&fe->ops.tuner_ops, &dib0090_fw_ops, sizeof(struct dvb_tuner_ops));
2665
2666 return fe;
2667free_mem:
2668 kfree(st);
2669 fe->tuner_priv = NULL;
2670 return NULL;
2671}
2672EXPORT_SYMBOL(dib0090_fw_register);
2673
2674MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
2675MODULE_AUTHOR("Olivier Grenie <olivier.grenie@parrot.com>");
2676MODULE_DESCRIPTION("Driver for the DiBcom 0090 base-band RF Tuner");
2677MODULE_LICENSE("GPL");
2678