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