- patches.suse/slab-handle-memoryless-nodes-v2a.patch: Refresh.
[linux-flexiantxendom0-3.2.10.git] / drivers / media / dvb / frontends / dib0090.c
1 /*
2  * Linux-DVB Driver for DiBcom's DiB0090 base-band RF Tuner.
3  *
4  * Copyright (C) 2005-9 DiBcom (http://www.dibcom.fr/)
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of the
9  * License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  *
21  *
22  * This code is more or less generated from another driver, please
23  * excuse some codingstyle oddities.
24  *
25  */
26
27 #include <linux/kernel.h>
28 #include <linux/i2c.h>
29
30 #include "dvb_frontend.h"
31
32 #include "dib0090.h"
33 #include "dibx000_common.h"
34
35 static int debug;
36 module_param(debug, int, 0644);
37 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
38
39 #define dprintk(args...) do { \
40         if (debug) { \
41                 printk(KERN_DEBUG "DiB0090: "); \
42                 printk(args); \
43                 printk("\n"); \
44         } \
45 } while (0)
46
47 #define CONFIG_SYS_ISDBT
48 #define CONFIG_BAND_CBAND
49 #define CONFIG_BAND_VHF
50 #define CONFIG_BAND_UHF
51 #define CONFIG_DIB0090_USE_PWM_AGC
52
53 #define EN_LNA0      0x8000
54 #define EN_LNA1      0x4000
55 #define EN_LNA2      0x2000
56 #define EN_LNA3      0x1000
57 #define EN_MIX0      0x0800
58 #define EN_MIX1      0x0400
59 #define EN_MIX2      0x0200
60 #define EN_MIX3      0x0100
61 #define EN_IQADC     0x0040
62 #define EN_PLL       0x0020
63 #define EN_TX        0x0010
64 #define EN_BB        0x0008
65 #define EN_LO        0x0004
66 #define EN_BIAS      0x0001
67
68 #define EN_IQANA     0x0002
69 #define EN_DIGCLK    0x0080     /* not in the 0x24 reg, only in 0x1b */
70 #define EN_CRYSTAL   0x0002
71
72 #define EN_UHF           0x22E9
73 #define EN_VHF           0x44E9
74 #define EN_LBD           0x11E9
75 #define EN_SBD           0x44E9
76 #define EN_CAB           0x88E9
77
78 #define pgm_read_word(w) (*w)
79
80 struct dc_calibration;
81
82 struct dib0090_tuning {
83         u32 max_freq;           /* for every frequency less than or equal to that field: this information is correct */
84         u8 switch_trim;
85         u8 lna_tune;
86         u8 lna_bias;
87         u16 v2i;
88         u16 mix;
89         u16 load;
90         u16 tuner_enable;
91 };
92
93 struct dib0090_pll {
94         u32 max_freq;           /* for every frequency less than or equal to that field: this information is correct */
95         u8 vco_band;
96         u8 hfdiv_code;
97         u8 hfdiv;
98         u8 topresc;
99 };
100
101 struct dib0090_state {
102         struct i2c_adapter *i2c;
103         struct dvb_frontend *fe;
104         const struct dib0090_config *config;
105
106         u8 current_band;
107         u16 revision;
108         enum frontend_tune_state tune_state;
109         u32 current_rf;
110
111         u16 wbd_offset;
112         s16 wbd_target;         /* in dB */
113
114         s16 rf_gain_limit;      /* take-over-point: where to split between bb and rf gain */
115         s16 current_gain;       /* keeps the currently programmed gain */
116         u8 agc_step;            /* new binary search */
117
118         u16 gain[2];            /* for channel monitoring */
119
120         const u16 *rf_ramp;
121         const u16 *bb_ramp;
122
123         /* for the software AGC ramps */
124         u16 bb_1_def;
125         u16 rf_lt_def;
126         u16 gain_reg[4];
127
128         /* for the captrim/dc-offset search */
129         s8 step;
130         s16 adc_diff;
131         s16 min_adc_diff;
132
133         s8 captrim;
134         s8 fcaptrim;
135
136         const struct dc_calibration *dc;
137         u16 bb6, bb7;
138
139         const struct dib0090_tuning *current_tune_table_index;
140         const struct dib0090_pll *current_pll_table_index;
141
142         u8 tuner_is_tuned;
143         u8 agc_freeze;
144
145         u8 reset;
146 };
147
148 static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg)
149 {
150         u8 b[2];
151         struct i2c_msg msg[2] = {
152                 {.addr = state->config->i2c_address, .flags = 0, .buf = &reg, .len = 1},
153                 {.addr = state->config->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2},
154         };
155         if (i2c_transfer(state->i2c, msg, 2) != 2) {
156                 printk(KERN_WARNING "DiB0090 I2C read failed\n");
157                 return 0;
158         }
159         return (b[0] << 8) | b[1];
160 }
161
162 static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
163 {
164         u8 b[3] = { reg & 0xff, val >> 8, val & 0xff };
165         struct i2c_msg msg = {.addr = state->config->i2c_address, .flags = 0, .buf = b, .len = 3 };
166         if (i2c_transfer(state->i2c, &msg, 1) != 1) {
167                 printk(KERN_WARNING "DiB0090 I2C write failed\n");
168                 return -EREMOTEIO;
169         }
170         return 0;
171 }
172
173 #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)
174 #define ADC_TARGET -220
175 #define GAIN_ALPHA 5
176 #define WBD_ALPHA 6
177 #define LPF     100
178 static void dib0090_write_regs(struct dib0090_state *state, u8 r, const u16 * b, u8 c)
179 {
180         do {
181                 dib0090_write_reg(state, r++, *b++);
182         } while (--c);
183 }
184
185 static u16 dib0090_identify(struct dvb_frontend *fe)
186 {
187         struct dib0090_state *state = fe->tuner_priv;
188         u16 v;
189
190         v = dib0090_read_reg(state, 0x1a);
191
192 #ifdef FIRMWARE_FIREFLY
193         /* pll is not locked locked */
194         if (!(v & 0x800))
195                 dprintk("FE%d : Identification : pll is not yet locked", fe->id);
196 #endif
197
198         /* without PLL lock info */
199         v &= 0x3ff;
200         dprintk("P/V: %04x:", v);
201
202         if ((v >> 8) & 0xf)
203                 dprintk("FE%d : Product ID = 0x%x : KROSUS", fe->id, (v >> 8) & 0xf);
204         else
205                 return 0xff;
206
207         v &= 0xff;
208         if (((v >> 5) & 0x7) == 0x1)
209                 dprintk("FE%d : MP001 : 9090/8096", fe->id);
210         else if (((v >> 5) & 0x7) == 0x4)
211                 dprintk("FE%d : MP005 : Single Sband", fe->id);
212         else if (((v >> 5) & 0x7) == 0x6)
213                 dprintk("FE%d : MP008 : diversity VHF-UHF-LBAND", fe->id);
214         else if (((v >> 5) & 0x7) == 0x7)
215                 dprintk("FE%d : MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND", fe->id);
216         else
217                 return 0xff;
218
219         /* revision only */
220         if ((v & 0x1f) == 0x3)
221                 dprintk("FE%d : P1-D/E/F detected", fe->id);
222         else if ((v & 0x1f) == 0x1)
223                 dprintk("FE%d : P1C detected", fe->id);
224         else if ((v & 0x1f) == 0x0) {
225 #ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT
226                 dprintk("FE%d : P1-A/B detected: using previous driver - support will be removed soon", fe->id);
227                 dib0090_p1b_register(fe);
228 #else
229                 dprintk("FE%d : P1-A/B detected: driver is deactivated - not available", fe->id);
230                 return 0xff;
231 #endif
232         }
233
234         return v;
235 }
236
237 static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
238 {
239         struct dib0090_state *state = fe->tuner_priv;
240
241         HARD_RESET(state);
242
243         dib0090_write_reg(state, 0x24, EN_PLL);
244         dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL);        /* PLL, DIG_CLK and CRYSTAL remain */
245
246         /* adcClkOutRatio=8->7, release reset */
247         dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0);
248         if (cfg->clkoutdrive != 0)
249                 dib0090_write_reg(state, 0x23,
250                                   (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 10) | (1 << 9) | (0 << 8) | (cfg->clkoutdrive << 5) | (cfg->
251                                                                                                                                            clkouttobamse
252                                                                                                                                            << 4) | (0
253                                                                                                                                                     <<
254                                                                                                                                                     2)
255                                   | (0));
256         else
257                 dib0090_write_reg(state, 0x23,
258                                   (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 10) | (1 << 9) | (0 << 8) | (7 << 5) | (cfg->
259                                                                                                                             clkouttobamse << 4) | (0
260                                                                                                                                                    <<
261                                                                                                                                                    2)
262                                   | (0));
263
264         /* enable pll, de-activate reset, ratio: 2/1 = 60MHz */
265         dib0090_write_reg(state, 0x21,
266                           (cfg->io.pll_bypass << 15) | (1 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv));
267
268 }
269
270 static int dib0090_wakeup(struct dvb_frontend *fe)
271 {
272         struct dib0090_state *state = fe->tuner_priv;
273         if (state->config->sleep)
274                 state->config->sleep(fe, 0);
275         return 0;
276 }
277
278 static int dib0090_sleep(struct dvb_frontend *fe)
279 {
280         struct dib0090_state *state = fe->tuner_priv;
281         if (state->config->sleep)
282                 state->config->sleep(fe, 1);
283         return 0;
284 }
285
286 extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
287 {
288         struct dib0090_state *state = fe->tuner_priv;
289         if (fast)
290                 dib0090_write_reg(state, 0x04, 0);
291         else
292                 dib0090_write_reg(state, 0x04, 1);
293 }
294 EXPORT_SYMBOL(dib0090_dcc_freq);
295
296 static const u16 rf_ramp_pwm_cband[] = {
297         0,                      /* max RF gain in 10th of dB */
298         0,                      /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
299         0,                      /* ramp_max = maximum X used on the ramp */
300         (0 << 10) | 0,          /* 0x2c, LNA 1 = 0dB */
301         (0 << 10) | 0,          /* 0x2d, LNA 1 */
302         (0 << 10) | 0,          /* 0x2e, LNA 2 = 0dB */
303         (0 << 10) | 0,          /* 0x2f, LNA 2 */
304         (0 << 10) | 0,          /* 0x30, LNA 3 = 0dB */
305         (0 << 10) | 0,          /* 0x31, LNA 3 */
306         (0 << 10) | 0,          /* GAIN_4_1, LNA 4 = 0dB */
307         (0 << 10) | 0,          /* GAIN_4_2, LNA 4 */
308 };
309
310 static const u16 rf_ramp_vhf[] = {
311         412,                    /* max RF gain in 10th of dB */
312         132, 307, 127,          /* LNA1,  13.2dB */
313         105, 412, 255,          /* LNA2,  10.5dB */
314         50, 50, 127,            /* LNA3,  5dB */
315         125, 175, 127,          /* LNA4,  12.5dB */
316         0, 0, 127,              /* CBAND, 0dB */
317 };
318
319 static const u16 rf_ramp_uhf[] = {
320         412,                    /* max RF gain in 10th of dB */
321         132, 307, 127,          /* LNA1  : total gain = 13.2dB, point on the ramp where this amp is full gain, value to write to get full gain */
322         105, 412, 255,          /* LNA2  : 10.5 dB */
323         50, 50, 127,            /* LNA3  :  5.0 dB */
324         125, 175, 127,          /* LNA4  : 12.5 dB */
325         0, 0, 127,              /* CBAND :  0.0 dB */
326 };
327
328 static const u16 rf_ramp_cband[] = {
329         332,                    /* max RF gain in 10th of dB */
330         132, 252, 127,          /* LNA1,  dB */
331         80, 332, 255,           /* LNA2,  dB */
332         0, 0, 127,              /* LNA3,  dB */
333         0, 0, 127,              /* LNA4,  dB */
334         120, 120, 127,          /* LT1 CBAND */
335 };
336
337 static const u16 rf_ramp_pwm_vhf[] = {
338         404,                    /* max RF gain in 10th of dB */
339         25,                     /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
340         1011,                   /* ramp_max = maximum X used on the ramp */
341         (6 << 10) | 417,        /* 0x2c, LNA 1 = 13.2dB */
342         (0 << 10) | 756,        /* 0x2d, LNA 1 */
343         (16 << 10) | 756,       /* 0x2e, LNA 2 = 10.5dB */
344         (0 << 10) | 1011,       /* 0x2f, LNA 2 */
345         (16 << 10) | 290,       /* 0x30, LNA 3 = 5dB */
346         (0 << 10) | 417,        /* 0x31, LNA 3 */
347         (7 << 10) | 0,          /* GAIN_4_1, LNA 4 = 12.5dB */
348         (0 << 10) | 290,        /* GAIN_4_2, LNA 4 */
349 };
350
351 static const u16 rf_ramp_pwm_uhf[] = {
352         404,                    /* max RF gain in 10th of dB */
353         25,                     /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
354         1011,                   /* ramp_max = maximum X used on the ramp */
355         (6 << 10) | 417,        /* 0x2c, LNA 1 = 13.2dB */
356         (0 << 10) | 756,        /* 0x2d, LNA 1 */
357         (16 << 10) | 756,       /* 0x2e, LNA 2 = 10.5dB */
358         (0 << 10) | 1011,       /* 0x2f, LNA 2 */
359         (16 << 10) | 0,         /* 0x30, LNA 3 = 5dB */
360         (0 << 10) | 127,        /* 0x31, LNA 3 */
361         (7 << 10) | 127,        /* GAIN_4_1, LNA 4 = 12.5dB */
362         (0 << 10) | 417,        /* GAIN_4_2, LNA 4 */
363 };
364
365 static const u16 bb_ramp_boost[] = {
366         550,                    /* max BB gain in 10th of dB */
367         260, 260, 26,           /* BB1, 26dB */
368         290, 550, 29,           /* BB2, 29dB */
369 };
370
371 static const u16 bb_ramp_pwm_normal[] = {
372         500,                    /* max RF gain in 10th of dB */
373         8,                      /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x34 */
374         400,
375         (2 << 9) | 0,           /* 0x35 = 21dB */
376         (0 << 9) | 168,         /* 0x36 */
377         (2 << 9) | 168,         /* 0x37 = 29dB */
378         (0 << 9) | 400,         /* 0x38 */
379 };
380
381 struct slope {
382         int16_t range;
383         int16_t slope;
384 };
385 static u16 slopes_to_scale(const struct slope *slopes, u8 num, s16 val)
386 {
387         u8 i;
388         u16 rest;
389         u16 ret = 0;
390         for (i = 0; i < num; i++) {
391                 if (val > slopes[i].range)
392                         rest = slopes[i].range;
393                 else
394                         rest = val;
395                 ret += (rest * slopes[i].slope) / slopes[i].range;
396                 val -= rest;
397         }
398         return ret;
399 }
400
401 static const struct slope dib0090_wbd_slopes[3] = {
402         {66, 120},              /* -64,-52: offset -   65 */
403         {600, 170},             /* -52,-35: 65     -  665 */
404         {170, 250},             /* -45,-10: 665    - 835 */
405 };
406
407 static s16 dib0090_wbd_to_db(struct dib0090_state *state, u16 wbd)
408 {
409         wbd &= 0x3ff;
410         if (wbd < state->wbd_offset)
411                 wbd = 0;
412         else
413                 wbd -= state->wbd_offset;
414         /* -64dB is the floor */
415         return -640 + (s16) slopes_to_scale(dib0090_wbd_slopes, ARRAY_SIZE(dib0090_wbd_slopes), wbd);
416 }
417
418 static void dib0090_wbd_target(struct dib0090_state *state, u32 rf)
419 {
420         u16 offset = 250;
421
422         /* TODO : DAB digital N+/-1 interferer perfs : offset = 10 */
423
424         if (state->current_band == BAND_VHF)
425                 offset = 650;
426 #ifndef FIRMWARE_FIREFLY
427         if (state->current_band == BAND_VHF)
428                 offset = state->config->wbd_vhf_offset;
429         if (state->current_band == BAND_CBAND)
430                 offset = state->config->wbd_cband_offset;
431 #endif
432
433         state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + offset);
434         dprintk("wbd-target: %d dB", (u32) state->wbd_target);
435 }
436
437 static const int gain_reg_addr[4] = {
438         0x08, 0x0a, 0x0f, 0x01
439 };
440
441 static void dib0090_gain_apply(struct dib0090_state *state, s16 gain_delta, s16 top_delta, u8 force)
442 {
443         u16 rf, bb, ref;
444         u16 i, v, gain_reg[4] = { 0 }, gain;
445         const u16 *g;
446
447         if (top_delta < -511)
448                 top_delta = -511;
449         if (top_delta > 511)
450                 top_delta = 511;
451
452         if (force) {
453                 top_delta *= (1 << WBD_ALPHA);
454                 gain_delta *= (1 << GAIN_ALPHA);
455         }
456
457         if (top_delta >= ((s16) (state->rf_ramp[0] << WBD_ALPHA) - state->rf_gain_limit))       /* overflow */
458                 state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
459         else
460                 state->rf_gain_limit += top_delta;
461
462         if (state->rf_gain_limit < 0)   /*underflow */
463                 state->rf_gain_limit = 0;
464
465         /* use gain as a temporary variable and correct current_gain */
466         gain = ((state->rf_gain_limit >> WBD_ALPHA) + state->bb_ramp[0]) << GAIN_ALPHA;
467         if (gain_delta >= ((s16) gain - state->current_gain))   /* overflow */
468                 state->current_gain = gain;
469         else
470                 state->current_gain += gain_delta;
471         /* cannot be less than 0 (only if gain_delta is less than 0 we can have current_gain < 0) */
472         if (state->current_gain < 0)
473                 state->current_gain = 0;
474
475         /* now split total gain to rf and bb gain */
476         gain = state->current_gain >> GAIN_ALPHA;
477
478         /* requested gain is bigger than rf gain limit - ACI/WBD adjustment */
479         if (gain > (state->rf_gain_limit >> WBD_ALPHA)) {
480                 rf = state->rf_gain_limit >> WBD_ALPHA;
481                 bb = gain - rf;
482                 if (bb > state->bb_ramp[0])
483                         bb = state->bb_ramp[0];
484         } else {                /* high signal level -> all gains put on RF */
485                 rf = gain;
486                 bb = 0;
487         }
488
489         state->gain[0] = rf;
490         state->gain[1] = bb;
491
492         /* software ramp */
493         /* Start with RF gains */
494         g = state->rf_ramp + 1; /* point on RF LNA1 max gain */
495         ref = rf;
496         for (i = 0; i < 7; i++) {       /* Go over all amplifiers => 5RF amps + 2 BB amps = 7 amps */
497                 if (g[0] == 0 || ref < (g[1] - g[0]))   /* if total gain of the current amp is null or this amp is not concerned because it starts to work from an higher gain value */
498                         v = 0;  /* force the gain to write for the current amp to be null */
499                 else if (ref >= g[1])   /* Gain to set is higher than the high working point of this amp */
500                         v = g[2];       /* force this amp to be full gain */
501                 else            /* compute the value to set to this amp because we are somewhere in his range */
502                         v = ((ref - (g[1] - g[0])) * g[2]) / g[0];
503
504                 if (i == 0)     /* LNA 1 reg mapping */
505                         gain_reg[0] = v;
506                 else if (i == 1)        /* LNA 2 reg mapping */
507                         gain_reg[0] |= v << 7;
508                 else if (i == 2)        /* LNA 3 reg mapping */
509                         gain_reg[1] = v;
510                 else if (i == 3)        /* LNA 4 reg mapping */
511                         gain_reg[1] |= v << 7;
512                 else if (i == 4)        /* CBAND LNA reg mapping */
513                         gain_reg[2] = v | state->rf_lt_def;
514                 else if (i == 5)        /* BB gain 1 reg mapping */
515                         gain_reg[3] = v << 3;
516                 else if (i == 6)        /* BB gain 2 reg mapping */
517                         gain_reg[3] |= v << 8;
518
519                 g += 3;         /* go to next gain bloc */
520
521                 /* When RF is finished, start with BB */
522                 if (i == 4) {
523                         g = state->bb_ramp + 1; /* point on BB gain 1 max gain */
524                         ref = bb;
525                 }
526         }
527         gain_reg[3] |= state->bb_1_def;
528         gain_reg[3] |= ((bb % 10) * 100) / 125;
529
530 #ifdef DEBUG_AGC
531         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", rf, bb, rf + bb,
532                 gain_reg[0], gain_reg[1], gain_reg[2], gain_reg[3]);
533 #endif
534
535         /* Write the amplifier regs */
536         for (i = 0; i < 4; i++) {
537                 v = gain_reg[i];
538                 if (force || state->gain_reg[i] != v) {
539                         state->gain_reg[i] = v;
540                         dib0090_write_reg(state, gain_reg_addr[i], v);
541                 }
542         }
543 }
544
545 static void dib0090_set_boost(struct dib0090_state *state, int onoff)
546 {
547         state->bb_1_def &= 0xdfff;
548         state->bb_1_def |= onoff << 13;
549 }
550
551 static void dib0090_set_rframp(struct dib0090_state *state, const u16 * cfg)
552 {
553         state->rf_ramp = cfg;
554 }
555
556 static void dib0090_set_rframp_pwm(struct dib0090_state *state, const u16 * cfg)
557 {
558         state->rf_ramp = cfg;
559
560         dib0090_write_reg(state, 0x2a, 0xffff);
561
562         dprintk("total RF gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x2a));
563
564         dib0090_write_regs(state, 0x2c, cfg + 3, 6);
565         dib0090_write_regs(state, 0x3e, cfg + 9, 2);
566 }
567
568 static void dib0090_set_bbramp(struct dib0090_state *state, const u16 * cfg)
569 {
570         state->bb_ramp = cfg;
571         dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */
572 }
573
574 static void dib0090_set_bbramp_pwm(struct dib0090_state *state, const u16 * cfg)
575 {
576         state->bb_ramp = cfg;
577
578         dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */
579
580         dib0090_write_reg(state, 0x33, 0xffff);
581         dprintk("total BB gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x33));
582         dib0090_write_regs(state, 0x35, cfg + 3, 4);
583 }
584
585 void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
586 {
587         struct dib0090_state *state = fe->tuner_priv;
588         /* reset the AGC */
589
590         if (state->config->use_pwm_agc) {
591 #ifdef CONFIG_BAND_SBAND
592                 if (state->current_band == BAND_SBAND) {
593                         dib0090_set_rframp_pwm(state, rf_ramp_pwm_sband);
594                         dib0090_set_bbramp_pwm(state, bb_ramp_pwm_boost);
595                 } else
596 #endif
597 #ifdef CONFIG_BAND_CBAND
598                 if (state->current_band == BAND_CBAND) {
599                         dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband);
600                         dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
601                 } else
602 #endif
603 #ifdef CONFIG_BAND_VHF
604                 if (state->current_band == BAND_VHF) {
605                         dib0090_set_rframp_pwm(state, rf_ramp_pwm_vhf);
606                         dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
607                 } else
608 #endif
609                 {
610                         dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf);
611                         dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
612                 }
613
614                 if (state->rf_ramp[0] != 0)
615                         dib0090_write_reg(state, 0x32, (3 << 11));
616                 else
617                         dib0090_write_reg(state, 0x32, (0 << 11));
618
619                 dib0090_write_reg(state, 0x39, (1 << 10));
620         }
621 }
622 EXPORT_SYMBOL(dib0090_pwm_gain_reset);
623
624 int dib0090_gain_control(struct dvb_frontend *fe)
625 {
626         struct dib0090_state *state = fe->tuner_priv;
627         enum frontend_tune_state *tune_state = &state->tune_state;
628         int ret = 10;
629
630         u16 wbd_val = 0;
631         u8 apply_gain_immediatly = 1;
632         s16 wbd_error = 0, adc_error = 0;
633
634         if (*tune_state == CT_AGC_START) {
635                 state->agc_freeze = 0;
636                 dib0090_write_reg(state, 0x04, 0x0);
637
638 #ifdef CONFIG_BAND_SBAND
639                 if (state->current_band == BAND_SBAND) {
640                         dib0090_set_rframp(state, rf_ramp_sband);
641                         dib0090_set_bbramp(state, bb_ramp_boost);
642                 } else
643 #endif
644 #ifdef CONFIG_BAND_VHF
645                 if (state->current_band == BAND_VHF) {
646                         dib0090_set_rframp(state, rf_ramp_vhf);
647                         dib0090_set_bbramp(state, bb_ramp_boost);
648                 } else
649 #endif
650 #ifdef CONFIG_BAND_CBAND
651                 if (state->current_band == BAND_CBAND) {
652                         dib0090_set_rframp(state, rf_ramp_cband);
653                         dib0090_set_bbramp(state, bb_ramp_boost);
654                 } else
655 #endif
656                 {
657                         dib0090_set_rframp(state, rf_ramp_uhf);
658                         dib0090_set_bbramp(state, bb_ramp_boost);
659                 }
660
661                 dib0090_write_reg(state, 0x32, 0);
662                 dib0090_write_reg(state, 0x39, 0);
663
664                 dib0090_wbd_target(state, state->current_rf);
665
666                 state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
667                 state->current_gain = ((state->rf_ramp[0] + state->bb_ramp[0]) / 2) << GAIN_ALPHA;
668
669                 *tune_state = CT_AGC_STEP_0;
670         } else if (!state->agc_freeze) {
671                 s16 wbd;
672
673                 int adc;
674                 wbd_val = dib0090_read_reg(state, 0x1d);
675
676                 /* read and calc the wbd power */
677                 wbd = dib0090_wbd_to_db(state, wbd_val);
678                 wbd_error = state->wbd_target - wbd;
679
680                 if (*tune_state == CT_AGC_STEP_0) {
681                         if (wbd_error < 0 && state->rf_gain_limit > 0) {
682 #ifdef CONFIG_BAND_CBAND
683                                 /* in case of CBAND tune reduce first the lt_gain2 before adjusting the RF gain */
684                                 u8 ltg2 = (state->rf_lt_def >> 10) & 0x7;
685                                 if (state->current_band == BAND_CBAND && ltg2) {
686                                         ltg2 >>= 1;
687                                         state->rf_lt_def &= ltg2 << 10; /* reduce in 3 steps from 7 to 0 */
688                                 }
689 #endif
690                         } else {
691                                 state->agc_step = 0;
692                                 *tune_state = CT_AGC_STEP_1;
693                         }
694                 } else {
695                         /* calc the adc power */
696                         adc = state->config->get_adc_power(fe);
697                         adc = (adc * ((s32) 355774) + (((s32) 1) << 20)) >> 21; /* included in [0:-700] */
698
699                         adc_error = (s16) (((s32) ADC_TARGET) - adc);
700 #ifdef CONFIG_STANDARD_DAB
701                         if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB)
702                                 adc_error += 130;
703 #endif
704 #ifdef CONFIG_STANDARD_DVBT
705                         if (state->fe->dtv_property_cache.delivery_system == STANDARD_DVBT &&
706                             (state->fe->dtv_property_cache.modulation == QAM_64 || state->fe->dtv_property_cache.modulation == QAM_16))
707                                 adc_error += 60;
708 #endif
709 #ifdef CONFIG_SYS_ISDBT
710                         if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) && (((state->fe->dtv_property_cache.layer[0].segment_count >
711                                                                                                0)
712                                                                                               &&
713                                                                                               ((state->fe->dtv_property_cache.layer[0].modulation ==
714                                                                                                 QAM_64)
715                                                                                                || (state->fe->dtv_property_cache.layer[0].
716                                                                                                    modulation == QAM_16)))
717                                                                                              ||
718                                                                                              ((state->fe->dtv_property_cache.layer[1].segment_count >
719                                                                                                0)
720                                                                                               &&
721                                                                                               ((state->fe->dtv_property_cache.layer[1].modulation ==
722                                                                                                 QAM_64)
723                                                                                                || (state->fe->dtv_property_cache.layer[1].
724                                                                                                    modulation == QAM_16)))
725                                                                                              ||
726                                                                                              ((state->fe->dtv_property_cache.layer[2].segment_count >
727                                                                                                0)
728                                                                                               &&
729                                                                                               ((state->fe->dtv_property_cache.layer[2].modulation ==
730                                                                                                 QAM_64)
731                                                                                                || (state->fe->dtv_property_cache.layer[2].
732                                                                                                    modulation == QAM_16)))
733                             )
734                             )
735                                 adc_error += 60;
736 #endif
737
738                         if (*tune_state == CT_AGC_STEP_1) {     /* quickly go to the correct range of the ADC power */
739                                 if (ABS(adc_error) < 50 || state->agc_step++ > 5) {
740
741 #ifdef CONFIG_STANDARD_DAB
742                                         if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) {
743                                                 dib0090_write_reg(state, 0x02, (1 << 15) | (15 << 11) | (31 << 6) | (63));      /* cap value = 63 : narrow BB filter : Fc = 1.8MHz */
744                                                 dib0090_write_reg(state, 0x04, 0x0);
745                                         } else
746 #endif
747                                         {
748                                                 dib0090_write_reg(state, 0x02, (1 << 15) | (3 << 11) | (6 << 6) | (32));
749                                                 dib0090_write_reg(state, 0x04, 0x01);   /*0 = 1KHz ; 1 = 150Hz ; 2 = 50Hz ; 3 = 50KHz ; 4 = servo fast */
750                                         }
751
752                                         *tune_state = CT_AGC_STOP;
753                                 }
754                         } else {
755                                 /* everything higher than or equal to CT_AGC_STOP means tracking */
756                                 ret = 100;      /* 10ms interval */
757                                 apply_gain_immediatly = 0;
758                         }
759                 }
760 #ifdef DEBUG_AGC
761                 dprintk
762                     ("FE: %d, tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm",
763                      (u32) fe->id, (u32) *tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val,
764                      (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA));
765 #endif
766         }
767
768         /* apply gain */
769         if (!state->agc_freeze)
770                 dib0090_gain_apply(state, adc_error, wbd_error, apply_gain_immediatly);
771         return ret;
772 }
773 EXPORT_SYMBOL(dib0090_gain_control);
774
775 void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt)
776 {
777         struct dib0090_state *state = fe->tuner_priv;
778         if (rf)
779                 *rf = state->gain[0];
780         if (bb)
781                 *bb = state->gain[1];
782         if (rf_gain_limit)
783                 *rf_gain_limit = state->rf_gain_limit;
784         if (rflt)
785                 *rflt = (state->rf_lt_def >> 10) & 0x7;
786 }
787 EXPORT_SYMBOL(dib0090_get_current_gain);
788
789 u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner)
790 {
791         struct dib0090_state *st = tuner->tuner_priv;
792         return st->wbd_offset;
793 }
794 EXPORT_SYMBOL(dib0090_get_wbd_offset);
795
796 static const u16 dib0090_defaults[] = {
797
798         25, 0x01,
799         0x0000,
800         0x99a0,
801         0x6008,
802         0x0000,
803         0x8acb,
804         0x0000,
805         0x0405,
806         0x0000,
807         0x0000,
808         0x0000,
809         0xb802,
810         0x0300,
811         0x2d12,
812         0xbac0,
813         0x7c00,
814         0xdbb9,
815         0x0954,
816         0x0743,
817         0x8000,
818         0x0001,
819         0x0040,
820         0x0100,
821         0x0000,
822         0xe910,
823         0x149e,
824
825         1, 0x1c,
826         0xff2d,
827
828         1, 0x39,
829         0x0000,
830
831         1, 0x1b,
832         EN_IQADC | EN_BB | EN_BIAS | EN_DIGCLK | EN_PLL | EN_CRYSTAL,
833         2, 0x1e,
834         0x07FF,
835         0x0007,
836
837         1, 0x24,
838         EN_UHF | EN_CRYSTAL,
839
840         2, 0x3c,
841         0x3ff,
842         0x111,
843         0
844 };
845
846 static int dib0090_reset(struct dvb_frontend *fe)
847 {
848         struct dib0090_state *state = fe->tuner_priv;
849         u16 l, r, *n;
850
851         dib0090_reset_digital(fe, state->config);
852         state->revision = dib0090_identify(fe);
853
854         /* Revision definition */
855         if (state->revision == 0xff)
856                 return -EINVAL;
857 #ifdef EFUSE
858         else if ((state->revision & 0x1f) >= 3) /* Update the efuse : Only available for KROSUS > P1C */
859                 dib0090_set_EFUSE(state);
860 #endif
861
862 #ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT
863         if (!(state->revision & 0x1))   /* it is P1B - reset is already done */
864                 return 0;
865 #endif
866
867         /* Upload the default values */
868         n = (u16 *) dib0090_defaults;
869         l = pgm_read_word(n++);
870         while (l) {
871                 r = pgm_read_word(n++);
872                 do {
873                         /* DEBUG_TUNER */
874                         /* dprintk("%d, %d, %d", l, r, pgm_read_word(n)); */
875                         dib0090_write_reg(state, r, pgm_read_word(n++));
876                         r++;
877                 } while (--l);
878                 l = pgm_read_word(n++);
879         }
880
881         /* Congigure in function of the crystal */
882         if (state->config->io.clock_khz >= 24000)
883                 l = 1;
884         else
885                 l = 2;
886         dib0090_write_reg(state, 0x14, l);
887         dprintk("Pll lock : %d", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1);
888
889         state->reset = 3;       /* enable iq-offset-calibration and wbd-calibration when tuning next time */
890
891         return 0;
892 }
893
894 #define steps(u) (((u) > 15) ? ((u)-16) : (u))
895 #define INTERN_WAIT 10
896 static int dib0090_get_offset(struct dib0090_state *state, enum frontend_tune_state *tune_state)
897 {
898         int ret = INTERN_WAIT * 10;
899
900         switch (*tune_state) {
901         case CT_TUNER_STEP_2:
902                 /* Turns to positive */
903                 dib0090_write_reg(state, 0x1f, 0x7);
904                 *tune_state = CT_TUNER_STEP_3;
905                 break;
906
907         case CT_TUNER_STEP_3:
908                 state->adc_diff = dib0090_read_reg(state, 0x1d);
909
910                 /* Turns to negative */
911                 dib0090_write_reg(state, 0x1f, 0x4);
912                 *tune_state = CT_TUNER_STEP_4;
913                 break;
914
915         case CT_TUNER_STEP_4:
916                 state->adc_diff -= dib0090_read_reg(state, 0x1d);
917                 *tune_state = CT_TUNER_STEP_5;
918                 ret = 0;
919                 break;
920
921         default:
922                 break;
923         }
924
925         return ret;
926 }
927
928 struct dc_calibration {
929         uint8_t addr;
930         uint8_t offset;
931         uint8_t pga:1;
932         uint16_t bb1;
933         uint8_t i:1;
934 };
935
936 static const struct dc_calibration dc_table[] = {
937         /* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */
938         {0x06, 5, 1, (1 << 13) | (0 << 8) | (26 << 3), 1},
939         {0x07, 11, 1, (1 << 13) | (0 << 8) | (26 << 3), 0},
940         /* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */
941         {0x06, 0, 0, (1 << 13) | (29 << 8) | (26 << 3), 1},
942         {0x06, 10, 0, (1 << 13) | (29 << 8) | (26 << 3), 0},
943         {0},
944 };
945
946 static void dib0090_set_trim(struct dib0090_state *state)
947 {
948         u16 *val;
949
950         if (state->dc->addr == 0x07)
951                 val = &state->bb7;
952         else
953                 val = &state->bb6;
954
955         *val &= ~(0x1f << state->dc->offset);
956         *val |= state->step << state->dc->offset;
957
958         dib0090_write_reg(state, state->dc->addr, *val);
959 }
960
961 static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
962 {
963         int ret = 0;
964
965         switch (*tune_state) {
966
967         case CT_TUNER_START:
968                 /* init */
969                 dprintk("Internal DC calibration");
970
971                 /* the LNA is off */
972                 dib0090_write_reg(state, 0x24, 0x02ed);
973
974                 /* force vcm2 = 0.8V */
975                 state->bb6 = 0;
976                 state->bb7 = 0x040d;
977
978                 state->dc = dc_table;
979
980                 *tune_state = CT_TUNER_STEP_0;
981
982                 /* fall through */
983
984         case CT_TUNER_STEP_0:
985                 dib0090_write_reg(state, 0x01, state->dc->bb1);
986                 dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7));
987
988                 state->step = 0;
989
990                 state->min_adc_diff = 1023;
991
992                 *tune_state = CT_TUNER_STEP_1;
993                 ret = 50;
994                 break;
995
996         case CT_TUNER_STEP_1:
997                 dib0090_set_trim(state);
998
999                 *tune_state = CT_TUNER_STEP_2;
1000                 break;
1001
1002         case CT_TUNER_STEP_2:
1003         case CT_TUNER_STEP_3:
1004         case CT_TUNER_STEP_4:
1005                 ret = dib0090_get_offset(state, tune_state);
1006                 break;
1007
1008         case CT_TUNER_STEP_5:   /* found an offset */
1009                 dprintk("FE%d: IQC read=%d, current=%x", state->fe->id, (u32) state->adc_diff, state->step);
1010
1011                 /* first turn for this frequency */
1012                 if (state->step == 0) {
1013                         if (state->dc->pga && state->adc_diff < 0)
1014                                 state->step = 0x10;
1015                         if (state->dc->pga == 0 && state->adc_diff > 0)
1016                                 state->step = 0x10;
1017                 }
1018
1019                 state->adc_diff = ABS(state->adc_diff);
1020
1021                 if (state->adc_diff < state->min_adc_diff && steps(state->step) < 15) { /* stop search when the delta to 0 is increasing */
1022                         state->step++;
1023                         state->min_adc_diff = state->adc_diff;
1024                         *tune_state = CT_TUNER_STEP_1;
1025                 } else {
1026
1027                         /* the minimum was what we have seen in the step before */
1028                         state->step--;
1029                         dib0090_set_trim(state);
1030
1031                         dprintk("FE%d: BB Offset Cal, BBreg=%hd,Offset=%hd,Value Set=%hd", state->fe->id, state->dc->addr, state->adc_diff,
1032                                 state->step);
1033
1034                         state->dc++;
1035                         if (state->dc->addr == 0)       /* done */
1036                                 *tune_state = CT_TUNER_STEP_6;
1037                         else
1038                                 *tune_state = CT_TUNER_STEP_0;
1039
1040                 }
1041                 break;
1042
1043         case CT_TUNER_STEP_6:
1044                 dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008);
1045                 dib0090_write_reg(state, 0x1f, 0x7);
1046                 *tune_state = CT_TUNER_START;   /* reset done -> real tuning can now begin */
1047                 state->reset &= ~0x1;
1048         default:
1049                 break;
1050         }
1051         return ret;
1052 }
1053
1054 static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1055 {
1056         switch (*tune_state) {
1057         case CT_TUNER_START:
1058                 /* WBD-mode=log, Bias=2, Gain=6, Testmode=1, en=1, WBDMUX=1 */
1059                 dib0090_write_reg(state, 0x10, 0xdb09 | (1 << 10));
1060                 dib0090_write_reg(state, 0x24, EN_UHF & 0x0fff);
1061
1062                 *tune_state = CT_TUNER_STEP_0;
1063                 return 90;      /* wait for the WBDMUX to switch and for the ADC to sample */
1064         case CT_TUNER_STEP_0:
1065                 state->wbd_offset = dib0090_read_reg(state, 0x1d);
1066                 dprintk("WBD calibration offset = %d", state->wbd_offset);
1067
1068                 *tune_state = CT_TUNER_START;   /* reset done -> real tuning can now begin */
1069                 state->reset &= ~0x2;
1070                 break;
1071         default:
1072                 break;
1073         }
1074         return 0;
1075 }
1076
1077 static void dib0090_set_bandwidth(struct dib0090_state *state)
1078 {
1079         u16 tmp;
1080
1081         if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 5000)
1082                 tmp = (3 << 14);
1083         else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 6000)
1084                 tmp = (2 << 14);
1085         else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 7000)
1086                 tmp = (1 << 14);
1087         else
1088                 tmp = (0 << 14);
1089
1090         state->bb_1_def &= 0x3fff;
1091         state->bb_1_def |= tmp;
1092
1093         dib0090_write_reg(state, 0x01, state->bb_1_def);        /* be sure that we have the right bb-filter */
1094 }
1095
1096 static const struct dib0090_pll dib0090_pll_table[] = {
1097 #ifdef CONFIG_BAND_CBAND
1098         {56000, 0, 9, 48, 6},
1099         {70000, 1, 9, 48, 6},
1100         {87000, 0, 8, 32, 4},
1101         {105000, 1, 8, 32, 4},
1102         {115000, 0, 7, 24, 6},
1103         {140000, 1, 7, 24, 6},
1104         {170000, 0, 6, 16, 4},
1105 #endif
1106 #ifdef CONFIG_BAND_VHF
1107         {200000, 1, 6, 16, 4},
1108         {230000, 0, 5, 12, 6},
1109         {280000, 1, 5, 12, 6},
1110         {340000, 0, 4, 8, 4},
1111         {380000, 1, 4, 8, 4},
1112         {450000, 0, 3, 6, 6},
1113 #endif
1114 #ifdef CONFIG_BAND_UHF
1115         {580000, 1, 3, 6, 6},
1116         {700000, 0, 2, 4, 4},
1117         {860000, 1, 2, 4, 4},
1118 #endif
1119 #ifdef CONFIG_BAND_LBAND
1120         {1800000, 1, 0, 2, 4},
1121 #endif
1122 #ifdef CONFIG_BAND_SBAND
1123         {2900000, 0, 14, 1, 4},
1124 #endif
1125 };
1126
1127 static const struct dib0090_tuning dib0090_tuning_table_fm_vhf_on_cband[] = {
1128
1129 #ifdef CONFIG_BAND_CBAND
1130         {184000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1131         {227000, 4, 3, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1132         {380000, 4, 7, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1133 #endif
1134 #ifdef CONFIG_BAND_UHF
1135         {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1136         {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1137         {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1138         {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1139         {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1140         {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1141 #endif
1142 #ifdef CONFIG_BAND_LBAND
1143         {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1144         {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1145         {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1146 #endif
1147 #ifdef CONFIG_BAND_SBAND
1148         {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1149         {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1150 #endif
1151 };
1152
1153 static const struct dib0090_tuning dib0090_tuning_table[] = {
1154
1155 #ifdef CONFIG_BAND_CBAND
1156         {170000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1157 #endif
1158 #ifdef CONFIG_BAND_VHF
1159         {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1160         {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1161         {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1162 #endif
1163 #ifdef CONFIG_BAND_UHF
1164         {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1165         {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1166         {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1167         {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1168         {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1169         {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1170 #endif
1171 #ifdef CONFIG_BAND_LBAND
1172         {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1173         {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1174         {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1175 #endif
1176 #ifdef CONFIG_BAND_SBAND
1177         {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1178         {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1179 #endif
1180 };
1181
1182 #define WBD     0x781           /* 1 1 1 1 0000 0 0 1 */
1183 static int dib0090_tune(struct dvb_frontend *fe)
1184 {
1185         struct dib0090_state *state = fe->tuner_priv;
1186         const struct dib0090_tuning *tune = state->current_tune_table_index;
1187         const struct dib0090_pll *pll = state->current_pll_table_index;
1188         enum frontend_tune_state *tune_state = &state->tune_state;
1189
1190         u32 rf;
1191         u16 lo4 = 0xe900, lo5, lo6, Den;
1192         u32 FBDiv, Rest, FREF, VCOF_kHz = 0;
1193         u16 tmp, adc;
1194         int8_t step_sign;
1195         int ret = 10;           /* 1ms is the default delay most of the time */
1196         u8 c, i;
1197
1198         state->current_band = (u8) BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000);
1199         rf = fe->dtv_property_cache.frequency / 1000 + (state->current_band ==
1200                                                         BAND_UHF ? state->config->freq_offset_khz_uhf : state->config->freq_offset_khz_vhf);
1201         /* in any case we first need to do a reset if needed */
1202         if (state->reset & 0x1)
1203                 return dib0090_dc_offset_calibration(state, tune_state);
1204         else if (state->reset & 0x2)
1205                 return dib0090_wbd_calibration(state, tune_state);
1206
1207     /************************* VCO ***************************/
1208         /* Default values for FG                                 */
1209         /* from these are needed :                               */
1210         /* Cp,HFdiv,VCOband,SD,Num,Den,FB and REFDiv             */
1211
1212 #ifdef CONFIG_SYS_ISDBT
1213         if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1)
1214                 rf += 850;
1215 #endif
1216
1217         if (state->current_rf != rf) {
1218                 state->tuner_is_tuned = 0;
1219
1220                 tune = dib0090_tuning_table;
1221
1222                 tmp = (state->revision >> 5) & 0x7;
1223                 if (tmp == 0x4 || tmp == 0x7) {
1224                         /* CBAND tuner version for VHF */
1225                         if (state->current_band == BAND_FM || state->current_band == BAND_VHF) {
1226                                 /* Force CBAND */
1227                                 state->current_band = BAND_CBAND;
1228                                 tune = dib0090_tuning_table_fm_vhf_on_cband;
1229                         }
1230                 }
1231
1232                 pll = dib0090_pll_table;
1233                 /* Look for the interval */
1234                 while (rf > tune->max_freq)
1235                         tune++;
1236                 while (rf > pll->max_freq)
1237                         pll++;
1238                 state->current_tune_table_index = tune;
1239                 state->current_pll_table_index = pll;
1240         }
1241
1242         if (*tune_state == CT_TUNER_START) {
1243
1244                 if (state->tuner_is_tuned == 0)
1245                         state->current_rf = 0;
1246
1247                 if (state->current_rf != rf) {
1248
1249                         dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim));
1250
1251                         /* external loop filter, otherwise:
1252                          * lo5 = (0 << 15) | (0 << 12) | (0 << 11) | (3 << 9) | (4 << 6) | (3 << 4) | 4;
1253                          * lo6 = 0x0e34 */
1254                         if (pll->vco_band)
1255                                 lo5 = 0x049e;
1256                         else if (state->config->analog_output)
1257                                 lo5 = 0x041d;
1258                         else
1259                                 lo5 = 0x041c;
1260
1261                         lo5 |= (pll->hfdiv_code << 11) | (pll->vco_band << 7);  /* bit 15 is the split to the slave, we do not do it here */
1262
1263                         if (!state->config->io.pll_int_loop_filt)
1264                                 lo6 = 0xff28;
1265                         else
1266                                 lo6 = (state->config->io.pll_int_loop_filt << 3);
1267
1268                         VCOF_kHz = (pll->hfdiv * rf) * 2;
1269
1270                         FREF = state->config->io.clock_khz;
1271
1272                         FBDiv = (VCOF_kHz / pll->topresc / FREF);
1273                         Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF;
1274
1275                         if (Rest < LPF)
1276                                 Rest = 0;
1277                         else if (Rest < 2 * LPF)
1278                                 Rest = 2 * LPF;
1279                         else if (Rest > (FREF - LPF)) {
1280                                 Rest = 0;
1281                                 FBDiv += 1;
1282                         } else if (Rest > (FREF - 2 * LPF))
1283                                 Rest = FREF - 2 * LPF;
1284                         Rest = (Rest * 6528) / (FREF / 10);
1285
1286                         Den = 1;
1287
1288                         dprintk(" *****  ******* Rest value = %d", Rest);
1289
1290                         if (Rest > 0) {
1291                                 if (state->config->analog_output)
1292                                         lo6 |= (1 << 2) | 2;
1293                                 else
1294                                         lo6 |= (1 << 2) | 1;
1295                                 Den = 255;
1296                         }
1297 #ifdef CONFIG_BAND_SBAND
1298                         if (state->current_band == BAND_SBAND)
1299                                 lo6 &= 0xfffb;
1300 #endif
1301
1302                         dib0090_write_reg(state, 0x15, (u16) FBDiv);
1303
1304                         dib0090_write_reg(state, 0x16, (Den << 8) | 1);
1305
1306                         dib0090_write_reg(state, 0x17, (u16) Rest);
1307
1308                         dib0090_write_reg(state, 0x19, lo5);
1309
1310                         dib0090_write_reg(state, 0x1c, lo6);
1311
1312                         lo6 = tune->tuner_enable;
1313                         if (state->config->analog_output)
1314                                 lo6 = (lo6 & 0xff9f) | 0x2;
1315
1316                         dib0090_write_reg(state, 0x24, lo6 | EN_LO
1317 #ifdef CONFIG_DIB0090_USE_PWM_AGC
1318                                           | state->config->use_pwm_agc * EN_CRYSTAL
1319 #endif
1320                             );
1321
1322                         state->current_rf = rf;
1323
1324                         /* prepare a complete captrim */
1325                         state->step = state->captrim = state->fcaptrim = 64;
1326
1327                 } else {        /* we are already tuned to this frequency - the configuration is correct  */
1328
1329                         /* do a minimal captrim even if the frequency has not changed */
1330                         state->step = 4;
1331                         state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f;
1332                 }
1333                 state->adc_diff = 3000;
1334
1335                 dib0090_write_reg(state, 0x10, 0x2B1);
1336
1337                 dib0090_write_reg(state, 0x1e, 0x0032);
1338
1339                 ret = 20;
1340                 *tune_state = CT_TUNER_STEP_1;
1341         } else if (*tune_state == CT_TUNER_STEP_0) {
1342                 /* nothing */
1343         } else if (*tune_state == CT_TUNER_STEP_1) {
1344                 state->step /= 2;
1345                 dib0090_write_reg(state, 0x18, lo4 | state->captrim);
1346                 *tune_state = CT_TUNER_STEP_2;
1347         } else if (*tune_state == CT_TUNER_STEP_2) {
1348
1349                 adc = dib0090_read_reg(state, 0x1d);
1350                 dprintk("FE %d CAPTRIM=%d; ADC = %d (ADC) & %dmV", (u32) fe->id, (u32) state->captrim, (u32) adc,
1351                         (u32) (adc) * (u32) 1800 / (u32) 1024);
1352
1353                 if (adc >= 400) {
1354                         adc -= 400;
1355                         step_sign = -1;
1356                 } else {
1357                         adc = 400 - adc;
1358                         step_sign = 1;
1359                 }
1360
1361                 if (adc < state->adc_diff) {
1362                         dprintk("FE %d CAPTRIM=%d is closer to target (%d/%d)", (u32) fe->id, (u32) state->captrim, (u32) adc, (u32) state->adc_diff);
1363                         state->adc_diff = adc;
1364                         state->fcaptrim = state->captrim;
1365
1366                 }
1367
1368                 state->captrim += step_sign * state->step;
1369                 if (state->step >= 1)
1370                         *tune_state = CT_TUNER_STEP_1;
1371                 else
1372                         *tune_state = CT_TUNER_STEP_3;
1373
1374                 ret = 15;
1375         } else if (*tune_state == CT_TUNER_STEP_3) {
1376                 /*write the final cptrim config */
1377                 dib0090_write_reg(state, 0x18, lo4 | state->fcaptrim);
1378
1379 #ifdef CONFIG_TUNER_DIB0090_CAPTRIM_MEMORY
1380                 state->memory[state->memory_index].cap = state->fcaptrim;
1381 #endif
1382
1383                 *tune_state = CT_TUNER_STEP_4;
1384         } else if (*tune_state == CT_TUNER_STEP_4) {
1385                 dib0090_write_reg(state, 0x1e, 0x07ff);
1386
1387                 dprintk("FE %d Final Captrim: %d", (u32) fe->id, (u32) state->fcaptrim);
1388                 dprintk("FE %d HFDIV code: %d", (u32) fe->id, (u32) pll->hfdiv_code);
1389                 dprintk("FE %d VCO = %d", (u32) fe->id, (u32) pll->vco_band);
1390                 dprintk("FE %d VCOF in kHz: %d ((%d*%d) << 1))", (u32) fe->id, (u32) ((pll->hfdiv * rf) * 2), (u32) pll->hfdiv, (u32) rf);
1391                 dprintk("FE %d REFDIV: %d, FREF: %d", (u32) fe->id, (u32) 1, (u32) state->config->io.clock_khz);
1392                 dprintk("FE %d FBDIV: %d, Rest: %d", (u32) fe->id, (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17));
1393                 dprintk("FE %d Num: %d, Den: %d, SD: %d", (u32) fe->id, (u32) dib0090_read_reg(state, 0x17),
1394                         (u32) (dib0090_read_reg(state, 0x16) >> 8), (u32) dib0090_read_reg(state, 0x1c) & 0x3);
1395
1396                 c = 4;
1397                 i = 3;
1398 #if defined(CONFIG_BAND_LBAND) || defined(CONFIG_BAND_SBAND)
1399                 if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND)) {
1400                         c = 2;
1401                         i = 2;
1402                 }
1403 #endif
1404                 dib0090_write_reg(state, 0x10, (c << 13) | (i << 11) | (WBD
1405 #ifdef CONFIG_DIB0090_USE_PWM_AGC
1406                                                                         | (state->config->use_pwm_agc << 1)
1407 #endif
1408                                   ));
1409                 dib0090_write_reg(state, 0x09, (tune->lna_tune << 5) | (tune->lna_bias << 0));
1410                 dib0090_write_reg(state, 0x0c, tune->v2i);
1411                 dib0090_write_reg(state, 0x0d, tune->mix);
1412                 dib0090_write_reg(state, 0x0e, tune->load);
1413
1414                 *tune_state = CT_TUNER_STEP_5;
1415         } else if (*tune_state == CT_TUNER_STEP_5) {
1416
1417                 /* initialize the lt gain register */
1418                 state->rf_lt_def = 0x7c00;
1419                 dib0090_write_reg(state, 0x0f, state->rf_lt_def);
1420
1421                 dib0090_set_bandwidth(state);
1422                 state->tuner_is_tuned = 1;
1423                 *tune_state = CT_TUNER_STOP;
1424         } else
1425                 ret = FE_CALLBACK_TIME_NEVER;
1426         return ret;
1427 }
1428
1429 static int dib0090_release(struct dvb_frontend *fe)
1430 {
1431         kfree(fe->tuner_priv);
1432         fe->tuner_priv = NULL;
1433         return 0;
1434 }
1435
1436 enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe)
1437 {
1438         struct dib0090_state *state = fe->tuner_priv;
1439
1440         return state->tune_state;
1441 }
1442 EXPORT_SYMBOL(dib0090_get_tune_state);
1443
1444 int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
1445 {
1446         struct dib0090_state *state = fe->tuner_priv;
1447
1448         state->tune_state = tune_state;
1449         return 0;
1450 }
1451 EXPORT_SYMBOL(dib0090_set_tune_state);
1452
1453 static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency)
1454 {
1455         struct dib0090_state *state = fe->tuner_priv;
1456
1457         *frequency = 1000 * state->current_rf;
1458         return 0;
1459 }
1460
1461 static int dib0090_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
1462 {
1463         struct dib0090_state *state = fe->tuner_priv;
1464         uint32_t ret;
1465
1466         state->tune_state = CT_TUNER_START;
1467
1468         do {
1469                 ret = dib0090_tune(fe);
1470                 if (ret != FE_CALLBACK_TIME_NEVER)
1471                         msleep(ret / 10);
1472                 else
1473                         break;
1474         } while (state->tune_state != CT_TUNER_STOP);
1475
1476         return 0;
1477 }
1478
1479 static const struct dvb_tuner_ops dib0090_ops = {
1480         .info = {
1481                  .name = "DiBcom DiB0090",
1482                  .frequency_min = 45000000,
1483                  .frequency_max = 860000000,
1484                  .frequency_step = 1000,
1485                  },
1486         .release = dib0090_release,
1487
1488         .init = dib0090_wakeup,
1489         .sleep = dib0090_sleep,
1490         .set_params = dib0090_set_params,
1491         .get_frequency = dib0090_get_frequency,
1492 };
1493
1494 struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
1495 {
1496         struct dib0090_state *st = kzalloc(sizeof(struct dib0090_state), GFP_KERNEL);
1497         if (st == NULL)
1498                 return NULL;
1499
1500         st->config = config;
1501         st->i2c = i2c;
1502         st->fe = fe;
1503         fe->tuner_priv = st;
1504
1505         if (dib0090_reset(fe) != 0)
1506                 goto free_mem;
1507
1508         printk(KERN_INFO "DiB0090: successfully identified\n");
1509         memcpy(&fe->ops.tuner_ops, &dib0090_ops, sizeof(struct dvb_tuner_ops));
1510
1511         return fe;
1512  free_mem:
1513         kfree(st);
1514         fe->tuner_priv = NULL;
1515         return NULL;
1516 }
1517 EXPORT_SYMBOL(dib0090_register);
1518
1519 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
1520 MODULE_AUTHOR("Olivier Grenie <olivier.grenie@dibcom.fr>");
1521 MODULE_DESCRIPTION("Driver for the DiBcom 0090 base-band RF Tuner");
1522 MODULE_LICENSE("GPL");