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