treewide: Use fallthrough pseudo-keyword
[linux-block.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                 fallthrough;
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=%u,Offset=%d,Value Set=%d\n",
1752                                 state->dc->addr, state->adc_diff, state->step);
1753
1754                         state->dc++;
1755                         if (state->dc->addr == 0)       /* done */
1756                                 *tune_state = CT_TUNER_STEP_6;
1757                         else
1758                                 *tune_state = CT_TUNER_STEP_0;
1759
1760                 }
1761                 break;
1762
1763         case CT_TUNER_STEP_6:
1764                 dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008);
1765                 dib0090_write_reg(state, 0x1f, 0x7);
1766                 *tune_state = CT_TUNER_START;   /* reset done -> real tuning can now begin */
1767                 state->calibrate &= ~DC_CAL;
1768         default:
1769                 break;
1770         }
1771         return ret;
1772 }
1773
1774 static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1775 {
1776         u8 wbd_gain;
1777         const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1778
1779         switch (*tune_state) {
1780         case CT_TUNER_START:
1781                 while (state->current_rf / 1000 > wbd->max_freq)
1782                         wbd++;
1783                 if (wbd->wbd_gain != 0)
1784                         wbd_gain = wbd->wbd_gain;
1785                 else {
1786                         wbd_gain = 4;
1787 #if defined(CONFIG_BAND_LBAND) || defined(CONFIG_BAND_SBAND)
1788                         if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND))
1789                                 wbd_gain = 2;
1790 #endif
1791                 }
1792
1793                 if (wbd_gain == state->wbd_calibration_gain) {  /* the WBD calibration has already been done */
1794                         *tune_state = CT_TUNER_START;
1795                         state->calibrate &= ~WBD_CAL;
1796                         return 0;
1797                 }
1798
1799                 dib0090_write_reg(state, 0x10, 0x1b81 | (1 << 10) | (wbd_gain << 13) | (1 << 3));
1800
1801                 dib0090_write_reg(state, 0x24, ((EN_UHF & 0x0fff) | (1 << 1)));
1802                 *tune_state = CT_TUNER_STEP_0;
1803                 state->wbd_calibration_gain = wbd_gain;
1804                 return 90;      /* wait for the WBDMUX to switch and for the ADC to sample */
1805
1806         case CT_TUNER_STEP_0:
1807                 state->wbd_offset = dib0090_get_slow_adc_val(state);
1808                 dprintk("WBD calibration offset = %d\n", state->wbd_offset);
1809                 *tune_state = CT_TUNER_START;   /* reset done -> real tuning can now begin */
1810                 state->calibrate &= ~WBD_CAL;
1811                 break;
1812
1813         default:
1814                 break;
1815         }
1816         return 0;
1817 }
1818
1819 static void dib0090_set_bandwidth(struct dib0090_state *state)
1820 {
1821         u16 tmp;
1822
1823         if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 5000)
1824                 tmp = (3 << 14);
1825         else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 6000)
1826                 tmp = (2 << 14);
1827         else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 <= 7000)
1828                 tmp = (1 << 14);
1829         else
1830                 tmp = (0 << 14);
1831
1832         state->bb_1_def &= 0x3fff;
1833         state->bb_1_def |= tmp;
1834
1835         dib0090_write_reg(state, 0x01, state->bb_1_def);        /* be sure that we have the right bb-filter */
1836
1837         dib0090_write_reg(state, 0x03, 0x6008); /* = 0x6008 : vcm3_trim = 1 ; filter2_gm1_trim = 8 ; filter2_cutoff_freq = 0 */
1838         dib0090_write_reg(state, 0x04, 0x1);    /* 0 = 1KHz ; 1 = 50Hz ; 2 = 150Hz ; 3 = 50KHz ; 4 = servo fast */
1839         if (state->identity.in_soc) {
1840                 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 */
1841         } else {
1842                 dib0090_write_reg(state, 0x02, (5 << 11) | (8 << 6) | (22 & 0x3f));     /* 22 = cap_value */
1843                 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 */
1844         }
1845 }
1846
1847 static const struct dib0090_pll dib0090_pll_table[] = {
1848 #ifdef CONFIG_BAND_CBAND
1849         {56000, 0, 9, 48, 6},
1850         {70000, 1, 9, 48, 6},
1851         {87000, 0, 8, 32, 4},
1852         {105000, 1, 8, 32, 4},
1853         {115000, 0, 7, 24, 6},
1854         {140000, 1, 7, 24, 6},
1855         {170000, 0, 6, 16, 4},
1856 #endif
1857 #ifdef CONFIG_BAND_VHF
1858         {200000, 1, 6, 16, 4},
1859         {230000, 0, 5, 12, 6},
1860         {280000, 1, 5, 12, 6},
1861         {340000, 0, 4, 8, 4},
1862         {380000, 1, 4, 8, 4},
1863         {450000, 0, 3, 6, 6},
1864 #endif
1865 #ifdef CONFIG_BAND_UHF
1866         {580000, 1, 3, 6, 6},
1867         {700000, 0, 2, 4, 4},
1868         {860000, 1, 2, 4, 4},
1869 #endif
1870 #ifdef CONFIG_BAND_LBAND
1871         {1800000, 1, 0, 2, 4},
1872 #endif
1873 #ifdef CONFIG_BAND_SBAND
1874         {2900000, 0, 14, 1, 4},
1875 #endif
1876 };
1877
1878 static const struct dib0090_tuning dib0090_tuning_table_fm_vhf_on_cband[] = {
1879
1880 #ifdef CONFIG_BAND_CBAND
1881         {184000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1882         {227000, 4, 3, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1883         {380000, 4, 7, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1884 #endif
1885 #ifdef CONFIG_BAND_UHF
1886         {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1887         {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1888         {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1889         {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1890         {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1891         {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1892 #endif
1893 #ifdef CONFIG_BAND_LBAND
1894         {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1895         {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1896         {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1897 #endif
1898 #ifdef CONFIG_BAND_SBAND
1899         {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1900         {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1901 #endif
1902 };
1903
1904 static const struct dib0090_tuning dib0090_tuning_table[] = {
1905
1906 #ifdef CONFIG_BAND_CBAND
1907         {170000, 4, 1, 15, 0x280, 0x2912, 0xb94e, EN_CAB},
1908 #endif
1909 #ifdef CONFIG_BAND_VHF
1910         {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1911         {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1912         {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1913 #endif
1914 #ifdef CONFIG_BAND_UHF
1915         {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1916         {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1917         {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1918         {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1919         {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1920         {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1921 #endif
1922 #ifdef CONFIG_BAND_LBAND
1923         {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1924         {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1925         {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1926 #endif
1927 #ifdef CONFIG_BAND_SBAND
1928         {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1929         {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1930 #endif
1931 };
1932
1933 static const struct dib0090_tuning dib0090_p1g_tuning_table[] = {
1934 #ifdef CONFIG_BAND_CBAND
1935         {170000, 4, 1, 0x820f, 0x300, 0x2d22, 0x82cb, EN_CAB},
1936 #endif
1937 #ifdef CONFIG_BAND_VHF
1938         {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1939         {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1940         {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1941 #endif
1942 #ifdef CONFIG_BAND_UHF
1943         {510000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1944         {540000, 2, 1, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1945         {600000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1946         {630000, 2, 4, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1947         {680000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1948         {720000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1949         {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1950 #endif
1951 #ifdef CONFIG_BAND_LBAND
1952         {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1953         {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1954         {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1955 #endif
1956 #ifdef CONFIG_BAND_SBAND
1957         {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1958         {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1959 #endif
1960 };
1961
1962 static const struct dib0090_pll dib0090_p1g_pll_table[] = {
1963 #ifdef CONFIG_BAND_CBAND
1964         {57000, 0, 11, 48, 6},
1965         {70000, 1, 11, 48, 6},
1966         {86000, 0, 10, 32, 4},
1967         {105000, 1, 10, 32, 4},
1968         {115000, 0, 9, 24, 6},
1969         {140000, 1, 9, 24, 6},
1970         {170000, 0, 8, 16, 4},
1971 #endif
1972 #ifdef CONFIG_BAND_VHF
1973         {200000, 1, 8, 16, 4},
1974         {230000, 0, 7, 12, 6},
1975         {280000, 1, 7, 12, 6},
1976         {340000, 0, 6, 8, 4},
1977         {380000, 1, 6, 8, 4},
1978         {455000, 0, 5, 6, 6},
1979 #endif
1980 #ifdef CONFIG_BAND_UHF
1981         {580000, 1, 5, 6, 6},
1982         {680000, 0, 4, 4, 4},
1983         {860000, 1, 4, 4, 4},
1984 #endif
1985 #ifdef CONFIG_BAND_LBAND
1986         {1800000, 1, 2, 2, 4},
1987 #endif
1988 #ifdef CONFIG_BAND_SBAND
1989         {2900000, 0, 1, 1, 6},
1990 #endif
1991 };
1992
1993 static const struct dib0090_tuning dib0090_p1g_tuning_table_fm_vhf_on_cband[] = {
1994 #ifdef CONFIG_BAND_CBAND
1995         {184000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
1996         {227000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
1997         {380000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
1998 #endif
1999 #ifdef CONFIG_BAND_UHF
2000         {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2001         {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2002         {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2003         {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2004         {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2005         {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
2006 #endif
2007 #ifdef CONFIG_BAND_LBAND
2008         {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
2009         {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
2010         {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
2011 #endif
2012 #ifdef CONFIG_BAND_SBAND
2013         {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
2014         {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
2015 #endif
2016 };
2017
2018 static const struct dib0090_tuning dib0090_tuning_table_cband_7090[] = {
2019 #ifdef CONFIG_BAND_CBAND
2020         {300000, 4, 3, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2021         {380000, 4, 10, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2022         {570000, 4, 10, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2023         {858000, 4, 5, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
2024 #endif
2025 };
2026
2027 static const struct dib0090_tuning dib0090_tuning_table_cband_7090e_sensitivity[] = {
2028 #ifdef CONFIG_BAND_CBAND
2029         { 300000,  0 ,  3,  0x8105, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
2030         { 380000,  0 ,  10, 0x810F, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
2031         { 600000,  0 ,  10, 0x815E, 0x280, 0x2d12, 0xb84e, EN_CAB },
2032         { 660000,  0 ,  5,  0x85E3, 0x280, 0x2d12, 0xb84e, EN_CAB },
2033         { 720000,  0 ,  5,  0x852E, 0x280, 0x2d12, 0xb84e, EN_CAB },
2034         { 860000,  0 ,  4,  0x85E5, 0x280, 0x2d12, 0xb84e, EN_CAB },
2035 #endif
2036 };
2037
2038 int dib0090_update_tuning_table_7090(struct dvb_frontend *fe,
2039                 u8 cfg_sensitivity)
2040 {
2041         struct dib0090_state *state = fe->tuner_priv;
2042         const struct dib0090_tuning *tune =
2043                 dib0090_tuning_table_cband_7090e_sensitivity;
2044         static const struct dib0090_tuning dib0090_tuning_table_cband_7090e_aci[] = {
2045                 { 300000,  0 ,  3,  0x8165, 0x2c0, 0x2d12, 0xb84e, EN_CAB },
2046                 { 650000,  0 ,  4,  0x815B, 0x280, 0x2d12, 0xb84e, EN_CAB },
2047                 { 860000,  0 ,  5,  0x84EF, 0x280, 0x2d12, 0xb84e, EN_CAB },
2048         };
2049
2050         if ((!state->identity.p1g) || (!state->identity.in_soc)
2051                         || ((state->identity.version != SOC_7090_P1G_21R1)
2052                                 && (state->identity.version != SOC_7090_P1G_11R1))) {
2053                 dprintk("%s() function can only be used for dib7090\n", __func__);
2054                 return -ENODEV;
2055         }
2056
2057         if (cfg_sensitivity)
2058                 tune = dib0090_tuning_table_cband_7090e_sensitivity;
2059         else
2060                 tune = dib0090_tuning_table_cband_7090e_aci;
2061
2062         while (state->rf_request > tune->max_freq)
2063                 tune++;
2064
2065         dib0090_write_reg(state, 0x09, (dib0090_read_reg(state, 0x09) & 0x8000)
2066                         | (tune->lna_bias & 0x7fff));
2067         dib0090_write_reg(state, 0x0b, (dib0090_read_reg(state, 0x0b) & 0xf83f)
2068                         | ((tune->lna_tune << 6) & 0x07c0));
2069         return 0;
2070 }
2071 EXPORT_SYMBOL(dib0090_update_tuning_table_7090);
2072
2073 static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tune_state *tune_state)
2074 {
2075         int ret = 0;
2076         u16 lo4 = 0xe900;
2077
2078         s16 adc_target;
2079         u16 adc;
2080         s8 step_sign;
2081         u8 force_soft_search = 0;
2082
2083         if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
2084                 force_soft_search = 1;
2085
2086         if (*tune_state == CT_TUNER_START) {
2087                 dprintk("Start Captrim search : %s\n",
2088                         (force_soft_search == 1) ? "FORCE SOFT SEARCH" : "AUTO");
2089                 dib0090_write_reg(state, 0x10, 0x2B1);
2090                 dib0090_write_reg(state, 0x1e, 0x0032);
2091
2092                 if (!state->tuner_is_tuned) {
2093                         /* prepare a complete captrim */
2094                         if (!state->identity.p1g || force_soft_search)
2095                                 state->step = state->captrim = state->fcaptrim = 64;
2096
2097                         state->current_rf = state->rf_request;
2098                 } else {        /* we are already tuned to this frequency - the configuration is correct  */
2099                         if (!state->identity.p1g || force_soft_search) {
2100                                 /* do a minimal captrim even if the frequency has not changed */
2101                                 state->step = 4;
2102                                 state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f;
2103                         }
2104                 }
2105                 state->adc_diff = 3000;
2106                 *tune_state = CT_TUNER_STEP_0;
2107
2108         } else if (*tune_state == CT_TUNER_STEP_0) {
2109                 if (state->identity.p1g && !force_soft_search) {
2110                         u8 ratio = 31;
2111
2112                         dib0090_write_reg(state, 0x40, (3 << 7) | (ratio << 2) | (1 << 1) | 1);
2113                         dib0090_read_reg(state, 0x40);
2114                         ret = 50;
2115                 } else {
2116                         state->step /= 2;
2117                         dib0090_write_reg(state, 0x18, lo4 | state->captrim);
2118
2119                         if (state->identity.in_soc)
2120                                 ret = 25;
2121                 }
2122                 *tune_state = CT_TUNER_STEP_1;
2123
2124         } else if (*tune_state == CT_TUNER_STEP_1) {
2125                 if (state->identity.p1g && !force_soft_search) {
2126                         dib0090_write_reg(state, 0x40, 0x18c | (0 << 1) | 0);
2127                         dib0090_read_reg(state, 0x40);
2128
2129                         state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7F;
2130                         dprintk("***Final Captrim= 0x%x\n", state->fcaptrim);
2131                         *tune_state = CT_TUNER_STEP_3;
2132
2133                 } else {
2134                         /* MERGE for all krosus before P1G */
2135                         adc = dib0090_get_slow_adc_val(state);
2136                         dprintk("CAPTRIM=%d; ADC = %d (ADC) & %dmV\n", (u32) state->captrim, (u32) adc, (u32) (adc) * (u32) 1800 / (u32) 1024);
2137
2138                         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 !!! */
2139                                 adc_target = 200;
2140                         } else
2141                                 adc_target = 400;
2142
2143                         if (adc >= adc_target) {
2144                                 adc -= adc_target;
2145                                 step_sign = -1;
2146                         } else {
2147                                 adc = adc_target - adc;
2148                                 step_sign = 1;
2149                         }
2150
2151                         if (adc < state->adc_diff) {
2152                                 dprintk("CAPTRIM=%d is closer to target (%d/%d)\n", (u32) state->captrim, (u32) adc, (u32) state->adc_diff);
2153                                 state->adc_diff = adc;
2154                                 state->fcaptrim = state->captrim;
2155                         }
2156
2157                         state->captrim += step_sign * state->step;
2158                         if (state->step >= 1)
2159                                 *tune_state = CT_TUNER_STEP_0;
2160                         else
2161                                 *tune_state = CT_TUNER_STEP_2;
2162
2163                         ret = 25;
2164                 }
2165         } else if (*tune_state == CT_TUNER_STEP_2) {    /* this step is only used by krosus < P1G */
2166                 /*write the final cptrim config */
2167                 dib0090_write_reg(state, 0x18, lo4 | state->fcaptrim);
2168
2169                 *tune_state = CT_TUNER_STEP_3;
2170
2171         } else if (*tune_state == CT_TUNER_STEP_3) {
2172                 state->calibrate &= ~CAPTRIM_CAL;
2173                 *tune_state = CT_TUNER_STEP_0;
2174         }
2175
2176         return ret;
2177 }
2178
2179 static int dib0090_get_temperature(struct dib0090_state *state, enum frontend_tune_state *tune_state)
2180 {
2181         int ret = 15;
2182         s16 val;
2183
2184         switch (*tune_state) {
2185         case CT_TUNER_START:
2186                 state->wbdmux = dib0090_read_reg(state, 0x10);
2187                 dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x8 << 3));
2188
2189                 state->bias = dib0090_read_reg(state, 0x13);
2190                 dib0090_write_reg(state, 0x13, state->bias | (0x3 << 8));
2191
2192                 *tune_state = CT_TUNER_STEP_0;
2193                 /* wait for the WBDMUX to switch and for the ADC to sample */
2194                 break;
2195
2196         case CT_TUNER_STEP_0:
2197                 state->adc_diff = dib0090_get_slow_adc_val(state);
2198                 dib0090_write_reg(state, 0x13, (state->bias & ~(0x3 << 8)) | (0x2 << 8));
2199                 *tune_state = CT_TUNER_STEP_1;
2200                 break;
2201
2202         case CT_TUNER_STEP_1:
2203                 val = dib0090_get_slow_adc_val(state);
2204                 state->temperature = ((s16) ((val - state->adc_diff) * 180) >> 8) + 55;
2205
2206                 dprintk("temperature: %d C\n", state->temperature - 30);
2207
2208                 *tune_state = CT_TUNER_STEP_2;
2209                 break;
2210
2211         case CT_TUNER_STEP_2:
2212                 dib0090_write_reg(state, 0x13, state->bias);
2213                 dib0090_write_reg(state, 0x10, state->wbdmux);  /* write back original WBDMUX */
2214
2215                 *tune_state = CT_TUNER_START;
2216                 state->calibrate &= ~TEMP_CAL;
2217                 if (state->config->analog_output == 0)
2218                         dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
2219
2220                 break;
2221
2222         default:
2223                 ret = 0;
2224                 break;
2225         }
2226         return ret;
2227 }
2228
2229 #define WBD     0x781           /* 1 1 1 1 0000 0 0 1 */
2230 static int dib0090_tune(struct dvb_frontend *fe)
2231 {
2232         struct dib0090_state *state = fe->tuner_priv;
2233         const struct dib0090_tuning *tune = state->current_tune_table_index;
2234         const struct dib0090_pll *pll = state->current_pll_table_index;
2235         enum frontend_tune_state *tune_state = &state->tune_state;
2236
2237         u16 lo5, lo6, Den, tmp;
2238         u32 FBDiv, Rest, FREF, VCOF_kHz = 0;
2239         int ret = 10;           /* 1ms is the default delay most of the time */
2240         u8 c, i;
2241
2242         /************************* VCO ***************************/
2243         /* Default values for FG                                 */
2244         /* from these are needed :                               */
2245         /* Cp,HFdiv,VCOband,SD,Num,Den,FB and REFDiv             */
2246
2247         /* in any case we first need to do a calibration if needed */
2248         if (*tune_state == CT_TUNER_START) {
2249                 /* deactivate DataTX before some calibrations */
2250                 if (state->calibrate & (DC_CAL | TEMP_CAL | WBD_CAL))
2251                         dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
2252                 else
2253                         /* Activate DataTX in case a calibration has been done before */
2254                         if (state->config->analog_output == 0)
2255                                 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
2256         }
2257
2258         if (state->calibrate & DC_CAL)
2259                 return dib0090_dc_offset_calibration(state, tune_state);
2260         else if (state->calibrate & WBD_CAL) {
2261                 if (state->current_rf == 0)
2262                         state->current_rf = state->fe->dtv_property_cache.frequency / 1000;
2263                 return dib0090_wbd_calibration(state, tune_state);
2264         } else if (state->calibrate & TEMP_CAL)
2265                 return dib0090_get_temperature(state, tune_state);
2266         else if (state->calibrate & CAPTRIM_CAL)
2267                 return dib0090_captrim_search(state, tune_state);
2268
2269         if (*tune_state == CT_TUNER_START) {
2270                 /* 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 */
2271                 if (state->config->use_pwm_agc && state->identity.in_soc) {
2272                         tmp = dib0090_read_reg(state, 0x39);
2273                         if ((tmp >> 10) & 0x1)
2274                                 dib0090_write_reg(state, 0x39, tmp & ~(1 << 10));
2275                 }
2276
2277                 state->current_band = (u8) BAND_OF_FREQUENCY(state->fe->dtv_property_cache.frequency / 1000);
2278                 state->rf_request =
2279                         state->fe->dtv_property_cache.frequency / 1000 + (state->current_band ==
2280                                         BAND_UHF ? state->config->freq_offset_khz_uhf : state->config->
2281                                         freq_offset_khz_vhf);
2282
2283                 /* in ISDB-T 1seg we shift tuning frequency */
2284                 if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1
2285                                         && state->fe->dtv_property_cache.isdbt_partial_reception == 0)) {
2286                         const struct dib0090_low_if_offset_table *LUT_offset = state->config->low_if;
2287                         u8 found_offset = 0;
2288                         u32 margin_khz = 100;
2289
2290                         if (LUT_offset != NULL) {
2291                                 while (LUT_offset->RF_freq != 0xffff) {
2292                                         if (((state->rf_request > (LUT_offset->RF_freq - margin_khz))
2293                                                                 && (state->rf_request < (LUT_offset->RF_freq + margin_khz)))
2294                                                         && LUT_offset->std == state->fe->dtv_property_cache.delivery_system) {
2295                                                 state->rf_request += LUT_offset->offset_khz;
2296                                                 found_offset = 1;
2297                                                 break;
2298                                         }
2299                                         LUT_offset++;
2300                                 }
2301                         }
2302
2303                         if (found_offset == 0)
2304                                 state->rf_request += 400;
2305                 }
2306                 if (state->current_rf != state->rf_request || (state->current_standard != state->fe->dtv_property_cache.delivery_system)) {
2307                         state->tuner_is_tuned = 0;
2308                         state->current_rf = 0;
2309                         state->current_standard = 0;
2310
2311                         tune = dib0090_tuning_table;
2312                         if (state->identity.p1g)
2313                                 tune = dib0090_p1g_tuning_table;
2314
2315                         tmp = (state->identity.version >> 5) & 0x7;
2316
2317                         if (state->identity.in_soc) {
2318                                 if (state->config->force_cband_input) { /* Use the CBAND input for all band */
2319                                         if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF
2320                                                         || state->current_band & BAND_UHF) {
2321                                                 state->current_band = BAND_CBAND;
2322                                                 if (state->config->is_dib7090e)
2323                                                         tune = dib0090_tuning_table_cband_7090e_sensitivity;
2324                                                 else
2325                                                         tune = dib0090_tuning_table_cband_7090;
2326                                         }
2327                                 } else {        /* Use the CBAND input for all band under UHF */
2328                                         if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF) {
2329                                                 state->current_band = BAND_CBAND;
2330                                                 if (state->config->is_dib7090e)
2331                                                         tune = dib0090_tuning_table_cband_7090e_sensitivity;
2332                                                 else
2333                                                         tune = dib0090_tuning_table_cband_7090;
2334                                         }
2335                                 }
2336                         } else
2337                          if (tmp == 0x4 || tmp == 0x7) {
2338                                 /* CBAND tuner version for VHF */
2339                                 if (state->current_band == BAND_FM || state->current_band == BAND_CBAND || state->current_band == BAND_VHF) {
2340                                         state->current_band = BAND_CBAND;       /* Force CBAND */
2341
2342                                         tune = dib0090_tuning_table_fm_vhf_on_cband;
2343                                         if (state->identity.p1g)
2344                                                 tune = dib0090_p1g_tuning_table_fm_vhf_on_cband;
2345                                 }
2346                         }
2347
2348                         pll = dib0090_pll_table;
2349                         if (state->identity.p1g)
2350                                 pll = dib0090_p1g_pll_table;
2351
2352                         /* Look for the interval */
2353                         while (state->rf_request > tune->max_freq)
2354                                 tune++;
2355                         while (state->rf_request > pll->max_freq)
2356                                 pll++;
2357
2358                         state->current_tune_table_index = tune;
2359                         state->current_pll_table_index = pll;
2360
2361                         dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim));
2362
2363                         VCOF_kHz = (pll->hfdiv * state->rf_request) * 2;
2364
2365                         FREF = state->config->io.clock_khz;
2366                         if (state->config->fref_clock_ratio != 0)
2367                                 FREF /= state->config->fref_clock_ratio;
2368
2369                         FBDiv = (VCOF_kHz / pll->topresc / FREF);
2370                         Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF;
2371
2372                         if (Rest < LPF)
2373                                 Rest = 0;
2374                         else if (Rest < 2 * LPF)
2375                                 Rest = 2 * LPF;
2376                         else if (Rest > (FREF - LPF)) {
2377                                 Rest = 0;
2378                                 FBDiv += 1;
2379                         } else if (Rest > (FREF - 2 * LPF))
2380                                 Rest = FREF - 2 * LPF;
2381                         Rest = (Rest * 6528) / (FREF / 10);
2382                         state->rest = Rest;
2383
2384                         /* external loop filter, otherwise:
2385                          * lo5 = (0 << 15) | (0 << 12) | (0 << 11) | (3 << 9) | (4 << 6) | (3 << 4) | 4;
2386                          * lo6 = 0x0e34 */
2387
2388                         if (Rest == 0) {
2389                                 if (pll->vco_band)
2390                                         lo5 = 0x049f;
2391                                 else
2392                                         lo5 = 0x041f;
2393                         } else {
2394                                 if (pll->vco_band)
2395                                         lo5 = 0x049e;
2396                                 else if (state->config->analog_output)
2397                                         lo5 = 0x041d;
2398                                 else
2399                                         lo5 = 0x041c;
2400                         }
2401
2402                         if (state->identity.p1g) {      /* Bias is done automatically in P1G */
2403                                 if (state->identity.in_soc) {
2404                                         if (state->identity.version == SOC_8090_P1G_11R1)
2405                                                 lo5 = 0x46f;
2406                                         else
2407                                                 lo5 = 0x42f;
2408                                 } else
2409                                         lo5 = 0x42c;
2410                         }
2411
2412                         lo5 |= (pll->hfdiv_code << 11) | (pll->vco_band << 7);  /* bit 15 is the split to the slave, we do not do it here */
2413
2414                         if (!state->config->io.pll_int_loop_filt) {
2415                                 if (state->identity.in_soc)
2416                                         lo6 = 0xff98;
2417                                 else if (state->identity.p1g || (Rest == 0))
2418                                         lo6 = 0xfff8;
2419                                 else
2420                                         lo6 = 0xff28;
2421                         } else
2422                                 lo6 = (state->config->io.pll_int_loop_filt << 3);
2423
2424                         Den = 1;
2425
2426                         if (Rest > 0) {
2427                                 lo6 |= (1 << 2) | 2;
2428                                 Den = 255;
2429                         }
2430                         dib0090_write_reg(state, 0x15, (u16) FBDiv);
2431                         if (state->config->fref_clock_ratio != 0)
2432                                 dib0090_write_reg(state, 0x16, (Den << 8) | state->config->fref_clock_ratio);
2433                         else
2434                                 dib0090_write_reg(state, 0x16, (Den << 8) | 1);
2435                         dib0090_write_reg(state, 0x17, (u16) Rest);
2436                         dib0090_write_reg(state, 0x19, lo5);
2437                         dib0090_write_reg(state, 0x1c, lo6);
2438
2439                         lo6 = tune->tuner_enable;
2440                         if (state->config->analog_output)
2441                                 lo6 = (lo6 & 0xff9f) | 0x2;
2442
2443                         dib0090_write_reg(state, 0x24, lo6 | EN_LO | state->config->use_pwm_agc * EN_CRYSTAL);
2444
2445                 }
2446
2447                 state->current_rf = state->rf_request;
2448                 state->current_standard = state->fe->dtv_property_cache.delivery_system;
2449
2450                 ret = 20;
2451                 state->calibrate = CAPTRIM_CAL; /* captrim search now */
2452         }
2453
2454         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 */
2455                 const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
2456
2457                 while (state->current_rf / 1000 > wbd->max_freq)
2458                         wbd++;
2459
2460                 dib0090_write_reg(state, 0x1e, 0x07ff);
2461                 dprintk("Final Captrim: %d\n", (u32) state->fcaptrim);
2462                 dprintk("HFDIV code: %d\n", (u32) pll->hfdiv_code);
2463                 dprintk("VCO = %d\n", (u32) pll->vco_band);
2464                 dprintk("VCOF in kHz: %d ((%d*%d) << 1))\n", (u32) ((pll->hfdiv * state->rf_request) * 2), (u32) pll->hfdiv, (u32) state->rf_request);
2465                 dprintk("REFDIV: %d, FREF: %d\n", (u32) 1, (u32) state->config->io.clock_khz);
2466                 dprintk("FBDIV: %d, Rest: %d\n", (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17));
2467                 dprintk("Num: %d, Den: %d, SD: %d\n", (u32) dib0090_read_reg(state, 0x17), (u32) (dib0090_read_reg(state, 0x16) >> 8),
2468                         (u32) dib0090_read_reg(state, 0x1c) & 0x3);
2469
2470 #define WBD     0x781           /* 1 1 1 1 0000 0 0 1 */
2471                 c = 4;
2472                 i = 3;
2473
2474                 if (wbd->wbd_gain != 0)
2475                         c = wbd->wbd_gain;
2476
2477                 state->wbdmux = (c << 13) | (i << 11) | (WBD | (state->config->use_pwm_agc << 1));
2478                 dib0090_write_reg(state, 0x10, state->wbdmux);
2479
2480                 if ((tune->tuner_enable == EN_CAB) && state->identity.p1g) {
2481                         dprintk("P1G : The cable band is selected and lna_tune = %d\n", tune->lna_tune);
2482                         dib0090_write_reg(state, 0x09, tune->lna_bias);
2483                         dib0090_write_reg(state, 0x0b, 0xb800 | (tune->lna_tune << 6) | (tune->switch_trim));
2484                 } else
2485                         dib0090_write_reg(state, 0x09, (tune->lna_tune << 5) | tune->lna_bias);
2486
2487                 dib0090_write_reg(state, 0x0c, tune->v2i);
2488                 dib0090_write_reg(state, 0x0d, tune->mix);
2489                 dib0090_write_reg(state, 0x0e, tune->load);
2490                 *tune_state = CT_TUNER_STEP_1;
2491
2492         } else if (*tune_state == CT_TUNER_STEP_1) {
2493                 /* initialize the lt gain register */
2494                 state->rf_lt_def = 0x7c00;
2495
2496                 dib0090_set_bandwidth(state);
2497                 state->tuner_is_tuned = 1;
2498
2499                 state->calibrate |= WBD_CAL;
2500                 state->calibrate |= TEMP_CAL;
2501                 *tune_state = CT_TUNER_STOP;
2502         } else
2503                 ret = FE_CALLBACK_TIME_NEVER;
2504         return ret;
2505 }
2506
2507 static void dib0090_release(struct dvb_frontend *fe)
2508 {
2509         kfree(fe->tuner_priv);
2510         fe->tuner_priv = NULL;
2511 }
2512
2513 enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe)
2514 {
2515         struct dib0090_state *state = fe->tuner_priv;
2516
2517         return state->tune_state;
2518 }
2519
2520 EXPORT_SYMBOL(dib0090_get_tune_state);
2521
2522 int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
2523 {
2524         struct dib0090_state *state = fe->tuner_priv;
2525
2526         state->tune_state = tune_state;
2527         return 0;
2528 }
2529
2530 EXPORT_SYMBOL(dib0090_set_tune_state);
2531
2532 static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency)
2533 {
2534         struct dib0090_state *state = fe->tuner_priv;
2535
2536         *frequency = 1000 * state->current_rf;
2537         return 0;
2538 }
2539
2540 static int dib0090_set_params(struct dvb_frontend *fe)
2541 {
2542         struct dib0090_state *state = fe->tuner_priv;
2543         u32 ret;
2544
2545         state->tune_state = CT_TUNER_START;
2546
2547         do {
2548                 ret = dib0090_tune(fe);
2549                 if (ret == FE_CALLBACK_TIME_NEVER)
2550                         break;
2551
2552                 /*
2553                  * Despite dib0090_tune returns time at a 0.1 ms range,
2554                  * the actual sleep time depends on CONFIG_HZ. The worse case
2555                  * is when CONFIG_HZ=100. In such case, the minimum granularity
2556                  * is 10ms. On some real field tests, the tuner sometimes don't
2557                  * lock when this timer is lower than 10ms. So, enforce a 10ms
2558                  * granularity and use usleep_range() instead of msleep().
2559                  */
2560                 ret = 10 * (ret + 99)/100;
2561                 usleep_range(ret * 1000, (ret + 1) * 1000);
2562         } while (state->tune_state != CT_TUNER_STOP);
2563
2564         return 0;
2565 }
2566
2567 static const struct dvb_tuner_ops dib0090_ops = {
2568         .info = {
2569                  .name = "DiBcom DiB0090",
2570                  .frequency_min_hz  =  45 * MHz,
2571                  .frequency_max_hz  = 860 * MHz,
2572                  .frequency_step_hz =   1 * kHz,
2573                  },
2574         .release = dib0090_release,
2575
2576         .init = dib0090_wakeup,
2577         .sleep = dib0090_sleep,
2578         .set_params = dib0090_set_params,
2579         .get_frequency = dib0090_get_frequency,
2580 };
2581
2582 static const struct dvb_tuner_ops dib0090_fw_ops = {
2583         .info = {
2584                  .name = "DiBcom DiB0090",
2585                  .frequency_min_hz  =  45 * MHz,
2586                  .frequency_max_hz  = 860 * MHz,
2587                  .frequency_step_hz =   1 * kHz,
2588                  },
2589         .release = dib0090_release,
2590
2591         .init = NULL,
2592         .sleep = NULL,
2593         .set_params = NULL,
2594         .get_frequency = NULL,
2595 };
2596
2597 static const struct dib0090_wbd_slope dib0090_wbd_table_default[] = {
2598         {470, 0, 250, 0, 100, 4},
2599         {860, 51, 866, 21, 375, 4},
2600         {1700, 0, 800, 0, 850, 4},
2601         {2900, 0, 250, 0, 100, 6},
2602         {0xFFFF, 0, 0, 0, 0, 0},
2603 };
2604
2605 struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
2606 {
2607         struct dib0090_state *st = kzalloc(sizeof(struct dib0090_state), GFP_KERNEL);
2608         if (st == NULL)
2609                 return NULL;
2610
2611         st->config = config;
2612         st->i2c = i2c;
2613         st->fe = fe;
2614         mutex_init(&st->i2c_buffer_lock);
2615         fe->tuner_priv = st;
2616
2617         if (config->wbd == NULL)
2618                 st->current_wbd_table = dib0090_wbd_table_default;
2619         else
2620                 st->current_wbd_table = config->wbd;
2621
2622         if (dib0090_reset(fe) != 0)
2623                 goto free_mem;
2624
2625         pr_info("DiB0090: successfully identified\n");
2626         memcpy(&fe->ops.tuner_ops, &dib0090_ops, sizeof(struct dvb_tuner_ops));
2627
2628         return fe;
2629  free_mem:
2630         kfree(st);
2631         fe->tuner_priv = NULL;
2632         return NULL;
2633 }
2634
2635 EXPORT_SYMBOL(dib0090_register);
2636
2637 struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
2638 {
2639         struct dib0090_fw_state *st = kzalloc(sizeof(struct dib0090_fw_state), GFP_KERNEL);
2640         if (st == NULL)
2641                 return NULL;
2642
2643         st->config = config;
2644         st->i2c = i2c;
2645         st->fe = fe;
2646         mutex_init(&st->i2c_buffer_lock);
2647         fe->tuner_priv = st;
2648
2649         if (dib0090_fw_reset_digital(fe, st->config) != 0)
2650                 goto free_mem;
2651
2652         dprintk("DiB0090 FW: successfully identified\n");
2653         memcpy(&fe->ops.tuner_ops, &dib0090_fw_ops, sizeof(struct dvb_tuner_ops));
2654
2655         return fe;
2656 free_mem:
2657         kfree(st);
2658         fe->tuner_priv = NULL;
2659         return NULL;
2660 }
2661 EXPORT_SYMBOL(dib0090_fw_register);
2662
2663 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
2664 MODULE_AUTHOR("Olivier Grenie <olivier.grenie@parrot.com>");
2665 MODULE_DESCRIPTION("Driver for the DiBcom 0090 base-band RF Tuner");
2666 MODULE_LICENSE("GPL");