Merge git://git.samba.org/sfrench/cifs-2.6
[sfrench/cifs-2.6.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 uint16_t rf_ramp_pwm_cband_7090e_sensitivity[] = {
721         186,
722         40,
723         746,
724         (10 << 10) | 345,
725         (0  << 10) | 746,
726         (0 << 10) | 0,
727         (0  << 10) | 0,
728         (28 << 10) | 200,
729         (0  << 10) | 345,
730         (20 << 10) | 0,
731         (0  << 10) | 200,
732 };
733
734 static const uint16_t rf_ramp_pwm_cband_7090e_aci[] = {
735         86,
736         40,
737         345,
738         (0 << 10) | 0,
739         (0 << 10) | 0,
740         (0 << 10) | 0,
741         (0 << 10) | 0,
742         (28 << 10) | 200,
743         (0  << 10) | 345,
744         (20 << 10) | 0,
745         (0  << 10) | 200,
746 };
747
748 static const u16 rf_ramp_pwm_cband_8090[] = {
749         345,                    /* max RF gain in 10th of dB */
750         29,                     /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
751         1000,                   /* ramp_max = maximum X used on the ramp */
752         (35 << 10) | 772,       /* RF_RAMP3, LNA 1 = 8dB */
753         (0 << 10) | 1000,       /* RF_RAMP4, LNA 1 */
754         (58 << 10) | 496,       /* RF_RAMP5, LNA 2 = 9.5dB */
755         (0 << 10) | 772,        /* RF_RAMP6, LNA 2 */
756         (27 << 10) | 200,       /* RF_RAMP7, LNA 3 = 10.5dB */
757         (0 << 10) | 496,        /* RF_RAMP8, LNA 3 */
758         (40 << 10) | 0,         /* GAIN_4_1, LNA 4 = 7dB */
759         (0 << 10) | 200,        /* GAIN_4_2, LNA 4 */
760 };
761
762 static const u16 rf_ramp_pwm_uhf_7090[] = {
763         407,                    /* max RF gain in 10th of dB */
764         13,                     /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
765         529,                    /* ramp_max = maximum X used on the ramp */
766         (23 << 10) | 0,         /* RF_RAMP3, LNA 1 = 14.7dB */
767         (0 << 10) | 176,        /* RF_RAMP4, LNA 1 */
768         (63 << 10) | 400,       /* RF_RAMP5, LNA 2 = 8dB */
769         (0 << 10) | 529,        /* RF_RAMP6, LNA 2 */
770         (48 << 10) | 316,       /* RF_RAMP7, LNA 3 = 6.8dB */
771         (0 << 10) | 400,        /* RF_RAMP8, LNA 3 */
772         (29 << 10) | 176,       /* GAIN_4_1, LNA 4 = 11.5dB */
773         (0 << 10) | 316,        /* GAIN_4_2, LNA 4 */
774 };
775
776 static const u16 rf_ramp_pwm_uhf_8090[] = {
777         388,                    /* max RF gain in 10th of dB */
778         26,                     /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
779         1008,                   /* ramp_max = maximum X used on the ramp */
780         (11 << 10) | 0,         /* RF_RAMP3, LNA 1 = 14.7dB */
781         (0 << 10) | 369,        /* RF_RAMP4, LNA 1 */
782         (41 << 10) | 809,       /* RF_RAMP5, LNA 2 = 8dB */
783         (0 << 10) | 1008,       /* RF_RAMP6, LNA 2 */
784         (27 << 10) | 659,       /* RF_RAMP7, LNA 3 = 6dB */
785         (0 << 10) | 809,        /* RF_RAMP8, LNA 3 */
786         (14 << 10) | 369,       /* GAIN_4_1, LNA 4 = 11.5dB */
787         (0 << 10) | 659,        /* GAIN_4_2, LNA 4 */
788 };
789
790 static const u16 rf_ramp_pwm_cband[] = {
791         0,                      /* max RF gain in 10th of dB */
792         0,                      /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
793         0,                      /* ramp_max = maximum X used on the ramp */
794         (0 << 10) | 0,          /* 0x2c, LNA 1 = 0dB */
795         (0 << 10) | 0,          /* 0x2d, LNA 1 */
796         (0 << 10) | 0,          /* 0x2e, LNA 2 = 0dB */
797         (0 << 10) | 0,          /* 0x2f, LNA 2 */
798         (0 << 10) | 0,          /* 0x30, LNA 3 = 0dB */
799         (0 << 10) | 0,          /* 0x31, LNA 3 */
800         (0 << 10) | 0,          /* GAIN_4_1, LNA 4 = 0dB */
801         (0 << 10) | 0,          /* GAIN_4_2, LNA 4 */
802 };
803
804 static const u16 rf_ramp_vhf[] = {
805         412,                    /* max RF gain in 10th of dB */
806         132, 307, 127,          /* LNA1,  13.2dB */
807         105, 412, 255,          /* LNA2,  10.5dB */
808         50, 50, 127,            /* LNA3,  5dB */
809         125, 175, 127,          /* LNA4,  12.5dB */
810         0, 0, 127,              /* CBAND, 0dB */
811 };
812
813 static const u16 rf_ramp_uhf[] = {
814         412,                    /* max RF gain in 10th of dB */
815         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 */
816         105, 412, 255,          /* LNA2  : 10.5 dB */
817         50, 50, 127,            /* LNA3  :  5.0 dB */
818         125, 175, 127,          /* LNA4  : 12.5 dB */
819         0, 0, 127,              /* CBAND :  0.0 dB */
820 };
821
822 static const u16 rf_ramp_cband_broadmatching[] =        /* for p1G only */
823 {
824         314,                    /* Calibrated at 200MHz order has been changed g4-g3-g2-g1 */
825         84, 314, 127,           /* LNA1 */
826         80, 230, 255,           /* LNA2 */
827         80, 150, 127,           /* LNA3  It was measured 12dB, do not lock if 120 */
828         70, 70, 127,            /* LNA4 */
829         0, 0, 127,              /* CBAND */
830 };
831
832 static const u16 rf_ramp_cband[] = {
833         332,                    /* max RF gain in 10th of dB */
834         132, 252, 127,          /* LNA1,  dB */
835         80, 332, 255,           /* LNA2,  dB */
836         0, 0, 127,              /* LNA3,  dB */
837         0, 0, 127,              /* LNA4,  dB */
838         120, 120, 127,          /* LT1 CBAND */
839 };
840
841 static const u16 rf_ramp_pwm_vhf[] = {
842         404,                    /* max RF gain in 10th of dB */
843         25,                     /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
844         1011,                   /* ramp_max = maximum X used on the ramp */
845         (6 << 10) | 417,        /* 0x2c, LNA 1 = 13.2dB */
846         (0 << 10) | 756,        /* 0x2d, LNA 1 */
847         (16 << 10) | 756,       /* 0x2e, LNA 2 = 10.5dB */
848         (0 << 10) | 1011,       /* 0x2f, LNA 2 */
849         (16 << 10) | 290,       /* 0x30, LNA 3 = 5dB */
850         (0 << 10) | 417,        /* 0x31, LNA 3 */
851         (7 << 10) | 0,          /* GAIN_4_1, LNA 4 = 12.5dB */
852         (0 << 10) | 290,        /* GAIN_4_2, LNA 4 */
853 };
854
855 static const u16 rf_ramp_pwm_uhf[] = {
856         404,                    /* max RF gain in 10th of dB */
857         25,                     /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
858         1011,                   /* ramp_max = maximum X used on the ramp */
859         (6 << 10) | 417,        /* 0x2c, LNA 1 = 13.2dB */
860         (0 << 10) | 756,        /* 0x2d, LNA 1 */
861         (16 << 10) | 756,       /* 0x2e, LNA 2 = 10.5dB */
862         (0 << 10) | 1011,       /* 0x2f, LNA 2 */
863         (16 << 10) | 0,         /* 0x30, LNA 3 = 5dB */
864         (0 << 10) | 127,        /* 0x31, LNA 3 */
865         (7 << 10) | 127,        /* GAIN_4_1, LNA 4 = 12.5dB */
866         (0 << 10) | 417,        /* GAIN_4_2, LNA 4 */
867 };
868
869 static const u16 bb_ramp_boost[] = {
870         550,                    /* max BB gain in 10th of dB */
871         260, 260, 26,           /* BB1, 26dB */
872         290, 550, 29,           /* BB2, 29dB */
873 };
874
875 static const u16 bb_ramp_pwm_normal[] = {
876         500,                    /* max RF gain in 10th of dB */
877         8,                      /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x34 */
878         400,
879         (2 << 9) | 0,           /* 0x35 = 21dB */
880         (0 << 9) | 168,         /* 0x36 */
881         (2 << 9) | 168,         /* 0x37 = 29dB */
882         (0 << 9) | 400,         /* 0x38 */
883 };
884
885 struct slope {
886         s16 range;
887         s16 slope;
888 };
889 static u16 slopes_to_scale(const struct slope *slopes, u8 num, s16 val)
890 {
891         u8 i;
892         u16 rest;
893         u16 ret = 0;
894         for (i = 0; i < num; i++) {
895                 if (val > slopes[i].range)
896                         rest = slopes[i].range;
897                 else
898                         rest = val;
899                 ret += (rest * slopes[i].slope) / slopes[i].range;
900                 val -= rest;
901         }
902         return ret;
903 }
904
905 static const struct slope dib0090_wbd_slopes[3] = {
906         {66, 120},              /* -64,-52: offset -   65 */
907         {600, 170},             /* -52,-35: 65     -  665 */
908         {170, 250},             /* -45,-10: 665    - 835 */
909 };
910
911 static s16 dib0090_wbd_to_db(struct dib0090_state *state, u16 wbd)
912 {
913         wbd &= 0x3ff;
914         if (wbd < state->wbd_offset)
915                 wbd = 0;
916         else
917                 wbd -= state->wbd_offset;
918         /* -64dB is the floor */
919         return -640 + (s16) slopes_to_scale(dib0090_wbd_slopes, ARRAY_SIZE(dib0090_wbd_slopes), wbd);
920 }
921
922 static void dib0090_wbd_target(struct dib0090_state *state, u32 rf)
923 {
924         u16 offset = 250;
925
926         /* TODO : DAB digital N+/-1 interferer perfs : offset = 10 */
927
928         if (state->current_band == BAND_VHF)
929                 offset = 650;
930 #ifndef FIRMWARE_FIREFLY
931         if (state->current_band == BAND_VHF)
932                 offset = state->config->wbd_vhf_offset;
933         if (state->current_band == BAND_CBAND)
934                 offset = state->config->wbd_cband_offset;
935 #endif
936
937         state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + offset);
938         dprintk("wbd-target: %d dB", (u32) state->wbd_target);
939 }
940
941 static const int gain_reg_addr[4] = {
942         0x08, 0x0a, 0x0f, 0x01
943 };
944
945 static void dib0090_gain_apply(struct dib0090_state *state, s16 gain_delta, s16 top_delta, u8 force)
946 {
947         u16 rf, bb, ref;
948         u16 i, v, gain_reg[4] = { 0 }, gain;
949         const u16 *g;
950
951         if (top_delta < -511)
952                 top_delta = -511;
953         if (top_delta > 511)
954                 top_delta = 511;
955
956         if (force) {
957                 top_delta *= (1 << WBD_ALPHA);
958                 gain_delta *= (1 << GAIN_ALPHA);
959         }
960
961         if (top_delta >= ((s16) (state->rf_ramp[0] << WBD_ALPHA) - state->rf_gain_limit))       /* overflow */
962                 state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
963         else
964                 state->rf_gain_limit += top_delta;
965
966         if (state->rf_gain_limit < 0)   /*underflow */
967                 state->rf_gain_limit = 0;
968
969         /* use gain as a temporary variable and correct current_gain */
970         gain = ((state->rf_gain_limit >> WBD_ALPHA) + state->bb_ramp[0]) << GAIN_ALPHA;
971         if (gain_delta >= ((s16) gain - state->current_gain))   /* overflow */
972                 state->current_gain = gain;
973         else
974                 state->current_gain += gain_delta;
975         /* cannot be less than 0 (only if gain_delta is less than 0 we can have current_gain < 0) */
976         if (state->current_gain < 0)
977                 state->current_gain = 0;
978
979         /* now split total gain to rf and bb gain */
980         gain = state->current_gain >> GAIN_ALPHA;
981
982         /* requested gain is bigger than rf gain limit - ACI/WBD adjustment */
983         if (gain > (state->rf_gain_limit >> WBD_ALPHA)) {
984                 rf = state->rf_gain_limit >> WBD_ALPHA;
985                 bb = gain - rf;
986                 if (bb > state->bb_ramp[0])
987                         bb = state->bb_ramp[0];
988         } else {                /* high signal level -> all gains put on RF */
989                 rf = gain;
990                 bb = 0;
991         }
992
993         state->gain[0] = rf;
994         state->gain[1] = bb;
995
996         /* software ramp */
997         /* Start with RF gains */
998         g = state->rf_ramp + 1; /* point on RF LNA1 max gain */
999         ref = rf;
1000         for (i = 0; i < 7; i++) {       /* Go over all amplifiers => 5RF amps + 2 BB amps = 7 amps */
1001                 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 */
1002                         v = 0;  /* force the gain to write for the current amp to be null */
1003                 else if (ref >= g[1])   /* Gain to set is higher than the high working point of this amp */
1004                         v = g[2];       /* force this amp to be full gain */
1005                 else            /* compute the value to set to this amp because we are somewhere in his range */
1006                         v = ((ref - (g[1] - g[0])) * g[2]) / g[0];
1007
1008                 if (i == 0)     /* LNA 1 reg mapping */
1009                         gain_reg[0] = v;
1010                 else if (i == 1)        /* LNA 2 reg mapping */
1011                         gain_reg[0] |= v << 7;
1012                 else if (i == 2)        /* LNA 3 reg mapping */
1013                         gain_reg[1] = v;
1014                 else if (i == 3)        /* LNA 4 reg mapping */
1015                         gain_reg[1] |= v << 7;
1016                 else if (i == 4)        /* CBAND LNA reg mapping */
1017                         gain_reg[2] = v | state->rf_lt_def;
1018                 else if (i == 5)        /* BB gain 1 reg mapping */
1019                         gain_reg[3] = v << 3;
1020                 else if (i == 6)        /* BB gain 2 reg mapping */
1021                         gain_reg[3] |= v << 8;
1022
1023                 g += 3;         /* go to next gain bloc */
1024
1025                 /* When RF is finished, start with BB */
1026                 if (i == 4) {
1027                         g = state->bb_ramp + 1; /* point on BB gain 1 max gain */
1028                         ref = bb;
1029                 }
1030         }
1031         gain_reg[3] |= state->bb_1_def;
1032         gain_reg[3] |= ((bb % 10) * 100) / 125;
1033
1034 #ifdef DEBUG_AGC
1035         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,
1036                 gain_reg[0], gain_reg[1], gain_reg[2], gain_reg[3]);
1037 #endif
1038
1039         /* Write the amplifier regs */
1040         for (i = 0; i < 4; i++) {
1041                 v = gain_reg[i];
1042                 if (force || state->gain_reg[i] != v) {
1043                         state->gain_reg[i] = v;
1044                         dib0090_write_reg(state, gain_reg_addr[i], v);
1045                 }
1046         }
1047 }
1048
1049 static void dib0090_set_boost(struct dib0090_state *state, int onoff)
1050 {
1051         state->bb_1_def &= 0xdfff;
1052         state->bb_1_def |= onoff << 13;
1053 }
1054
1055 static void dib0090_set_rframp(struct dib0090_state *state, const u16 * cfg)
1056 {
1057         state->rf_ramp = cfg;
1058 }
1059
1060 static void dib0090_set_rframp_pwm(struct dib0090_state *state, const u16 * cfg)
1061 {
1062         state->rf_ramp = cfg;
1063
1064         dib0090_write_reg(state, 0x2a, 0xffff);
1065
1066         dprintk("total RF gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x2a));
1067
1068         dib0090_write_regs(state, 0x2c, cfg + 3, 6);
1069         dib0090_write_regs(state, 0x3e, cfg + 9, 2);
1070 }
1071
1072 static void dib0090_set_bbramp(struct dib0090_state *state, const u16 * cfg)
1073 {
1074         state->bb_ramp = cfg;
1075         dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */
1076 }
1077
1078 static void dib0090_set_bbramp_pwm(struct dib0090_state *state, const u16 * cfg)
1079 {
1080         state->bb_ramp = cfg;
1081
1082         dib0090_set_boost(state, cfg[0] > 500); /* we want the boost if the gain is higher that 50dB */
1083
1084         dib0090_write_reg(state, 0x33, 0xffff);
1085         dprintk("total BB gain: %ddB, step: %d", (u32) cfg[0], dib0090_read_reg(state, 0x33));
1086         dib0090_write_regs(state, 0x35, cfg + 3, 4);
1087 }
1088
1089 void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
1090 {
1091         struct dib0090_state *state = fe->tuner_priv;
1092         /* reset the AGC */
1093
1094         if (state->config->use_pwm_agc) {
1095 #ifdef CONFIG_BAND_SBAND
1096                 if (state->current_band == BAND_SBAND) {
1097                         dib0090_set_rframp_pwm(state, rf_ramp_pwm_sband);
1098                         dib0090_set_bbramp_pwm(state, bb_ramp_pwm_boost);
1099                 } else
1100 #endif
1101 #ifdef CONFIG_BAND_CBAND
1102                 if (state->current_band == BAND_CBAND) {
1103                         if (state->identity.in_soc) {
1104                                 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
1105                                 if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
1106                                         dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_8090);
1107                                 else if (state->identity.version == SOC_7090_P1G_11R1
1108                                                 || state->identity.version == SOC_7090_P1G_21R1) {
1109                                         if (state->config->is_dib7090e) {
1110                                                 if (state->rf_ramp == NULL)
1111                                                         dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090e_sensitivity);
1112                                                 else
1113                                                         dib0090_set_rframp_pwm(state, state->rf_ramp);
1114                                         } else
1115                                                 dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090);
1116                                 }
1117                         } else {
1118                                 dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband);
1119                                 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
1120                         }
1121                 } else
1122 #endif
1123 #ifdef CONFIG_BAND_VHF
1124                 if (state->current_band == BAND_VHF) {
1125                         if (state->identity.in_soc) {
1126                                 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
1127                         } else {
1128                                 dib0090_set_rframp_pwm(state, rf_ramp_pwm_vhf);
1129                                 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
1130                         }
1131                 } else
1132 #endif
1133                 {
1134                         if (state->identity.in_soc) {
1135                                 if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
1136                                         dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf_8090);
1137                                 else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
1138                                         dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf_7090);
1139                                 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
1140                         } else {
1141                                 dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf);
1142                                 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
1143                         }
1144                 }
1145
1146                 if (state->rf_ramp[0] != 0)
1147                         dib0090_write_reg(state, 0x32, (3 << 11));
1148                 else
1149                         dib0090_write_reg(state, 0x32, (0 << 11));
1150
1151                 dib0090_write_reg(state, 0x04, 0x03);
1152                 dib0090_write_reg(state, 0x39, (1 << 10));
1153         }
1154 }
1155
1156 EXPORT_SYMBOL(dib0090_pwm_gain_reset);
1157
1158 void dib0090_set_dc_servo(struct dvb_frontend *fe, u8 DC_servo_cutoff)
1159 {
1160         struct dib0090_state *state = fe->tuner_priv;
1161         if (DC_servo_cutoff < 4)
1162                 dib0090_write_reg(state, 0x04, DC_servo_cutoff);
1163 }
1164 EXPORT_SYMBOL(dib0090_set_dc_servo);
1165
1166 static u32 dib0090_get_slow_adc_val(struct dib0090_state *state)
1167 {
1168         u16 adc_val = dib0090_read_reg(state, 0x1d);
1169         if (state->identity.in_soc)
1170                 adc_val >>= 2;
1171         return adc_val;
1172 }
1173
1174 int dib0090_gain_control(struct dvb_frontend *fe)
1175 {
1176         struct dib0090_state *state = fe->tuner_priv;
1177         enum frontend_tune_state *tune_state = &state->tune_state;
1178         int ret = 10;
1179
1180         u16 wbd_val = 0;
1181         u8 apply_gain_immediatly = 1;
1182         s16 wbd_error = 0, adc_error = 0;
1183
1184         if (*tune_state == CT_AGC_START) {
1185                 state->agc_freeze = 0;
1186                 dib0090_write_reg(state, 0x04, 0x0);
1187
1188 #ifdef CONFIG_BAND_SBAND
1189                 if (state->current_band == BAND_SBAND) {
1190                         dib0090_set_rframp(state, rf_ramp_sband);
1191                         dib0090_set_bbramp(state, bb_ramp_boost);
1192                 } else
1193 #endif
1194 #ifdef CONFIG_BAND_VHF
1195                 if (state->current_band == BAND_VHF && !state->identity.p1g) {
1196                         dib0090_set_rframp(state, rf_ramp_vhf);
1197                         dib0090_set_bbramp(state, bb_ramp_boost);
1198                 } else
1199 #endif
1200 #ifdef CONFIG_BAND_CBAND
1201                 if (state->current_band == BAND_CBAND && !state->identity.p1g) {
1202                         dib0090_set_rframp(state, rf_ramp_cband);
1203                         dib0090_set_bbramp(state, bb_ramp_boost);
1204                 } else
1205 #endif
1206                 if ((state->current_band == BAND_CBAND || state->current_band == BAND_VHF) && state->identity.p1g) {
1207                         dib0090_set_rframp(state, rf_ramp_cband_broadmatching);
1208                         dib0090_set_bbramp(state, bb_ramp_boost);
1209                 } else {
1210                         dib0090_set_rframp(state, rf_ramp_uhf);
1211                         dib0090_set_bbramp(state, bb_ramp_boost);
1212                 }
1213
1214                 dib0090_write_reg(state, 0x32, 0);
1215                 dib0090_write_reg(state, 0x39, 0);
1216
1217                 dib0090_wbd_target(state, state->current_rf);
1218
1219                 state->rf_gain_limit = state->rf_ramp[0] << WBD_ALPHA;
1220                 state->current_gain = ((state->rf_ramp[0] + state->bb_ramp[0]) / 2) << GAIN_ALPHA;
1221
1222                 *tune_state = CT_AGC_STEP_0;
1223         } else if (!state->agc_freeze) {
1224                 s16 wbd = 0, i, cnt;
1225
1226                 int adc;
1227                 wbd_val = dib0090_get_slow_adc_val(state);
1228
1229                 if (*tune_state == CT_AGC_STEP_0)
1230                         cnt = 5;
1231                 else
1232                         cnt = 1;
1233
1234                 for (i = 0; i < cnt; i++) {
1235                         wbd_val = dib0090_get_slow_adc_val(state);
1236                         wbd += dib0090_wbd_to_db(state, wbd_val);
1237                 }
1238                 wbd /= cnt;
1239                 wbd_error = state->wbd_target - wbd;
1240
1241                 if (*tune_state == CT_AGC_STEP_0) {
1242                         if (wbd_error < 0 && state->rf_gain_limit > 0 && !state->identity.p1g) {
1243 #ifdef CONFIG_BAND_CBAND
1244                                 /* in case of CBAND tune reduce first the lt_gain2 before adjusting the RF gain */
1245                                 u8 ltg2 = (state->rf_lt_def >> 10) & 0x7;
1246                                 if (state->current_band == BAND_CBAND && ltg2) {
1247                                         ltg2 >>= 1;
1248                                         state->rf_lt_def &= ltg2 << 10; /* reduce in 3 steps from 7 to 0 */
1249                                 }
1250 #endif
1251                         } else {
1252                                 state->agc_step = 0;
1253                                 *tune_state = CT_AGC_STEP_1;
1254                         }
1255                 } else {
1256                         /* calc the adc power */
1257                         adc = state->config->get_adc_power(fe);
1258                         adc = (adc * ((s32) 355774) + (((s32) 1) << 20)) >> 21; /* included in [0:-700] */
1259
1260                         adc_error = (s16) (((s32) ADC_TARGET) - adc);
1261 #ifdef CONFIG_STANDARD_DAB
1262                         if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB)
1263                                 adc_error -= 10;
1264 #endif
1265 #ifdef CONFIG_STANDARD_DVBT
1266                         if (state->fe->dtv_property_cache.delivery_system == STANDARD_DVBT &&
1267                                         (state->fe->dtv_property_cache.modulation == QAM_64 || state->fe->dtv_property_cache.modulation == QAM_16))
1268                                 adc_error += 60;
1269 #endif
1270 #ifdef CONFIG_SYS_ISDBT
1271                         if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) && (((state->fe->dtv_property_cache.layer[0].segment_count >
1272                                                                 0)
1273                                                         &&
1274                                                         ((state->fe->dtv_property_cache.layer[0].modulation ==
1275                                                           QAM_64)
1276                                                          || (state->fe->dtv_property_cache.
1277                                                                  layer[0].modulation == QAM_16)))
1278                                                 ||
1279                                                 ((state->fe->dtv_property_cache.layer[1].segment_count >
1280                                                   0)
1281                                                  &&
1282                                                  ((state->fe->dtv_property_cache.layer[1].modulation ==
1283                                                    QAM_64)
1284                                                   || (state->fe->dtv_property_cache.
1285                                                           layer[1].modulation == QAM_16)))
1286                                                 ||
1287                                                 ((state->fe->dtv_property_cache.layer[2].segment_count >
1288                                                   0)
1289                                                  &&
1290                                                  ((state->fe->dtv_property_cache.layer[2].modulation ==
1291                                                    QAM_64)
1292                                                   || (state->fe->dtv_property_cache.
1293                                                           layer[2].modulation == QAM_16)))
1294                                                 )
1295                                 )
1296                                 adc_error += 60;
1297 #endif
1298
1299                         if (*tune_state == CT_AGC_STEP_1) {     /* quickly go to the correct range of the ADC power */
1300                                 if (ABS(adc_error) < 50 || state->agc_step++ > 5) {
1301
1302 #ifdef CONFIG_STANDARD_DAB
1303                                         if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) {
1304                                                 dib0090_write_reg(state, 0x02, (1 << 15) | (15 << 11) | (31 << 6) | (63));      /* cap value = 63 : narrow BB filter : Fc = 1.8MHz */
1305                                                 dib0090_write_reg(state, 0x04, 0x0);
1306                                         } else
1307 #endif
1308                                         {
1309                                                 dib0090_write_reg(state, 0x02, (1 << 15) | (3 << 11) | (6 << 6) | (32));
1310                                                 dib0090_write_reg(state, 0x04, 0x01);   /*0 = 1KHz ; 1 = 150Hz ; 2 = 50Hz ; 3 = 50KHz ; 4 = servo fast */
1311                                         }
1312
1313                                         *tune_state = CT_AGC_STOP;
1314                                 }
1315                         } else {
1316                                 /* everything higher than or equal to CT_AGC_STOP means tracking */
1317                                 ret = 100;      /* 10ms interval */
1318                                 apply_gain_immediatly = 0;
1319                         }
1320                 }
1321 #ifdef DEBUG_AGC
1322                 dprintk
1323                         ("tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm",
1324                          (u32) *tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val,
1325                          (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA));
1326 #endif
1327         }
1328
1329         /* apply gain */
1330         if (!state->agc_freeze)
1331                 dib0090_gain_apply(state, adc_error, wbd_error, apply_gain_immediatly);
1332         return ret;
1333 }
1334
1335 EXPORT_SYMBOL(dib0090_gain_control);
1336
1337 void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt)
1338 {
1339         struct dib0090_state *state = fe->tuner_priv;
1340         if (rf)
1341                 *rf = state->gain[0];
1342         if (bb)
1343                 *bb = state->gain[1];
1344         if (rf_gain_limit)
1345                 *rf_gain_limit = state->rf_gain_limit;
1346         if (rflt)
1347                 *rflt = (state->rf_lt_def >> 10) & 0x7;
1348 }
1349
1350 EXPORT_SYMBOL(dib0090_get_current_gain);
1351
1352 u16 dib0090_get_wbd_target(struct dvb_frontend *fe)
1353 {
1354         struct dib0090_state *state = fe->tuner_priv;
1355         u32 f_MHz = state->fe->dtv_property_cache.frequency / 1000000;
1356         s32 current_temp = state->temperature;
1357         s32 wbd_thot, wbd_tcold;
1358         const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1359
1360         while (f_MHz > wbd->max_freq)
1361                 wbd++;
1362
1363         dprintk("using wbd-table-entry with max freq %d", wbd->max_freq);
1364
1365         if (current_temp < 0)
1366                 current_temp = 0;
1367         if (current_temp > 128)
1368                 current_temp = 128;
1369
1370         state->wbdmux &= ~(7 << 13);
1371         if (wbd->wbd_gain != 0)
1372                 state->wbdmux |= (wbd->wbd_gain << 13);
1373         else
1374                 state->wbdmux |= (4 << 13);
1375
1376         dib0090_write_reg(state, 0x10, state->wbdmux);
1377
1378         wbd_thot = wbd->offset_hot - (((u32) wbd->slope_hot * f_MHz) >> 6);
1379         wbd_tcold = wbd->offset_cold - (((u32) wbd->slope_cold * f_MHz) >> 6);
1380
1381         wbd_tcold += ((wbd_thot - wbd_tcold) * current_temp) >> 7;
1382
1383         state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + wbd_tcold);
1384         dprintk("wbd-target: %d dB", (u32) state->wbd_target);
1385         dprintk("wbd offset applied is %d", wbd_tcold);
1386
1387         return state->wbd_offset + wbd_tcold;
1388 }
1389 EXPORT_SYMBOL(dib0090_get_wbd_target);
1390
1391 u16 dib0090_get_wbd_offset(struct dvb_frontend *fe)
1392 {
1393         struct dib0090_state *state = fe->tuner_priv;
1394         return state->wbd_offset;
1395 }
1396 EXPORT_SYMBOL(dib0090_get_wbd_offset);
1397
1398 int dib0090_set_switch(struct dvb_frontend *fe, u8 sw1, u8 sw2, u8 sw3)
1399 {
1400         struct dib0090_state *state = fe->tuner_priv;
1401
1402         dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xfff8)
1403                         | ((sw3 & 1) << 2) | ((sw2 & 1) << 1) | (sw1 & 1));
1404
1405         return 0;
1406 }
1407 EXPORT_SYMBOL(dib0090_set_switch);
1408
1409 int dib0090_set_vga(struct dvb_frontend *fe, u8 onoff)
1410 {
1411         struct dib0090_state *state = fe->tuner_priv;
1412
1413         dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x7fff)
1414                         | ((onoff & 1) << 15));
1415         return 0;
1416 }
1417 EXPORT_SYMBOL(dib0090_set_vga);
1418
1419 int dib0090_update_rframp_7090(struct dvb_frontend *fe, u8 cfg_sensitivity)
1420 {
1421         struct dib0090_state *state = fe->tuner_priv;
1422
1423         if ((!state->identity.p1g) || (!state->identity.in_soc)
1424                         || ((state->identity.version != SOC_7090_P1G_21R1)
1425                                 && (state->identity.version != SOC_7090_P1G_11R1))) {
1426                 dprintk("%s() function can only be used for dib7090P", __func__);
1427                 return -ENODEV;
1428         }
1429
1430         if (cfg_sensitivity)
1431                 state->rf_ramp = (const u16 *)&rf_ramp_pwm_cband_7090e_sensitivity;
1432         else
1433                 state->rf_ramp = (const u16 *)&rf_ramp_pwm_cband_7090e_aci;
1434         dib0090_pwm_gain_reset(fe);
1435
1436         return 0;
1437 }
1438 EXPORT_SYMBOL(dib0090_update_rframp_7090);
1439
1440 static const u16 dib0090_defaults[] = {
1441
1442         25, 0x01,
1443         0x0000,
1444         0x99a0,
1445         0x6008,
1446         0x0000,
1447         0x8bcb,
1448         0x0000,
1449         0x0405,
1450         0x0000,
1451         0x0000,
1452         0x0000,
1453         0xb802,
1454         0x0300,
1455         0x2d12,
1456         0xbac0,
1457         0x7c00,
1458         0xdbb9,
1459         0x0954,
1460         0x0743,
1461         0x8000,
1462         0x0001,
1463         0x0040,
1464         0x0100,
1465         0x0000,
1466         0xe910,
1467         0x149e,
1468
1469         1, 0x1c,
1470         0xff2d,
1471
1472         1, 0x39,
1473         0x0000,
1474
1475         2, 0x1e,
1476         0x07FF,
1477         0x0007,
1478
1479         1, 0x24,
1480         EN_UHF | EN_CRYSTAL,
1481
1482         2, 0x3c,
1483         0x3ff,
1484         0x111,
1485         0
1486 };
1487
1488 static const u16 dib0090_p1g_additionnal_defaults[] = {
1489         1, 0x05,
1490         0xabcd,
1491
1492         1, 0x11,
1493         0x00b4,
1494
1495         1, 0x1c,
1496         0xfffd,
1497
1498         1, 0x40,
1499         0x108,
1500         0
1501 };
1502
1503 static void dib0090_set_default_config(struct dib0090_state *state, const u16 * n)
1504 {
1505         u16 l, r;
1506
1507         l = pgm_read_word(n++);
1508         while (l) {
1509                 r = pgm_read_word(n++);
1510                 do {
1511                         dib0090_write_reg(state, r, pgm_read_word(n++));
1512                         r++;
1513                 } while (--l);
1514                 l = pgm_read_word(n++);
1515         }
1516 }
1517
1518 #define CAP_VALUE_MIN (u8)  9
1519 #define CAP_VALUE_MAX (u8) 40
1520 #define HR_MIN        (u8) 25
1521 #define HR_MAX        (u8) 40
1522 #define POLY_MIN      (u8)  0
1523 #define POLY_MAX      (u8)  8
1524
1525 static void dib0090_set_EFUSE(struct dib0090_state *state)
1526 {
1527         u8 c, h, n;
1528         u16 e2, e4;
1529         u16 cal;
1530
1531         e2 = dib0090_read_reg(state, 0x26);
1532         e4 = dib0090_read_reg(state, 0x28);
1533
1534         if ((state->identity.version == P1D_E_F) ||
1535                         (state->identity.version == P1G) || (e2 == 0xffff)) {
1536
1537                 dib0090_write_reg(state, 0x22, 0x10);
1538                 cal = (dib0090_read_reg(state, 0x22) >> 6) & 0x3ff;
1539
1540                 if ((cal < 670) || (cal == 1023))
1541                         cal = 850;
1542                 n = 165 - ((cal * 10)>>6) ;
1543                 e2 = e4 = (3<<12) | (34<<6) | (n);
1544         }
1545
1546         if (e2 != e4)
1547                 e2 &= e4; /* Remove the redundancy  */
1548
1549         if (e2 != 0xffff) {
1550                 c = e2 & 0x3f;
1551                 n = (e2 >> 12) & 0xf;
1552                 h = (e2 >> 6) & 0x3f;
1553
1554                 if ((c >= CAP_VALUE_MAX) || (c <= CAP_VALUE_MIN))
1555                         c = 32;
1556                 if ((h >= HR_MAX) || (h <= HR_MIN))
1557                         h = 34;
1558                 if ((n >= POLY_MAX) || (n <= POLY_MIN))
1559                         n = 3;
1560
1561                 dib0090_write_reg(state, 0x13, (h << 10)) ;
1562                 e2 = (n<<11) | ((h>>2)<<6) | (c);
1563                 dib0090_write_reg(state, 0x2, e2) ; /* Load the BB_2 */
1564         }
1565 }
1566
1567 static int dib0090_reset(struct dvb_frontend *fe)
1568 {
1569         struct dib0090_state *state = fe->tuner_priv;
1570
1571         dib0090_reset_digital(fe, state->config);
1572         if (dib0090_identify(fe) < 0)
1573                 return -EIO;
1574
1575 #ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT
1576         if (!(state->identity.version & 0x1))   /* it is P1B - reset is already done */
1577                 return 0;
1578 #endif
1579
1580         if (!state->identity.in_soc) {
1581                 if ((dib0090_read_reg(state, 0x1a) >> 5) & 0x2)
1582                         dib0090_write_reg(state, 0x1b, (EN_IQADC | EN_BB | EN_BIAS | EN_DIGCLK | EN_PLL | EN_CRYSTAL));
1583                 else
1584                         dib0090_write_reg(state, 0x1b, (EN_DIGCLK | EN_PLL | EN_CRYSTAL));
1585         }
1586
1587         dib0090_set_default_config(state, dib0090_defaults);
1588
1589         if (state->identity.in_soc)
1590                 dib0090_write_reg(state, 0x18, 0x2910);  /* charge pump current = 0 */
1591
1592         if (state->identity.p1g)
1593                 dib0090_set_default_config(state, dib0090_p1g_additionnal_defaults);
1594
1595         /* Update the efuse : Only available for KROSUS > P1C  and SOC as well*/
1596         if (((state->identity.version & 0x1f) >= P1D_E_F) || (state->identity.in_soc))
1597                 dib0090_set_EFUSE(state);
1598
1599         /* Congigure in function of the crystal */
1600         if (state->config->force_crystal_mode != 0)
1601                 dib0090_write_reg(state, 0x14,
1602                                 state->config->force_crystal_mode & 3);
1603         else if (state->config->io.clock_khz >= 24000)
1604                 dib0090_write_reg(state, 0x14, 1);
1605         else
1606                 dib0090_write_reg(state, 0x14, 2);
1607         dprintk("Pll lock : %d", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1);
1608
1609         state->calibrate = DC_CAL | WBD_CAL | TEMP_CAL; /* enable iq-offset-calibration and wbd-calibration when tuning next time */
1610
1611         return 0;
1612 }
1613
1614 #define steps(u) (((u) > 15) ? ((u)-16) : (u))
1615 #define INTERN_WAIT 10
1616 static int dib0090_get_offset(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1617 {
1618         int ret = INTERN_WAIT * 10;
1619
1620         switch (*tune_state) {
1621         case CT_TUNER_STEP_2:
1622                 /* Turns to positive */
1623                 dib0090_write_reg(state, 0x1f, 0x7);
1624                 *tune_state = CT_TUNER_STEP_3;
1625                 break;
1626
1627         case CT_TUNER_STEP_3:
1628                 state->adc_diff = dib0090_read_reg(state, 0x1d);
1629
1630                 /* Turns to negative */
1631                 dib0090_write_reg(state, 0x1f, 0x4);
1632                 *tune_state = CT_TUNER_STEP_4;
1633                 break;
1634
1635         case CT_TUNER_STEP_4:
1636                 state->adc_diff -= dib0090_read_reg(state, 0x1d);
1637                 *tune_state = CT_TUNER_STEP_5;
1638                 ret = 0;
1639                 break;
1640
1641         default:
1642                 break;
1643         }
1644
1645         return ret;
1646 }
1647
1648 struct dc_calibration {
1649         u8 addr;
1650         u8 offset;
1651         u8 pga:1;
1652         u16 bb1;
1653         u8 i:1;
1654 };
1655
1656 static const struct dc_calibration dc_table[] = {
1657         /* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */
1658         {0x06, 5, 1, (1 << 13) | (0 << 8) | (26 << 3), 1},
1659         {0x07, 11, 1, (1 << 13) | (0 << 8) | (26 << 3), 0},
1660         /* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */
1661         {0x06, 0, 0, (1 << 13) | (29 << 8) | (26 << 3), 1},
1662         {0x06, 10, 0, (1 << 13) | (29 << 8) | (26 << 3), 0},
1663         {0},
1664 };
1665
1666 static const struct dc_calibration dc_p1g_table[] = {
1667         /* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */
1668         /* addr ; trim reg offset ; pga ; CTRL_BB1 value ; i or q */
1669         {0x06, 5, 1, (1 << 13) | (0 << 8) | (15 << 3), 1},
1670         {0x07, 11, 1, (1 << 13) | (0 << 8) | (15 << 3), 0},
1671         /* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */
1672         {0x06, 0, 0, (1 << 13) | (29 << 8) | (15 << 3), 1},
1673         {0x06, 10, 0, (1 << 13) | (29 << 8) | (15 << 3), 0},
1674         {0},
1675 };
1676
1677 static void dib0090_set_trim(struct dib0090_state *state)
1678 {
1679         u16 *val;
1680
1681         if (state->dc->addr == 0x07)
1682                 val = &state->bb7;
1683         else
1684                 val = &state->bb6;
1685
1686         *val &= ~(0x1f << state->dc->offset);
1687         *val |= state->step << state->dc->offset;
1688
1689         dib0090_write_reg(state, state->dc->addr, *val);
1690 }
1691
1692 static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1693 {
1694         int ret = 0;
1695         u16 reg;
1696
1697         switch (*tune_state) {
1698         case CT_TUNER_START:
1699                 dprintk("Start DC offset calibration");
1700
1701                 /* force vcm2 = 0.8V */
1702                 state->bb6 = 0;
1703                 state->bb7 = 0x040d;
1704
1705                 /* the LNA AND LO are off */
1706                 reg = dib0090_read_reg(state, 0x24) & 0x0ffb;   /* shutdown lna and lo */
1707                 dib0090_write_reg(state, 0x24, reg);
1708
1709                 state->wbdmux = dib0090_read_reg(state, 0x10);
1710                 dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x7 << 3) | 0x3);
1711                 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
1712
1713                 state->dc = dc_table;
1714
1715                 if (state->identity.p1g)
1716                         state->dc = dc_p1g_table;
1717                 *tune_state = CT_TUNER_STEP_0;
1718
1719                 /* fall through */
1720
1721         case CT_TUNER_STEP_0:
1722                 dprintk("Sart/continue DC calibration for %s path", (state->dc->i == 1) ? "I" : "Q");
1723                 dib0090_write_reg(state, 0x01, state->dc->bb1);
1724                 dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7));
1725
1726                 state->step = 0;
1727                 state->min_adc_diff = 1023;
1728                 *tune_state = CT_TUNER_STEP_1;
1729                 ret = 50;
1730                 break;
1731
1732         case CT_TUNER_STEP_1:
1733                 dib0090_set_trim(state);
1734                 *tune_state = CT_TUNER_STEP_2;
1735                 break;
1736
1737         case CT_TUNER_STEP_2:
1738         case CT_TUNER_STEP_3:
1739         case CT_TUNER_STEP_4:
1740                 ret = dib0090_get_offset(state, tune_state);
1741                 break;
1742
1743         case CT_TUNER_STEP_5:   /* found an offset */
1744                 dprintk("adc_diff = %d, current step= %d", (u32) state->adc_diff, state->step);
1745                 if (state->step == 0 && state->adc_diff < 0) {
1746                         state->min_adc_diff = -1023;
1747                         dprintk("Change of sign of the minimum adc diff");
1748                 }
1749
1750                 dprintk("adc_diff = %d, min_adc_diff = %d current_step = %d", state->adc_diff, state->min_adc_diff, state->step);
1751
1752                 /* first turn for this frequency */
1753                 if (state->step == 0) {
1754                         if (state->dc->pga && state->adc_diff < 0)
1755                                 state->step = 0x10;
1756                         if (state->dc->pga == 0 && state->adc_diff > 0)
1757                                 state->step = 0x10;
1758                 }
1759
1760                 /* Look for a change of Sign in the Adc_diff.min_adc_diff is used to STORE the setp N-1 */
1761                 if ((state->adc_diff & 0x8000) == (state->min_adc_diff & 0x8000) && steps(state->step) < 15) {
1762                         /* stop search when the delta the sign is changing and Steps =15 and Step=0 is force for continuance */
1763                         state->step++;
1764                         state->min_adc_diff = state->adc_diff;
1765                         *tune_state = CT_TUNER_STEP_1;
1766                 } else {
1767                         /* the minimum was what we have seen in the step before */
1768                         if (ABS(state->adc_diff) > ABS(state->min_adc_diff)) {
1769                                 dprintk("Since adc_diff N = %d  > adc_diff step N-1 = %d, Come back one step", state->adc_diff, state->min_adc_diff);
1770                                 state->step--;
1771                         }
1772
1773                         dib0090_set_trim(state);
1774                         dprintk("BB Offset Cal, BBreg=%hd,Offset=%hd,Value Set=%hd", state->dc->addr, state->adc_diff, state->step);
1775
1776                         state->dc++;
1777                         if (state->dc->addr == 0)       /* done */
1778                                 *tune_state = CT_TUNER_STEP_6;
1779                         else
1780                                 *tune_state = CT_TUNER_STEP_0;
1781
1782                 }
1783                 break;
1784
1785         case CT_TUNER_STEP_6:
1786                 dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008);
1787                 dib0090_write_reg(state, 0x1f, 0x7);
1788                 *tune_state = CT_TUNER_START;   /* reset done -> real tuning can now begin */
1789                 state->calibrate &= ~DC_CAL;
1790         default:
1791                 break;
1792         }
1793         return ret;
1794 }
1795
1796 static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1797 {
1798         u8 wbd_gain;
1799         const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1800
1801         switch (*tune_state) {
1802         case CT_TUNER_START:
1803                 while (state->current_rf / 1000 > wbd->max_freq)
1804                         wbd++;
1805                 if (wbd->wbd_gain != 0)
1806                         wbd_gain = wbd->wbd_gain;
1807                 else {
1808                         wbd_gain = 4;
1809 #if defined(CONFIG_BAND_LBAND) || defined(CONFIG_BAND_SBAND)
1810                         if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND))
1811                                 wbd_gain = 2;
1812 #endif
1813                 }
1814
1815                 if (wbd_gain == state->wbd_calibration_gain) {  /* the WBD calibration has already been done */
1816                         *tune_state = CT_TUNER_START;
1817                         state->calibrate &= ~WBD_CAL;
1818                         return 0;
1819                 }
1820
1821                 dib0090_write_reg(state, 0x10, 0x1b81 | (1 << 10) | (wbd_gain << 13) | (1 << 3));
1822
1823                 dib0090_write_reg(state, 0x24, ((EN_UHF & 0x0fff) | (1 << 1)));
1824                 *tune_state = CT_TUNER_STEP_0;
1825                 state->wbd_calibration_gain = wbd_gain;
1826                 return 90;      /* wait for the WBDMUX to switch and for the ADC to sample */
1827
1828         case CT_TUNER_STEP_0:
1829                 state->wbd_offset = dib0090_get_slow_adc_val(state);
1830                 dprintk("WBD calibration offset = %d", state->wbd_offset);
1831                 *tune_state = CT_TUNER_START;   /* reset done -> real tuning can now begin */
1832                 state->calibrate &= ~WBD_CAL;
1833                 break;
1834
1835         default:
1836                 break;
1837         }
1838         return 0;
1839 }
1840
1841 static void dib0090_set_bandwidth(struct dib0090_state *state)
1842 {
1843         u16 tmp;
1844
1845         if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 5000)
1846                 tmp = (3 << 14);
1847         else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 6000)
1848                 tmp = (2 << 14);
1849         else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 7000)
1850                 tmp = (1 << 14);
1851         else
1852                 tmp = (0 << 14);
1853
1854         state->bb_1_def &= 0x3fff;
1855         state->bb_1_def |= tmp;
1856
1857         dib0090_write_reg(state, 0x01, state->bb_1_def);        /* be sure that we have the right bb-filter */
1858
1859         dib0090_write_reg(state, 0x03, 0x6008); /* = 0x6008 : vcm3_trim = 1 ; filter2_gm1_trim = 8 ; filter2_cutoff_freq = 0 */
1860         dib0090_write_reg(state, 0x04, 0x1);    /* 0 = 1KHz ; 1 = 50Hz ; 2 = 150Hz ; 3 = 50KHz ; 4 = servo fast */
1861         if (state->identity.in_soc) {
1862                 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 */
1863         } else {
1864                 dib0090_write_reg(state, 0x02, (5 << 11) | (8 << 6) | (22 & 0x3f));     /* 22 = cap_value */
1865                 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 */
1866         }
1867 }
1868
1869 static const struct dib0090_pll dib0090_pll_table[] = {
1870 #ifdef CONFIG_BAND_CBAND
1871         {56000, 0, 9, 48, 6},
1872         {70000, 1, 9, 48, 6},
1873         {87000, 0, 8, 32, 4},
1874         {105000, 1, 8, 32, 4},
1875         {115000, 0, 7, 24, 6},
1876         {140000, 1, 7, 24, 6},
1877         {170000, 0, 6, 16, 4},
1878 #endif
1879 #ifdef CONFIG_BAND_VHF
1880         {200000, 1, 6, 16, 4},
1881         {230000, 0, 5, 12, 6},
1882         {280000, 1, 5, 12, 6},
1883         {340000, 0, 4, 8, 4},
1884         {380000, 1, 4, 8, 4},
1885         {450000, 0, 3, 6, 6},
1886 #endif
1887 #ifdef CONFIG_BAND_UHF
1888         {580000, 1, 3, 6, 6},
1889         {700000, 0, 2, 4, 4},
1890         {860000, 1, 2, 4, 4},
1891 #endif
1892 #ifdef CONFIG_BAND_LBAND
1893         {1800000, 1, 0, 2, 4},
1894 #endif
1895 #ifdef CONFIG_BAND_SBAND
1896         {2900000, 0, 14, 1, 4},
1897 #endif
1898 };
1899
1900 static const struct dib0090_tuning dib0090_tuning_table_fm_vhf_on_cband[] = {
1901
1902 #ifdef CONFIG_BAND_CBAND
1903         {184000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1904         {227000, 4, 3, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1905         {380000, 4, 7, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1906 #endif
1907 #ifdef CONFIG_BAND_UHF
1908         {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1909         {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1910         {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1911         {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1912         {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1913         {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1914 #endif
1915 #ifdef CONFIG_BAND_LBAND
1916         {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1917         {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1918         {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1919 #endif
1920 #ifdef CONFIG_BAND_SBAND
1921         {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1922         {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1923 #endif
1924 };
1925
1926 static const struct dib0090_tuning dib0090_tuning_table[] = {
1927
1928 #ifdef CONFIG_BAND_CBAND
1929         {170000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1930 #endif
1931 #ifdef CONFIG_BAND_VHF
1932         {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1933         {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1934         {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1935 #endif
1936 #ifdef CONFIG_BAND_UHF
1937         {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1938         {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1939         {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1940         {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1941         {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1942         {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1943 #endif
1944 #ifdef CONFIG_BAND_LBAND
1945         {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1946         {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1947         {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1948 #endif
1949 #ifdef CONFIG_BAND_SBAND
1950         {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1951         {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1952 #endif
1953 };
1954
1955 static const struct dib0090_tuning dib0090_p1g_tuning_table[] = {
1956 #ifdef CONFIG_BAND_CBAND
1957         {170000, 4, 1, 0x820f, 0x300, 0x2d22, 0x82cb, EN_CAB},
1958 #endif
1959 #ifdef CONFIG_BAND_VHF
1960         {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1961         {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1962         {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1963 #endif
1964 #ifdef CONFIG_BAND_UHF
1965         {510000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1966         {540000, 2, 1, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1967         {600000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1968         {630000, 2, 4, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1969         {680000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1970         {720000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1971         {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1972 #endif
1973 #ifdef CONFIG_BAND_LBAND
1974         {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1975         {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1976         {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1977 #endif
1978 #ifdef CONFIG_BAND_SBAND
1979         {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1980         {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1981 #endif
1982 };
1983
1984 static const struct dib0090_pll dib0090_p1g_pll_table[] = {
1985 #ifdef CONFIG_BAND_CBAND
1986         {57000, 0, 11, 48, 6},
1987         {70000, 1, 11, 48, 6},
1988         {86000, 0, 10, 32, 4},
1989         {105000, 1, 10, 32, 4},
1990         {115000, 0, 9, 24, 6},
1991         {140000, 1, 9, 24, 6},
1992         {170000, 0, 8, 16, 4},
1993 #endif
1994 #ifdef CONFIG_BAND_VHF
1995         {200000, 1, 8, 16, 4},
1996         {230000, 0, 7, 12, 6},
1997         {280000, 1, 7, 12, 6},
1998         {340000, 0, 6, 8, 4},
1999         {380000, 1, 6, 8, 4},
2000         {455000, 0, 5, 6, 6},
2001 #endif
2002 #ifdef CONFIG_BAND_UHF
2003         {580000, 1, 5, 6, 6},
2004         {680000, 0, 4, 4, 4},
2005         {860000, 1, 4, 4, 4},
2006 #endif
2007 #ifdef CONFIG_BAND_LBAND
2008         {1800000, 1, 2, 2, 4},
2009 #endif
2010 #ifdef CONFIG_BAND_SBAND
2011         {2900000, 0, 1, 1, 6},
2012 #endif
2013 };
2014
2015 static const struct dib0090_tuning dib0090_p1g_tuning_table_fm_vhf_on_cband[] = {
2016 #ifdef CONFIG_BAND_CBAND
2017         {184000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
2018         {227000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
2019         {380000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
2020 #endif
2021 #ifdef CONFIG_BAND_UHF
2022         {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2023         {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2024         {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2025         {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2026         {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2027         {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2028 #endif
2029 #ifdef CONFIG_BAND_LBAND
2030         {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
2031         {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
2032         {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
2033 #endif
2034 #ifdef CONFIG_BAND_SBAND
2035         {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
2036         {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
2037 #endif
2038 };
2039
2040 static const struct dib0090_tuning dib0090_tuning_table_cband_7090[] = {
2041 #ifdef CONFIG_BAND_CBAND
2042         {300000, 4, 3, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2043         {380000, 4, 10, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2044         {570000, 4, 10, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2045         {858000, 4, 5, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2046 #endif
2047 };
2048
2049 static const struct dib0090_tuning dib0090_tuning_table_cband_7090e_sensitivity[] = {
2050 #ifdef CONFIG_BAND_CBAND
2051         { 300000,  0 ,  3,  0x8105, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
2052         { 380000,  0 ,  10, 0x810F, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
2053         { 600000,  0 ,  10, 0x815E, 0x280, 0x2d12, 0xb84e, EN_CAB },
2054         { 660000,  0 ,  5,  0x85E3, 0x280, 0x2d12, 0xb84e, EN_CAB },
2055         { 720000,  0 ,  5,  0x852E, 0x280, 0x2d12, 0xb84e, EN_CAB },
2056         { 860000,  0 ,  4,  0x85E5, 0x280, 0x2d12, 0xb84e, EN_CAB },
2057 #endif
2058 };
2059
2060 int dib0090_update_tuning_table_7090(struct dvb_frontend *fe,
2061                 u8 cfg_sensitivity)
2062 {
2063         struct dib0090_state *state = fe->tuner_priv;
2064         const struct dib0090_tuning *tune =
2065                 dib0090_tuning_table_cband_7090e_sensitivity;
2066         const struct dib0090_tuning dib0090_tuning_table_cband_7090e_aci[] = {
2067                 { 300000,  0 ,  3,  0x8165, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
2068                 { 650000,  0 ,  4,  0x815B, 0x280, 0x2d12, 0xb84e, EN_CAB },
2069                 { 860000,  0 ,  5,  0x84EF, 0x280, 0x2d12, 0xb84e, EN_CAB },
2070         };
2071
2072         if ((!state->identity.p1g) || (!state->identity.in_soc)
2073                         || ((state->identity.version != SOC_7090_P1G_21R1)
2074                                 && (state->identity.version != SOC_7090_P1G_11R1))) {
2075                 dprintk("%s() function can only be used for dib7090", __func__);
2076                 return -ENODEV;
2077         }
2078
2079         if (cfg_sensitivity)
2080                 tune = dib0090_tuning_table_cband_7090e_sensitivity;
2081         else
2082                 tune = dib0090_tuning_table_cband_7090e_aci;
2083
2084         while (state->rf_request > tune->max_freq)
2085                 tune++;
2086
2087         dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x8000)
2088                         | (tune->lna_bias & 0x7fff));
2089         dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xf83f)
2090                         | ((tune->lna_tune << 6) & 0x07c0));
2091         return 0;
2092 }
2093 EXPORT_SYMBOL(dib0090_update_tuning_table_7090);
2094
2095 static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tune_state *tune_state)
2096 {
2097         int ret = 0;
2098         u16 lo4 = 0xe900;
2099
2100         s16 adc_target;
2101         u16 adc;
2102         s8 step_sign;
2103         u8 force_soft_search = 0;
2104
2105         if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
2106                 force_soft_search = 1;
2107
2108         if (*tune_state == CT_TUNER_START) {
2109                 dprintk("Start Captrim search : %s", (force_soft_search == 1) ? "FORCE SOFT SEARCH" : "AUTO");
2110                 dib0090_write_reg(state, 0x10, 0x2B1);
2111                 dib0090_write_reg(state, 0x1e, 0x0032);
2112
2113                 if (!state->tuner_is_tuned) {
2114                         /* prepare a complete captrim */
2115                         if (!state->identity.p1g || force_soft_search)
2116                                 state->step = state->captrim = state->fcaptrim = 64;
2117
2118                         state->current_rf = state->rf_request;
2119                 } else {        /* we are already tuned to this frequency - the configuration is correct  */
2120                         if (!state->identity.p1g || force_soft_search) {
2121                                 /* do a minimal captrim even if the frequency has not changed */
2122                                 state->step = 4;
2123                                 state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f;
2124                         }
2125                 }
2126                 state->adc_diff = 3000;
2127                 *tune_state = CT_TUNER_STEP_0;
2128
2129         } else if (*tune_state == CT_TUNER_STEP_0) {
2130                 if (state->identity.p1g && !force_soft_search) {
2131                         u8 ratio = 31;
2132
2133                         dib0090_write_reg(state, 0x40, (3 << 7) | (ratio << 2) | (1 << 1) | 1);
2134                         dib0090_read_reg(state, 0x40);
2135                         ret = 50;
2136                 } else {
2137                         state->step /= 2;
2138                         dib0090_write_reg(state, 0x18, lo4 | state->captrim);
2139
2140                         if (state->identity.in_soc)
2141                                 ret = 25;
2142                 }
2143                 *tune_state = CT_TUNER_STEP_1;
2144
2145         } else if (*tune_state == CT_TUNER_STEP_1) {
2146                 if (state->identity.p1g && !force_soft_search) {
2147                         dib0090_write_reg(state, 0x40, 0x18c | (0 << 1) | 0);
2148                         dib0090_read_reg(state, 0x40);
2149
2150                         state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7F;
2151                         dprintk("***Final Captrim= 0x%x", state->fcaptrim);
2152                         *tune_state = CT_TUNER_STEP_3;
2153
2154                 } else {
2155                         /* MERGE for all krosus before P1G */
2156                         adc = dib0090_get_slow_adc_val(state);
2157                         dprintk("CAPTRIM=%d; ADC = %d (ADC) & %dmV", (u32) state->captrim, (u32) adc, (u32) (adc) * (u32) 1800 / (u32) 1024);
2158
2159                         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 !!! */
2160                                 adc_target = 200;
2161                         } else
2162                                 adc_target = 400;
2163
2164                         if (adc >= adc_target) {
2165                                 adc -= adc_target;
2166                                 step_sign = -1;
2167                         } else {
2168                                 adc = adc_target - adc;
2169                                 step_sign = 1;
2170                         }
2171
2172                         if (adc < state->adc_diff) {
2173                                 dprintk("CAPTRIM=%d is closer to target (%d/%d)", (u32) state->captrim, (u32) adc, (u32) state->adc_diff);
2174                                 state->adc_diff = adc;
2175                                 state->fcaptrim = state->captrim;
2176                         }
2177
2178                         state->captrim += step_sign * state->step;
2179                         if (state->step >= 1)
2180                                 *tune_state = CT_TUNER_STEP_0;
2181                         else
2182                                 *tune_state = CT_TUNER_STEP_2;
2183
2184                         ret = 25;
2185                 }
2186         } else if (*tune_state == CT_TUNER_STEP_2) {    /* this step is only used by krosus < P1G */
2187                 /*write the final cptrim config */
2188                 dib0090_write_reg(state, 0x18, lo4 | state->fcaptrim);
2189
2190                 *tune_state = CT_TUNER_STEP_3;
2191
2192         } else if (*tune_state == CT_TUNER_STEP_3) {
2193                 state->calibrate &= ~CAPTRIM_CAL;
2194                 *tune_state = CT_TUNER_STEP_0;
2195         }
2196
2197         return ret;
2198 }
2199
2200 static int dib0090_get_temperature(struct dib0090_state *state, enum frontend_tune_state *tune_state)
2201 {
2202         int ret = 15;
2203         s16 val;
2204
2205         switch (*tune_state) {
2206         case CT_TUNER_START:
2207                 state->wbdmux = dib0090_read_reg(state, 0x10);
2208                 dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x8 << 3));
2209
2210                 state->bias = dib0090_read_reg(state, 0x13);
2211                 dib0090_write_reg(state, 0x13, state->bias | (0x3 << 8));
2212
2213                 *tune_state = CT_TUNER_STEP_0;
2214                 /* wait for the WBDMUX to switch and for the ADC to sample */
2215                 break;
2216
2217         case CT_TUNER_STEP_0:
2218                 state->adc_diff = dib0090_get_slow_adc_val(state);
2219                 dib0090_write_reg(state, 0x13, (state->bias & ~(0x3 << 8)) | (0x2 << 8));
2220                 *tune_state = CT_TUNER_STEP_1;
2221                 break;
2222
2223         case CT_TUNER_STEP_1:
2224                 val = dib0090_get_slow_adc_val(state);
2225                 state->temperature = ((s16) ((val - state->adc_diff) * 180) >> 8) + 55;
2226
2227                 dprintk("temperature: %d C", state->temperature - 30);
2228
2229                 *tune_state = CT_TUNER_STEP_2;
2230                 break;
2231
2232         case CT_TUNER_STEP_2:
2233                 dib0090_write_reg(state, 0x13, state->bias);
2234                 dib0090_write_reg(state, 0x10, state->wbdmux);  /* write back original WBDMUX */
2235
2236                 *tune_state = CT_TUNER_START;
2237                 state->calibrate &= ~TEMP_CAL;
2238                 if (state->config->analog_output == 0)
2239                         dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
2240
2241                 break;
2242
2243         default:
2244                 ret = 0;
2245                 break;
2246         }
2247         return ret;
2248 }
2249
2250 #define WBD     0x781           /* 1 1 1 1 0000 0 0 1 */
2251 static int dib0090_tune(struct dvb_frontend *fe)
2252 {
2253         struct dib0090_state *state = fe->tuner_priv;
2254         const struct dib0090_tuning *tune = state->current_tune_table_index;
2255         const struct dib0090_pll *pll = state->current_pll_table_index;
2256         enum frontend_tune_state *tune_state = &state->tune_state;
2257
2258         u16 lo5, lo6, Den, tmp;
2259         u32 FBDiv, Rest, FREF, VCOF_kHz = 0;
2260         int ret = 10;           /* 1ms is the default delay most of the time */
2261         u8 c, i;
2262
2263         /************************* VCO ***************************/
2264         /* Default values for FG                                 */
2265         /* from these are needed :                               */
2266         /* Cp,HFdiv,VCOband,SD,Num,Den,FB and REFDiv             */
2267
2268         /* in any case we first need to do a calibration if needed */
2269         if (*tune_state == CT_TUNER_START) {
2270                 /* deactivate DataTX before some calibrations */
2271                 if (state->calibrate & (DC_CAL | TEMP_CAL | WBD_CAL))
2272                         dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
2273                 else
2274                         /* Activate DataTX in case a calibration has been done before */
2275                         if (state->config->analog_output == 0)
2276                                 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
2277         }
2278
2279         if (state->calibrate & DC_CAL)
2280                 return dib0090_dc_offset_calibration(state, tune_state);
2281         else if (state->calibrate & WBD_CAL) {
2282                 if (state->current_rf == 0)
2283                         state->current_rf = state->fe->dtv_property_cache.frequency / 1000;
2284                 return dib0090_wbd_calibration(state, tune_state);
2285         } else if (state->calibrate & TEMP_CAL)
2286                 return dib0090_get_temperature(state, tune_state);
2287         else if (state->calibrate & CAPTRIM_CAL)
2288                 return dib0090_captrim_search(state, tune_state);
2289
2290         if (*tune_state == CT_TUNER_START) {
2291                 /* 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 */
2292                 if (state->config->use_pwm_agc && state->identity.in_soc) {
2293                         tmp = dib0090_read_reg(state, 0x39);
2294                         if ((tmp >> 10) & 0x1)
2295                                 dib0090_write_reg(state, 0x39, tmp & ~(1 << 10));
2296                 }
2297
2298                 state->current_band = (u8) BAND_OF_FREQUENCY(state->fe->dtv_property_cache.frequency / 1000);
2299                 state->rf_request =
2300                         state->fe->dtv_property_cache.frequency / 1000 + (state->current_band ==
2301                                         BAND_UHF ? state->config->freq_offset_khz_uhf : state->config->
2302                                         freq_offset_khz_vhf);
2303
2304                 /* in ISDB-T 1seg we shift tuning frequency */
2305                 if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1
2306                                         && state->fe->dtv_property_cache.isdbt_partial_reception == 0)) {
2307                         const struct dib0090_low_if_offset_table *LUT_offset = state->config->low_if;
2308                         u8 found_offset = 0;
2309                         u32 margin_khz = 100;
2310
2311                         if (LUT_offset != NULL) {
2312                                 while (LUT_offset->RF_freq != 0xffff) {
2313                                         if (((state->rf_request > (LUT_offset->RF_freq - margin_khz))
2314                                                                 && (state->rf_request < (LUT_offset->RF_freq + margin_khz)))
2315                                                         && LUT_offset->std == state->fe->dtv_property_cache.delivery_system) {
2316                                                 state->rf_request += LUT_offset->offset_khz;
2317                                                 found_offset = 1;
2318                                                 break;
2319                                         }
2320                                         LUT_offset++;
2321                                 }
2322                         }
2323
2324                         if (found_offset == 0)
2325                                 state->rf_request += 400;
2326                 }
2327                 if (state->current_rf != state->rf_request || (state->current_standard != state->fe->dtv_property_cache.delivery_system)) {
2328                         state->tuner_is_tuned = 0;
2329                         state->current_rf = 0;
2330                         state->current_standard = 0;
2331
2332                         tune = dib0090_tuning_table;
2333                         if (state->identity.p1g)
2334                                 tune = dib0090_p1g_tuning_table;
2335
2336                         tmp = (state->identity.version >> 5) & 0x7;
2337
2338                         if (state->identity.in_soc) {
2339                                 if (state->config->force_cband_input) { /* Use the CBAND input for all band */
2340                                         if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF
2341                                                         || state->current_band & BAND_UHF) {
2342                                                 state->current_band = BAND_CBAND;
2343                                                 if (state->config->is_dib7090e)
2344                                                         tune = dib0090_tuning_table_cband_7090e_sensitivity;
2345                                                 else
2346                                                         tune = dib0090_tuning_table_cband_7090;
2347                                         }
2348                                 } else {        /* Use the CBAND input for all band under UHF */
2349                                         if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF) {
2350                                                 state->current_band = BAND_CBAND;
2351                                                 if (state->config->is_dib7090e)
2352                                                         tune = dib0090_tuning_table_cband_7090e_sensitivity;
2353                                                 else
2354                                                         tune = dib0090_tuning_table_cband_7090;
2355                                         }
2356                                 }
2357                         } else
2358                          if (tmp == 0x4 || tmp == 0x7) {
2359                                 /* CBAND tuner version for VHF */
2360                                 if (state->current_band == BAND_FM || state->current_band == BAND_CBAND || state->current_band == BAND_VHF) {
2361                                         state->current_band = BAND_CBAND;       /* Force CBAND */
2362
2363                                         tune = dib0090_tuning_table_fm_vhf_on_cband;
2364                                         if (state->identity.p1g)
2365                                                 tune = dib0090_p1g_tuning_table_fm_vhf_on_cband;
2366                                 }
2367                         }
2368
2369                         pll = dib0090_pll_table;
2370                         if (state->identity.p1g)
2371                                 pll = dib0090_p1g_pll_table;
2372
2373                         /* Look for the interval */
2374                         while (state->rf_request > tune->max_freq)
2375                                 tune++;
2376                         while (state->rf_request > pll->max_freq)
2377                                 pll++;
2378
2379                         state->current_tune_table_index = tune;
2380                         state->current_pll_table_index = pll;
2381
2382                         dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim));
2383
2384                         VCOF_kHz = (pll->hfdiv * state->rf_request) * 2;
2385
2386                         FREF = state->config->io.clock_khz;
2387                         if (state->config->fref_clock_ratio != 0)
2388                                 FREF /= state->config->fref_clock_ratio;
2389
2390                         FBDiv = (VCOF_kHz / pll->topresc / FREF);
2391                         Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF;
2392
2393                         if (Rest < LPF)
2394                                 Rest = 0;
2395                         else if (Rest < 2 * LPF)
2396                                 Rest = 2 * LPF;
2397                         else if (Rest > (FREF - LPF)) {
2398                                 Rest = 0;
2399                                 FBDiv += 1;
2400                         } else if (Rest > (FREF - 2 * LPF))
2401                                 Rest = FREF - 2 * LPF;
2402                         Rest = (Rest * 6528) / (FREF / 10);
2403                         state->rest = Rest;
2404
2405                         /* external loop filter, otherwise:
2406                          * lo5 = (0 << 15) | (0 << 12) | (0 << 11) | (3 << 9) | (4 << 6) | (3 << 4) | 4;
2407                          * lo6 = 0x0e34 */
2408
2409                         if (Rest == 0) {
2410                                 if (pll->vco_band)
2411                                         lo5 = 0x049f;
2412                                 else
2413                                         lo5 = 0x041f;
2414                         } else {
2415                                 if (pll->vco_band)
2416                                         lo5 = 0x049e;
2417                                 else if (state->config->analog_output)
2418                                         lo5 = 0x041d;
2419                                 else
2420                                         lo5 = 0x041c;
2421                         }
2422
2423                         if (state->identity.p1g) {      /* Bias is done automatically in P1G */
2424                                 if (state->identity.in_soc) {
2425                                         if (state->identity.version == SOC_8090_P1G_11R1)
2426                                                 lo5 = 0x46f;
2427                                         else
2428                                                 lo5 = 0x42f;
2429                                 } else
2430                                         lo5 = 0x42c;
2431                         }
2432
2433                         lo5 |= (pll->hfdiv_code << 11) | (pll->vco_band << 7);  /* bit 15 is the split to the slave, we do not do it here */
2434
2435                         if (!state->config->io.pll_int_loop_filt) {
2436                                 if (state->identity.in_soc)
2437                                         lo6 = 0xff98;
2438                                 else if (state->identity.p1g || (Rest == 0))
2439                                         lo6 = 0xfff8;
2440                                 else
2441                                         lo6 = 0xff28;
2442                         } else
2443                                 lo6 = (state->config->io.pll_int_loop_filt << 3);
2444
2445                         Den = 1;
2446
2447                         if (Rest > 0) {
2448                                 if (state->config->analog_output)
2449                                         lo6 |= (1 << 2) | 2;
2450                                 else {
2451                                         if (state->identity.in_soc)
2452                                                 lo6 |= (1 << 2) | 2;
2453                                         else
2454                                                 lo6 |= (1 << 2) | 2;
2455                                 }
2456                                 Den = 255;
2457                         }
2458                         dib0090_write_reg(state, 0x15, (u16) FBDiv);
2459                         if (state->config->fref_clock_ratio != 0)
2460                                 dib0090_write_reg(state, 0x16, (Den << 8) | state->config->fref_clock_ratio);
2461                         else
2462                                 dib0090_write_reg(state, 0x16, (Den << 8) | 1);
2463                         dib0090_write_reg(state, 0x17, (u16) Rest);
2464                         dib0090_write_reg(state, 0x19, lo5);
2465                         dib0090_write_reg(state, 0x1c, lo6);
2466
2467                         lo6 = tune->tuner_enable;
2468                         if (state->config->analog_output)
2469                                 lo6 = (lo6 & 0xff9f) | 0x2;
2470
2471                         dib0090_write_reg(state, 0x24, lo6 | EN_LO | state->config->use_pwm_agc * EN_CRYSTAL);
2472
2473                 }
2474
2475                 state->current_rf = state->rf_request;
2476                 state->current_standard = state->fe->dtv_property_cache.delivery_system;
2477
2478                 ret = 20;
2479                 state->calibrate = CAPTRIM_CAL; /* captrim serach now */
2480         }
2481
2482         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 */
2483                 const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
2484
2485                 while (state->current_rf / 1000 > wbd->max_freq)
2486                         wbd++;
2487
2488                 dib0090_write_reg(state, 0x1e, 0x07ff);
2489                 dprintk("Final Captrim: %d", (u32) state->fcaptrim);
2490                 dprintk("HFDIV code: %d", (u32) pll->hfdiv_code);
2491                 dprintk("VCO = %d", (u32) pll->vco_band);
2492                 dprintk("VCOF in kHz: %d ((%d*%d) << 1))", (u32) ((pll->hfdiv * state->rf_request) * 2), (u32) pll->hfdiv, (u32) state->rf_request);
2493                 dprintk("REFDIV: %d, FREF: %d", (u32) 1, (u32) state->config->io.clock_khz);
2494                 dprintk("FBDIV: %d, Rest: %d", (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17));
2495                 dprintk("Num: %d, Den: %d, SD: %d", (u32) dib0090_read_reg(state, 0x17), (u32) (dib0090_read_reg(state, 0x16) >> 8),
2496                         (u32) dib0090_read_reg(state, 0x1c) & 0x3);
2497
2498 #define WBD     0x781           /* 1 1 1 1 0000 0 0 1 */
2499                 c = 4;
2500                 i = 3;
2501
2502                 if (wbd->wbd_gain != 0)
2503                         c = wbd->wbd_gain;
2504
2505                 state->wbdmux = (c << 13) | (i << 11) | (WBD | (state->config->use_pwm_agc << 1));
2506                 dib0090_write_reg(state, 0x10, state->wbdmux);
2507
2508                 if ((tune->tuner_enable == EN_CAB) && state->identity.p1g) {
2509                         dprintk("P1G : The cable band is selected and lna_tune = %d", tune->lna_tune);
2510                         dib0090_write_reg(state, 0x09, tune->lna_bias);
2511                         dib0090_write_reg(state, 0x0b, 0xb800 | (tune->lna_tune << 6) | (tune->switch_trim));
2512                 } else
2513                         dib0090_write_reg(state, 0x09, (tune->lna_tune << 5) | tune->lna_bias);
2514
2515                 dib0090_write_reg(state, 0x0c, tune->v2i);
2516                 dib0090_write_reg(state, 0x0d, tune->mix);
2517                 dib0090_write_reg(state, 0x0e, tune->load);
2518                 *tune_state = CT_TUNER_STEP_1;
2519
2520         } else if (*tune_state == CT_TUNER_STEP_1) {
2521                 /* initialize the lt gain register */
2522                 state->rf_lt_def = 0x7c00;
2523
2524                 dib0090_set_bandwidth(state);
2525                 state->tuner_is_tuned = 1;
2526
2527                 state->calibrate |= WBD_CAL;
2528                 state->calibrate |= TEMP_CAL;
2529                 *tune_state = CT_TUNER_STOP;
2530         } else
2531                 ret = FE_CALLBACK_TIME_NEVER;
2532         return ret;
2533 }
2534
2535 static int dib0090_release(struct dvb_frontend *fe)
2536 {
2537         kfree(fe->tuner_priv);
2538         fe->tuner_priv = NULL;
2539         return 0;
2540 }
2541
2542 enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe)
2543 {
2544         struct dib0090_state *state = fe->tuner_priv;
2545
2546         return state->tune_state;
2547 }
2548
2549 EXPORT_SYMBOL(dib0090_get_tune_state);
2550
2551 int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
2552 {
2553         struct dib0090_state *state = fe->tuner_priv;
2554
2555         state->tune_state = tune_state;
2556         return 0;
2557 }
2558
2559 EXPORT_SYMBOL(dib0090_set_tune_state);
2560
2561 static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency)
2562 {
2563         struct dib0090_state *state = fe->tuner_priv;
2564
2565         *frequency = 1000 * state->current_rf;
2566         return 0;
2567 }
2568
2569 static int dib0090_set_params(struct dvb_frontend *fe)
2570 {
2571         struct dib0090_state *state = fe->tuner_priv;
2572         u32 ret;
2573
2574         state->tune_state = CT_TUNER_START;
2575
2576         do {
2577                 ret = dib0090_tune(fe);
2578                 if (ret != FE_CALLBACK_TIME_NEVER)
2579                         msleep(ret / 10);
2580                 else
2581                         break;
2582         } while (state->tune_state != CT_TUNER_STOP);
2583
2584         return 0;
2585 }
2586
2587 static const struct dvb_tuner_ops dib0090_ops = {
2588         .info = {
2589                  .name = "DiBcom DiB0090",
2590                  .frequency_min = 45000000,
2591                  .frequency_max = 860000000,
2592                  .frequency_step = 1000,
2593                  },
2594         .release = dib0090_release,
2595
2596         .init = dib0090_wakeup,
2597         .sleep = dib0090_sleep,
2598         .set_params = dib0090_set_params,
2599         .get_frequency = dib0090_get_frequency,
2600 };
2601
2602 static const struct dvb_tuner_ops dib0090_fw_ops = {
2603         .info = {
2604                  .name = "DiBcom DiB0090",
2605                  .frequency_min = 45000000,
2606                  .frequency_max = 860000000,
2607                  .frequency_step = 1000,
2608                  },
2609         .release = dib0090_release,
2610
2611         .init = NULL,
2612         .sleep = NULL,
2613         .set_params = NULL,
2614         .get_frequency = NULL,
2615 };
2616
2617 static const struct dib0090_wbd_slope dib0090_wbd_table_default[] = {
2618         {470, 0, 250, 0, 100, 4},
2619         {860, 51, 866, 21, 375, 4},
2620         {1700, 0, 800, 0, 850, 4},
2621         {2900, 0, 250, 0, 100, 6},
2622         {0xFFFF, 0, 0, 0, 0, 0},
2623 };
2624
2625 struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
2626 {
2627         struct dib0090_state *st = kzalloc(sizeof(struct dib0090_state), GFP_KERNEL);
2628         if (st == NULL)
2629                 return NULL;
2630
2631         st->config = config;
2632         st->i2c = i2c;
2633         st->fe = fe;
2634         mutex_init(&st->i2c_buffer_lock);
2635         fe->tuner_priv = st;
2636
2637         if (config->wbd == NULL)
2638                 st->current_wbd_table = dib0090_wbd_table_default;
2639         else
2640                 st->current_wbd_table = config->wbd;
2641
2642         if (dib0090_reset(fe) != 0)
2643                 goto free_mem;
2644
2645         printk(KERN_INFO "DiB0090: successfully identified\n");
2646         memcpy(&fe->ops.tuner_ops, &dib0090_ops, sizeof(struct dvb_tuner_ops));
2647
2648         return fe;
2649  free_mem:
2650         kfree(st);
2651         fe->tuner_priv = NULL;
2652         return NULL;
2653 }
2654
2655 EXPORT_SYMBOL(dib0090_register);
2656
2657 struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
2658 {
2659         struct dib0090_fw_state *st = kzalloc(sizeof(struct dib0090_fw_state), GFP_KERNEL);
2660         if (st == NULL)
2661                 return NULL;
2662
2663         st->config = config;
2664         st->i2c = i2c;
2665         st->fe = fe;
2666         mutex_init(&st->i2c_buffer_lock);
2667         fe->tuner_priv = st;
2668
2669         if (dib0090_fw_reset_digital(fe, st->config) != 0)
2670                 goto free_mem;
2671
2672         dprintk("DiB0090 FW: successfully identified");
2673         memcpy(&fe->ops.tuner_ops, &dib0090_fw_ops, sizeof(struct dvb_tuner_ops));
2674
2675         return fe;
2676 free_mem:
2677         kfree(st);
2678         fe->tuner_priv = NULL;
2679         return NULL;
2680 }
2681 EXPORT_SYMBOL(dib0090_fw_register);
2682
2683 MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
2684 MODULE_AUTHOR("Olivier Grenie <olivier.grenie@dibcom.fr>");
2685 MODULE_DESCRIPTION("Driver for the DiBcom 0090 base-band RF Tuner");
2686 MODULE_LICENSE("GPL");