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