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