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