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