linux/drivers/media/dvb-frontends/dib7000p.c
<<
>>
Prefs
   1/*
   2 * Linux-DVB Driver for DiBcom's second generation DiB7000P (PC).
   3 *
   4 * Copyright (C) 2005-7 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, version 2.
   9 */
  10#include <linux/kernel.h>
  11#include <linux/slab.h>
  12#include <linux/i2c.h>
  13#include <linux/mutex.h>
  14
  15#include "dvb_math.h"
  16#include "dvb_frontend.h"
  17
  18#include "dib7000p.h"
  19
  20static int debug;
  21module_param(debug, int, 0644);
  22MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
  23
  24static int buggy_sfn_workaround;
  25module_param(buggy_sfn_workaround, int, 0644);
  26MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
  27
  28#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0)
  29
  30struct i2c_device {
  31        struct i2c_adapter *i2c_adap;
  32        u8 i2c_addr;
  33};
  34
  35struct dib7000p_state {
  36        struct dvb_frontend demod;
  37        struct dib7000p_config cfg;
  38
  39        u8 i2c_addr;
  40        struct i2c_adapter *i2c_adap;
  41
  42        struct dibx000_i2c_master i2c_master;
  43
  44        u16 wbd_ref;
  45
  46        u8 current_band;
  47        u32 current_bandwidth;
  48        struct dibx000_agc_config *current_agc;
  49        u32 timf;
  50
  51        u8 div_force_off:1;
  52        u8 div_state:1;
  53        u16 div_sync_wait;
  54
  55        u8 agc_state;
  56
  57        u16 gpio_dir;
  58        u16 gpio_val;
  59
  60        u8 sfn_workaround_active:1;
  61
  62#define SOC7090 0x7090
  63        u16 version;
  64
  65        u16 tuner_enable;
  66        struct i2c_adapter dib7090_tuner_adap;
  67
  68        /* for the I2C transfer */
  69        struct i2c_msg msg[2];
  70        u8 i2c_write_buffer[4];
  71        u8 i2c_read_buffer[2];
  72        struct mutex i2c_buffer_lock;
  73
  74        u8 input_mode_mpeg;
  75};
  76
  77enum dib7000p_power_mode {
  78        DIB7000P_POWER_ALL = 0,
  79        DIB7000P_POWER_ANALOG_ADC,
  80        DIB7000P_POWER_INTERFACE_ONLY,
  81};
  82
  83/* dib7090 specific fonctions */
  84static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode);
  85static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff);
  86static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode);
  87static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode);
  88
  89static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
  90{
  91        u16 ret;
  92
  93        if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
  94                dprintk("could not acquire lock");
  95                return 0;
  96        }
  97
  98        state->i2c_write_buffer[0] = reg >> 8;
  99        state->i2c_write_buffer[1] = reg & 0xff;
 100
 101        memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
 102        state->msg[0].addr = state->i2c_addr >> 1;
 103        state->msg[0].flags = 0;
 104        state->msg[0].buf = state->i2c_write_buffer;
 105        state->msg[0].len = 2;
 106        state->msg[1].addr = state->i2c_addr >> 1;
 107        state->msg[1].flags = I2C_M_RD;
 108        state->msg[1].buf = state->i2c_read_buffer;
 109        state->msg[1].len = 2;
 110
 111        if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
 112                dprintk("i2c read error on %d", reg);
 113
 114        ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
 115        mutex_unlock(&state->i2c_buffer_lock);
 116        return ret;
 117}
 118
 119static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
 120{
 121        int ret;
 122
 123        if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
 124                dprintk("could not acquire lock");
 125                return -EINVAL;
 126        }
 127
 128        state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
 129        state->i2c_write_buffer[1] = reg & 0xff;
 130        state->i2c_write_buffer[2] = (val >> 8) & 0xff;
 131        state->i2c_write_buffer[3] = val & 0xff;
 132
 133        memset(&state->msg[0], 0, sizeof(struct i2c_msg));
 134        state->msg[0].addr = state->i2c_addr >> 1;
 135        state->msg[0].flags = 0;
 136        state->msg[0].buf = state->i2c_write_buffer;
 137        state->msg[0].len = 4;
 138
 139        ret = (i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ?
 140                        -EREMOTEIO : 0);
 141        mutex_unlock(&state->i2c_buffer_lock);
 142        return ret;
 143}
 144
 145static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf)
 146{
 147        u16 l = 0, r, *n;
 148        n = buf;
 149        l = *n++;
 150        while (l) {
 151                r = *n++;
 152
 153                do {
 154                        dib7000p_write_word(state, r, *n++);
 155                        r++;
 156                } while (--l);
 157                l = *n++;
 158        }
 159}
 160
 161static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
 162{
 163        int ret = 0;
 164        u16 outreg, fifo_threshold, smo_mode;
 165
 166        outreg = 0;
 167        fifo_threshold = 1792;
 168        smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
 169
 170        dprintk("setting output mode for demod %p to %d", &state->demod, mode);
 171
 172        switch (mode) {
 173        case OUTMODE_MPEG2_PAR_GATED_CLK:
 174                outreg = (1 << 10);     /* 0x0400 */
 175                break;
 176        case OUTMODE_MPEG2_PAR_CONT_CLK:
 177                outreg = (1 << 10) | (1 << 6);  /* 0x0440 */
 178                break;
 179        case OUTMODE_MPEG2_SERIAL:
 180                outreg = (1 << 10) | (2 << 6) | (0 << 1);       /* 0x0480 */
 181                break;
 182        case OUTMODE_DIVERSITY:
 183                if (state->cfg.hostbus_diversity)
 184                        outreg = (1 << 10) | (4 << 6);  /* 0x0500 */
 185                else
 186                        outreg = (1 << 11);
 187                break;
 188        case OUTMODE_MPEG2_FIFO:
 189                smo_mode |= (3 << 1);
 190                fifo_threshold = 512;
 191                outreg = (1 << 10) | (5 << 6);
 192                break;
 193        case OUTMODE_ANALOG_ADC:
 194                outreg = (1 << 10) | (3 << 6);
 195                break;
 196        case OUTMODE_HIGH_Z:
 197                outreg = 0;
 198                break;
 199        default:
 200                dprintk("Unhandled output_mode passed to be set for demod %p", &state->demod);
 201                break;
 202        }
 203
 204        if (state->cfg.output_mpeg2_in_188_bytes)
 205                smo_mode |= (1 << 5);
 206
 207        ret |= dib7000p_write_word(state, 235, smo_mode);
 208        ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
 209        if (state->version != SOC7090)
 210                ret |= dib7000p_write_word(state, 1286, outreg);        /* P_Div_active */
 211
 212        return ret;
 213}
 214
 215static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
 216{
 217        struct dib7000p_state *state = demod->demodulator_priv;
 218
 219        if (state->div_force_off) {
 220                dprintk("diversity combination deactivated - forced by COFDM parameters");
 221                onoff = 0;
 222                dib7000p_write_word(state, 207, 0);
 223        } else
 224                dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
 225
 226        state->div_state = (u8) onoff;
 227
 228        if (onoff) {
 229                dib7000p_write_word(state, 204, 6);
 230                dib7000p_write_word(state, 205, 16);
 231                /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
 232        } else {
 233                dib7000p_write_word(state, 204, 1);
 234                dib7000p_write_word(state, 205, 0);
 235        }
 236
 237        return 0;
 238}
 239
 240static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode)
 241{
 242        /* by default everything is powered off */
 243        u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0x0007, reg_899 = 0x0003, reg_1280 = (0xfe00) | (dib7000p_read_word(state, 1280) & 0x01ff);
 244
 245        /* now, depending on the requested mode, we power on */
 246        switch (mode) {
 247                /* power up everything in the demod */
 248        case DIB7000P_POWER_ALL:
 249                reg_774 = 0x0000;
 250                reg_775 = 0x0000;
 251                reg_776 = 0x0;
 252                reg_899 = 0x0;
 253                if (state->version == SOC7090)
 254                        reg_1280 &= 0x001f;
 255                else
 256                        reg_1280 &= 0x01ff;
 257                break;
 258
 259        case DIB7000P_POWER_ANALOG_ADC:
 260                /* dem, cfg, iqc, sad, agc */
 261                reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
 262                /* nud */
 263                reg_776 &= ~((1 << 0));
 264                /* Dout */
 265                if (state->version != SOC7090)
 266                        reg_1280 &= ~((1 << 11));
 267                reg_1280 &= ~(1 << 6);
 268                /* fall through wanted to enable the interfaces */
 269
 270                /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
 271        case DIB7000P_POWER_INTERFACE_ONLY:     /* TODO power up either SDIO or I2C */
 272                if (state->version == SOC7090)
 273                        reg_1280 &= ~((1 << 7) | (1 << 5));
 274                else
 275                        reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
 276                break;
 277
 278/* TODO following stuff is just converted from the dib7000-driver - check when is used what */
 279        }
 280
 281        dib7000p_write_word(state, 774, reg_774);
 282        dib7000p_write_word(state, 775, reg_775);
 283        dib7000p_write_word(state, 776, reg_776);
 284        dib7000p_write_word(state, 1280, reg_1280);
 285        if (state->version != SOC7090)
 286                dib7000p_write_word(state, 899, reg_899);
 287
 288        return 0;
 289}
 290
 291static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no)
 292{
 293        u16 reg_908 = 0, reg_909 = 0;
 294        u16 reg;
 295
 296        if (state->version != SOC7090) {
 297                reg_908 = dib7000p_read_word(state, 908);
 298                reg_909 = dib7000p_read_word(state, 909);
 299        }
 300
 301        switch (no) {
 302        case DIBX000_SLOW_ADC_ON:
 303                if (state->version == SOC7090) {
 304                        reg = dib7000p_read_word(state, 1925);
 305
 306                        dib7000p_write_word(state, 1925, reg | (1 << 4) | (1 << 2));    /* en_slowAdc = 1 & reset_sladc = 1 */
 307
 308                        reg = dib7000p_read_word(state, 1925);  /* read acces to make it works... strange ... */
 309                        msleep(200);
 310                        dib7000p_write_word(state, 1925, reg & ~(1 << 4));      /* en_slowAdc = 1 & reset_sladc = 0 */
 311
 312                        reg = dib7000p_read_word(state, 72) & ~((0x3 << 14) | (0x3 << 12));
 313                        dib7000p_write_word(state, 72, reg | (1 << 14) | (3 << 12) | 524);      /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ; (Vin2 = Vcm) */
 314                } else {
 315                        reg_909 |= (1 << 1) | (1 << 0);
 316                        dib7000p_write_word(state, 909, reg_909);
 317                        reg_909 &= ~(1 << 1);
 318                }
 319                break;
 320
 321        case DIBX000_SLOW_ADC_OFF:
 322                if (state->version == SOC7090) {
 323                        reg = dib7000p_read_word(state, 1925);
 324                        dib7000p_write_word(state, 1925, (reg & ~(1 << 2)) | (1 << 4)); /* reset_sladc = 1 en_slowAdc = 0 */
 325                } else
 326                        reg_909 |= (1 << 1) | (1 << 0);
 327                break;
 328
 329        case DIBX000_ADC_ON:
 330                reg_908 &= 0x0fff;
 331                reg_909 &= 0x0003;
 332                break;
 333
 334        case DIBX000_ADC_OFF:
 335                reg_908 |= (1 << 14) | (1 << 13) | (1 << 12);
 336                reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
 337                break;
 338
 339        case DIBX000_VBG_ENABLE:
 340                reg_908 &= ~(1 << 15);
 341                break;
 342
 343        case DIBX000_VBG_DISABLE:
 344                reg_908 |= (1 << 15);
 345                break;
 346
 347        default:
 348                break;
 349        }
 350
 351//      dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
 352
 353        reg_909 |= (state->cfg.disable_sample_and_hold & 1) << 4;
 354        reg_908 |= (state->cfg.enable_current_mirror & 1) << 7;
 355
 356        if (state->version != SOC7090) {
 357                dib7000p_write_word(state, 908, reg_908);
 358                dib7000p_write_word(state, 909, reg_909);
 359        }
 360}
 361
 362static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
 363{
 364        u32 timf;
 365
 366        // store the current bandwidth for later use
 367        state->current_bandwidth = bw;
 368
 369        if (state->timf == 0) {
 370                dprintk("using default timf");
 371                timf = state->cfg.bw->timf;
 372        } else {
 373                dprintk("using updated timf");
 374                timf = state->timf;
 375        }
 376
 377        timf = timf * (bw / 50) / 160;
 378
 379        dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
 380        dib7000p_write_word(state, 24, (u16) ((timf) & 0xffff));
 381
 382        return 0;
 383}
 384
 385static int dib7000p_sad_calib(struct dib7000p_state *state)
 386{
 387/* internal */
 388        dib7000p_write_word(state, 73, (0 << 1) | (0 << 0));
 389
 390        if (state->version == SOC7090)
 391                dib7000p_write_word(state, 74, 2048);
 392        else
 393                dib7000p_write_word(state, 74, 776);
 394
 395        /* do the calibration */
 396        dib7000p_write_word(state, 73, (1 << 0));
 397        dib7000p_write_word(state, 73, (0 << 0));
 398
 399        msleep(1);
 400
 401        return 0;
 402}
 403
 404int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
 405{
 406        struct dib7000p_state *state = demod->demodulator_priv;
 407        if (value > 4095)
 408                value = 4095;
 409        state->wbd_ref = value;
 410        return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value);
 411}
 412EXPORT_SYMBOL(dib7000p_set_wbd_ref);
 413
 414int dib7000p_get_agc_values(struct dvb_frontend *fe,
 415                u16 *agc_global, u16 *agc1, u16 *agc2, u16 *wbd)
 416{
 417        struct dib7000p_state *state = fe->demodulator_priv;
 418
 419        if (agc_global != NULL)
 420                *agc_global = dib7000p_read_word(state, 394);
 421        if (agc1 != NULL)
 422                *agc1 = dib7000p_read_word(state, 392);
 423        if (agc2 != NULL)
 424                *agc2 = dib7000p_read_word(state, 393);
 425        if (wbd != NULL)
 426                *wbd = dib7000p_read_word(state, 397);
 427
 428        return 0;
 429}
 430EXPORT_SYMBOL(dib7000p_get_agc_values);
 431
 432int dib7000p_set_agc1_min(struct dvb_frontend *fe, u16 v)
 433{
 434        struct dib7000p_state *state = fe->demodulator_priv;
 435        return dib7000p_write_word(state, 108,  v);
 436}
 437EXPORT_SYMBOL(dib7000p_set_agc1_min);
 438
 439static void dib7000p_reset_pll(struct dib7000p_state *state)
 440{
 441        struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
 442        u16 clk_cfg0;
 443
 444        if (state->version == SOC7090) {
 445                dib7000p_write_word(state, 1856, (!bw->pll_reset << 13) | (bw->pll_range << 12) | (bw->pll_ratio << 6) | (bw->pll_prediv));
 446
 447                while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
 448                        ;
 449
 450                dib7000p_write_word(state, 1857, dib7000p_read_word(state, 1857) | (!bw->pll_bypass << 15));
 451        } else {
 452                /* force PLL bypass */
 453                clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) |
 454                        (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0);
 455
 456                dib7000p_write_word(state, 900, clk_cfg0);
 457
 458                /* P_pll_cfg */
 459                dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset);
 460                clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff);
 461                dib7000p_write_word(state, 900, clk_cfg0);
 462        }
 463
 464        dib7000p_write_word(state, 18, (u16) (((bw->internal * 1000) >> 16) & 0xffff));
 465        dib7000p_write_word(state, 19, (u16) ((bw->internal * 1000) & 0xffff));
 466        dib7000p_write_word(state, 21, (u16) ((bw->ifreq >> 16) & 0xffff));
 467        dib7000p_write_word(state, 22, (u16) ((bw->ifreq) & 0xffff));
 468
 469        dib7000p_write_word(state, 72, bw->sad_cfg);
 470}
 471
 472static u32 dib7000p_get_internal_freq(struct dib7000p_state *state)
 473{
 474        u32 internal = (u32) dib7000p_read_word(state, 18) << 16;
 475        internal |= (u32) dib7000p_read_word(state, 19);
 476        internal /= 1000;
 477
 478        return internal;
 479}
 480
 481int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
 482{
 483        struct dib7000p_state *state = fe->demodulator_priv;
 484        u16 reg_1857, reg_1856 = dib7000p_read_word(state, 1856);
 485        u8 loopdiv, prediv;
 486        u32 internal, xtal;
 487
 488        /* get back old values */
 489        prediv = reg_1856 & 0x3f;
 490        loopdiv = (reg_1856 >> 6) & 0x3f;
 491
 492        if ((bw != NULL) && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) {
 493                dprintk("Updating pll (prediv: old =  %d new = %d ; loopdiv : old = %d new = %d)", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio);
 494                reg_1856 &= 0xf000;
 495                reg_1857 = dib7000p_read_word(state, 1857);
 496                dib7000p_write_word(state, 1857, reg_1857 & ~(1 << 15));
 497
 498                dib7000p_write_word(state, 1856, reg_1856 | ((bw->pll_ratio & 0x3f) << 6) | (bw->pll_prediv & 0x3f));
 499
 500                /* write new system clk into P_sec_len */
 501                internal = dib7000p_get_internal_freq(state);
 502                xtal = (internal / loopdiv) * prediv;
 503                internal = 1000 * (xtal / bw->pll_prediv) * bw->pll_ratio;      /* new internal */
 504                dib7000p_write_word(state, 18, (u16) ((internal >> 16) & 0xffff));
 505                dib7000p_write_word(state, 19, (u16) (internal & 0xffff));
 506
 507                dib7000p_write_word(state, 1857, reg_1857 | (1 << 15));
 508
 509                while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
 510                        dprintk("Waiting for PLL to lock");
 511
 512                return 0;
 513        }
 514        return -EIO;
 515}
 516EXPORT_SYMBOL(dib7000p_update_pll);
 517
 518static int dib7000p_reset_gpio(struct dib7000p_state *st)
 519{
 520        /* reset the GPIOs */
 521        dprintk("gpio dir: %x: val: %x, pwm_pos: %x", st->gpio_dir, st->gpio_val, st->cfg.gpio_pwm_pos);
 522
 523        dib7000p_write_word(st, 1029, st->gpio_dir);
 524        dib7000p_write_word(st, 1030, st->gpio_val);
 525
 526        /* TODO 1031 is P_gpio_od */
 527
 528        dib7000p_write_word(st, 1032, st->cfg.gpio_pwm_pos);
 529
 530        dib7000p_write_word(st, 1037, st->cfg.pwm_freq_div);
 531        return 0;
 532}
 533
 534static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val)
 535{
 536        st->gpio_dir = dib7000p_read_word(st, 1029);
 537        st->gpio_dir &= ~(1 << num);    /* reset the direction bit */
 538        st->gpio_dir |= (dir & 0x1) << num;     /* set the new direction */
 539        dib7000p_write_word(st, 1029, st->gpio_dir);
 540
 541        st->gpio_val = dib7000p_read_word(st, 1030);
 542        st->gpio_val &= ~(1 << num);    /* reset the direction bit */
 543        st->gpio_val |= (val & 0x01) << num;    /* set the new value */
 544        dib7000p_write_word(st, 1030, st->gpio_val);
 545
 546        return 0;
 547}
 548
 549int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val)
 550{
 551        struct dib7000p_state *state = demod->demodulator_priv;
 552        return dib7000p_cfg_gpio(state, num, dir, val);
 553}
 554EXPORT_SYMBOL(dib7000p_set_gpio);
 555
 556static u16 dib7000p_defaults[] = {
 557        // auto search configuration
 558        3, 2,
 559        0x0004,
 560        (1<<3)|(1<<11)|(1<<12)|(1<<13),
 561        0x0814,                 /* Equal Lock */
 562
 563        12, 6,
 564        0x001b,
 565        0x7740,
 566        0x005b,
 567        0x8d80,
 568        0x01c9,
 569        0xc380,
 570        0x0000,
 571        0x0080,
 572        0x0000,
 573        0x0090,
 574        0x0001,
 575        0xd4c0,
 576
 577        1, 26,
 578        0x6680,
 579
 580        /* set ADC level to -16 */
 581        11, 79,
 582        (1 << 13) - 825 - 117,
 583        (1 << 13) - 837 - 117,
 584        (1 << 13) - 811 - 117,
 585        (1 << 13) - 766 - 117,
 586        (1 << 13) - 737 - 117,
 587        (1 << 13) - 693 - 117,
 588        (1 << 13) - 648 - 117,
 589        (1 << 13) - 619 - 117,
 590        (1 << 13) - 575 - 117,
 591        (1 << 13) - 531 - 117,
 592        (1 << 13) - 501 - 117,
 593
 594        1, 142,
 595        0x0410,
 596
 597        /* disable power smoothing */
 598        8, 145,
 599        0,
 600        0,
 601        0,
 602        0,
 603        0,
 604        0,
 605        0,
 606        0,
 607
 608        1, 154,
 609        1 << 13,
 610
 611        1, 168,
 612        0x0ccd,
 613
 614        1, 183,
 615        0x200f,
 616
 617        1, 212,
 618                0x169,
 619
 620        5, 187,
 621        0x023d,
 622        0x00a4,
 623        0x00a4,
 624        0x7ff0,
 625        0x3ccc,
 626
 627        1, 198,
 628        0x800,
 629
 630        1, 222,
 631        0x0010,
 632
 633        1, 235,
 634        0x0062,
 635
 636        0,
 637};
 638
 639static int dib7000p_demod_reset(struct dib7000p_state *state)
 640{
 641        dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
 642
 643        if (state->version == SOC7090)
 644                dibx000_reset_i2c_master(&state->i2c_master);
 645
 646        dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE);
 647
 648        /* restart all parts */
 649        dib7000p_write_word(state, 770, 0xffff);
 650        dib7000p_write_word(state, 771, 0xffff);
 651        dib7000p_write_word(state, 772, 0x001f);
 652        dib7000p_write_word(state, 1280, 0x001f - ((1 << 4) | (1 << 3)));
 653
 654        dib7000p_write_word(state, 770, 0);
 655        dib7000p_write_word(state, 771, 0);
 656        dib7000p_write_word(state, 772, 0);
 657        dib7000p_write_word(state, 1280, 0);
 658
 659        if (state->version != SOC7090) {
 660                dib7000p_write_word(state,  898, 0x0003);
 661                dib7000p_write_word(state,  898, 0);
 662        }
 663
 664        /* default */
 665        dib7000p_reset_pll(state);
 666
 667        if (dib7000p_reset_gpio(state) != 0)
 668                dprintk("GPIO reset was not successful.");
 669
 670        if (state->version == SOC7090) {
 671                dib7000p_write_word(state, 899, 0);
 672
 673                /* impulse noise */
 674                dib7000p_write_word(state, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */
 675                dib7000p_write_word(state, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */
 676                dib7000p_write_word(state, 44, 300); /* 300 fag P_iqc_dect_min = +280 */
 677                dib7000p_write_word(state, 273, (0<<6) | 30);
 678        }
 679        if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
 680                dprintk("OUTPUT_MODE could not be reset.");
 681
 682        dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
 683        dib7000p_sad_calib(state);
 684        dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
 685
 686        /* unforce divstr regardless whether i2c enumeration was done or not */
 687        dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1));
 688
 689        dib7000p_set_bandwidth(state, 8000);
 690
 691        if (state->version == SOC7090) {
 692                dib7000p_write_word(state, 36, 0x0755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */
 693        } else {
 694                if (state->cfg.tuner_is_baseband)
 695                        dib7000p_write_word(state, 36, 0x0755);
 696                else
 697                        dib7000p_write_word(state, 36, 0x1f55);
 698        }
 699
 700        dib7000p_write_tab(state, dib7000p_defaults);
 701        if (state->version != SOC7090) {
 702                dib7000p_write_word(state, 901, 0x0006);
 703                dib7000p_write_word(state, 902, (3 << 10) | (1 << 6));
 704                dib7000p_write_word(state, 905, 0x2c8e);
 705        }
 706
 707        dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
 708
 709        return 0;
 710}
 711
 712static void dib7000p_pll_clk_cfg(struct dib7000p_state *state)
 713{
 714        u16 tmp = 0;
 715        tmp = dib7000p_read_word(state, 903);
 716        dib7000p_write_word(state, 903, (tmp | 0x1));
 717        tmp = dib7000p_read_word(state, 900);
 718        dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6));
 719}
 720
 721static void dib7000p_restart_agc(struct dib7000p_state *state)
 722{
 723        // P_restart_iqc & P_restart_agc
 724        dib7000p_write_word(state, 770, (1 << 11) | (1 << 9));
 725        dib7000p_write_word(state, 770, 0x0000);
 726}
 727
 728static int dib7000p_update_lna(struct dib7000p_state *state)
 729{
 730        u16 dyn_gain;
 731
 732        if (state->cfg.update_lna) {
 733                dyn_gain = dib7000p_read_word(state, 394);
 734                if (state->cfg.update_lna(&state->demod, dyn_gain)) {
 735                        dib7000p_restart_agc(state);
 736                        return 1;
 737                }
 738        }
 739
 740        return 0;
 741}
 742
 743static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
 744{
 745        struct dibx000_agc_config *agc = NULL;
 746        int i;
 747        if (state->current_band == band && state->current_agc != NULL)
 748                return 0;
 749        state->current_band = band;
 750
 751        for (i = 0; i < state->cfg.agc_config_count; i++)
 752                if (state->cfg.agc[i].band_caps & band) {
 753                        agc = &state->cfg.agc[i];
 754                        break;
 755                }
 756
 757        if (agc == NULL) {
 758                dprintk("no valid AGC configuration found for band 0x%02x", band);
 759                return -EINVAL;
 760        }
 761
 762        state->current_agc = agc;
 763
 764        /* AGC */
 765        dib7000p_write_word(state, 75, agc->setup);
 766        dib7000p_write_word(state, 76, agc->inv_gain);
 767        dib7000p_write_word(state, 77, agc->time_stabiliz);
 768        dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);
 769
 770        // Demod AGC loop configuration
 771        dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);
 772        dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp);
 773
 774        /* AGC continued */
 775        dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
 776                state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
 777
 778        if (state->wbd_ref != 0)
 779                dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref);
 780        else
 781                dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref);
 782
 783        dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
 784
 785        dib7000p_write_word(state, 107, agc->agc1_max);
 786        dib7000p_write_word(state, 108, agc->agc1_min);
 787        dib7000p_write_word(state, 109, agc->agc2_max);
 788        dib7000p_write_word(state, 110, agc->agc2_min);
 789        dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
 790        dib7000p_write_word(state, 112, agc->agc1_pt3);
 791        dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
 792        dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
 793        dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
 794        return 0;
 795}
 796
 797static void dib7000p_set_dds(struct dib7000p_state *state, s32 offset_khz)
 798{
 799        u32 internal = dib7000p_get_internal_freq(state);
 800        s32 unit_khz_dds_val = 67108864 / (internal);   /* 2**26 / Fsampling is the unit 1KHz offset */
 801        u32 abs_offset_khz = ABS(offset_khz);
 802        u32 dds = state->cfg.bw->ifreq & 0x1ffffff;
 803        u8 invert = !!(state->cfg.bw->ifreq & (1 << 25));
 804
 805        dprintk("setting a frequency offset of %dkHz internal freq = %d invert = %d", offset_khz, internal, invert);
 806
 807        if (offset_khz < 0)
 808                unit_khz_dds_val *= -1;
 809
 810        /* IF tuner */
 811        if (invert)
 812                dds -= (abs_offset_khz * unit_khz_dds_val);     /* /100 because of /100 on the unit_khz_dds_val line calc for better accuracy */
 813        else
 814                dds += (abs_offset_khz * unit_khz_dds_val);
 815
 816        if (abs_offset_khz <= (internal / 2)) { /* Max dds offset is the half of the demod freq */
 817                dib7000p_write_word(state, 21, (u16) (((dds >> 16) & 0x1ff) | (0 << 10) | (invert << 9)));
 818                dib7000p_write_word(state, 22, (u16) (dds & 0xffff));
 819        }
 820}
 821
 822static int dib7000p_agc_startup(struct dvb_frontend *demod)
 823{
 824        struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
 825        struct dib7000p_state *state = demod->demodulator_priv;
 826        int ret = -1;
 827        u8 *agc_state = &state->agc_state;
 828        u8 agc_split;
 829        u16 reg;
 830        u32 upd_demod_gain_period = 0x1000;
 831        s32 frequency_offset = 0;
 832
 833        switch (state->agc_state) {
 834        case 0:
 835                dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
 836                if (state->version == SOC7090) {
 837                        reg = dib7000p_read_word(state, 0x79b) & 0xff00;
 838                        dib7000p_write_word(state, 0x79a, upd_demod_gain_period & 0xFFFF);      /* lsb */
 839                        dib7000p_write_word(state, 0x79b, reg | (1 << 14) | ((upd_demod_gain_period >> 16) & 0xFF));
 840
 841                        /* enable adc i & q */
 842                        reg = dib7000p_read_word(state, 0x780);
 843                        dib7000p_write_word(state, 0x780, (reg | (0x3)) & (~(1 << 7)));
 844                } else {
 845                        dib7000p_set_adc_state(state, DIBX000_ADC_ON);
 846                        dib7000p_pll_clk_cfg(state);
 847                }
 848
 849                if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency / 1000)) != 0)
 850                        return -1;
 851
 852                if (demod->ops.tuner_ops.get_frequency) {
 853                        u32 frequency_tuner;
 854
 855                        demod->ops.tuner_ops.get_frequency(demod, &frequency_tuner);
 856                        frequency_offset = (s32)frequency_tuner / 1000 - ch->frequency / 1000;
 857                }
 858
 859                dib7000p_set_dds(state, frequency_offset);
 860                ret = 7;
 861                (*agc_state)++;
 862                break;
 863
 864        case 1:
 865                if (state->cfg.agc_control)
 866                        state->cfg.agc_control(&state->demod, 1);
 867
 868                dib7000p_write_word(state, 78, 32768);
 869                if (!state->current_agc->perform_agc_softsplit) {
 870                        /* we are using the wbd - so slow AGC startup */
 871                        /* force 0 split on WBD and restart AGC */
 872                        dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));
 873                        (*agc_state)++;
 874                        ret = 5;
 875                } else {
 876                        /* default AGC startup */
 877                        (*agc_state) = 4;
 878                        /* wait AGC rough lock time */
 879                        ret = 7;
 880                }
 881
 882                dib7000p_restart_agc(state);
 883                break;
 884
 885        case 2:         /* fast split search path after 5sec */
 886                dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4));   /* freeze AGC loop */
 887                dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8));     /* fast split search 0.25kHz */
 888                (*agc_state)++;
 889                ret = 14;
 890                break;
 891
 892        case 3:         /* split search ended */
 893                agc_split = (u8) dib7000p_read_word(state, 396);        /* store the split value for the next time */
 894                dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */
 895
 896                dib7000p_write_word(state, 75, state->current_agc->setup);      /* std AGC loop */
 897                dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split);        /* standard split search */
 898
 899                dib7000p_restart_agc(state);
 900
 901                dprintk("SPLIT %p: %hd", demod, agc_split);
 902
 903                (*agc_state)++;
 904                ret = 5;
 905                break;
 906
 907        case 4:         /* LNA startup */
 908                ret = 7;
 909
 910                if (dib7000p_update_lna(state))
 911                        ret = 5;
 912                else
 913                        (*agc_state)++;
 914                break;
 915
 916        case 5:
 917                if (state->cfg.agc_control)
 918                        state->cfg.agc_control(&state->demod, 0);
 919                (*agc_state)++;
 920                break;
 921        default:
 922                break;
 923        }
 924        return ret;
 925}
 926
 927static void dib7000p_update_timf(struct dib7000p_state *state)
 928{
 929        u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428);
 930        state->timf = timf * 160 / (state->current_bandwidth / 50);
 931        dib7000p_write_word(state, 23, (u16) (timf >> 16));
 932        dib7000p_write_word(state, 24, (u16) (timf & 0xffff));
 933        dprintk("updated timf_frequency: %d (default: %d)", state->timf, state->cfg.bw->timf);
 934
 935}
 936
 937u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
 938{
 939        struct dib7000p_state *state = fe->demodulator_priv;
 940        switch (op) {
 941        case DEMOD_TIMF_SET:
 942                state->timf = timf;
 943                break;
 944        case DEMOD_TIMF_UPDATE:
 945                dib7000p_update_timf(state);
 946                break;
 947        case DEMOD_TIMF_GET:
 948                break;
 949        }
 950        dib7000p_set_bandwidth(state, state->current_bandwidth);
 951        return state->timf;
 952}
 953EXPORT_SYMBOL(dib7000p_ctrl_timf);
 954
 955static void dib7000p_set_channel(struct dib7000p_state *state,
 956                                 struct dtv_frontend_properties *ch, u8 seq)
 957{
 958        u16 value, est[4];
 959
 960        dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
 961
 962        /* nfft, guard, qam, alpha */
 963        value = 0;
 964        switch (ch->transmission_mode) {
 965        case TRANSMISSION_MODE_2K:
 966                value |= (0 << 7);
 967                break;
 968        case TRANSMISSION_MODE_4K:
 969                value |= (2 << 7);
 970                break;
 971        default:
 972        case TRANSMISSION_MODE_8K:
 973                value |= (1 << 7);
 974                break;
 975        }
 976        switch (ch->guard_interval) {
 977        case GUARD_INTERVAL_1_32:
 978                value |= (0 << 5);
 979                break;
 980        case GUARD_INTERVAL_1_16:
 981                value |= (1 << 5);
 982                break;
 983        case GUARD_INTERVAL_1_4:
 984                value |= (3 << 5);
 985                break;
 986        default:
 987        case GUARD_INTERVAL_1_8:
 988                value |= (2 << 5);
 989                break;
 990        }
 991        switch (ch->modulation) {
 992        case QPSK:
 993                value |= (0 << 3);
 994                break;
 995        case QAM_16:
 996                value |= (1 << 3);
 997                break;
 998        default:
 999        case QAM_64:
1000                value |= (2 << 3);
1001                break;
1002        }
1003        switch (HIERARCHY_1) {
1004        case HIERARCHY_2:
1005                value |= 2;
1006                break;
1007        case HIERARCHY_4:
1008                value |= 4;
1009                break;
1010        default:
1011        case HIERARCHY_1:
1012                value |= 1;
1013                break;
1014        }
1015        dib7000p_write_word(state, 0, value);
1016        dib7000p_write_word(state, 5, (seq << 4) | 1);  /* do not force tps, search list 0 */
1017
1018        /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
1019        value = 0;
1020        if (1 != 0)
1021                value |= (1 << 6);
1022        if (ch->hierarchy == 1)
1023                value |= (1 << 4);
1024        if (1 == 1)
1025                value |= 1;
1026        switch ((ch->hierarchy == 0 || 1 == 1) ? ch->code_rate_HP : ch->code_rate_LP) {
1027        case FEC_2_3:
1028                value |= (2 << 1);
1029                break;
1030        case FEC_3_4:
1031                value |= (3 << 1);
1032                break;
1033        case FEC_5_6:
1034                value |= (5 << 1);
1035                break;
1036        case FEC_7_8:
1037                value |= (7 << 1);
1038                break;
1039        default:
1040        case FEC_1_2:
1041                value |= (1 << 1);
1042                break;
1043        }
1044        dib7000p_write_word(state, 208, value);
1045
1046        /* offset loop parameters */
1047        dib7000p_write_word(state, 26, 0x6680);
1048        dib7000p_write_word(state, 32, 0x0003);
1049        dib7000p_write_word(state, 29, 0x1273);
1050        dib7000p_write_word(state, 33, 0x0005);
1051
1052        /* P_dvsy_sync_wait */
1053        switch (ch->transmission_mode) {
1054        case TRANSMISSION_MODE_8K:
1055                value = 256;
1056                break;
1057        case TRANSMISSION_MODE_4K:
1058                value = 128;
1059                break;
1060        case TRANSMISSION_MODE_2K:
1061        default:
1062                value = 64;
1063                break;
1064        }
1065        switch (ch->guard_interval) {
1066        case GUARD_INTERVAL_1_16:
1067                value *= 2;
1068                break;
1069        case GUARD_INTERVAL_1_8:
1070                value *= 4;
1071                break;
1072        case GUARD_INTERVAL_1_4:
1073                value *= 8;
1074                break;
1075        default:
1076        case GUARD_INTERVAL_1_32:
1077                value *= 1;
1078                break;
1079        }
1080        if (state->cfg.diversity_delay == 0)
1081                state->div_sync_wait = (value * 3) / 2 + 48;
1082        else
1083                state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay;
1084
1085        /* deactive the possibility of diversity reception if extended interleaver */
1086        state->div_force_off = !1 && ch->transmission_mode != TRANSMISSION_MODE_8K;
1087        dib7000p_set_diversity_in(&state->demod, state->div_state);
1088
1089        /* channel estimation fine configuration */
1090        switch (ch->modulation) {
1091        case QAM_64:
1092                est[0] = 0x0148;        /* P_adp_regul_cnt 0.04 */
1093                est[1] = 0xfff0;        /* P_adp_noise_cnt -0.002 */
1094                est[2] = 0x00a4;        /* P_adp_regul_ext 0.02 */
1095                est[3] = 0xfff8;        /* P_adp_noise_ext -0.001 */
1096                break;
1097        case QAM_16:
1098                est[0] = 0x023d;        /* P_adp_regul_cnt 0.07 */
1099                est[1] = 0xffdf;        /* P_adp_noise_cnt -0.004 */
1100                est[2] = 0x00a4;        /* P_adp_regul_ext 0.02 */
1101                est[3] = 0xfff0;        /* P_adp_noise_ext -0.002 */
1102                break;
1103        default:
1104                est[0] = 0x099a;        /* P_adp_regul_cnt 0.3 */
1105                est[1] = 0xffae;        /* P_adp_noise_cnt -0.01 */
1106                est[2] = 0x0333;        /* P_adp_regul_ext 0.1 */
1107                est[3] = 0xfff8;        /* P_adp_noise_ext -0.002 */
1108                break;
1109        }
1110        for (value = 0; value < 4; value++)
1111                dib7000p_write_word(state, 187 + value, est[value]);
1112}
1113
1114static int dib7000p_autosearch_start(struct dvb_frontend *demod)
1115{
1116        struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
1117        struct dib7000p_state *state = demod->demodulator_priv;
1118        struct dtv_frontend_properties schan;
1119        u32 value, factor;
1120        u32 internal = dib7000p_get_internal_freq(state);
1121
1122        schan = *ch;
1123        schan.modulation = QAM_64;
1124        schan.guard_interval = GUARD_INTERVAL_1_32;
1125        schan.transmission_mode = TRANSMISSION_MODE_8K;
1126        schan.code_rate_HP = FEC_2_3;
1127        schan.code_rate_LP = FEC_3_4;
1128        schan.hierarchy = 0;
1129
1130        dib7000p_set_channel(state, &schan, 7);
1131
1132        factor = BANDWIDTH_TO_KHZ(ch->bandwidth_hz);
1133        if (factor >= 5000) {
1134                if (state->version == SOC7090)
1135                        factor = 2;
1136                else
1137                        factor = 1;
1138        } else
1139                factor = 6;
1140
1141        value = 30 * internal * factor;
1142        dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff));
1143        dib7000p_write_word(state, 7, (u16) (value & 0xffff));
1144        value = 100 * internal * factor;
1145        dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff));
1146        dib7000p_write_word(state, 9, (u16) (value & 0xffff));
1147        value = 500 * internal * factor;
1148        dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff));
1149        dib7000p_write_word(state, 11, (u16) (value & 0xffff));
1150
1151        value = dib7000p_read_word(state, 0);
1152        dib7000p_write_word(state, 0, (u16) ((1 << 9) | value));
1153        dib7000p_read_word(state, 1284);
1154        dib7000p_write_word(state, 0, (u16) value);
1155
1156        return 0;
1157}
1158
1159static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod)
1160{
1161        struct dib7000p_state *state = demod->demodulator_priv;
1162        u16 irq_pending = dib7000p_read_word(state, 1284);
1163
1164        if (irq_pending & 0x1)
1165                return 1;
1166
1167        if (irq_pending & 0x2)
1168                return 2;
1169
1170        return 0;
1171}
1172
1173static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw)
1174{
1175        static s16 notch[] = { 16143, 14402, 12238, 9713, 6902, 3888, 759, -2392 };
1176        static u8 sine[] = { 0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
1177                24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
1178                53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
1179                82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
1180                107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
1181                128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
1182                147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
1183                166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
1184                183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
1185                199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
1186                213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
1187                225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
1188                235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
1189                244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
1190                250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
1191                254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
1192                255, 255, 255, 255, 255, 255
1193        };
1194
1195        u32 xtal = state->cfg.bw->xtal_hz / 1000;
1196        int f_rel = DIV_ROUND_CLOSEST(rf_khz, xtal) * xtal - rf_khz;
1197        int k;
1198        int coef_re[8], coef_im[8];
1199        int bw_khz = bw;
1200        u32 pha;
1201
1202        dprintk("relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal);
1203
1204        if (f_rel < -bw_khz / 2 || f_rel > bw_khz / 2)
1205                return;
1206
1207        bw_khz /= 100;
1208
1209        dib7000p_write_word(state, 142, 0x0610);
1210
1211        for (k = 0; k < 8; k++) {
1212                pha = ((f_rel * (k + 1) * 112 * 80 / bw_khz) / 1000) & 0x3ff;
1213
1214                if (pha == 0) {
1215                        coef_re[k] = 256;
1216                        coef_im[k] = 0;
1217                } else if (pha < 256) {
1218                        coef_re[k] = sine[256 - (pha & 0xff)];
1219                        coef_im[k] = sine[pha & 0xff];
1220                } else if (pha == 256) {
1221                        coef_re[k] = 0;
1222                        coef_im[k] = 256;
1223                } else if (pha < 512) {
1224                        coef_re[k] = -sine[pha & 0xff];
1225                        coef_im[k] = sine[256 - (pha & 0xff)];
1226                } else if (pha == 512) {
1227                        coef_re[k] = -256;
1228                        coef_im[k] = 0;
1229                } else if (pha < 768) {
1230                        coef_re[k] = -sine[256 - (pha & 0xff)];
1231                        coef_im[k] = -sine[pha & 0xff];
1232                } else if (pha == 768) {
1233                        coef_re[k] = 0;
1234                        coef_im[k] = -256;
1235                } else {
1236                        coef_re[k] = sine[pha & 0xff];
1237                        coef_im[k] = -sine[256 - (pha & 0xff)];
1238                }
1239
1240                coef_re[k] *= notch[k];
1241                coef_re[k] += (1 << 14);
1242                if (coef_re[k] >= (1 << 24))
1243                        coef_re[k] = (1 << 24) - 1;
1244                coef_re[k] /= (1 << 15);
1245
1246                coef_im[k] *= notch[k];
1247                coef_im[k] += (1 << 14);
1248                if (coef_im[k] >= (1 << 24))
1249                        coef_im[k] = (1 << 24) - 1;
1250                coef_im[k] /= (1 << 15);
1251
1252                dprintk("PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]);
1253
1254                dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
1255                dib7000p_write_word(state, 144, coef_im[k] & 0x3ff);
1256                dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
1257        }
1258        dib7000p_write_word(state, 143, 0);
1259}
1260
1261static int dib7000p_tune(struct dvb_frontend *demod)
1262{
1263        struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
1264        struct dib7000p_state *state = demod->demodulator_priv;
1265        u16 tmp = 0;
1266
1267        if (ch != NULL)
1268                dib7000p_set_channel(state, ch, 0);
1269        else
1270                return -EINVAL;
1271
1272        // restart demod
1273        dib7000p_write_word(state, 770, 0x4000);
1274        dib7000p_write_word(state, 770, 0x0000);
1275        msleep(45);
1276
1277        /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */
1278        tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
1279        if (state->sfn_workaround_active) {
1280                dprintk("SFN workaround is active");
1281                tmp |= (1 << 9);
1282                dib7000p_write_word(state, 166, 0x4000);
1283        } else {
1284                dib7000p_write_word(state, 166, 0x0000);
1285        }
1286        dib7000p_write_word(state, 29, tmp);
1287
1288        // never achieved a lock with that bandwidth so far - wait for osc-freq to update
1289        if (state->timf == 0)
1290                msleep(200);
1291
1292        /* offset loop parameters */
1293
1294        /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
1295        tmp = (6 << 8) | 0x80;
1296        switch (ch->transmission_mode) {
1297        case TRANSMISSION_MODE_2K:
1298                tmp |= (2 << 12);
1299                break;
1300        case TRANSMISSION_MODE_4K:
1301                tmp |= (3 << 12);
1302                break;
1303        default:
1304        case TRANSMISSION_MODE_8K:
1305                tmp |= (4 << 12);
1306                break;
1307        }
1308        dib7000p_write_word(state, 26, tmp);    /* timf_a(6xxx) */
1309
1310        /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1311        tmp = (0 << 4);
1312        switch (ch->transmission_mode) {
1313        case TRANSMISSION_MODE_2K:
1314                tmp |= 0x6;
1315                break;
1316        case TRANSMISSION_MODE_4K:
1317                tmp |= 0x7;
1318                break;
1319        default:
1320        case TRANSMISSION_MODE_8K:
1321                tmp |= 0x8;
1322                break;
1323        }
1324        dib7000p_write_word(state, 32, tmp);
1325
1326        /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1327        tmp = (0 << 4);
1328        switch (ch->transmission_mode) {
1329        case TRANSMISSION_MODE_2K:
1330                tmp |= 0x6;
1331                break;
1332        case TRANSMISSION_MODE_4K:
1333                tmp |= 0x7;
1334                break;
1335        default:
1336        case TRANSMISSION_MODE_8K:
1337                tmp |= 0x8;
1338                break;
1339        }
1340        dib7000p_write_word(state, 33, tmp);
1341
1342        tmp = dib7000p_read_word(state, 509);
1343        if (!((tmp >> 6) & 0x1)) {
1344                /* restart the fec */
1345                tmp = dib7000p_read_word(state, 771);
1346                dib7000p_write_word(state, 771, tmp | (1 << 1));
1347                dib7000p_write_word(state, 771, tmp);
1348                msleep(40);
1349                tmp = dib7000p_read_word(state, 509);
1350        }
1351        // we achieved a lock - it's time to update the osc freq
1352        if ((tmp >> 6) & 0x1) {
1353                dib7000p_update_timf(state);
1354                /* P_timf_alpha += 2 */
1355                tmp = dib7000p_read_word(state, 26);
1356                dib7000p_write_word(state, 26, (tmp & ~(0xf << 12)) | ((((tmp >> 12) & 0xf) + 5) << 12));
1357        }
1358
1359        if (state->cfg.spur_protect)
1360                dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
1361
1362        dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
1363        return 0;
1364}
1365
1366static int dib7000p_wakeup(struct dvb_frontend *demod)
1367{
1368        struct dib7000p_state *state = demod->demodulator_priv;
1369        dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
1370        dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
1371        if (state->version == SOC7090)
1372                dib7000p_sad_calib(state);
1373        return 0;
1374}
1375
1376static int dib7000p_sleep(struct dvb_frontend *demod)
1377{
1378        struct dib7000p_state *state = demod->demodulator_priv;
1379        if (state->version == SOC7090)
1380                return dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1381        return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1382}
1383
1384static int dib7000p_identify(struct dib7000p_state *st)
1385{
1386        u16 value;
1387        dprintk("checking demod on I2C address: %d (%x)", st->i2c_addr, st->i2c_addr);
1388
1389        if ((value = dib7000p_read_word(st, 768)) != 0x01b3) {
1390                dprintk("wrong Vendor ID (read=0x%x)", value);
1391                return -EREMOTEIO;
1392        }
1393
1394        if ((value = dib7000p_read_word(st, 769)) != 0x4000) {
1395                dprintk("wrong Device ID (%x)", value);
1396                return -EREMOTEIO;
1397        }
1398
1399        return 0;
1400}
1401
1402static int dib7000p_get_frontend(struct dvb_frontend *fe)
1403{
1404        struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
1405        struct dib7000p_state *state = fe->demodulator_priv;
1406        u16 tps = dib7000p_read_word(state, 463);
1407
1408        fep->inversion = INVERSION_AUTO;
1409
1410        fep->bandwidth_hz = BANDWIDTH_TO_HZ(state->current_bandwidth);
1411
1412        switch ((tps >> 8) & 0x3) {
1413        case 0:
1414                fep->transmission_mode = TRANSMISSION_MODE_2K;
1415                break;
1416        case 1:
1417                fep->transmission_mode = TRANSMISSION_MODE_8K;
1418                break;
1419        /* case 2: fep->transmission_mode = TRANSMISSION_MODE_4K; break; */
1420        }
1421
1422        switch (tps & 0x3) {
1423        case 0:
1424                fep->guard_interval = GUARD_INTERVAL_1_32;
1425                break;
1426        case 1:
1427                fep->guard_interval = GUARD_INTERVAL_1_16;
1428                break;
1429        case 2:
1430                fep->guard_interval = GUARD_INTERVAL_1_8;
1431                break;
1432        case 3:
1433                fep->guard_interval = GUARD_INTERVAL_1_4;
1434                break;
1435        }
1436
1437        switch ((tps >> 14) & 0x3) {
1438        case 0:
1439                fep->modulation = QPSK;
1440                break;
1441        case 1:
1442                fep->modulation = QAM_16;
1443                break;
1444        case 2:
1445        default:
1446                fep->modulation = QAM_64;
1447                break;
1448        }
1449
1450        /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1451        /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1452
1453        fep->hierarchy = HIERARCHY_NONE;
1454        switch ((tps >> 5) & 0x7) {
1455        case 1:
1456                fep->code_rate_HP = FEC_1_2;
1457                break;
1458        case 2:
1459                fep->code_rate_HP = FEC_2_3;
1460                break;
1461        case 3:
1462                fep->code_rate_HP = FEC_3_4;
1463                break;
1464        case 5:
1465                fep->code_rate_HP = FEC_5_6;
1466                break;
1467        case 7:
1468        default:
1469                fep->code_rate_HP = FEC_7_8;
1470                break;
1471
1472        }
1473
1474        switch ((tps >> 2) & 0x7) {
1475        case 1:
1476                fep->code_rate_LP = FEC_1_2;
1477                break;
1478        case 2:
1479                fep->code_rate_LP = FEC_2_3;
1480                break;
1481        case 3:
1482                fep->code_rate_LP = FEC_3_4;
1483                break;
1484        case 5:
1485                fep->code_rate_LP = FEC_5_6;
1486                break;
1487        case 7:
1488        default:
1489                fep->code_rate_LP = FEC_7_8;
1490                break;
1491        }
1492
1493        /* native interleaver: (dib7000p_read_word(state, 464) >>  5) & 0x1 */
1494
1495        return 0;
1496}
1497
1498static int dib7000p_set_frontend(struct dvb_frontend *fe)
1499{
1500        struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
1501        struct dib7000p_state *state = fe->demodulator_priv;
1502        int time, ret;
1503
1504        if (state->version == SOC7090)
1505                dib7090_set_diversity_in(fe, 0);
1506        else
1507                dib7000p_set_output_mode(state, OUTMODE_HIGH_Z);
1508
1509        /* maybe the parameter has been changed */
1510        state->sfn_workaround_active = buggy_sfn_workaround;
1511
1512        if (fe->ops.tuner_ops.set_params)
1513                fe->ops.tuner_ops.set_params(fe);
1514
1515        /* start up the AGC */
1516        state->agc_state = 0;
1517        do {
1518                time = dib7000p_agc_startup(fe);
1519                if (time != -1)
1520                        msleep(time);
1521        } while (time != -1);
1522
1523        if (fep->transmission_mode == TRANSMISSION_MODE_AUTO ||
1524                fep->guard_interval == GUARD_INTERVAL_AUTO || fep->modulation == QAM_AUTO || fep->code_rate_HP == FEC_AUTO) {
1525                int i = 800, found;
1526
1527                dib7000p_autosearch_start(fe);
1528                do {
1529                        msleep(1);
1530                        found = dib7000p_autosearch_is_irq(fe);
1531                } while (found == 0 && i--);
1532
1533                dprintk("autosearch returns: %d", found);
1534                if (found == 0 || found == 1)
1535                        return 0;
1536
1537                dib7000p_get_frontend(fe);
1538        }
1539
1540        ret = dib7000p_tune(fe);
1541
1542        /* make this a config parameter */
1543        if (state->version == SOC7090) {
1544                dib7090_set_output_mode(fe, state->cfg.output_mode);
1545                if (state->cfg.enMpegOutput == 0) {
1546                        dib7090_setDibTxMux(state, MPEG_ON_DIBTX);
1547                        dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS);
1548                }
1549        } else
1550                dib7000p_set_output_mode(state, state->cfg.output_mode);
1551
1552        return ret;
1553}
1554
1555static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t * stat)
1556{
1557        struct dib7000p_state *state = fe->demodulator_priv;
1558        u16 lock = dib7000p_read_word(state, 509);
1559
1560        *stat = 0;
1561
1562        if (lock & 0x8000)
1563                *stat |= FE_HAS_SIGNAL;
1564        if (lock & 0x3000)
1565                *stat |= FE_HAS_CARRIER;
1566        if (lock & 0x0100)
1567                *stat |= FE_HAS_VITERBI;
1568        if (lock & 0x0010)
1569                *stat |= FE_HAS_SYNC;
1570        if ((lock & 0x0038) == 0x38)
1571                *stat |= FE_HAS_LOCK;
1572
1573        return 0;
1574}
1575
1576static int dib7000p_read_ber(struct dvb_frontend *fe, u32 * ber)
1577{
1578        struct dib7000p_state *state = fe->demodulator_priv;
1579        *ber = (dib7000p_read_word(state, 500) << 16) | dib7000p_read_word(state, 501);
1580        return 0;
1581}
1582
1583static int dib7000p_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
1584{
1585        struct dib7000p_state *state = fe->demodulator_priv;
1586        *unc = dib7000p_read_word(state, 506);
1587        return 0;
1588}
1589
1590static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
1591{
1592        struct dib7000p_state *state = fe->demodulator_priv;
1593        u16 val = dib7000p_read_word(state, 394);
1594        *strength = 65535 - val;
1595        return 0;
1596}
1597
1598static int dib7000p_read_snr(struct dvb_frontend *fe, u16 * snr)
1599{
1600        struct dib7000p_state *state = fe->demodulator_priv;
1601        u16 val;
1602        s32 signal_mant, signal_exp, noise_mant, noise_exp;
1603        u32 result = 0;
1604
1605        val = dib7000p_read_word(state, 479);
1606        noise_mant = (val >> 4) & 0xff;
1607        noise_exp = ((val & 0xf) << 2);
1608        val = dib7000p_read_word(state, 480);
1609        noise_exp += ((val >> 14) & 0x3);
1610        if ((noise_exp & 0x20) != 0)
1611                noise_exp -= 0x40;
1612
1613        signal_mant = (val >> 6) & 0xFF;
1614        signal_exp = (val & 0x3F);
1615        if ((signal_exp & 0x20) != 0)
1616                signal_exp -= 0x40;
1617
1618        if (signal_mant != 0)
1619                result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
1620        else
1621                result = intlog10(2) * 10 * signal_exp - 100;
1622
1623        if (noise_mant != 0)
1624                result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
1625        else
1626                result -= intlog10(2) * 10 * noise_exp - 100;
1627
1628        *snr = result / ((1 << 24) / 10);
1629        return 0;
1630}
1631
1632static int dib7000p_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
1633{
1634        tune->min_delay_ms = 1000;
1635        return 0;
1636}
1637
1638static void dib7000p_release(struct dvb_frontend *demod)
1639{
1640        struct dib7000p_state *st = demod->demodulator_priv;
1641        dibx000_exit_i2c_master(&st->i2c_master);
1642        i2c_del_adapter(&st->dib7090_tuner_adap);
1643        kfree(st);
1644}
1645
1646int dib7000pc_detection(struct i2c_adapter *i2c_adap)
1647{
1648        u8 *tx, *rx;
1649        struct i2c_msg msg[2] = {
1650                {.addr = 18 >> 1, .flags = 0, .len = 2},
1651                {.addr = 18 >> 1, .flags = I2C_M_RD, .len = 2},
1652        };
1653        int ret = 0;
1654
1655        tx = kzalloc(2*sizeof(u8), GFP_KERNEL);
1656        if (!tx)
1657                return -ENOMEM;
1658        rx = kzalloc(2*sizeof(u8), GFP_KERNEL);
1659        if (!rx) {
1660                ret = -ENOMEM;
1661                goto rx_memory_error;
1662        }
1663
1664        msg[0].buf = tx;
1665        msg[1].buf = rx;
1666
1667        tx[0] = 0x03;
1668        tx[1] = 0x00;
1669
1670        if (i2c_transfer(i2c_adap, msg, 2) == 2)
1671                if (rx[0] == 0x01 && rx[1] == 0xb3) {
1672                        dprintk("-D-  DiB7000PC detected");
1673                        return 1;
1674                }
1675
1676        msg[0].addr = msg[1].addr = 0x40;
1677
1678        if (i2c_transfer(i2c_adap, msg, 2) == 2)
1679                if (rx[0] == 0x01 && rx[1] == 0xb3) {
1680                        dprintk("-D-  DiB7000PC detected");
1681                        return 1;
1682                }
1683
1684        dprintk("-D-  DiB7000PC not detected");
1685
1686        kfree(rx);
1687rx_memory_error:
1688        kfree(tx);
1689        return ret;
1690}
1691EXPORT_SYMBOL(dib7000pc_detection);
1692
1693struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
1694{
1695        struct dib7000p_state *st = demod->demodulator_priv;
1696        return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1697}
1698EXPORT_SYMBOL(dib7000p_get_i2c_master);
1699
1700int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1701{
1702        struct dib7000p_state *state = fe->demodulator_priv;
1703        u16 val = dib7000p_read_word(state, 235) & 0xffef;
1704        val |= (onoff & 0x1) << 4;
1705        dprintk("PID filter enabled %d", onoff);
1706        return dib7000p_write_word(state, 235, val);
1707}
1708EXPORT_SYMBOL(dib7000p_pid_filter_ctrl);
1709
1710int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1711{
1712        struct dib7000p_state *state = fe->demodulator_priv;
1713        dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
1714        return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0);
1715}
1716EXPORT_SYMBOL(dib7000p_pid_filter);
1717
1718int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
1719{
1720        struct dib7000p_state *dpst;
1721        int k = 0;
1722        u8 new_addr = 0;
1723
1724        dpst = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
1725        if (!dpst)
1726                return -ENOMEM;
1727
1728        dpst->i2c_adap = i2c;
1729        mutex_init(&dpst->i2c_buffer_lock);
1730
1731        for (k = no_of_demods - 1; k >= 0; k--) {
1732                dpst->cfg = cfg[k];
1733
1734                /* designated i2c address */
1735                if (cfg[k].default_i2c_addr != 0)
1736                        new_addr = cfg[k].default_i2c_addr + (k << 1);
1737                else
1738                        new_addr = (0x40 + k) << 1;
1739                dpst->i2c_addr = new_addr;
1740                dib7000p_write_word(dpst, 1287, 0x0003);        /* sram lead in, rdy */
1741                if (dib7000p_identify(dpst) != 0) {
1742                        dpst->i2c_addr = default_addr;
1743                        dib7000p_write_word(dpst, 1287, 0x0003);        /* sram lead in, rdy */
1744                        if (dib7000p_identify(dpst) != 0) {
1745                                dprintk("DiB7000P #%d: not identified\n", k);
1746                                kfree(dpst);
1747                                return -EIO;
1748                        }
1749                }
1750
1751                /* start diversity to pull_down div_str - just for i2c-enumeration */
1752                dib7000p_set_output_mode(dpst, OUTMODE_DIVERSITY);
1753
1754                /* set new i2c address and force divstart */
1755                dib7000p_write_word(dpst, 1285, (new_addr << 2) | 0x2);
1756
1757                dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
1758        }
1759
1760        for (k = 0; k < no_of_demods; k++) {
1761                dpst->cfg = cfg[k];
1762                if (cfg[k].default_i2c_addr != 0)
1763                        dpst->i2c_addr = (cfg[k].default_i2c_addr + k) << 1;
1764                else
1765                        dpst->i2c_addr = (0x40 + k) << 1;
1766
1767                // unforce divstr
1768                dib7000p_write_word(dpst, 1285, dpst->i2c_addr << 2);
1769
1770                /* deactivate div - it was just for i2c-enumeration */
1771                dib7000p_set_output_mode(dpst, OUTMODE_HIGH_Z);
1772        }
1773
1774        kfree(dpst);
1775        return 0;
1776}
1777EXPORT_SYMBOL(dib7000p_i2c_enumeration);
1778
1779static const s32 lut_1000ln_mant[] = {
1780        6908, 6956, 7003, 7047, 7090, 7131, 7170, 7208, 7244, 7279, 7313, 7346, 7377, 7408, 7438, 7467, 7495, 7523, 7549, 7575, 7600
1781};
1782
1783static s32 dib7000p_get_adc_power(struct dvb_frontend *fe)
1784{
1785        struct dib7000p_state *state = fe->demodulator_priv;
1786        u32 tmp_val = 0, exp = 0, mant = 0;
1787        s32 pow_i;
1788        u16 buf[2];
1789        u8 ix = 0;
1790
1791        buf[0] = dib7000p_read_word(state, 0x184);
1792        buf[1] = dib7000p_read_word(state, 0x185);
1793        pow_i = (buf[0] << 16) | buf[1];
1794        dprintk("raw pow_i = %d", pow_i);
1795
1796        tmp_val = pow_i;
1797        while (tmp_val >>= 1)
1798                exp++;
1799
1800        mant = (pow_i * 1000 / (1 << exp));
1801        dprintk(" mant = %d exp = %d", mant / 1000, exp);
1802
1803        ix = (u8) ((mant - 1000) / 100);        /* index of the LUT */
1804        dprintk(" ix = %d", ix);
1805
1806        pow_i = (lut_1000ln_mant[ix] + 693 * (exp - 20) - 6908);
1807        pow_i = (pow_i << 8) / 1000;
1808        dprintk(" pow_i = %d", pow_i);
1809
1810        return pow_i;
1811}
1812
1813static int map_addr_to_serpar_number(struct i2c_msg *msg)
1814{
1815        if ((msg->buf[0] <= 15))
1816                msg->buf[0] -= 1;
1817        else if (msg->buf[0] == 17)
1818                msg->buf[0] = 15;
1819        else if (msg->buf[0] == 16)
1820                msg->buf[0] = 17;
1821        else if (msg->buf[0] == 19)
1822                msg->buf[0] = 16;
1823        else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
1824                msg->buf[0] -= 3;
1825        else if (msg->buf[0] == 28)
1826                msg->buf[0] = 23;
1827        else
1828                return -EINVAL;
1829        return 0;
1830}
1831
1832static int w7090p_tuner_write_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1833{
1834        struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1835        u8 n_overflow = 1;
1836        u16 i = 1000;
1837        u16 serpar_num = msg[0].buf[0];
1838
1839        while (n_overflow == 1 && i) {
1840                n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
1841                i--;
1842                if (i == 0)
1843                        dprintk("Tuner ITF: write busy (overflow)");
1844        }
1845        dib7000p_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
1846        dib7000p_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
1847
1848        return num;
1849}
1850
1851static int w7090p_tuner_read_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1852{
1853        struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1854        u8 n_overflow = 1, n_empty = 1;
1855        u16 i = 1000;
1856        u16 serpar_num = msg[0].buf[0];
1857        u16 read_word;
1858
1859        while (n_overflow == 1 && i) {
1860                n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
1861                i--;
1862                if (i == 0)
1863                        dprintk("TunerITF: read busy (overflow)");
1864        }
1865        dib7000p_write_word(state, 1985, (0 << 6) | (serpar_num & 0x3f));
1866
1867        i = 1000;
1868        while (n_empty == 1 && i) {
1869                n_empty = dib7000p_read_word(state, 1984) & 0x1;
1870                i--;
1871                if (i == 0)
1872                        dprintk("TunerITF: read busy (empty)");
1873        }
1874        read_word = dib7000p_read_word(state, 1987);
1875        msg[1].buf[0] = (read_word >> 8) & 0xff;
1876        msg[1].buf[1] = (read_word) & 0xff;
1877
1878        return num;
1879}
1880
1881static int w7090p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1882{
1883        if (map_addr_to_serpar_number(&msg[0]) == 0) {  /* else = Tuner regs to ignore : DIG_CFG, CTRL_RF_LT, PLL_CFG, PWM1_REG, ADCCLK, DIG_CFG_3; SLEEP_EN... */
1884                if (num == 1) { /* write */
1885                        return w7090p_tuner_write_serpar(i2c_adap, msg, 1);
1886                } else {        /* read */
1887                        return w7090p_tuner_read_serpar(i2c_adap, msg, 2);
1888                }
1889        }
1890        return num;
1891}
1892
1893static int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap,
1894                struct i2c_msg msg[], int num, u16 apb_address)
1895{
1896        struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1897        u16 word;
1898
1899        if (num == 1) {         /* write */
1900                dib7000p_write_word(state, apb_address, ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
1901        } else {
1902                word = dib7000p_read_word(state, apb_address);
1903                msg[1].buf[0] = (word >> 8) & 0xff;
1904                msg[1].buf[1] = (word) & 0xff;
1905        }
1906
1907        return num;
1908}
1909
1910static int dib7090_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1911{
1912        struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1913
1914        u16 apb_address = 0, word;
1915        int i = 0;
1916        switch (msg[0].buf[0]) {
1917        case 0x12:
1918                apb_address = 1920;
1919                break;
1920        case 0x14:
1921                apb_address = 1921;
1922                break;
1923        case 0x24:
1924                apb_address = 1922;
1925                break;
1926        case 0x1a:
1927                apb_address = 1923;
1928                break;
1929        case 0x22:
1930                apb_address = 1924;
1931                break;
1932        case 0x33:
1933                apb_address = 1926;
1934                break;
1935        case 0x34:
1936                apb_address = 1927;
1937                break;
1938        case 0x35:
1939                apb_address = 1928;
1940                break;
1941        case 0x36:
1942                apb_address = 1929;
1943                break;
1944        case 0x37:
1945                apb_address = 1930;
1946                break;
1947        case 0x38:
1948                apb_address = 1931;
1949                break;
1950        case 0x39:
1951                apb_address = 1932;
1952                break;
1953        case 0x2a:
1954                apb_address = 1935;
1955                break;
1956        case 0x2b:
1957                apb_address = 1936;
1958                break;
1959        case 0x2c:
1960                apb_address = 1937;
1961                break;
1962        case 0x2d:
1963                apb_address = 1938;
1964                break;
1965        case 0x2e:
1966                apb_address = 1939;
1967                break;
1968        case 0x2f:
1969                apb_address = 1940;
1970                break;
1971        case 0x30:
1972                apb_address = 1941;
1973                break;
1974        case 0x31:
1975                apb_address = 1942;
1976                break;
1977        case 0x32:
1978                apb_address = 1943;
1979                break;
1980        case 0x3e:
1981                apb_address = 1944;
1982                break;
1983        case 0x3f:
1984                apb_address = 1945;
1985                break;
1986        case 0x40:
1987                apb_address = 1948;
1988                break;
1989        case 0x25:
1990                apb_address = 914;
1991                break;
1992        case 0x26:
1993                apb_address = 915;
1994                break;
1995        case 0x27:
1996                apb_address = 917;
1997                break;
1998        case 0x28:
1999                apb_address = 916;
2000                break;
2001        case 0x1d:
2002                i = ((dib7000p_read_word(state, 72) >> 12) & 0x3);
2003                word = dib7000p_read_word(state, 384 + i);
2004                msg[1].buf[0] = (word >> 8) & 0xff;
2005                msg[1].buf[1] = (word) & 0xff;
2006                return num;
2007        case 0x1f:
2008                if (num == 1) { /* write */
2009                        word = (u16) ((msg[0].buf[1] << 8) | msg[0].buf[2]);
2010                        word &= 0x3;
2011                        word = (dib7000p_read_word(state, 72) & ~(3 << 12)) | (word << 12);
2012                        dib7000p_write_word(state, 72, word);   /* Set the proper input */
2013                        return num;
2014                }
2015        }
2016
2017        if (apb_address != 0)   /* R/W acces via APB */
2018                return dib7090p_rw_on_apb(i2c_adap, msg, num, apb_address);
2019        else                    /* R/W access via SERPAR  */
2020                return w7090p_tuner_rw_serpar(i2c_adap, msg, num);
2021
2022        return 0;
2023}
2024
2025static u32 dib7000p_i2c_func(struct i2c_adapter *adapter)
2026{
2027        return I2C_FUNC_I2C;
2028}
2029
2030static struct i2c_algorithm dib7090_tuner_xfer_algo = {
2031        .master_xfer = dib7090_tuner_xfer,
2032        .functionality = dib7000p_i2c_func,
2033};
2034
2035struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
2036{
2037        struct dib7000p_state *st = fe->demodulator_priv;
2038        return &st->dib7090_tuner_adap;
2039}
2040EXPORT_SYMBOL(dib7090_get_i2c_tuner);
2041
2042static int dib7090_host_bus_drive(struct dib7000p_state *state, u8 drive)
2043{
2044        u16 reg;
2045
2046        /* drive host bus 2, 3, 4 */
2047        reg = dib7000p_read_word(state, 1798) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
2048        reg |= (drive << 12) | (drive << 6) | drive;
2049        dib7000p_write_word(state, 1798, reg);
2050
2051        /* drive host bus 5,6 */
2052        reg = dib7000p_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
2053        reg |= (drive << 8) | (drive << 2);
2054        dib7000p_write_word(state, 1799, reg);
2055
2056        /* drive host bus 7, 8, 9 */
2057        reg = dib7000p_read_word(state, 1800) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
2058        reg |= (drive << 12) | (drive << 6) | drive;
2059        dib7000p_write_word(state, 1800, reg);
2060
2061        /* drive host bus 10, 11 */
2062        reg = dib7000p_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
2063        reg |= (drive << 8) | (drive << 2);
2064        dib7000p_write_word(state, 1801, reg);
2065
2066        /* drive host bus 12, 13, 14 */
2067        reg = dib7000p_read_word(state, 1802) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
2068        reg |= (drive << 12) | (drive << 6) | drive;
2069        dib7000p_write_word(state, 1802, reg);
2070
2071        return 0;
2072}
2073
2074static u32 dib7090_calcSyncFreq(u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 syncSize)
2075{
2076        u32 quantif = 3;
2077        u32 nom = (insertExtSynchro * P_Kin + syncSize);
2078        u32 denom = P_Kout;
2079        u32 syncFreq = ((nom << quantif) / denom);
2080
2081        if ((syncFreq & ((1 << quantif) - 1)) != 0)
2082                syncFreq = (syncFreq >> quantif) + 1;
2083        else
2084                syncFreq = (syncFreq >> quantif);
2085
2086        if (syncFreq != 0)
2087                syncFreq = syncFreq - 1;
2088
2089        return syncFreq;
2090}
2091
2092static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize)
2093{
2094        dprintk("Configure DibStream Tx");
2095
2096        dib7000p_write_word(state, 1615, 1);
2097        dib7000p_write_word(state, 1603, P_Kin);
2098        dib7000p_write_word(state, 1605, P_Kout);
2099        dib7000p_write_word(state, 1606, insertExtSynchro);
2100        dib7000p_write_word(state, 1608, synchroMode);
2101        dib7000p_write_word(state, 1609, (syncWord >> 16) & 0xffff);
2102        dib7000p_write_word(state, 1610, syncWord & 0xffff);
2103        dib7000p_write_word(state, 1612, syncSize);
2104        dib7000p_write_word(state, 1615, 0);
2105
2106        return 0;
2107}
2108
2109static int dib7090_cfg_DibRx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 synchroMode, u32 insertExtSynchro, u32 syncWord, u32 syncSize,
2110                u32 dataOutRate)
2111{
2112        u32 syncFreq;
2113
2114        dprintk("Configure DibStream Rx");
2115        if ((P_Kin != 0) && (P_Kout != 0)) {
2116                syncFreq = dib7090_calcSyncFreq(P_Kin, P_Kout, insertExtSynchro, syncSize);
2117                dib7000p_write_word(state, 1542, syncFreq);
2118        }
2119        dib7000p_write_word(state, 1554, 1);
2120        dib7000p_write_word(state, 1536, P_Kin);
2121        dib7000p_write_word(state, 1537, P_Kout);
2122        dib7000p_write_word(state, 1539, synchroMode);
2123        dib7000p_write_word(state, 1540, (syncWord >> 16) & 0xffff);
2124        dib7000p_write_word(state, 1541, syncWord & 0xffff);
2125        dib7000p_write_word(state, 1543, syncSize);
2126        dib7000p_write_word(state, 1544, dataOutRate);
2127        dib7000p_write_word(state, 1554, 0);
2128
2129        return 0;
2130}
2131
2132static void dib7090_enMpegMux(struct dib7000p_state *state, int onoff)
2133{
2134        u16 reg_1287 = dib7000p_read_word(state, 1287);
2135
2136        switch (onoff) {
2137        case 1:
2138                        reg_1287 &= ~(1<<7);
2139                        break;
2140        case 0:
2141                        reg_1287 |= (1<<7);
2142                        break;
2143        }
2144
2145        dib7000p_write_word(state, 1287, reg_1287);
2146}
2147
2148static void dib7090_configMpegMux(struct dib7000p_state *state,
2149                u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
2150{
2151        dprintk("Enable Mpeg mux");
2152
2153        dib7090_enMpegMux(state, 0);
2154
2155        /* If the input mode is MPEG do not divide the serial clock */
2156        if ((enSerialMode == 1) && (state->input_mode_mpeg == 1))
2157                enSerialClkDiv2 = 0;
2158
2159        dib7000p_write_word(state, 1287, ((pulseWidth & 0x1f) << 2)
2160                        | ((enSerialMode & 0x1) << 1)
2161                        | (enSerialClkDiv2 & 0x1));
2162
2163        dib7090_enMpegMux(state, 1);
2164}
2165
2166static void dib7090_setDibTxMux(struct dib7000p_state *state, int mode)
2167{
2168        u16 reg_1288 = dib7000p_read_word(state, 1288) & ~(0x7 << 7);
2169
2170        switch (mode) {
2171        case MPEG_ON_DIBTX:
2172                        dprintk("SET MPEG ON DIBSTREAM TX");
2173                        dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
2174                        reg_1288 |= (1<<9);
2175                        break;
2176        case DIV_ON_DIBTX:
2177                        dprintk("SET DIV_OUT ON DIBSTREAM TX");
2178                        dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
2179                        reg_1288 |= (1<<8);
2180                        break;
2181        case ADC_ON_DIBTX:
2182                        dprintk("SET ADC_OUT ON DIBSTREAM TX");
2183                        dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
2184                        reg_1288 |= (1<<7);
2185                        break;
2186        default:
2187                        break;
2188        }
2189        dib7000p_write_word(state, 1288, reg_1288);
2190}
2191
2192static void dib7090_setHostBusMux(struct dib7000p_state *state, int mode)
2193{
2194        u16 reg_1288 = dib7000p_read_word(state, 1288) & ~(0x7 << 4);
2195
2196        switch (mode) {
2197        case DEMOUT_ON_HOSTBUS:
2198                        dprintk("SET DEM OUT OLD INTERF ON HOST BUS");
2199                        dib7090_enMpegMux(state, 0);
2200                        reg_1288 |= (1<<6);
2201                        break;
2202        case DIBTX_ON_HOSTBUS:
2203                        dprintk("SET DIBSTREAM TX ON HOST BUS");
2204                        dib7090_enMpegMux(state, 0);
2205                        reg_1288 |= (1<<5);
2206                        break;
2207        case MPEG_ON_HOSTBUS:
2208                        dprintk("SET MPEG MUX ON HOST BUS");
2209                        reg_1288 |= (1<<4);
2210                        break;
2211        default:
2212                        break;
2213        }
2214        dib7000p_write_word(state, 1288, reg_1288);
2215}
2216
2217int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff)
2218{
2219        struct dib7000p_state *state = fe->demodulator_priv;
2220        u16 reg_1287;
2221
2222        switch (onoff) {
2223        case 0: /* only use the internal way - not the diversity input */
2224                        dprintk("%s mode OFF : by default Enable Mpeg INPUT", __func__);
2225                        dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0);
2226
2227                        /* Do not divide the serial clock of MPEG MUX */
2228                        /* in SERIAL MODE in case input mode MPEG is used */
2229                        reg_1287 = dib7000p_read_word(state, 1287);
2230                        /* enSerialClkDiv2 == 1 ? */
2231                        if ((reg_1287 & 0x1) == 1) {
2232                                /* force enSerialClkDiv2 = 0 */
2233                                reg_1287 &= ~0x1;
2234                                dib7000p_write_word(state, 1287, reg_1287);
2235                        }
2236                        state->input_mode_mpeg = 1;
2237                        break;
2238        case 1: /* both ways */
2239        case 2: /* only the diversity input */
2240                        dprintk("%s ON : Enable diversity INPUT", __func__);
2241                        dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
2242                        state->input_mode_mpeg = 0;
2243                        break;
2244        }
2245
2246        dib7000p_set_diversity_in(&state->demod, onoff);
2247        return 0;
2248}
2249
2250static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode)
2251{
2252        struct dib7000p_state *state = fe->demodulator_priv;
2253
2254        u16 outreg, smo_mode, fifo_threshold;
2255        u8 prefer_mpeg_mux_use = 1;
2256        int ret = 0;
2257
2258        dib7090_host_bus_drive(state, 1);
2259
2260        fifo_threshold = 1792;
2261        smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
2262        outreg = dib7000p_read_word(state, 1286) & ~((1 << 10) | (0x7 << 6) | (1 << 1));
2263
2264        switch (mode) {
2265        case OUTMODE_HIGH_Z:
2266                outreg = 0;
2267                break;
2268
2269        case OUTMODE_MPEG2_SERIAL:
2270                if (prefer_mpeg_mux_use) {
2271                        dprintk("setting output mode TS_SERIAL using Mpeg Mux");
2272                        dib7090_configMpegMux(state, 3, 1, 1);
2273                        dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS);
2274                } else {/* Use Smooth block */
2275                        dprintk("setting output mode TS_SERIAL using Smooth bloc");
2276                        dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
2277                        outreg |= (2<<6) | (0 << 1);
2278                }
2279                break;
2280
2281        case OUTMODE_MPEG2_PAR_GATED_CLK:
2282                if (prefer_mpeg_mux_use) {
2283                        dprintk("setting output mode TS_PARALLEL_GATED using Mpeg Mux");
2284                        dib7090_configMpegMux(state, 2, 0, 0);
2285                        dib7090_setHostBusMux(state, MPEG_ON_HOSTBUS);
2286                } else { /* Use Smooth block */
2287                        dprintk("setting output mode TS_PARALLEL_GATED using Smooth block");
2288                        dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
2289                        outreg |= (0<<6);
2290                }
2291                break;
2292
2293        case OUTMODE_MPEG2_PAR_CONT_CLK:        /* Using Smooth block only */
2294                dprintk("setting output mode TS_PARALLEL_CONT using Smooth block");
2295                dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
2296                outreg |= (1<<6);
2297                break;
2298
2299        case OUTMODE_MPEG2_FIFO:        /* Using Smooth block because not supported by new Mpeg Mux bloc */
2300                dprintk("setting output mode TS_FIFO using Smooth block");
2301                dib7090_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
2302                outreg |= (5<<6);
2303                smo_mode |= (3 << 1);
2304                fifo_threshold = 512;
2305                break;
2306
2307        case OUTMODE_DIVERSITY:
2308                dprintk("setting output mode MODE_DIVERSITY");
2309                dib7090_setDibTxMux(state, DIV_ON_DIBTX);
2310                dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS);
2311                break;
2312
2313        case OUTMODE_ANALOG_ADC:
2314                dprintk("setting output mode MODE_ANALOG_ADC");
2315                dib7090_setDibTxMux(state, ADC_ON_DIBTX);
2316                dib7090_setHostBusMux(state, DIBTX_ON_HOSTBUS);
2317                break;
2318        }
2319        if (mode != OUTMODE_HIGH_Z)
2320                outreg |= (1 << 10);
2321
2322        if (state->cfg.output_mpeg2_in_188_bytes)
2323                smo_mode |= (1 << 5);
2324
2325        ret |= dib7000p_write_word(state, 235, smo_mode);
2326        ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
2327        ret |= dib7000p_write_word(state, 1286, outreg);
2328
2329        return ret;
2330}
2331
2332int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
2333{
2334        struct dib7000p_state *state = fe->demodulator_priv;
2335        u16 en_cur_state;
2336
2337        dprintk("sleep dib7090: %d", onoff);
2338
2339        en_cur_state = dib7000p_read_word(state, 1922);
2340
2341        if (en_cur_state > 0xff)
2342                state->tuner_enable = en_cur_state;
2343
2344        if (onoff)
2345                en_cur_state &= 0x00ff;
2346        else {
2347                if (state->tuner_enable != 0)
2348                        en_cur_state = state->tuner_enable;
2349        }
2350
2351        dib7000p_write_word(state, 1922, en_cur_state);
2352
2353        return 0;
2354}
2355EXPORT_SYMBOL(dib7090_tuner_sleep);
2356
2357int dib7090_get_adc_power(struct dvb_frontend *fe)
2358{
2359        return dib7000p_get_adc_power(fe);
2360}
2361EXPORT_SYMBOL(dib7090_get_adc_power);
2362
2363int dib7090_slave_reset(struct dvb_frontend *fe)
2364{
2365        struct dib7000p_state *state = fe->demodulator_priv;
2366        u16 reg;
2367
2368        reg = dib7000p_read_word(state, 1794);
2369        dib7000p_write_word(state, 1794, reg | (4 << 12));
2370
2371        dib7000p_write_word(state, 1032, 0xffff);
2372        return 0;
2373}
2374EXPORT_SYMBOL(dib7090_slave_reset);
2375
2376static struct dvb_frontend_ops dib7000p_ops;
2377struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
2378{
2379        struct dvb_frontend *demod;
2380        struct dib7000p_state *st;
2381        st = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
2382        if (st == NULL)
2383                return NULL;
2384
2385        memcpy(&st->cfg, cfg, sizeof(struct dib7000p_config));
2386        st->i2c_adap = i2c_adap;
2387        st->i2c_addr = i2c_addr;
2388        st->gpio_val = cfg->gpio_val;
2389        st->gpio_dir = cfg->gpio_dir;
2390
2391        /* Ensure the output mode remains at the previous default if it's
2392         * not specifically set by the caller.
2393         */
2394        if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2395                st->cfg.output_mode = OUTMODE_MPEG2_FIFO;
2396
2397        demod = &st->demod;
2398        demod->demodulator_priv = st;
2399        memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));
2400        mutex_init(&st->i2c_buffer_lock);
2401
2402        dib7000p_write_word(st, 1287, 0x0003);  /* sram lead in, rdy */
2403
2404        if (dib7000p_identify(st) != 0)
2405                goto error;
2406
2407        st->version = dib7000p_read_word(st, 897);
2408
2409        /* FIXME: make sure the dev.parent field is initialized, or else
2410           request_firmware() will hit an OOPS (this should be moved somewhere
2411           more common) */
2412        st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent;
2413
2414        dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr);
2415
2416        /* init 7090 tuner adapter */
2417        strncpy(st->dib7090_tuner_adap.name, "DiB7090 tuner interface", sizeof(st->dib7090_tuner_adap.name));
2418        st->dib7090_tuner_adap.algo = &dib7090_tuner_xfer_algo;
2419        st->dib7090_tuner_adap.algo_data = NULL;
2420        st->dib7090_tuner_adap.dev.parent = st->i2c_adap->dev.parent;
2421        i2c_set_adapdata(&st->dib7090_tuner_adap, st);
2422        i2c_add_adapter(&st->dib7090_tuner_adap);
2423
2424        dib7000p_demod_reset(st);
2425
2426        if (st->version == SOC7090) {
2427                dib7090_set_output_mode(demod, st->cfg.output_mode);
2428                dib7090_set_diversity_in(demod, 0);
2429        }
2430
2431        return demod;
2432
2433error:
2434        kfree(st);
2435        return NULL;
2436}
2437EXPORT_SYMBOL(dib7000p_attach);
2438
2439static struct dvb_frontend_ops dib7000p_ops = {
2440        .delsys = { SYS_DVBT },
2441        .info = {
2442                 .name = "DiBcom 7000PC",
2443                 .frequency_min = 44250000,
2444                 .frequency_max = 867250000,
2445                 .frequency_stepsize = 62500,
2446                 .caps = FE_CAN_INVERSION_AUTO |
2447                 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2448                 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2449                 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2450                 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2451                 },
2452
2453        .release = dib7000p_release,
2454
2455        .init = dib7000p_wakeup,
2456        .sleep = dib7000p_sleep,
2457
2458        .set_frontend = dib7000p_set_frontend,
2459        .get_tune_settings = dib7000p_fe_get_tune_settings,
2460        .get_frontend = dib7000p_get_frontend,
2461
2462        .read_status = dib7000p_read_status,
2463        .read_ber = dib7000p_read_ber,
2464        .read_signal_strength = dib7000p_read_signal_strength,
2465        .read_snr = dib7000p_read_snr,
2466        .read_ucblocks = dib7000p_read_unc_blocks,
2467};
2468
2469MODULE_AUTHOR("Olivier Grenie <ogrenie@dibcom.fr>");
2470MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
2471MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
2472MODULE_LICENSE("GPL");
2473