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