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