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