root/drivers/media/dvb-frontends/dib0090.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dib0090_read_reg
  2. dib0090_write_reg
  3. dib0090_fw_read_reg
  4. dib0090_fw_write_reg
  5. dib0090_write_regs
  6. dib0090_identify
  7. dib0090_fw_identify
  8. dib0090_reset_digital
  9. dib0090_fw_reset_digital
  10. dib0090_wakeup
  11. dib0090_sleep
  12. dib0090_dcc_freq
  13. slopes_to_scale
  14. dib0090_wbd_to_db
  15. dib0090_wbd_target
  16. dib0090_gain_apply
  17. dib0090_set_boost
  18. dib0090_set_rframp
  19. dib0090_set_rframp_pwm
  20. dib0090_set_bbramp
  21. dib0090_set_bbramp_pwm
  22. dib0090_pwm_gain_reset
  23. dib0090_set_dc_servo
  24. dib0090_get_slow_adc_val
  25. dib0090_gain_control
  26. dib0090_get_current_gain
  27. dib0090_get_wbd_target
  28. dib0090_get_wbd_offset
  29. dib0090_set_switch
  30. dib0090_set_vga
  31. dib0090_update_rframp_7090
  32. dib0090_set_default_config
  33. dib0090_set_EFUSE
  34. dib0090_reset
  35. dib0090_get_offset
  36. dib0090_set_trim
  37. dib0090_dc_offset_calibration
  38. dib0090_wbd_calibration
  39. dib0090_set_bandwidth
  40. dib0090_update_tuning_table_7090
  41. dib0090_captrim_search
  42. dib0090_get_temperature
  43. dib0090_tune
  44. dib0090_release
  45. dib0090_get_tune_state
  46. dib0090_set_tune_state
  47. dib0090_get_frequency
  48. dib0090_set_params
  49. dib0090_register
  50. dib0090_fw_register

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

/* [<][>][^][v][top][bottom][index][help] */