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