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