linux/drivers/media/dvb-frontends/dib8000.c
<<
>>
Prefs
   1/*
   2 * Linux-DVB Driver for DiBcom's DiB8000 chip (ISDB-T).
   3 *
   4 * Copyright (C) 2009 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
  17#include "dvb_frontend.h"
  18
  19#include "dib8000.h"
  20
  21#define LAYER_ALL -1
  22#define LAYER_A   1
  23#define LAYER_B   2
  24#define LAYER_C   3
  25
  26#define MAX_NUMBER_OF_FRONTENDS 6
  27/* #define DIB8000_AGC_FREEZE */
  28
  29static int debug;
  30module_param(debug, int, 0644);
  31MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
  32
  33#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0)
  34
  35struct i2c_device {
  36        struct i2c_adapter *adap;
  37        u8 addr;
  38        u8 *i2c_write_buffer;
  39        u8 *i2c_read_buffer;
  40        struct mutex *i2c_buffer_lock;
  41};
  42
  43enum param_loop_step {
  44        LOOP_TUNE_1,
  45        LOOP_TUNE_2
  46};
  47
  48enum dib8000_autosearch_step {
  49        AS_START = 0,
  50        AS_SEARCHING_FFT,
  51        AS_SEARCHING_GUARD,
  52        AS_DONE = 100,
  53};
  54
  55enum timeout_mode {
  56        SYMBOL_DEPENDENT_OFF = 0,
  57        SYMBOL_DEPENDENT_ON,
  58};
  59
  60struct dib8000_state {
  61        struct dib8000_config cfg;
  62
  63        struct i2c_device i2c;
  64
  65        struct dibx000_i2c_master i2c_master;
  66
  67        u16 wbd_ref;
  68
  69        u8 current_band;
  70        u32 current_bandwidth;
  71        struct dibx000_agc_config *current_agc;
  72        u32 timf;
  73        u32 timf_default;
  74
  75        u8 div_force_off:1;
  76        u8 div_state:1;
  77        u16 div_sync_wait;
  78
  79        u8 agc_state;
  80        u8 differential_constellation;
  81        u8 diversity_onoff;
  82
  83        s16 ber_monitored_layer;
  84        u16 gpio_dir;
  85        u16 gpio_val;
  86
  87        u16 revision;
  88        u8 isdbt_cfg_loaded;
  89        enum frontend_tune_state tune_state;
  90        s32 status;
  91
  92        struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
  93
  94        /* for the I2C transfer */
  95        struct i2c_msg msg[2];
  96        u8 i2c_write_buffer[4];
  97        u8 i2c_read_buffer[2];
  98        struct mutex i2c_buffer_lock;
  99        u8 input_mode_mpeg;
 100
 101        u16 tuner_enable;
 102        struct i2c_adapter dib8096p_tuner_adap;
 103        u16 current_demod_bw;
 104
 105        u16 seg_mask;
 106        u16 seg_diff_mask;
 107        u16 mode;
 108        u8 layer_b_nb_seg;
 109        u8 layer_c_nb_seg;
 110
 111        u8 channel_parameters_set;
 112        u16 autosearch_state;
 113        u16 found_nfft;
 114        u16 found_guard;
 115        u8 subchannel;
 116        u8 symbol_duration;
 117        u32 timeout;
 118        u8 longest_intlv_layer;
 119        u16 output_mode;
 120
 121#ifdef DIB8000_AGC_FREEZE
 122        u16 agc1_max;
 123        u16 agc1_min;
 124        u16 agc2_max;
 125        u16 agc2_min;
 126#endif
 127};
 128
 129enum dib8000_power_mode {
 130        DIB8000_POWER_ALL = 0,
 131        DIB8000_POWER_INTERFACE_ONLY,
 132};
 133
 134static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
 135{
 136        u16 ret;
 137        struct i2c_msg msg[2] = {
 138                {.addr = i2c->addr >> 1, .flags = 0, .len = 2},
 139                {.addr = i2c->addr >> 1, .flags = I2C_M_RD, .len = 2},
 140        };
 141
 142        if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) {
 143                dprintk("could not acquire lock");
 144                return 0;
 145        }
 146
 147        msg[0].buf    = i2c->i2c_write_buffer;
 148        msg[0].buf[0] = reg >> 8;
 149        msg[0].buf[1] = reg & 0xff;
 150        msg[1].buf    = i2c->i2c_read_buffer;
 151
 152        if (i2c_transfer(i2c->adap, msg, 2) != 2)
 153                dprintk("i2c read error on %d", reg);
 154
 155        ret = (msg[1].buf[0] << 8) | msg[1].buf[1];
 156        mutex_unlock(i2c->i2c_buffer_lock);
 157        return ret;
 158}
 159
 160static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
 161{
 162        u16 ret;
 163
 164        if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
 165                dprintk("could not acquire lock");
 166                return 0;
 167        }
 168
 169        state->i2c_write_buffer[0] = reg >> 8;
 170        state->i2c_write_buffer[1] = reg & 0xff;
 171
 172        memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
 173        state->msg[0].addr = state->i2c.addr >> 1;
 174        state->msg[0].flags = 0;
 175        state->msg[0].buf = state->i2c_write_buffer;
 176        state->msg[0].len = 2;
 177        state->msg[1].addr = state->i2c.addr >> 1;
 178        state->msg[1].flags = I2C_M_RD;
 179        state->msg[1].buf = state->i2c_read_buffer;
 180        state->msg[1].len = 2;
 181
 182        if (i2c_transfer(state->i2c.adap, state->msg, 2) != 2)
 183                dprintk("i2c read error on %d", reg);
 184
 185        ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
 186        mutex_unlock(&state->i2c_buffer_lock);
 187
 188        return ret;
 189}
 190
 191static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
 192{
 193        u16 rw[2];
 194
 195        rw[0] = dib8000_read_word(state, reg + 0);
 196        rw[1] = dib8000_read_word(state, reg + 1);
 197
 198        return ((rw[0] << 16) | (rw[1]));
 199}
 200
 201static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
 202{
 203        struct i2c_msg msg = {.addr = i2c->addr >> 1, .flags = 0, .len = 4};
 204        int ret = 0;
 205
 206        if (mutex_lock_interruptible(i2c->i2c_buffer_lock) < 0) {
 207                dprintk("could not acquire lock");
 208                return -EINVAL;
 209        }
 210
 211        msg.buf    = i2c->i2c_write_buffer;
 212        msg.buf[0] = (reg >> 8) & 0xff;
 213        msg.buf[1] = reg & 0xff;
 214        msg.buf[2] = (val >> 8) & 0xff;
 215        msg.buf[3] = val & 0xff;
 216
 217        ret = i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
 218        mutex_unlock(i2c->i2c_buffer_lock);
 219
 220        return ret;
 221}
 222
 223static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
 224{
 225        int ret;
 226
 227        if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
 228                dprintk("could not acquire lock");
 229                return -EINVAL;
 230        }
 231
 232        state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
 233        state->i2c_write_buffer[1] = reg & 0xff;
 234        state->i2c_write_buffer[2] = (val >> 8) & 0xff;
 235        state->i2c_write_buffer[3] = val & 0xff;
 236
 237        memset(&state->msg[0], 0, sizeof(struct i2c_msg));
 238        state->msg[0].addr = state->i2c.addr >> 1;
 239        state->msg[0].flags = 0;
 240        state->msg[0].buf = state->i2c_write_buffer;
 241        state->msg[0].len = 4;
 242
 243        ret = (i2c_transfer(state->i2c.adap, state->msg, 1) != 1 ?
 244                        -EREMOTEIO : 0);
 245        mutex_unlock(&state->i2c_buffer_lock);
 246
 247        return ret;
 248}
 249
 250static const s16 coeff_2k_sb_1seg_dqpsk[8] = {
 251        (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
 252                (920 << 5) | 0x09
 253};
 254
 255static const s16 coeff_2k_sb_1seg[8] = {
 256        (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
 257};
 258
 259static const s16 coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
 260        (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
 261                (-931 << 5) | 0x0f
 262};
 263
 264static const s16 coeff_2k_sb_3seg_0dqpsk[8] = {
 265        (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
 266                (982 << 5) | 0x0c
 267};
 268
 269static const s16 coeff_2k_sb_3seg_1dqpsk[8] = {
 270        (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
 271                (-720 << 5) | 0x0d
 272};
 273
 274static const s16 coeff_2k_sb_3seg[8] = {
 275        (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
 276                (-610 << 5) | 0x0a
 277};
 278
 279static const s16 coeff_4k_sb_1seg_dqpsk[8] = {
 280        (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
 281                (-922 << 5) | 0x0d
 282};
 283
 284static const s16 coeff_4k_sb_1seg[8] = {
 285        (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
 286                (-655 << 5) | 0x0a
 287};
 288
 289static const s16 coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
 290        (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
 291                (-958 << 5) | 0x13
 292};
 293
 294static const s16 coeff_4k_sb_3seg_0dqpsk[8] = {
 295        (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
 296                (-568 << 5) | 0x0f
 297};
 298
 299static const s16 coeff_4k_sb_3seg_1dqpsk[8] = {
 300        (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
 301                (-848 << 5) | 0x13
 302};
 303
 304static const s16 coeff_4k_sb_3seg[8] = {
 305        (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
 306                (-869 << 5) | 0x13
 307};
 308
 309static const s16 coeff_8k_sb_1seg_dqpsk[8] = {
 310        (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
 311                (-598 << 5) | 0x10
 312};
 313
 314static const s16 coeff_8k_sb_1seg[8] = {
 315        (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
 316                (585 << 5) | 0x0f
 317};
 318
 319static const s16 coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
 320        (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
 321                (0 << 5) | 0x14
 322};
 323
 324static const s16 coeff_8k_sb_3seg_0dqpsk[8] = {
 325        (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
 326                (-877 << 5) | 0x15
 327};
 328
 329static const s16 coeff_8k_sb_3seg_1dqpsk[8] = {
 330        (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
 331                (-921 << 5) | 0x14
 332};
 333
 334static const s16 coeff_8k_sb_3seg[8] = {
 335        (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
 336                (690 << 5) | 0x14
 337};
 338
 339static const s16 ana_fe_coeff_3seg[24] = {
 340        81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
 341};
 342
 343static const s16 ana_fe_coeff_1seg[24] = {
 344        249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
 345};
 346
 347static const s16 ana_fe_coeff_13seg[24] = {
 348        396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
 349};
 350
 351static u16 fft_to_mode(struct dib8000_state *state)
 352{
 353        u16 mode;
 354        switch (state->fe[0]->dtv_property_cache.transmission_mode) {
 355        case TRANSMISSION_MODE_2K:
 356                mode = 1;
 357                break;
 358        case TRANSMISSION_MODE_4K:
 359                mode = 2;
 360                break;
 361        default:
 362        case TRANSMISSION_MODE_AUTO:
 363        case TRANSMISSION_MODE_8K:
 364                mode = 3;
 365                break;
 366        }
 367        return mode;
 368}
 369
 370static void dib8000_set_acquisition_mode(struct dib8000_state *state)
 371{
 372        u16 nud = dib8000_read_word(state, 298);
 373        nud |= (1 << 3) | (1 << 0);
 374        dprintk("acquisition mode activated");
 375        dib8000_write_word(state, 298, nud);
 376}
 377static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode)
 378{
 379        struct dib8000_state *state = fe->demodulator_priv;
 380        u16 outreg, fifo_threshold, smo_mode, sram = 0x0205;    /* by default SDRAM deintlv is enabled */
 381
 382        state->output_mode = mode;
 383        outreg = 0;
 384        fifo_threshold = 1792;
 385        smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
 386
 387        dprintk("-I-    Setting output mode for demod %p to %d",
 388                        &state->fe[0], mode);
 389
 390        switch (mode) {
 391        case OUTMODE_MPEG2_PAR_GATED_CLK:       // STBs with parallel gated clock
 392                outreg = (1 << 10);     /* 0x0400 */
 393                break;
 394        case OUTMODE_MPEG2_PAR_CONT_CLK:        // STBs with parallel continues clock
 395                outreg = (1 << 10) | (1 << 6);  /* 0x0440 */
 396                break;
 397        case OUTMODE_MPEG2_SERIAL:      // STBs with serial input
 398                outreg = (1 << 10) | (2 << 6) | (0 << 1);       /* 0x0482 */
 399                break;
 400        case OUTMODE_DIVERSITY:
 401                if (state->cfg.hostbus_diversity) {
 402                        outreg = (1 << 10) | (4 << 6);  /* 0x0500 */
 403                        sram &= 0xfdff;
 404                } else
 405                        sram |= 0x0c00;
 406                break;
 407        case OUTMODE_MPEG2_FIFO:        // e.g. USB feeding
 408                smo_mode |= (3 << 1);
 409                fifo_threshold = 512;
 410                outreg = (1 << 10) | (5 << 6);
 411                break;
 412        case OUTMODE_HIGH_Z:    // disable
 413                outreg = 0;
 414                break;
 415
 416        case OUTMODE_ANALOG_ADC:
 417                outreg = (1 << 10) | (3 << 6);
 418                dib8000_set_acquisition_mode(state);
 419                break;
 420
 421        default:
 422                dprintk("Unhandled output_mode passed to be set for demod %p",
 423                                &state->fe[0]);
 424                return -EINVAL;
 425        }
 426
 427        if (state->cfg.output_mpeg2_in_188_bytes)
 428                smo_mode |= (1 << 5);
 429
 430        dib8000_write_word(state, 299, smo_mode);
 431        dib8000_write_word(state, 300, fifo_threshold); /* synchronous fread */
 432        dib8000_write_word(state, 1286, outreg);
 433        dib8000_write_word(state, 1291, sram);
 434
 435        return 0;
 436}
 437
 438static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff)
 439{
 440        struct dib8000_state *state = fe->demodulator_priv;
 441        u16 tmp, sync_wait = dib8000_read_word(state, 273) & 0xfff0;
 442
 443        dprintk("set diversity input to %i", onoff);
 444        if (!state->differential_constellation) {
 445                dib8000_write_word(state, 272, 1 << 9); //dvsy_off_lmod4 = 1
 446                dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2);       // sync_enable = 1; comb_mode = 2
 447        } else {
 448                dib8000_write_word(state, 272, 0);      //dvsy_off_lmod4 = 0
 449                dib8000_write_word(state, 273, sync_wait);      // sync_enable = 0; comb_mode = 0
 450        }
 451        state->diversity_onoff = onoff;
 452
 453        switch (onoff) {
 454        case 0:         /* only use the internal way - not the diversity input */
 455                dib8000_write_word(state, 270, 1);
 456                dib8000_write_word(state, 271, 0);
 457                break;
 458        case 1:         /* both ways */
 459                dib8000_write_word(state, 270, 6);
 460                dib8000_write_word(state, 271, 6);
 461                break;
 462        case 2:         /* only the diversity input */
 463                dib8000_write_word(state, 270, 0);
 464                dib8000_write_word(state, 271, 1);
 465                break;
 466        }
 467
 468        if (state->revision == 0x8002) {
 469                tmp = dib8000_read_word(state, 903);
 470                dib8000_write_word(state, 903, tmp & ~(1 << 3));
 471                msleep(30);
 472                dib8000_write_word(state, 903, tmp | (1 << 3));
 473        }
 474        return 0;
 475}
 476
 477static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_power_mode mode)
 478{
 479        /* by default everything is going to be powered off */
 480        u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
 481                reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3,
 482                reg_1280;
 483
 484        if (state->revision != 0x8090)
 485                reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
 486        else
 487                reg_1280 = (dib8000_read_word(state, 1280) & 0x707f) | 0x8f80;
 488
 489        /* now, depending on the requested mode, we power on */
 490        switch (mode) {
 491                /* power up everything in the demod */
 492        case DIB8000_POWER_ALL:
 493                reg_774 = 0x0000;
 494                reg_775 = 0x0000;
 495                reg_776 = 0x0000;
 496                reg_900 &= 0xfffc;
 497                if (state->revision != 0x8090)
 498                        reg_1280 &= 0x00ff;
 499                else
 500                        reg_1280 &= 0x707f;
 501                break;
 502        case DIB8000_POWER_INTERFACE_ONLY:
 503                if (state->revision != 0x8090)
 504                        reg_1280 &= 0x00ff;
 505                else
 506                        reg_1280 &= 0xfa7b;
 507                break;
 508        }
 509
 510        dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x", reg_774, reg_775, reg_776, reg_900, reg_1280);
 511        dib8000_write_word(state, 774, reg_774);
 512        dib8000_write_word(state, 775, reg_775);
 513        dib8000_write_word(state, 776, reg_776);
 514        dib8000_write_word(state, 900, reg_900);
 515        dib8000_write_word(state, 1280, reg_1280);
 516}
 517
 518static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no)
 519{
 520        int ret = 0;
 521        u16 reg, reg_907 = dib8000_read_word(state, 907);
 522        u16 reg_908 = dib8000_read_word(state, 908);
 523
 524        switch (no) {
 525        case DIBX000_SLOW_ADC_ON:
 526                if (state->revision != 0x8090) {
 527                        reg_908 |= (1 << 1) | (1 << 0);
 528                        ret |= dib8000_write_word(state, 908, reg_908);
 529                        reg_908 &= ~(1 << 1);
 530                } else {
 531                        reg = dib8000_read_word(state, 1925);
 532                        /* en_slowAdc = 1 & reset_sladc = 1 */
 533                        dib8000_write_word(state, 1925, reg |
 534                                        (1<<4) | (1<<2));
 535
 536                        /* read acces to make it works... strange ... */
 537                        reg = dib8000_read_word(state, 1925);
 538                        msleep(20);
 539                        /* en_slowAdc = 1 & reset_sladc = 0 */
 540                        dib8000_write_word(state, 1925, reg & ~(1<<4));
 541
 542                        reg = dib8000_read_word(state, 921) & ~((0x3 << 14)
 543                                        | (0x3 << 12));
 544                        /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ;
 545                           (Vin2 = Vcm) */
 546                        dib8000_write_word(state, 921, reg | (1 << 14)
 547                                        | (3 << 12));
 548                }
 549                break;
 550
 551        case DIBX000_SLOW_ADC_OFF:
 552                if (state->revision == 0x8090) {
 553                        reg = dib8000_read_word(state, 1925);
 554                        /* reset_sladc = 1 en_slowAdc = 0 */
 555                        dib8000_write_word(state, 1925,
 556                                        (reg & ~(1<<2)) | (1<<4));
 557                }
 558                reg_908 |= (1 << 1) | (1 << 0);
 559                break;
 560
 561        case DIBX000_ADC_ON:
 562                reg_907 &= 0x0fff;
 563                reg_908 &= 0x0003;
 564                break;
 565
 566        case DIBX000_ADC_OFF:   // leave the VBG voltage on
 567                reg_907 |= (1 << 14) | (1 << 13) | (1 << 12);
 568                reg_908 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
 569                break;
 570
 571        case DIBX000_VBG_ENABLE:
 572                reg_907 &= ~(1 << 15);
 573                break;
 574
 575        case DIBX000_VBG_DISABLE:
 576                reg_907 |= (1 << 15);
 577                break;
 578
 579        default:
 580                break;
 581        }
 582
 583        ret |= dib8000_write_word(state, 907, reg_907);
 584        ret |= dib8000_write_word(state, 908, reg_908);
 585
 586        return ret;
 587}
 588
 589static int dib8000_set_bandwidth(struct dvb_frontend *fe, u32 bw)
 590{
 591        struct dib8000_state *state = fe->demodulator_priv;
 592        u32 timf;
 593
 594        if (bw == 0)
 595                bw = 6000;
 596
 597        if (state->timf == 0) {
 598                dprintk("using default timf");
 599                timf = state->timf_default;
 600        } else {
 601                dprintk("using updated timf");
 602                timf = state->timf;
 603        }
 604
 605        dib8000_write_word(state, 29, (u16) ((timf >> 16) & 0xffff));
 606        dib8000_write_word(state, 30, (u16) ((timf) & 0xffff));
 607
 608        return 0;
 609}
 610
 611static int dib8000_sad_calib(struct dib8000_state *state)
 612{
 613        u8 sad_sel = 3;
 614
 615        if (state->revision == 0x8090) {
 616                dib8000_write_word(state, 922, (sad_sel << 2));
 617                dib8000_write_word(state, 923, 2048);
 618
 619                dib8000_write_word(state, 922, (sad_sel << 2) | 0x1);
 620                dib8000_write_word(state, 922, (sad_sel << 2));
 621        } else {
 622                /* internal */
 623                dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
 624                dib8000_write_word(state, 924, 776);
 625
 626                /* do the calibration */
 627                dib8000_write_word(state, 923, (1 << 0));
 628                dib8000_write_word(state, 923, (0 << 0));
 629        }
 630
 631        msleep(1);
 632        return 0;
 633}
 634
 635int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
 636{
 637        struct dib8000_state *state = fe->demodulator_priv;
 638        if (value > 4095)
 639                value = 4095;
 640        state->wbd_ref = value;
 641        return dib8000_write_word(state, 106, value);
 642}
 643EXPORT_SYMBOL(dib8000_set_wbd_ref);
 644
 645static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
 646{
 647        dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25);
 648        if (state->revision != 0x8090) {
 649                dib8000_write_word(state, 23,
 650                                (u16) (((bw->internal * 1000) >> 16) & 0xffff));
 651                dib8000_write_word(state, 24,
 652                                (u16) ((bw->internal * 1000) & 0xffff));
 653        } else {
 654                dib8000_write_word(state, 23, (u16) (((bw->internal / 2 * 1000) >> 16) & 0xffff));
 655                dib8000_write_word(state, 24,
 656                                (u16) ((bw->internal  / 2 * 1000) & 0xffff));
 657        }
 658        dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff));
 659        dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff));
 660        dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003));
 661
 662        if (state->revision != 0x8090)
 663                dib8000_write_word(state, 922, bw->sad_cfg);
 664}
 665
 666static void dib8000_reset_pll(struct dib8000_state *state)
 667{
 668        const struct dibx000_bandwidth_config *pll = state->cfg.pll;
 669        u16 clk_cfg1, reg;
 670
 671        if (state->revision != 0x8090) {
 672                dib8000_write_word(state, 901,
 673                                (pll->pll_prediv << 8) | (pll->pll_ratio << 0));
 674
 675                clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
 676                        (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) |
 677                        (1 << 3) | (pll->pll_range << 1) |
 678                        (pll->pll_reset << 0);
 679
 680                dib8000_write_word(state, 902, clk_cfg1);
 681                clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
 682                dib8000_write_word(state, 902, clk_cfg1);
 683
 684                dprintk("clk_cfg1: 0x%04x", clk_cfg1);
 685
 686                /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
 687                if (state->cfg.pll->ADClkSrc == 0)
 688                        dib8000_write_word(state, 904,
 689                                        (0 << 15) | (0 << 12) | (0 << 10) |
 690                                        (pll->modulo << 8) |
 691                                        (pll->ADClkSrc << 7) | (0 << 1));
 692                else if (state->cfg.refclksel != 0)
 693                        dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
 694                                        ((state->cfg.refclksel & 0x3) << 10) |
 695                                        (pll->modulo << 8) |
 696                                        (pll->ADClkSrc << 7) | (0 << 1));
 697                else
 698                        dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
 699                                        (3 << 10) | (pll->modulo << 8) |
 700                                        (pll->ADClkSrc << 7) | (0 << 1));
 701        } else {
 702                dib8000_write_word(state, 1856, (!pll->pll_reset<<13) |
 703                                (pll->pll_range<<12) | (pll->pll_ratio<<6) |
 704                                (pll->pll_prediv));
 705
 706                reg = dib8000_read_word(state, 1857);
 707                dib8000_write_word(state, 1857, reg|(!pll->pll_bypass<<15));
 708
 709                reg = dib8000_read_word(state, 1858); /* Force clk out pll /2 */
 710                dib8000_write_word(state, 1858, reg | 1);
 711
 712                dib8000_write_word(state, 904, (pll->modulo << 8));
 713        }
 714
 715        dib8000_reset_pll_common(state, pll);
 716}
 717
 718int dib8000_update_pll(struct dvb_frontend *fe,
 719                struct dibx000_bandwidth_config *pll, u32 bw, u8 ratio)
 720{
 721        struct dib8000_state *state = fe->demodulator_priv;
 722        u16 reg_1857, reg_1856 = dib8000_read_word(state, 1856);
 723        u8 loopdiv, prediv, oldprediv = state->cfg.pll->pll_prediv ;
 724        u32 internal, xtal;
 725
 726        /* get back old values */
 727        prediv = reg_1856 & 0x3f;
 728        loopdiv = (reg_1856 >> 6) & 0x3f;
 729
 730        if ((pll == NULL) || (pll->pll_prediv == prediv &&
 731                                pll->pll_ratio == loopdiv))
 732                return -EINVAL;
 733
 734        dprintk("Updating pll (prediv: old =  %d new = %d ; loopdiv : old = %d new = %d)", prediv, pll->pll_prediv, loopdiv, pll->pll_ratio);
 735        if (state->revision == 0x8090) {
 736                reg_1856 &= 0xf000;
 737                reg_1857 = dib8000_read_word(state, 1857);
 738                /* disable PLL */
 739                dib8000_write_word(state, 1857, reg_1857 & ~(1 << 15));
 740
 741                dib8000_write_word(state, 1856, reg_1856 |
 742                                ((pll->pll_ratio & 0x3f) << 6) |
 743                                (pll->pll_prediv & 0x3f));
 744
 745                /* write new system clk into P_sec_len */
 746                internal = dib8000_read32(state, 23) / 1000;
 747                dprintk("Old Internal = %d", internal);
 748                xtal = 2 * (internal / loopdiv) * prediv;
 749                internal = 1000 * (xtal/pll->pll_prediv) * pll->pll_ratio;
 750                dprintk("Xtal = %d , New Fmem = %d New Fdemod = %d, New Fsampling = %d", xtal, internal/1000, internal/2000, internal/8000);
 751                dprintk("New Internal = %d", internal);
 752
 753                dib8000_write_word(state, 23,
 754                                (u16) (((internal / 2) >> 16) & 0xffff));
 755                dib8000_write_word(state, 24, (u16) ((internal / 2) & 0xffff));
 756                /* enable PLL */
 757                dib8000_write_word(state, 1857, reg_1857 | (1 << 15));
 758
 759                while (((dib8000_read_word(state, 1856)>>15)&0x1) != 1)
 760                        dprintk("Waiting for PLL to lock");
 761
 762                /* verify */
 763                reg_1856 = dib8000_read_word(state, 1856);
 764                dprintk("PLL Updated with prediv = %d and loopdiv = %d",
 765                                reg_1856&0x3f, (reg_1856>>6)&0x3f);
 766        } else {
 767                if (bw != state->current_demod_bw) {
 768                        /** Bandwidth change => force PLL update **/
 769                        dprintk("PLL: Bandwidth Change %d MHz -> %d MHz (prediv: %d->%d)", state->current_demod_bw / 1000, bw / 1000, oldprediv, state->cfg.pll->pll_prediv);
 770
 771                        if (state->cfg.pll->pll_prediv != oldprediv) {
 772                                /** Full PLL change only if prediv is changed **/
 773
 774                                /** full update => bypass and reconfigure **/
 775                                dprintk("PLL: New Setting for %d MHz Bandwidth (prediv: %d, ratio: %d)", bw/1000, state->cfg.pll->pll_prediv, state->cfg.pll->pll_ratio);
 776                                dib8000_write_word(state, 902, dib8000_read_word(state, 902) | (1<<3)); /* bypass PLL */
 777                                dib8000_reset_pll(state);
 778                                dib8000_write_word(state, 898, 0x0004); /* sad */
 779                        } else
 780                                ratio = state->cfg.pll->pll_ratio;
 781
 782                        state->current_demod_bw = bw;
 783                }
 784
 785                if (ratio != 0) {
 786                        /** ratio update => only change ratio **/
 787                        dprintk("PLL: Update ratio (prediv: %d, ratio: %d)", state->cfg.pll->pll_prediv, ratio);
 788                        dib8000_write_word(state, 901, (state->cfg.pll->pll_prediv << 8) | (ratio << 0)); /* only the PLL ratio is updated. */
 789                }
 790}
 791
 792        return 0;
 793}
 794EXPORT_SYMBOL(dib8000_update_pll);
 795
 796
 797static int dib8000_reset_gpio(struct dib8000_state *st)
 798{
 799        /* reset the GPIOs */
 800        dib8000_write_word(st, 1029, st->cfg.gpio_dir);
 801        dib8000_write_word(st, 1030, st->cfg.gpio_val);
 802
 803        /* TODO 782 is P_gpio_od */
 804
 805        dib8000_write_word(st, 1032, st->cfg.gpio_pwm_pos);
 806
 807        dib8000_write_word(st, 1037, st->cfg.pwm_freq_div);
 808        return 0;
 809}
 810
 811static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val)
 812{
 813        st->cfg.gpio_dir = dib8000_read_word(st, 1029);
 814        st->cfg.gpio_dir &= ~(1 << num);        /* reset the direction bit */
 815        st->cfg.gpio_dir |= (dir & 0x1) << num; /* set the new direction */
 816        dib8000_write_word(st, 1029, st->cfg.gpio_dir);
 817
 818        st->cfg.gpio_val = dib8000_read_word(st, 1030);
 819        st->cfg.gpio_val &= ~(1 << num);        /* reset the direction bit */
 820        st->cfg.gpio_val |= (val & 0x01) << num;        /* set the new value */
 821        dib8000_write_word(st, 1030, st->cfg.gpio_val);
 822
 823        dprintk("gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val);
 824
 825        return 0;
 826}
 827
 828int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
 829{
 830        struct dib8000_state *state = fe->demodulator_priv;
 831        return dib8000_cfg_gpio(state, num, dir, val);
 832}
 833
 834EXPORT_SYMBOL(dib8000_set_gpio);
 835static const u16 dib8000_defaults[] = {
 836        /* auto search configuration - lock0 by default waiting
 837         * for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */
 838        3, 7,
 839        0x0004,
 840        0x0400,
 841        0x0814,
 842
 843        12, 11,
 844        0x001b,
 845        0x7740,
 846        0x005b,
 847        0x8d80,
 848        0x01c9,
 849        0xc380,
 850        0x0000,
 851        0x0080,
 852        0x0000,
 853        0x0090,
 854        0x0001,
 855        0xd4c0,
 856
 857        /*1, 32,
 858                0x6680 // P_corm_thres Lock algorithms configuration */
 859
 860        11, 80,                 /* set ADC level to -16 */
 861        (1 << 13) - 825 - 117,
 862        (1 << 13) - 837 - 117,
 863        (1 << 13) - 811 - 117,
 864        (1 << 13) - 766 - 117,
 865        (1 << 13) - 737 - 117,
 866        (1 << 13) - 693 - 117,
 867        (1 << 13) - 648 - 117,
 868        (1 << 13) - 619 - 117,
 869        (1 << 13) - 575 - 117,
 870        (1 << 13) - 531 - 117,
 871        (1 << 13) - 501 - 117,
 872
 873        4, 108,
 874        0,
 875        0,
 876        0,
 877        0,
 878
 879        1, 175,
 880        0x0410,
 881        1, 179,
 882        8192,                   // P_fft_nb_to_cut
 883
 884        6, 181,
 885        0x2800,                 // P_coff_corthres_ ( 2k 4k 8k ) 0x2800
 886        0x2800,
 887        0x2800,
 888        0x2800,                 // P_coff_cpilthres_ ( 2k 4k 8k ) 0x2800
 889        0x2800,
 890        0x2800,
 891
 892        2, 193,
 893        0x0666,                 // P_pha3_thres
 894        0x0000,                 // P_cti_use_cpe, P_cti_use_prog
 895
 896        2, 205,
 897        0x200f,                 // P_cspu_regul, P_cspu_win_cut
 898        0x000f,                 // P_des_shift_work
 899
 900        5, 215,
 901        0x023d,                 // P_adp_regul_cnt
 902        0x00a4,                 // P_adp_noise_cnt
 903        0x00a4,                 // P_adp_regul_ext
 904        0x7ff0,                 // P_adp_noise_ext
 905        0x3ccc,                 // P_adp_fil
 906
 907        1, 230,
 908        0x0000,                 // P_2d_byp_ti_num
 909
 910        1, 263,
 911        0x800,                  //P_equal_thres_wgn
 912
 913        1, 268,
 914        (2 << 9) | 39,          // P_equal_ctrl_synchro, P_equal_speedmode
 915
 916        1, 270,
 917        0x0001,                 // P_div_lock0_wait
 918        1, 285,
 919        0x0020,                 //p_fec_
 920        1, 299,
 921        0x0062,                 /* P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard */
 922
 923        1, 338,
 924        (1 << 12) |             // P_ctrl_corm_thres4pre_freq_inh=1
 925                (1 << 10) |
 926                (0 << 9) |              /* P_ctrl_pre_freq_inh=0 */
 927                (3 << 5) |              /* P_ctrl_pre_freq_step=3 */
 928                (1 << 0),               /* P_pre_freq_win_len=1 */
 929
 930        0,
 931};
 932
 933static u16 dib8000_identify(struct i2c_device *client)
 934{
 935        u16 value;
 936
 937        //because of glitches sometimes
 938        value = dib8000_i2c_read16(client, 896);
 939
 940        if ((value = dib8000_i2c_read16(client, 896)) != 0x01b3) {
 941                dprintk("wrong Vendor ID (read=0x%x)", value);
 942                return 0;
 943        }
 944
 945        value = dib8000_i2c_read16(client, 897);
 946        if (value != 0x8000 && value != 0x8001 &&
 947                        value != 0x8002 && value != 0x8090) {
 948                dprintk("wrong Device ID (%x)", value);
 949                return 0;
 950        }
 951
 952        switch (value) {
 953        case 0x8000:
 954                dprintk("found DiB8000A");
 955                break;
 956        case 0x8001:
 957                dprintk("found DiB8000B");
 958                break;
 959        case 0x8002:
 960                dprintk("found DiB8000C");
 961                break;
 962        case 0x8090:
 963                dprintk("found DiB8096P");
 964                break;
 965        }
 966        return value;
 967}
 968
 969static int dib8000_reset(struct dvb_frontend *fe)
 970{
 971        struct dib8000_state *state = fe->demodulator_priv;
 972
 973        if ((state->revision = dib8000_identify(&state->i2c)) == 0)
 974                return -EINVAL;
 975
 976        /* sram lead in, rdy */
 977        if (state->revision != 0x8090)
 978                dib8000_write_word(state, 1287, 0x0003);
 979
 980        if (state->revision == 0x8000)
 981                dprintk("error : dib8000 MA not supported");
 982
 983        dibx000_reset_i2c_master(&state->i2c_master);
 984
 985        dib8000_set_power_mode(state, DIB8000_POWER_ALL);
 986
 987        /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
 988        dib8000_set_adc_state(state, DIBX000_ADC_OFF);
 989
 990        /* restart all parts */
 991        dib8000_write_word(state, 770, 0xffff);
 992        dib8000_write_word(state, 771, 0xffff);
 993        dib8000_write_word(state, 772, 0xfffc);
 994        if (state->revision == 0x8090)
 995                dib8000_write_word(state, 1280, 0x0045);
 996        else
 997                dib8000_write_word(state, 1280, 0x004d);
 998        dib8000_write_word(state, 1281, 0x000c);
 999
1000        dib8000_write_word(state, 770, 0x0000);
1001        dib8000_write_word(state, 771, 0x0000);
1002        dib8000_write_word(state, 772, 0x0000);
1003        dib8000_write_word(state, 898, 0x0004); // sad
1004        dib8000_write_word(state, 1280, 0x0000);
1005        dib8000_write_word(state, 1281, 0x0000);
1006
1007        /* drives */
1008        if (state->revision != 0x8090) {
1009                if (state->cfg.drives)
1010                        dib8000_write_word(state, 906, state->cfg.drives);
1011                else {
1012                        dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.");
1013                        /* min drive SDRAM - not optimal - adjust */
1014                        dib8000_write_word(state, 906, 0x2d98);
1015                }
1016        }
1017
1018        dib8000_reset_pll(state);
1019        if (state->revision != 0x8090)
1020                dib8000_write_word(state, 898, 0x0004);
1021
1022        if (dib8000_reset_gpio(state) != 0)
1023                dprintk("GPIO reset was not successful.");
1024
1025        if ((state->revision != 0x8090) &&
1026                        (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0))
1027                dprintk("OUTPUT_MODE could not be resetted.");
1028
1029        state->current_agc = NULL;
1030
1031        // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
1032        /* P_iqc_ca2 = 0; P_iqc_impnc_on = 0; P_iqc_mode = 0; */
1033        if (state->cfg.pll->ifreq == 0)
1034                dib8000_write_word(state, 40, 0x0755);  /* P_iqc_corr_inh = 0 enable IQcorr block */
1035        else
1036                dib8000_write_word(state, 40, 0x1f55);  /* P_iqc_corr_inh = 1 disable IQcorr block */
1037
1038        {
1039                u16 l = 0, r;
1040                const u16 *n;
1041                n = dib8000_defaults;
1042                l = *n++;
1043                while (l) {
1044                        r = *n++;
1045                        do {
1046                                dib8000_write_word(state, r, *n++);
1047                                r++;
1048                        } while (--l);
1049                        l = *n++;
1050                }
1051        }
1052
1053        state->isdbt_cfg_loaded = 0;
1054
1055        //div_cfg override for special configs
1056        if ((state->revision != 8090) && (state->cfg.div_cfg != 0))
1057                dib8000_write_word(state, 903, state->cfg.div_cfg);
1058
1059        /* unforce divstr regardless whether i2c enumeration was done or not */
1060        dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1));
1061
1062        dib8000_set_bandwidth(fe, 6000);
1063
1064        dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
1065        dib8000_sad_calib(state);
1066        if (state->revision != 0x8090)
1067                dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
1068
1069        /* ber_rs_len = 3 */
1070        dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5));
1071
1072        dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY);
1073
1074        return 0;
1075}
1076
1077static void dib8000_restart_agc(struct dib8000_state *state)
1078{
1079        // P_restart_iqc & P_restart_agc
1080        dib8000_write_word(state, 770, 0x0a00);
1081        dib8000_write_word(state, 770, 0x0000);
1082}
1083
1084static int dib8000_update_lna(struct dib8000_state *state)
1085{
1086        u16 dyn_gain;
1087
1088        if (state->cfg.update_lna) {
1089                // read dyn_gain here (because it is demod-dependent and not tuner)
1090                dyn_gain = dib8000_read_word(state, 390);
1091
1092                if (state->cfg.update_lna(state->fe[0], dyn_gain)) {
1093                        dib8000_restart_agc(state);
1094                        return 1;
1095                }
1096        }
1097        return 0;
1098}
1099
1100static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
1101{
1102        struct dibx000_agc_config *agc = NULL;
1103        int i;
1104        u16 reg;
1105
1106        if (state->current_band == band && state->current_agc != NULL)
1107                return 0;
1108        state->current_band = band;
1109
1110        for (i = 0; i < state->cfg.agc_config_count; i++)
1111                if (state->cfg.agc[i].band_caps & band) {
1112                        agc = &state->cfg.agc[i];
1113                        break;
1114                }
1115
1116        if (agc == NULL) {
1117                dprintk("no valid AGC configuration found for band 0x%02x", band);
1118                return -EINVAL;
1119        }
1120
1121        state->current_agc = agc;
1122
1123        /* AGC */
1124        dib8000_write_word(state, 76, agc->setup);
1125        dib8000_write_word(state, 77, agc->inv_gain);
1126        dib8000_write_word(state, 78, agc->time_stabiliz);
1127        dib8000_write_word(state, 101, (agc->alpha_level << 12) | agc->thlock);
1128
1129        // Demod AGC loop configuration
1130        dib8000_write_word(state, 102, (agc->alpha_mant << 5) | agc->alpha_exp);
1131        dib8000_write_word(state, 103, (agc->beta_mant << 6) | agc->beta_exp);
1132
1133        dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
1134                state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
1135
1136        /* AGC continued */
1137        if (state->wbd_ref != 0)
1138                dib8000_write_word(state, 106, state->wbd_ref);
1139        else                    // use default
1140                dib8000_write_word(state, 106, agc->wbd_ref);
1141
1142        if (state->revision == 0x8090) {
1143                reg = dib8000_read_word(state, 922) & (0x3 << 2);
1144                dib8000_write_word(state, 922, reg | (agc->wbd_sel << 2));
1145        }
1146
1147        dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
1148        dib8000_write_word(state, 108, agc->agc1_max);
1149        dib8000_write_word(state, 109, agc->agc1_min);
1150        dib8000_write_word(state, 110, agc->agc2_max);
1151        dib8000_write_word(state, 111, agc->agc2_min);
1152        dib8000_write_word(state, 112, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
1153        dib8000_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
1154        dib8000_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
1155        dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
1156
1157        dib8000_write_word(state, 75, agc->agc1_pt3);
1158        if (state->revision != 0x8090)
1159                dib8000_write_word(state, 923,
1160                                (dib8000_read_word(state, 923) & 0xffe3) |
1161                                (agc->wbd_inv << 4) | (agc->wbd_sel << 2));
1162
1163        return 0;
1164}
1165
1166void dib8000_pwm_agc_reset(struct dvb_frontend *fe)
1167{
1168        struct dib8000_state *state = fe->demodulator_priv;
1169        dib8000_set_adc_state(state, DIBX000_ADC_ON);
1170        dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000)));
1171}
1172EXPORT_SYMBOL(dib8000_pwm_agc_reset);
1173
1174static int dib8000_agc_soft_split(struct dib8000_state *state)
1175{
1176        u16 agc, split_offset;
1177
1178        if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
1179                return FE_CALLBACK_TIME_NEVER;
1180
1181        // n_agc_global
1182        agc = dib8000_read_word(state, 390);
1183
1184        if (agc > state->current_agc->split.min_thres)
1185                split_offset = state->current_agc->split.min;
1186        else if (agc < state->current_agc->split.max_thres)
1187                split_offset = state->current_agc->split.max;
1188        else
1189                split_offset = state->current_agc->split.max *
1190                        (agc - state->current_agc->split.min_thres) /
1191                        (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
1192
1193        dprintk("AGC split_offset: %d", split_offset);
1194
1195        // P_agc_force_split and P_agc_split_offset
1196        dib8000_write_word(state, 107, (dib8000_read_word(state, 107) & 0xff00) | split_offset);
1197        return 5000;
1198}
1199
1200static int dib8000_agc_startup(struct dvb_frontend *fe)
1201{
1202        struct dib8000_state *state = fe->demodulator_priv;
1203        enum frontend_tune_state *tune_state = &state->tune_state;
1204        int ret = 0;
1205        u16 reg, upd_demod_gain_period = 0x8000;
1206
1207        switch (*tune_state) {
1208        case CT_AGC_START:
1209                // set power-up level: interf+analog+AGC
1210
1211                if (state->revision != 0x8090)
1212                        dib8000_set_adc_state(state, DIBX000_ADC_ON);
1213                else {
1214                        dib8000_set_power_mode(state, DIB8000_POWER_ALL);
1215
1216                        reg = dib8000_read_word(state, 1947)&0xff00;
1217                        dib8000_write_word(state, 1946,
1218                                        upd_demod_gain_period & 0xFFFF);
1219                        /* bit 14 = enDemodGain */
1220                        dib8000_write_word(state, 1947, reg | (1<<14) |
1221                                        ((upd_demod_gain_period >> 16) & 0xFF));
1222
1223                        /* enable adc i & q */
1224                        reg = dib8000_read_word(state, 1920);
1225                        dib8000_write_word(state, 1920, (reg | 0x3) &
1226                                        (~(1 << 7)));
1227                }
1228
1229                if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) {
1230                        *tune_state = CT_AGC_STOP;
1231                        state->status = FE_STATUS_TUNE_FAILED;
1232                        break;
1233                }
1234
1235                ret = 70;
1236                *tune_state = CT_AGC_STEP_0;
1237                break;
1238
1239        case CT_AGC_STEP_0:
1240                //AGC initialization
1241                if (state->cfg.agc_control)
1242                        state->cfg.agc_control(fe, 1);
1243
1244                dib8000_restart_agc(state);
1245
1246                // wait AGC rough lock time
1247                ret = 50;
1248                *tune_state = CT_AGC_STEP_1;
1249                break;
1250
1251        case CT_AGC_STEP_1:
1252                // wait AGC accurate lock time
1253                ret = 70;
1254
1255                if (dib8000_update_lna(state))
1256                        // wait only AGC rough lock time
1257                        ret = 50;
1258                else
1259                        *tune_state = CT_AGC_STEP_2;
1260                break;
1261
1262        case CT_AGC_STEP_2:
1263                dib8000_agc_soft_split(state);
1264
1265                if (state->cfg.agc_control)
1266                        state->cfg.agc_control(fe, 0);
1267
1268                *tune_state = CT_AGC_STOP;
1269                break;
1270        default:
1271                ret = dib8000_agc_soft_split(state);
1272                break;
1273        }
1274        return ret;
1275
1276}
1277
1278static void dib8096p_host_bus_drive(struct dib8000_state *state, u8 drive)
1279{
1280        u16 reg;
1281
1282        drive &= 0x7;
1283
1284        /* drive host bus 2, 3, 4 */
1285        reg = dib8000_read_word(state, 1798) &
1286                ~(0x7 | (0x7 << 6) | (0x7 << 12));
1287        reg |= (drive<<12) | (drive<<6) | drive;
1288        dib8000_write_word(state, 1798, reg);
1289
1290        /* drive host bus 5,6 */
1291        reg = dib8000_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
1292        reg |= (drive<<8) | (drive<<2);
1293        dib8000_write_word(state, 1799, reg);
1294
1295        /* drive host bus 7, 8, 9 */
1296        reg = dib8000_read_word(state, 1800) &
1297                ~(0x7 | (0x7 << 6) | (0x7 << 12));
1298        reg |= (drive<<12) | (drive<<6) | drive;
1299        dib8000_write_word(state, 1800, reg);
1300
1301        /* drive host bus 10, 11 */
1302        reg = dib8000_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
1303        reg |= (drive<<8) | (drive<<2);
1304        dib8000_write_word(state, 1801, reg);
1305
1306        /* drive host bus 12, 13, 14 */
1307        reg = dib8000_read_word(state, 1802) &
1308                ~(0x7 | (0x7 << 6) | (0x7 << 12));
1309        reg |= (drive<<12) | (drive<<6) | drive;
1310        dib8000_write_word(state, 1802, reg);
1311}
1312
1313static u32 dib8096p_calcSyncFreq(u32 P_Kin, u32 P_Kout,
1314                u32 insertExtSynchro, u32 syncSize)
1315{
1316        u32 quantif = 3;
1317        u32 nom = (insertExtSynchro * P_Kin+syncSize);
1318        u32 denom = P_Kout;
1319        u32 syncFreq = ((nom << quantif) / denom);
1320
1321        if ((syncFreq & ((1 << quantif) - 1)) != 0)
1322                syncFreq = (syncFreq >> quantif) + 1;
1323        else
1324                syncFreq = (syncFreq >> quantif);
1325
1326        if (syncFreq != 0)
1327                syncFreq = syncFreq - 1;
1328
1329        return syncFreq;
1330}
1331
1332static void dib8096p_cfg_DibTx(struct dib8000_state *state, u32 P_Kin,
1333                u32 P_Kout, u32 insertExtSynchro, u32 synchroMode,
1334                u32 syncWord, u32 syncSize)
1335{
1336        dprintk("Configure DibStream Tx");
1337
1338        dib8000_write_word(state, 1615, 1);
1339        dib8000_write_word(state, 1603, P_Kin);
1340        dib8000_write_word(state, 1605, P_Kout);
1341        dib8000_write_word(state, 1606, insertExtSynchro);
1342        dib8000_write_word(state, 1608, synchroMode);
1343        dib8000_write_word(state, 1609, (syncWord >> 16) & 0xffff);
1344        dib8000_write_word(state, 1610, syncWord & 0xffff);
1345        dib8000_write_word(state, 1612, syncSize);
1346        dib8000_write_word(state, 1615, 0);
1347}
1348
1349static void dib8096p_cfg_DibRx(struct dib8000_state *state, u32 P_Kin,
1350                u32 P_Kout, u32 synchroMode, u32 insertExtSynchro,
1351                u32 syncWord, u32 syncSize, u32 dataOutRate)
1352{
1353        u32 syncFreq;
1354
1355        dprintk("Configure DibStream Rx synchroMode = %d", synchroMode);
1356
1357        if ((P_Kin != 0) && (P_Kout != 0)) {
1358                syncFreq = dib8096p_calcSyncFreq(P_Kin, P_Kout,
1359                                insertExtSynchro, syncSize);
1360                dib8000_write_word(state, 1542, syncFreq);
1361        }
1362
1363        dib8000_write_word(state, 1554, 1);
1364        dib8000_write_word(state, 1536, P_Kin);
1365        dib8000_write_word(state, 1537, P_Kout);
1366        dib8000_write_word(state, 1539, synchroMode);
1367        dib8000_write_word(state, 1540, (syncWord >> 16) & 0xffff);
1368        dib8000_write_word(state, 1541, syncWord & 0xffff);
1369        dib8000_write_word(state, 1543, syncSize);
1370        dib8000_write_word(state, 1544, dataOutRate);
1371        dib8000_write_word(state, 1554, 0);
1372}
1373
1374static void dib8096p_enMpegMux(struct dib8000_state *state, int onoff)
1375{
1376        u16 reg_1287;
1377
1378        reg_1287 = dib8000_read_word(state, 1287);
1379
1380        switch (onoff) {
1381        case 1:
1382                        reg_1287 &= ~(1 << 8);
1383                        break;
1384        case 0:
1385                        reg_1287 |= (1 << 8);
1386                        break;
1387        }
1388
1389        dib8000_write_word(state, 1287, reg_1287);
1390}
1391
1392static void dib8096p_configMpegMux(struct dib8000_state *state,
1393                u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
1394{
1395        u16 reg_1287;
1396
1397        dprintk("Enable Mpeg mux");
1398
1399        dib8096p_enMpegMux(state, 0);
1400
1401        /* If the input mode is MPEG do not divide the serial clock */
1402        if ((enSerialMode == 1) && (state->input_mode_mpeg == 1))
1403                enSerialClkDiv2 = 0;
1404
1405        reg_1287 = ((pulseWidth & 0x1f) << 3) |
1406                ((enSerialMode & 0x1) << 2) | (enSerialClkDiv2 & 0x1);
1407        dib8000_write_word(state, 1287, reg_1287);
1408
1409        dib8096p_enMpegMux(state, 1);
1410}
1411
1412static void dib8096p_setDibTxMux(struct dib8000_state *state, int mode)
1413{
1414        u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 7);
1415
1416        switch (mode) {
1417        case MPEG_ON_DIBTX:
1418                        dprintk("SET MPEG ON DIBSTREAM TX");
1419                        dib8096p_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
1420                        reg_1288 |= (1 << 9); break;
1421        case DIV_ON_DIBTX:
1422                        dprintk("SET DIV_OUT ON DIBSTREAM TX");
1423                        dib8096p_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
1424                        reg_1288 |= (1 << 8); break;
1425        case ADC_ON_DIBTX:
1426                        dprintk("SET ADC_OUT ON DIBSTREAM TX");
1427                        dib8096p_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
1428                        reg_1288 |= (1 << 7); break;
1429        default:
1430                        break;
1431        }
1432        dib8000_write_word(state, 1288, reg_1288);
1433}
1434
1435static void dib8096p_setHostBusMux(struct dib8000_state *state, int mode)
1436{
1437        u16 reg_1288 = dib8000_read_word(state, 1288) & ~(0x7 << 4);
1438
1439        switch (mode) {
1440        case DEMOUT_ON_HOSTBUS:
1441                        dprintk("SET DEM OUT OLD INTERF ON HOST BUS");
1442                        dib8096p_enMpegMux(state, 0);
1443                        reg_1288 |= (1 << 6);
1444                        break;
1445        case DIBTX_ON_HOSTBUS:
1446                        dprintk("SET DIBSTREAM TX ON HOST BUS");
1447                        dib8096p_enMpegMux(state, 0);
1448                        reg_1288 |= (1 << 5);
1449                        break;
1450        case MPEG_ON_HOSTBUS:
1451                        dprintk("SET MPEG MUX ON HOST BUS");
1452                        reg_1288 |= (1 << 4);
1453                        break;
1454        default:
1455                        break;
1456        }
1457        dib8000_write_word(state, 1288, reg_1288);
1458}
1459
1460static int dib8096p_set_diversity_in(struct dvb_frontend *fe, int onoff)
1461{
1462        struct dib8000_state *state = fe->demodulator_priv;
1463        u16 reg_1287;
1464
1465        switch (onoff) {
1466        case 0: /* only use the internal way - not the diversity input */
1467                        dprintk("%s mode OFF : by default Enable Mpeg INPUT",
1468                                        __func__);
1469                        /* outputRate = 8 */
1470                        dib8096p_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0);
1471
1472                        /* Do not divide the serial clock of MPEG MUX in
1473                           SERIAL MODE in case input mode MPEG is used */
1474                        reg_1287 = dib8000_read_word(state, 1287);
1475                        /* enSerialClkDiv2 == 1 ? */
1476                        if ((reg_1287 & 0x1) == 1) {
1477                                /* force enSerialClkDiv2 = 0 */
1478                                reg_1287 &= ~0x1;
1479                                dib8000_write_word(state, 1287, reg_1287);
1480                        }
1481                        state->input_mode_mpeg = 1;
1482                        break;
1483        case 1: /* both ways */
1484        case 2: /* only the diversity input */
1485                        dprintk("%s ON : Enable diversity INPUT", __func__);
1486                        dib8096p_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
1487                        state->input_mode_mpeg = 0;
1488                        break;
1489        }
1490
1491        dib8000_set_diversity_in(state->fe[0], onoff);
1492        return 0;
1493}
1494
1495static int dib8096p_set_output_mode(struct dvb_frontend *fe, int mode)
1496{
1497        struct dib8000_state *state = fe->demodulator_priv;
1498        u16 outreg, smo_mode, fifo_threshold;
1499        u8 prefer_mpeg_mux_use = 1;
1500        int ret = 0;
1501
1502        state->output_mode = mode;
1503        dib8096p_host_bus_drive(state, 1);
1504
1505        fifo_threshold = 1792;
1506        smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
1507        outreg   = dib8000_read_word(state, 1286) &
1508                ~((1 << 10) | (0x7 << 6) | (1 << 1));
1509
1510        switch (mode) {
1511        case OUTMODE_HIGH_Z:
1512                        outreg = 0;
1513                        break;
1514
1515        case OUTMODE_MPEG2_SERIAL:
1516                        if (prefer_mpeg_mux_use) {
1517                                dprintk("dib8096P setting output mode TS_SERIAL using Mpeg Mux");
1518                                dib8096p_configMpegMux(state, 3, 1, 1);
1519                                dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS);
1520                        } else {/* Use Smooth block */
1521                                dprintk("dib8096P setting output mode TS_SERIAL using Smooth bloc");
1522                                dib8096p_setHostBusMux(state,
1523                                                DEMOUT_ON_HOSTBUS);
1524                                outreg |= (2 << 6) | (0 << 1);
1525                        }
1526                        break;
1527
1528        case OUTMODE_MPEG2_PAR_GATED_CLK:
1529                        if (prefer_mpeg_mux_use) {
1530                                dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Mpeg Mux");
1531                                dib8096p_configMpegMux(state, 2, 0, 0);
1532                                dib8096p_setHostBusMux(state, MPEG_ON_HOSTBUS);
1533                        } else { /* Use Smooth block */
1534                                dprintk("dib8096P setting output mode TS_PARALLEL_GATED using Smooth block");
1535                                dib8096p_setHostBusMux(state,
1536                                                DEMOUT_ON_HOSTBUS);
1537                                outreg |= (0 << 6);
1538                        }
1539                        break;
1540
1541        case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */
1542                        dprintk("dib8096P setting output mode TS_PARALLEL_CONT using Smooth block");
1543                        dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
1544                        outreg |= (1 << 6);
1545                        break;
1546
1547        case OUTMODE_MPEG2_FIFO:
1548                        /* Using Smooth block because not supported
1549                           by new Mpeg Mux bloc */
1550                        dprintk("dib8096P setting output mode TS_FIFO using Smooth block");
1551                        dib8096p_setHostBusMux(state, DEMOUT_ON_HOSTBUS);
1552                        outreg |= (5 << 6);
1553                        smo_mode |= (3 << 1);
1554                        fifo_threshold = 512;
1555                        break;
1556
1557        case OUTMODE_DIVERSITY:
1558                        dprintk("dib8096P setting output mode MODE_DIVERSITY");
1559                        dib8096p_setDibTxMux(state, DIV_ON_DIBTX);
1560                        dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
1561                        break;
1562
1563        case OUTMODE_ANALOG_ADC:
1564                        dprintk("dib8096P setting output mode MODE_ANALOG_ADC");
1565                        dib8096p_setDibTxMux(state, ADC_ON_DIBTX);
1566                        dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
1567                        break;
1568        }
1569
1570        if (mode != OUTMODE_HIGH_Z)
1571                outreg |= (1<<10);
1572
1573        dprintk("output_mpeg2_in_188_bytes = %d",
1574                        state->cfg.output_mpeg2_in_188_bytes);
1575        if (state->cfg.output_mpeg2_in_188_bytes)
1576                smo_mode |= (1 << 5);
1577
1578        ret |= dib8000_write_word(state, 299, smo_mode);
1579        /* synchronous fread */
1580        ret |= dib8000_write_word(state, 299 + 1, fifo_threshold);
1581        ret |= dib8000_write_word(state, 1286, outreg);
1582
1583        return ret;
1584}
1585
1586static int map_addr_to_serpar_number(struct i2c_msg *msg)
1587{
1588        if (msg->buf[0] <= 15)
1589                msg->buf[0] -= 1;
1590        else if (msg->buf[0] == 17)
1591                msg->buf[0] = 15;
1592        else if (msg->buf[0] == 16)
1593                msg->buf[0] = 17;
1594        else if (msg->buf[0] == 19)
1595                msg->buf[0] = 16;
1596        else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
1597                msg->buf[0] -= 3;
1598        else if (msg->buf[0] == 28)
1599                msg->buf[0] = 23;
1600        else if (msg->buf[0] == 99)
1601                msg->buf[0] = 99;
1602        else
1603                return -EINVAL;
1604        return 0;
1605}
1606
1607static int dib8096p_tuner_write_serpar(struct i2c_adapter *i2c_adap,
1608                struct i2c_msg msg[], int num)
1609{
1610        struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1611        u8 n_overflow = 1;
1612        u16 i = 1000;
1613        u16 serpar_num = msg[0].buf[0];
1614
1615        while (n_overflow == 1 && i) {
1616                n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1;
1617                i--;
1618                if (i == 0)
1619                        dprintk("Tuner ITF: write busy (overflow)");
1620        }
1621        dib8000_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
1622        dib8000_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
1623
1624        return num;
1625}
1626
1627static int dib8096p_tuner_read_serpar(struct i2c_adapter *i2c_adap,
1628                struct i2c_msg msg[], int num)
1629{
1630        struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1631        u8 n_overflow = 1, n_empty = 1;
1632        u16 i = 1000;
1633        u16 serpar_num = msg[0].buf[0];
1634        u16 read_word;
1635
1636        while (n_overflow == 1 && i) {
1637                n_overflow = (dib8000_read_word(state, 1984) >> 1) & 0x1;
1638                i--;
1639                if (i == 0)
1640                        dprintk("TunerITF: read busy (overflow)");
1641        }
1642        dib8000_write_word(state, 1985, (0<<6) | (serpar_num&0x3f));
1643
1644        i = 1000;
1645        while (n_empty == 1 && i) {
1646                n_empty = dib8000_read_word(state, 1984)&0x1;
1647                i--;
1648                if (i == 0)
1649                        dprintk("TunerITF: read busy (empty)");
1650        }
1651
1652        read_word = dib8000_read_word(state, 1987);
1653        msg[1].buf[0] = (read_word >> 8) & 0xff;
1654        msg[1].buf[1] = (read_word) & 0xff;
1655
1656        return num;
1657}
1658
1659static int dib8096p_tuner_rw_serpar(struct i2c_adapter *i2c_adap,
1660                struct i2c_msg msg[], int num)
1661{
1662        if (map_addr_to_serpar_number(&msg[0]) == 0) {
1663                if (num == 1) /* write */
1664                        return dib8096p_tuner_write_serpar(i2c_adap, msg, 1);
1665                else /* read */
1666                        return dib8096p_tuner_read_serpar(i2c_adap, msg, 2);
1667        }
1668        return num;
1669}
1670
1671static int dib8096p_rw_on_apb(struct i2c_adapter *i2c_adap,
1672                struct i2c_msg msg[], int num, u16 apb_address)
1673{
1674        struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1675        u16 word;
1676
1677        if (num == 1) {         /* write */
1678                dib8000_write_word(state, apb_address,
1679                                ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
1680        } else {
1681                word = dib8000_read_word(state, apb_address);
1682                msg[1].buf[0] = (word >> 8) & 0xff;
1683                msg[1].buf[1] = (word) & 0xff;
1684        }
1685        return num;
1686}
1687
1688static int dib8096p_tuner_xfer(struct i2c_adapter *i2c_adap,
1689                struct i2c_msg msg[], int num)
1690{
1691        struct dib8000_state *state = i2c_get_adapdata(i2c_adap);
1692        u16 apb_address = 0, word;
1693        int i = 0;
1694
1695        switch (msg[0].buf[0]) {
1696        case 0x12:
1697                        apb_address = 1920;
1698                        break;
1699        case 0x14:
1700                        apb_address = 1921;
1701                        break;
1702        case 0x24:
1703                        apb_address = 1922;
1704                        break;
1705        case 0x1a:
1706                        apb_address = 1923;
1707                        break;
1708        case 0x22:
1709                        apb_address = 1924;
1710                        break;
1711        case 0x33:
1712                        apb_address = 1926;
1713                        break;
1714        case 0x34:
1715                        apb_address = 1927;
1716                        break;
1717        case 0x35:
1718                        apb_address = 1928;
1719                        break;
1720        case 0x36:
1721                        apb_address = 1929;
1722                        break;
1723        case 0x37:
1724                        apb_address = 1930;
1725                        break;
1726        case 0x38:
1727                        apb_address = 1931;
1728                        break;
1729        case 0x39:
1730                        apb_address = 1932;
1731                        break;
1732        case 0x2a:
1733                        apb_address = 1935;
1734                        break;
1735        case 0x2b:
1736                        apb_address = 1936;
1737                        break;
1738        case 0x2c:
1739                        apb_address = 1937;
1740                        break;
1741        case 0x2d:
1742                        apb_address = 1938;
1743                        break;
1744        case 0x2e:
1745                        apb_address = 1939;
1746                        break;
1747        case 0x2f:
1748                        apb_address = 1940;
1749                        break;
1750        case 0x30:
1751                        apb_address = 1941;
1752                        break;
1753        case 0x31:
1754                        apb_address = 1942;
1755                        break;
1756        case 0x32:
1757                        apb_address = 1943;
1758                        break;
1759        case 0x3e:
1760                        apb_address = 1944;
1761                        break;
1762        case 0x3f:
1763                        apb_address = 1945;
1764                        break;
1765        case 0x40:
1766                        apb_address = 1948;
1767                        break;
1768        case 0x25:
1769                        apb_address = 936;
1770                        break;
1771        case 0x26:
1772                        apb_address = 937;
1773                        break;
1774        case 0x27:
1775                        apb_address = 938;
1776                        break;
1777        case 0x28:
1778                        apb_address = 939;
1779                        break;
1780        case 0x1d:
1781                        /* get sad sel request */
1782                        i = ((dib8000_read_word(state, 921) >> 12)&0x3);
1783                        word = dib8000_read_word(state, 924+i);
1784                        msg[1].buf[0] = (word >> 8) & 0xff;
1785                        msg[1].buf[1] = (word) & 0xff;
1786                        return num;
1787        case 0x1f:
1788                        if (num == 1) { /* write */
1789                                word = (u16) ((msg[0].buf[1] << 8) |
1790                                                msg[0].buf[2]);
1791                                /* in the VGAMODE Sel are located on bit 0/1 */
1792                                word &= 0x3;
1793                                word = (dib8000_read_word(state, 921) &
1794                                                ~(3<<12)) | (word<<12);
1795                                /* Set the proper input */
1796                                dib8000_write_word(state, 921, word);
1797                                return num;
1798                        }
1799        }
1800
1801        if (apb_address != 0) /* R/W acces via APB */
1802                return dib8096p_rw_on_apb(i2c_adap, msg, num, apb_address);
1803        else  /* R/W access via SERPAR  */
1804                return dib8096p_tuner_rw_serpar(i2c_adap, msg, num);
1805
1806        return 0;
1807}
1808
1809static u32 dib8096p_i2c_func(struct i2c_adapter *adapter)
1810{
1811        return I2C_FUNC_I2C;
1812}
1813
1814static struct i2c_algorithm dib8096p_tuner_xfer_algo = {
1815        .master_xfer = dib8096p_tuner_xfer,
1816        .functionality = dib8096p_i2c_func,
1817};
1818
1819struct i2c_adapter *dib8096p_get_i2c_tuner(struct dvb_frontend *fe)
1820{
1821        struct dib8000_state *st = fe->demodulator_priv;
1822        return &st->dib8096p_tuner_adap;
1823}
1824EXPORT_SYMBOL(dib8096p_get_i2c_tuner);
1825
1826int dib8096p_tuner_sleep(struct dvb_frontend *fe, int onoff)
1827{
1828        struct dib8000_state *state = fe->demodulator_priv;
1829        u16 en_cur_state;
1830
1831        dprintk("sleep dib8096p: %d", onoff);
1832
1833        en_cur_state = dib8000_read_word(state, 1922);
1834
1835        /* LNAs and MIX are ON and therefore it is a valid configuration */
1836        if (en_cur_state > 0xff)
1837                state->tuner_enable = en_cur_state ;
1838
1839        if (onoff)
1840                en_cur_state &= 0x00ff;
1841        else {
1842                if (state->tuner_enable != 0)
1843                        en_cur_state = state->tuner_enable;
1844        }
1845
1846        dib8000_write_word(state, 1922, en_cur_state);
1847
1848        return 0;
1849}
1850EXPORT_SYMBOL(dib8096p_tuner_sleep);
1851
1852static const s32 lut_1000ln_mant[] =
1853{
1854        908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600
1855};
1856
1857s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
1858{
1859        struct dib8000_state *state = fe->demodulator_priv;
1860        u32 ix = 0, tmp_val = 0, exp = 0, mant = 0;
1861        s32 val;
1862
1863        val = dib8000_read32(state, 384);
1864        if (mode) {
1865                tmp_val = val;
1866                while (tmp_val >>= 1)
1867                        exp++;
1868                mant = (val * 1000 / (1<<exp));
1869                ix = (u8)((mant-1000)/100); /* index of the LUT */
1870                val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908);
1871                val = (val*256)/1000;
1872        }
1873        return val;
1874}
1875EXPORT_SYMBOL(dib8000_get_adc_power);
1876
1877int dib8090p_get_dc_power(struct dvb_frontend *fe, u8 IQ)
1878{
1879        struct dib8000_state *state = fe->demodulator_priv;
1880        int val = 0;
1881
1882        switch (IQ) {
1883        case 1:
1884                        val = dib8000_read_word(state, 403);
1885                        break;
1886        case 0:
1887                        val = dib8000_read_word(state, 404);
1888                        break;
1889        }
1890        if (val  & 0x200)
1891                val -= 1024;
1892
1893        return val;
1894}
1895EXPORT_SYMBOL(dib8090p_get_dc_power);
1896
1897static void dib8000_update_timf(struct dib8000_state *state)
1898{
1899        u32 timf = state->timf = dib8000_read32(state, 435);
1900
1901        dib8000_write_word(state, 29, (u16) (timf >> 16));
1902        dib8000_write_word(state, 30, (u16) (timf & 0xffff));
1903        dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
1904}
1905
1906u32 dib8000_ctrl_timf(struct dvb_frontend *fe, uint8_t op, uint32_t timf)
1907{
1908        struct dib8000_state *state = fe->demodulator_priv;
1909
1910        switch (op) {
1911        case DEMOD_TIMF_SET:
1912                        state->timf = timf;
1913                        break;
1914        case DEMOD_TIMF_UPDATE:
1915                        dib8000_update_timf(state);
1916                        break;
1917        case DEMOD_TIMF_GET:
1918                        break;
1919        }
1920        dib8000_set_bandwidth(state->fe[0], 6000);
1921
1922        return state->timf;
1923}
1924EXPORT_SYMBOL(dib8000_ctrl_timf);
1925
1926static const u16 adc_target_16dB[11] = {
1927        (1 << 13) - 825 - 117,
1928        (1 << 13) - 837 - 117,
1929        (1 << 13) - 811 - 117,
1930        (1 << 13) - 766 - 117,
1931        (1 << 13) - 737 - 117,
1932        (1 << 13) - 693 - 117,
1933        (1 << 13) - 648 - 117,
1934        (1 << 13) - 619 - 117,
1935        (1 << 13) - 575 - 117,
1936        (1 << 13) - 531 - 117,
1937        (1 << 13) - 501 - 117
1938};
1939static const u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
1940
1941static u16 dib8000_set_layer(struct dib8000_state *state, u8 layer_index, u16 max_constellation)
1942{
1943        u8  cr, constellation, time_intlv;
1944        struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
1945
1946        switch (c->layer[layer_index].modulation) {
1947        case DQPSK:
1948                        constellation = 0;
1949                        break;
1950        case  QPSK:
1951                        constellation = 1;
1952                        break;
1953        case QAM_16:
1954                        constellation = 2;
1955                        break;
1956        case QAM_64:
1957        default:
1958                        constellation = 3;
1959                        break;
1960        }
1961
1962        switch (c->layer[layer_index].fec) {
1963        case FEC_1_2:
1964                        cr = 1;
1965                        break;
1966        case FEC_2_3:
1967                        cr = 2;
1968                        break;
1969        case FEC_3_4:
1970                        cr = 3;
1971                        break;
1972        case FEC_5_6:
1973                        cr = 5;
1974                        break;
1975        case FEC_7_8:
1976        default:
1977                        cr = 7;
1978                        break;
1979        }
1980
1981        if ((c->layer[layer_index].interleaving > 0) && ((c->layer[layer_index].interleaving <= 3) || (c->layer[layer_index].interleaving == 4 && c->isdbt_sb_mode == 1)))
1982                time_intlv = c->layer[layer_index].interleaving;
1983        else
1984                time_intlv = 0;
1985
1986        dib8000_write_word(state, 2 + layer_index, (constellation << 10) | ((c->layer[layer_index].segment_count & 0xf) << 6) | (cr << 3) | time_intlv);
1987        if (c->layer[layer_index].segment_count > 0) {
1988                switch (max_constellation) {
1989                case DQPSK:
1990                case QPSK:
1991                                if (c->layer[layer_index].modulation == QAM_16 || c->layer[layer_index].modulation == QAM_64)
1992                                        max_constellation = c->layer[layer_index].modulation;
1993                                break;
1994                case QAM_16:
1995                                if (c->layer[layer_index].modulation == QAM_64)
1996                                        max_constellation = c->layer[layer_index].modulation;
1997                                break;
1998                }
1999        }
2000
2001        return  max_constellation;
2002}
2003
2004static const u16 adp_Q64[4] = {0x0148, 0xfff0, 0x00a4, 0xfff8}; /* P_adp_regul_cnt 0.04, P_adp_noise_cnt -0.002, P_adp_regul_ext 0.02, P_adp_noise_ext -0.001 */
2005static const u16 adp_Q16[4] = {0x023d, 0xffdf, 0x00a4, 0xfff0}; /* P_adp_regul_cnt 0.07, P_adp_noise_cnt -0.004, P_adp_regul_ext 0.02, P_adp_noise_ext -0.002 */
2006static const u16 adp_Qdefault[4] = {0x099a, 0xffae, 0x0333, 0xfff8}; /* P_adp_regul_cnt 0.3,  P_adp_noise_cnt -0.01,  P_adp_regul_ext 0.1,  P_adp_noise_ext -0.002 */
2007static u16 dib8000_adp_fine_tune(struct dib8000_state *state, u16 max_constellation)
2008{
2009        u16 i, ana_gain = 0;
2010        const u16 *adp;
2011
2012        /* channel estimation fine configuration */
2013        switch (max_constellation) {
2014        case QAM_64:
2015                        ana_gain = 0x7;
2016                        adp = &adp_Q64[0];
2017                        break;
2018        case QAM_16:
2019                        ana_gain = 0x7;
2020                        adp = &adp_Q16[0];
2021                        break;
2022        default:
2023                        ana_gain = 0;
2024                        adp = &adp_Qdefault[0];
2025                        break;
2026        }
2027
2028        for (i = 0; i < 4; i++)
2029                dib8000_write_word(state, 215 + i, adp[i]);
2030
2031        return ana_gain;
2032}
2033
2034static void dib8000_update_ana_gain(struct dib8000_state *state, u16 ana_gain)
2035{
2036        u16 i;
2037
2038        dib8000_write_word(state, 116, ana_gain);
2039
2040        /* update ADC target depending on ana_gain */
2041        if (ana_gain) { /* set -16dB ADC target for ana_gain=-1 */
2042                for (i = 0; i < 10; i++)
2043                        dib8000_write_word(state, 80 + i, adc_target_16dB[i]);
2044        } else { /* set -22dB ADC target for ana_gain=0 */
2045                for (i = 0; i < 10; i++)
2046                        dib8000_write_word(state, 80 + i, adc_target_16dB[i] - 355);
2047        }
2048}
2049
2050static void dib8000_load_ana_fe_coefs(struct dib8000_state *state, const s16 *ana_fe)
2051{
2052        u16 mode = 0;
2053
2054        if (state->isdbt_cfg_loaded == 0)
2055                for (mode = 0; mode < 24; mode++)
2056                        dib8000_write_word(state, 117 + mode, ana_fe[mode]);
2057}
2058
2059static const u16 lut_prbs_2k[14] = {
2060        0, 0x423, 0x009, 0x5C7, 0x7A6, 0x3D8, 0x527, 0x7FF, 0x79B, 0x3D6, 0x3A2, 0x53B, 0x2F4, 0x213
2061};
2062static const u16 lut_prbs_4k[14] = {
2063        0, 0x208, 0x0C3, 0x7B9, 0x423, 0x5C7, 0x3D8, 0x7FF, 0x3D6, 0x53B, 0x213, 0x029, 0x0D0, 0x48E
2064};
2065static const u16 lut_prbs_8k[14] = {
2066        0, 0x740, 0x069, 0x7DD, 0x208, 0x7B9, 0x5C7, 0x7FF, 0x53B, 0x029, 0x48E, 0x4C4, 0x367, 0x684
2067};
2068
2069static u16 dib8000_get_init_prbs(struct dib8000_state *state, u16 subchannel)
2070{
2071        int sub_channel_prbs_group = 0;
2072
2073        sub_channel_prbs_group = (subchannel / 3) + 1;
2074        dprintk("sub_channel_prbs_group = %d , subchannel =%d prbs = 0x%04x", sub_channel_prbs_group, subchannel, lut_prbs_8k[sub_channel_prbs_group]);
2075
2076        switch (state->fe[0]->dtv_property_cache.transmission_mode) {
2077        case TRANSMISSION_MODE_2K:
2078                        return lut_prbs_2k[sub_channel_prbs_group];
2079        case TRANSMISSION_MODE_4K:
2080                        return lut_prbs_4k[sub_channel_prbs_group];
2081        default:
2082        case TRANSMISSION_MODE_8K:
2083                        return lut_prbs_8k[sub_channel_prbs_group];
2084        }
2085}
2086
2087static void dib8000_set_13seg_channel(struct dib8000_state *state)
2088{
2089        u16 i;
2090        u16 coff_pow = 0x2800;
2091
2092        state->seg_mask = 0x1fff; /* All 13 segments enabled */
2093
2094        /* ---- COFF ---- Carloff, the most robust --- */
2095        if (state->isdbt_cfg_loaded == 0) {  /* if not Sound Broadcasting mode : put default values for 13 segments */
2096                dib8000_write_word(state, 180, (16 << 6) | 9);
2097                dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2);
2098                coff_pow = 0x2800;
2099                for (i = 0; i < 6; i++)
2100                        dib8000_write_word(state, 181+i, coff_pow);
2101
2102                /* P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1 */
2103                /* P_ctrl_pre_freq_mode_sat=1, P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 3, P_pre_freq_win_len=1 */
2104                dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1);
2105
2106                /* P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6 */
2107                dib8000_write_word(state, 340, (8 << 6) | (6 << 0));
2108                /* P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1 */
2109                dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
2110
2111                dib8000_write_word(state, 228, 0);  /* default value */
2112                dib8000_write_word(state, 265, 31); /* default value */
2113                dib8000_write_word(state, 205, 0x200f); /* init value */
2114        }
2115
2116        /*
2117         * make the cpil_coff_lock more robust but slower p_coff_winlen
2118         * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
2119         */
2120
2121        if (state->cfg.pll->ifreq == 0)
2122                dib8000_write_word(state, 266, ~state->seg_mask | state->seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */
2123
2124        dib8000_load_ana_fe_coefs(state, ana_fe_coeff_13seg);
2125}
2126
2127static void dib8000_set_subchannel_prbs(struct dib8000_state *state, u16 init_prbs)
2128{
2129        u16 reg_1;
2130
2131        reg_1 = dib8000_read_word(state, 1);
2132        dib8000_write_word(state, 1, (init_prbs << 2) | (reg_1 & 0x3)); /* ADDR 1 */
2133}
2134
2135static void dib8000_small_fine_tune(struct dib8000_state *state)
2136{
2137        u16 i;
2138        const s16 *ncoeff;
2139        struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2140
2141        dib8000_write_word(state, 352, state->seg_diff_mask);
2142        dib8000_write_word(state, 353, state->seg_mask);
2143
2144        /* P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5 */
2145        dib8000_write_word(state, 351, (c->isdbt_sb_mode << 9) | (c->isdbt_sb_mode << 8) | (13 << 4) | 5);
2146
2147        if (c->isdbt_sb_mode) {
2148                /* ---- SMALL ---- */
2149                switch (c->transmission_mode) {
2150                case TRANSMISSION_MODE_2K:
2151                                if (c->isdbt_partial_reception == 0) { /* 1-seg */
2152                                        if (c->layer[0].modulation == DQPSK) /* DQPSK */
2153                                                ncoeff = coeff_2k_sb_1seg_dqpsk;
2154                                        else /* QPSK or QAM */
2155                                                ncoeff = coeff_2k_sb_1seg;
2156                                } else { /* 3-segments */
2157                                        if (c->layer[0].modulation == DQPSK) { /* DQPSK on central segment */
2158                                                if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
2159                                                        ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
2160                                                else /* QPSK or QAM on external segments */
2161                                                        ncoeff = coeff_2k_sb_3seg_0dqpsk;
2162                                        } else { /* QPSK or QAM on central segment */
2163                                                if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
2164                                                        ncoeff = coeff_2k_sb_3seg_1dqpsk;
2165                                                else /* QPSK or QAM on external segments */
2166                                                        ncoeff = coeff_2k_sb_3seg;
2167                                        }
2168                                }
2169                                break;
2170                case TRANSMISSION_MODE_4K:
2171                                if (c->isdbt_partial_reception == 0) { /* 1-seg */
2172                                        if (c->layer[0].modulation == DQPSK) /* DQPSK */
2173                                                ncoeff = coeff_4k_sb_1seg_dqpsk;
2174                                        else /* QPSK or QAM */
2175                                                ncoeff = coeff_4k_sb_1seg;
2176                                } else { /* 3-segments */
2177                                        if (c->layer[0].modulation == DQPSK) { /* DQPSK on central segment */
2178                                                if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
2179                                                        ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
2180                                                else /* QPSK or QAM on external segments */
2181                                                        ncoeff = coeff_4k_sb_3seg_0dqpsk;
2182                                        } else { /* QPSK or QAM on central segment */
2183                                                if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
2184                                                        ncoeff = coeff_4k_sb_3seg_1dqpsk;
2185                                                else /* QPSK or QAM on external segments */
2186                                                        ncoeff = coeff_4k_sb_3seg;
2187                                        }
2188                                }
2189                                break;
2190                case TRANSMISSION_MODE_AUTO:
2191                case TRANSMISSION_MODE_8K:
2192                default:
2193                                if (c->isdbt_partial_reception == 0) { /* 1-seg */
2194                                        if (c->layer[0].modulation == DQPSK) /* DQPSK */
2195                                                ncoeff = coeff_8k_sb_1seg_dqpsk;
2196                                        else /* QPSK or QAM */
2197                                                ncoeff = coeff_8k_sb_1seg;
2198                                } else { /* 3-segments */
2199                                        if (c->layer[0].modulation == DQPSK) { /* DQPSK on central segment */
2200                                                if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
2201                                                        ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
2202                                                else /* QPSK or QAM on external segments */
2203                                                        ncoeff = coeff_8k_sb_3seg_0dqpsk;
2204                                        } else { /* QPSK or QAM on central segment */
2205                                                if (c->layer[1].modulation == DQPSK) /* DQPSK on external segments */
2206                                                        ncoeff = coeff_8k_sb_3seg_1dqpsk;
2207                                                else /* QPSK or QAM on external segments */
2208                                                        ncoeff = coeff_8k_sb_3seg;
2209                                        }
2210                                }
2211                                break;
2212                }
2213
2214                for (i = 0; i < 8; i++)
2215                        dib8000_write_word(state, 343 + i, ncoeff[i]);
2216        }
2217}
2218
2219static const u16 coff_thres_1seg[3] = {300, 150, 80};
2220static const u16 coff_thres_3seg[3] = {350, 300, 250};
2221static void dib8000_set_sb_channel(struct dib8000_state *state)
2222{
2223        struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2224        const u16 *coff;
2225        u16 i;
2226
2227        if (c->transmission_mode == TRANSMISSION_MODE_2K || c->transmission_mode == TRANSMISSION_MODE_4K) {
2228                dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); /* adp_pass =1 */
2229                dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); /* pha3_force_pha_shift = 1 */
2230        } else {
2231                dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); /* adp_pass =0 */
2232                dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); /* pha3_force_pha_shift = 0 */
2233        }
2234
2235        if (c->isdbt_partial_reception == 1) /* 3-segments */
2236                state->seg_mask = 0x00E0;
2237        else /* 1-segment */
2238                state->seg_mask = 0x0040;
2239
2240        dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
2241
2242        /* ---- COFF ---- Carloff, the most robust --- */
2243        /* P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64, P_coff_narrow_band=1, P_coff_square_val=1, P_coff_one_seg=~partial_rcpt, P_coff_use_tmcc=1, P_coff_use_ac=1 */
2244        dib8000_write_word(state, 187, (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~c->isdbt_partial_reception & 1) << 2) | 0x3);
2245
2246        dib8000_write_word(state, 340, (16 << 6) | (8 << 0)); /* P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8 */
2247        dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));/* P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1 */
2248
2249        /* Sound Broadcasting mode 1 seg */
2250        if (c->isdbt_partial_reception == 0) {
2251                /* P_coff_winlen=63, P_coff_thres_lock=15, P_coff_one_seg_width = (P_mode == 3) , P_coff_one_seg_sym = (P_mode-1) */
2252                if (state->mode == 3)
2253                        dib8000_write_word(state, 180, 0x1fcf | ((state->mode - 1) << 14));
2254                else
2255                        dib8000_write_word(state, 180, 0x0fcf | ((state->mode - 1) << 14));
2256
2257                /* P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1, P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4 */
2258                dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
2259                coff = &coff_thres_1seg[0];
2260        } else {   /* Sound Broadcasting mode 3 seg */
2261                dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
2262                /* P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1, P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4 */
2263                dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
2264                coff = &coff_thres_3seg[0];
2265        }
2266
2267        dib8000_write_word(state, 228, 1); /* P_2d_mode_byp=1 */
2268        dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); /* P_cspu_win_cut = 0 */
2269
2270        if (c->isdbt_partial_reception == 0 && c->transmission_mode == TRANSMISSION_MODE_2K)
2271                dib8000_write_word(state, 265, 15); /* P_equal_noise_sel = 15 */
2272
2273        /* Write COFF thres */
2274        for (i = 0 ; i < 3; i++) {
2275                dib8000_write_word(state, 181+i, coff[i]);
2276                dib8000_write_word(state, 184+i, coff[i]);
2277        }
2278
2279        /*
2280         * make the cpil_coff_lock more robust but slower p_coff_winlen
2281         * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
2282         */
2283
2284        dib8000_write_word(state, 266, ~state->seg_mask | state->seg_diff_mask); /* P_equal_noise_seg_inh */
2285
2286        if (c->isdbt_partial_reception == 0)
2287                dib8000_write_word(state, 178, 64); /* P_fft_powrange = 64 */
2288        else
2289                dib8000_write_word(state, 178, 32); /* P_fft_powrange = 32 */
2290}
2291
2292static void dib8000_set_isdbt_common_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
2293{
2294        u16 p_cfr_left_edge  = 0, p_cfr_right_edge = 0;
2295        u16 tmcc_pow = 0, ana_gain = 0, tmp = 0, i = 0, nbseg_diff = 0 ;
2296        u16 max_constellation = DQPSK;
2297        int init_prbs;
2298        struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2299
2300        /* P_mode */
2301        dib8000_write_word(state, 10, (seq << 4));
2302
2303        /* init mode */
2304        state->mode = fft_to_mode(state);
2305
2306        /* set guard */
2307        tmp = dib8000_read_word(state, 1);
2308        dib8000_write_word(state, 1, (tmp&0xfffc) | (c->guard_interval & 0x3));
2309
2310        dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) | ((c->isdbt_partial_reception & 1) << 5) | ((c->isdbt_sb_mode & 1) << 4));
2311
2312        /* signal optimization parameter */
2313        if (c->isdbt_partial_reception) {
2314                state->seg_diff_mask = (c->layer[0].modulation == DQPSK) << permu_seg[0];
2315                for (i = 1; i < 3; i++)
2316                        nbseg_diff += (c->layer[i].modulation == DQPSK) * c->layer[i].segment_count;
2317                for (i = 0; i < nbseg_diff; i++)
2318                        state->seg_diff_mask |= 1 << permu_seg[i+1];
2319        } else {
2320                for (i = 0; i < 3; i++)
2321                        nbseg_diff += (c->layer[i].modulation == DQPSK) * c->layer[i].segment_count;
2322                for (i = 0; i < nbseg_diff; i++)
2323                        state->seg_diff_mask |= 1 << permu_seg[i];
2324        }
2325
2326        if (state->seg_diff_mask)
2327                dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
2328        else
2329                dib8000_write_word(state, 268, (2 << 9) | 39); /*init value */
2330
2331        for (i = 0; i < 3; i++)
2332                max_constellation = dib8000_set_layer(state, i, max_constellation);
2333        if (autosearching == 0) {
2334                state->layer_b_nb_seg = c->layer[1].segment_count;
2335                state->layer_c_nb_seg = c->layer[2].segment_count;
2336        }
2337
2338        /* WRITE: Mode & Diff mask */
2339        dib8000_write_word(state, 0, (state->mode << 13) | state->seg_diff_mask);
2340
2341        state->differential_constellation = (state->seg_diff_mask != 0);
2342
2343        /* channel estimation fine configuration */
2344        ana_gain = dib8000_adp_fine_tune(state, max_constellation);
2345
2346        /* update ana_gain depending on max constellation */
2347        dib8000_update_ana_gain(state, ana_gain);
2348
2349        /* ---- ANA_FE ---- */
2350        if (c->isdbt_partial_reception) /* 3-segments */
2351                dib8000_load_ana_fe_coefs(state, ana_fe_coeff_3seg);
2352        else
2353                dib8000_load_ana_fe_coefs(state, ana_fe_coeff_1seg); /* 1-segment */
2354
2355        /* TSB or ISDBT ? apply it now */
2356        if (c->isdbt_sb_mode) {
2357                dib8000_set_sb_channel(state);
2358                if (c->isdbt_sb_subchannel < 14)
2359                        init_prbs = dib8000_get_init_prbs(state, c->isdbt_sb_subchannel);
2360                else
2361                        init_prbs = 0;
2362        } else {
2363                dib8000_set_13seg_channel(state);
2364                init_prbs = 0xfff;
2365        }
2366
2367        /* SMALL */
2368        dib8000_small_fine_tune(state);
2369
2370        dib8000_set_subchannel_prbs(state, init_prbs);
2371
2372        /* ---- CHAN_BLK ---- */
2373        for (i = 0; i < 13; i++) {
2374                if ((((~state->seg_diff_mask) >> i) & 1) == 1) {
2375                        p_cfr_left_edge  += (1 << i) * ((i == 0) || ((((state->seg_mask & (~state->seg_diff_mask)) >> (i - 1)) & 1) == 0));
2376                        p_cfr_right_edge += (1 << i) * ((i == 12) || ((((state->seg_mask & (~state->seg_diff_mask)) >> (i + 1)) & 1) == 0));
2377                }
2378        }
2379        dib8000_write_word(state, 222, p_cfr_left_edge); /* p_cfr_left_edge */
2380        dib8000_write_word(state, 223, p_cfr_right_edge); /* p_cfr_right_edge */
2381        /* "P_cspu_left_edge" & "P_cspu_right_edge" not used => do not care */
2382
2383        dib8000_write_word(state, 189, ~state->seg_mask | state->seg_diff_mask); /* P_lmod4_seg_inh */
2384        dib8000_write_word(state, 192, ~state->seg_mask | state->seg_diff_mask); /* P_pha3_seg_inh */
2385        dib8000_write_word(state, 225, ~state->seg_mask | state->seg_diff_mask); /* P_tac_seg_inh */
2386
2387        if (!autosearching)
2388                dib8000_write_word(state, 288, (~state->seg_mask | state->seg_diff_mask) & 0x1fff); /* P_tmcc_seg_eq_inh */
2389        else
2390                dib8000_write_word(state, 288, 0x1fff); /*disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels. */
2391
2392        dib8000_write_word(state, 211, state->seg_mask & (~state->seg_diff_mask)); /* P_des_seg_enabled */
2393        dib8000_write_word(state, 287, ~state->seg_mask | 0x1000); /* P_tmcc_seg_inh */
2394
2395        dib8000_write_word(state, 178, 32); /* P_fft_powrange = 32 */
2396
2397        /* ---- TMCC ---- */
2398        for (i = 0; i < 3; i++)
2399                tmcc_pow += (((c->layer[i].modulation == DQPSK) * 4 + 1) * c->layer[i].segment_count) ;
2400
2401        /* Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9); */
2402        /* Threshold is set at 1/4 of max power. */
2403        tmcc_pow *= (1 << (9-2));
2404        dib8000_write_word(state, 290, tmcc_pow); /* P_tmcc_dec_thres_2k */
2405        dib8000_write_word(state, 291, tmcc_pow); /* P_tmcc_dec_thres_4k */
2406        dib8000_write_word(state, 292, tmcc_pow); /* P_tmcc_dec_thres_8k */
2407        /*dib8000_write_word(state, 287, (1 << 13) | 0x1000 ); */
2408
2409        /* ---- PHA3 ---- */
2410        if (state->isdbt_cfg_loaded == 0)
2411                dib8000_write_word(state, 250, 3285); /* p_2d_hspeed_thr0 */
2412
2413        state->isdbt_cfg_loaded = 0;
2414}
2415
2416static u32 dib8000_wait_lock(struct dib8000_state *state, u32 internal,
2417                             u32 wait0_ms, u32 wait1_ms, u32 wait2_ms)
2418{
2419        u32 value = 0;  /* P_search_end0 wait time */
2420        u16 reg = 11;   /* P_search_end0 start addr */
2421
2422        for (reg = 11; reg < 16; reg += 2) {
2423                if (reg == 11) {
2424                        if (state->revision == 0x8090)
2425                                value = internal * wait1_ms;
2426                        else
2427                                value = internal * wait0_ms;
2428                } else if (reg == 13)
2429                        value = internal * wait1_ms;
2430                else if (reg == 15)
2431                        value = internal * wait2_ms;
2432                dib8000_write_word(state, reg, (u16)((value >> 16) & 0xffff));
2433                dib8000_write_word(state, (reg + 1), (u16)(value & 0xffff));
2434        }
2435        return value;
2436}
2437
2438static int dib8000_autosearch_start(struct dvb_frontend *fe)
2439{
2440        struct dib8000_state *state = fe->demodulator_priv;
2441        struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2442        u8 slist = 0;
2443        u32 value, internal = state->cfg.pll->internal;
2444
2445        if (state->revision == 0x8090)
2446                internal = dib8000_read32(state, 23) / 1000;
2447
2448        if (state->autosearch_state == AS_SEARCHING_FFT) {
2449                dib8000_write_word(state,  37, 0x0065); /* P_ctrl_pha_off_max default values */
2450                dib8000_write_word(state, 116, 0x0000); /* P_ana_gain to 0 */
2451
2452                dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x1fff) | (0 << 13) | (1 << 15)); /* P_mode = 0, P_restart_search=1 */
2453                dib8000_write_word(state, 1, (dib8000_read_word(state, 1) & 0xfffc) | 0); /* P_guard = 0 */
2454                dib8000_write_word(state, 6, 0); /* P_lock0_mask = 0 */
2455                dib8000_write_word(state, 7, 0); /* P_lock1_mask = 0 */
2456                dib8000_write_word(state, 8, 0); /* P_lock2_mask = 0 */
2457                dib8000_write_word(state, 10, (dib8000_read_word(state, 10) & 0x200) | (16 << 4) | (0 << 0)); /* P_search_list=16, P_search_maxtrial=0 */
2458
2459                if (state->revision == 0x8090)
2460                        value = dib8000_wait_lock(state, internal, 10, 10, 10); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2461                else
2462                        value = dib8000_wait_lock(state, internal, 20, 20, 20); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2463
2464                dib8000_write_word(state, 17, 0);
2465                dib8000_write_word(state, 18, 200); /* P_search_rstst = 200 */
2466                dib8000_write_word(state, 19, 0);
2467                dib8000_write_word(state, 20, 400); /* P_search_rstend = 400 */
2468                dib8000_write_word(state, 21, (value >> 16) & 0xffff); /* P_search_checkst */
2469                dib8000_write_word(state, 22, value & 0xffff);
2470
2471                if (state->revision == 0x8090)
2472                        dib8000_write_word(state, 32, (dib8000_read_word(state, 32) & 0xf0ff) | (0 << 8)); /* P_corm_alpha = 0 */
2473                else
2474                        dib8000_write_word(state, 32, (dib8000_read_word(state, 32) & 0xf0ff) | (9 << 8)); /* P_corm_alpha = 3 */
2475                dib8000_write_word(state, 355, 2); /* P_search_param_max = 2 */
2476
2477                /* P_search_param_select = (1 | 1<<4 | 1 << 8) */
2478                dib8000_write_word(state, 356, 0);
2479                dib8000_write_word(state, 357, 0x111);
2480
2481                dib8000_write_word(state, 770, (dib8000_read_word(state, 770) & 0xdfff) | (1 << 13)); /* P_restart_ccg = 1 */
2482                dib8000_write_word(state, 770, (dib8000_read_word(state, 770) & 0xdfff) | (0 << 13)); /* P_restart_ccg = 0 */
2483                dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x7ff) | (0 << 15) | (1 << 13)); /* P_restart_search = 0; */
2484        } else if (state->autosearch_state == AS_SEARCHING_GUARD) {
2485                c->transmission_mode = TRANSMISSION_MODE_8K;
2486                c->guard_interval = GUARD_INTERVAL_1_8;
2487                c->inversion = 0;
2488                c->layer[0].modulation = QAM_64;
2489                c->layer[0].fec = FEC_2_3;
2490                c->layer[0].interleaving = 0;
2491                c->layer[0].segment_count = 13;
2492
2493                slist = 16;
2494                c->transmission_mode = state->found_nfft;
2495
2496                dib8000_set_isdbt_common_channel(state, slist, 1);
2497
2498                /* set lock_mask values */
2499                dib8000_write_word(state, 6, 0x4);
2500                if (state->revision == 0x8090)
2501                        dib8000_write_word(state, 7, ((1 << 12) | (1 << 11) | (1 << 10)));/* tmcc_dec_lock, tmcc_sync_lock, tmcc_data_lock, tmcc_bch_uncor */
2502                else
2503                        dib8000_write_word(state, 7, 0x8);
2504                dib8000_write_word(state, 8, 0x1000);
2505
2506                /* set lock_mask wait time values */
2507                if (state->revision == 0x8090)
2508                        dib8000_wait_lock(state, internal, 50, 100, 1000); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2509                else
2510                        dib8000_wait_lock(state, internal, 50, 200, 1000); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2511
2512                dib8000_write_word(state, 355, 3); /* P_search_param_max = 3 */
2513
2514                /* P_search_param_select = 0xf; look for the 4 different guard intervals */
2515                dib8000_write_word(state, 356, 0);
2516                dib8000_write_word(state, 357, 0xf);
2517
2518                value = dib8000_read_word(state, 0);
2519                dib8000_write_word(state, 0, (u16)((1 << 15) | value));
2520                dib8000_read_word(state, 1284);  /* reset the INT. n_irq_pending */
2521                dib8000_write_word(state, 0, (u16)value);
2522        } else {
2523                c->inversion = 0;
2524                c->layer[0].modulation = QAM_64;
2525                c->layer[0].fec = FEC_2_3;
2526                c->layer[0].interleaving = 0;
2527                c->layer[0].segment_count = 13;
2528                if (!c->isdbt_sb_mode)
2529                        c->layer[0].segment_count = 13;
2530
2531                /* choose the right list, in sb, always do everything */
2532                if (c->isdbt_sb_mode) {
2533                        slist = 7;
2534                        dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));
2535                } else {
2536                        if (c->guard_interval == GUARD_INTERVAL_AUTO) {
2537                                if (c->transmission_mode == TRANSMISSION_MODE_AUTO) {
2538                                        c->transmission_mode = TRANSMISSION_MODE_8K;
2539                                        c->guard_interval = GUARD_INTERVAL_1_8;
2540                                        slist = 7;
2541                                        dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));  /* P_mode = 1 to have autosearch start ok with mode2 */
2542                                } else {
2543                                        c->guard_interval = GUARD_INTERVAL_1_8;
2544                                        slist = 3;
2545                                }
2546                        } else {
2547                                if (c->transmission_mode == TRANSMISSION_MODE_AUTO) {
2548                                        c->transmission_mode = TRANSMISSION_MODE_8K;
2549                                        slist = 2;
2550                                        dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));  /* P_mode = 1 */
2551                                } else
2552                                        slist = 0;
2553                        }
2554                }
2555                dprintk("Using list for autosearch : %d", slist);
2556
2557                dib8000_set_isdbt_common_channel(state, slist, 1);
2558
2559                /* set lock_mask values */
2560                dib8000_write_word(state, 6, 0x4);
2561                if (state->revision == 0x8090)
2562                        dib8000_write_word(state, 7, (1 << 12) | (1 << 11) | (1 << 10));
2563                else
2564                        dib8000_write_word(state, 7, 0x8);
2565                dib8000_write_word(state, 8, 0x1000);
2566
2567                /* set lock_mask wait time values */
2568                if (state->revision == 0x8090)
2569                        dib8000_wait_lock(state, internal, 50, 200, 1000); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2570                else
2571                        dib8000_wait_lock(state, internal, 50, 100, 1000); /* time in ms configure P_search_end0 P_search_end1 P_search_end2 */
2572
2573                value = dib8000_read_word(state, 0);
2574                dib8000_write_word(state, 0, (u16)((1 << 15) | value));
2575                dib8000_read_word(state, 1284);  /* reset the INT. n_irq_pending */
2576                dib8000_write_word(state, 0, (u16)value);
2577        }
2578        return 0;
2579}
2580
2581static int dib8000_autosearch_irq(struct dvb_frontend *fe)
2582{
2583        struct dib8000_state *state = fe->demodulator_priv;
2584        u16 irq_pending = dib8000_read_word(state, 1284);
2585
2586        if (state->autosearch_state == AS_SEARCHING_FFT) {
2587                if (irq_pending & 0x1) {
2588                        dprintk("dib8000_autosearch_irq: max correlation result available");
2589                        return 3;
2590                }
2591        } else {
2592                if (irq_pending & 0x1) {        /* failed */
2593                        dprintk("dib8000_autosearch_irq failed");
2594                        return 1;
2595                }
2596
2597                if (irq_pending & 0x2) {        /* succeeded */
2598                        dprintk("dib8000_autosearch_irq succeeded");
2599                        return 2;
2600                }
2601        }
2602
2603        return 0;               // still pending
2604}
2605
2606static void dib8000_viterbi_state(struct dib8000_state *state, u8 onoff)
2607{
2608        u16 tmp;
2609
2610        tmp = dib8000_read_word(state, 771);
2611        if (onoff) /* start P_restart_chd : channel_decoder */
2612                dib8000_write_word(state, 771, tmp & 0xfffd);
2613        else /* stop P_restart_chd : channel_decoder */
2614                dib8000_write_word(state, 771, tmp | (1<<1));
2615}
2616
2617static void dib8000_set_dds(struct dib8000_state *state, s32 offset_khz)
2618{
2619        s16 unit_khz_dds_val;
2620        u32 abs_offset_khz = ABS(offset_khz);
2621        u32 dds = state->cfg.pll->ifreq & 0x1ffffff;
2622        u8 invert = !!(state->cfg.pll->ifreq & (1 << 25));
2623        u8 ratio;
2624
2625        if (state->revision == 0x8090) {
2626                ratio = 4;
2627                unit_khz_dds_val = (1<<26) / (dib8000_read32(state, 23) / 1000);
2628                if (offset_khz < 0)
2629                        dds = (1 << 26) - (abs_offset_khz * unit_khz_dds_val);
2630                else
2631                        dds = (abs_offset_khz * unit_khz_dds_val);
2632
2633                if (invert)
2634                        dds = (1<<26) - dds;
2635        } else {
2636                ratio = 2;
2637                unit_khz_dds_val = (u16) (67108864 / state->cfg.pll->internal);
2638
2639                if (offset_khz < 0)
2640                        unit_khz_dds_val *= -1;
2641
2642                /* IF tuner */
2643                if (invert)
2644                        dds -= abs_offset_khz * unit_khz_dds_val;
2645                else
2646                        dds += abs_offset_khz * unit_khz_dds_val;
2647        }
2648
2649        dprintk("setting a DDS frequency offset of %c%dkHz", invert ? '-' : ' ', dds / unit_khz_dds_val);
2650
2651        if (abs_offset_khz <= (state->cfg.pll->internal / ratio)) {
2652                /* Max dds offset is the half of the demod freq */
2653                dib8000_write_word(state, 26, invert);
2654                dib8000_write_word(state, 27, (u16)(dds >> 16) & 0x1ff);
2655                dib8000_write_word(state, 28, (u16)(dds & 0xffff));
2656        }
2657}
2658
2659static void dib8000_set_frequency_offset(struct dib8000_state *state)
2660{
2661        struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2662        int i;
2663        u32 current_rf;
2664        int total_dds_offset_khz;
2665
2666        if (state->fe[0]->ops.tuner_ops.get_frequency)
2667                state->fe[0]->ops.tuner_ops.get_frequency(state->fe[0], &current_rf);
2668        else
2669                current_rf = c->frequency;
2670        current_rf /= 1000;
2671        total_dds_offset_khz = (int)current_rf - (int)c->frequency / 1000;
2672
2673        if (c->isdbt_sb_mode) {
2674                state->subchannel = c->isdbt_sb_subchannel;
2675
2676                i = dib8000_read_word(state, 26) & 1; /* P_dds_invspec */
2677                dib8000_write_word(state, 26, c->inversion ^ i);
2678
2679                if (state->cfg.pll->ifreq == 0) { /* low if tuner */
2680                        if ((c->inversion ^ i) == 0)
2681                                dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
2682                } else {
2683                        if ((c->inversion ^ i) == 0)
2684                                total_dds_offset_khz *= -1;
2685                }
2686        }
2687
2688        dprintk("%dkhz tuner offset (frequency = %dHz & current_rf = %dHz) total_dds_offset_hz = %d", c->frequency - current_rf, c->frequency, current_rf, total_dds_offset_khz);
2689
2690        /* apply dds offset now */
2691        dib8000_set_dds(state, total_dds_offset_khz);
2692}
2693
2694static u16 LUT_isdbt_symbol_duration[4] = { 26, 101, 63 };
2695
2696static u32 dib8000_get_symbol_duration(struct dib8000_state *state)
2697{
2698        struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2699        u16 i;
2700
2701        switch (c->transmission_mode) {
2702        case TRANSMISSION_MODE_2K:
2703                        i = 0;
2704                        break;
2705        case TRANSMISSION_MODE_4K:
2706                        i = 2;
2707                        break;
2708        default:
2709        case TRANSMISSION_MODE_AUTO:
2710        case TRANSMISSION_MODE_8K:
2711                        i = 1;
2712                        break;
2713        }
2714
2715        return (LUT_isdbt_symbol_duration[i] / (c->bandwidth_hz / 1000)) + 1;
2716}
2717
2718static void dib8000_set_isdbt_loop_params(struct dib8000_state *state, enum param_loop_step loop_step)
2719{
2720        struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2721        u16 reg_32 = 0, reg_37 = 0;
2722
2723        switch (loop_step) {
2724        case LOOP_TUNE_1:
2725                        if (c->isdbt_sb_mode)  {
2726                                if (c->isdbt_partial_reception == 0) {
2727                                        reg_32 = ((11 - state->mode) << 12) | (6 << 8) | 0x40; /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x40 */
2728                                        reg_37 = (3 << 5) | (0 << 4) | (10 - state->mode); /* P_ctrl_pha_off_max=3   P_ctrl_sfreq_inh =0  P_ctrl_sfreq_step = (10-P_mode)  */
2729                                } else { /* Sound Broadcasting mode 3 seg */
2730                                        reg_32 = ((10 - state->mode) << 12) | (6 << 8) | 0x60; /* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x60 */
2731                                        reg_37 = (3 << 5) | (0 << 4) | (9 - state->mode); /* P_ctrl_pha_off_max=3   P_ctrl_sfreq_inh =0  P_ctrl_sfreq_step = (9-P_mode)  */
2732                                }
2733                        } else { /* 13-seg start conf offset loop parameters */
2734                                reg_32 = ((9 - state->mode) << 12) | (6 << 8) | 0x80; /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
2735                                reg_37 = (3 << 5) | (0 << 4) | (8 - state->mode); /* P_ctrl_pha_off_max=3   P_ctrl_sfreq_inh =0  P_ctrl_sfreq_step = 9  */
2736                        }
2737                        break;
2738        case LOOP_TUNE_2:
2739                        if (c->isdbt_sb_mode)  {
2740                                if (c->isdbt_partial_reception == 0) {  /* Sound Broadcasting mode 1 seg */
2741                                        reg_32 = ((13-state->mode) << 12) | (6 << 8) | 0x40; /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40*/
2742                                        reg_37 = (12-state->mode) | ((5 + state->mode) << 5);
2743                                } else {  /* Sound Broadcasting mode 3 seg */
2744                                        reg_32 = ((12-state->mode) << 12) | (6 << 8) | 0x60; /* P_timf_alpha = (12-P_mode) , P_corm_alpha=6, P_corm_thres=0x60 */
2745                                        reg_37 = (11-state->mode) | ((5 + state->mode) << 5);
2746                                }
2747                        } else {  /* 13 seg */
2748                                reg_32 = ((11-state->mode) << 12) | (6 << 8) | 0x80; /* P_timf_alpha = 8 , P_corm_alpha=6, P_corm_thres=0x80 */
2749                                reg_37 = ((5+state->mode) << 5) | (10 - state->mode);
2750                        }
2751                        break;
2752        }
2753        dib8000_write_word(state, 32, reg_32);
2754        dib8000_write_word(state, 37, reg_37);
2755}
2756
2757static void dib8000_demod_restart(struct dib8000_state *state)
2758{
2759        dib8000_write_word(state, 770, 0x4000);
2760        dib8000_write_word(state, 770, 0x0000);
2761        return;
2762}
2763
2764static void dib8000_set_sync_wait(struct dib8000_state *state)
2765{
2766        struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2767        u16 sync_wait = 64;
2768
2769        /* P_dvsy_sync_wait - reuse mode */
2770        switch (c->transmission_mode) {
2771        case TRANSMISSION_MODE_8K:
2772                        sync_wait = 256;
2773                        break;
2774        case TRANSMISSION_MODE_4K:
2775                        sync_wait = 128;
2776                        break;
2777        default:
2778        case TRANSMISSION_MODE_2K:
2779                        sync_wait =  64;
2780                        break;
2781        }
2782
2783        if (state->cfg.diversity_delay == 0)
2784                sync_wait = (sync_wait * (1 << (c->guard_interval)) * 3) / 2 + 48; /* add 50% SFN margin + compensate for one DVSY-fifo */
2785        else
2786                sync_wait = (sync_wait * (1 << (c->guard_interval)) * 3) / 2 + state->cfg.diversity_delay; /* add 50% SFN margin + compensate for DVSY-fifo */
2787
2788        dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | (sync_wait << 4));
2789}
2790
2791static u32 dib8000_get_timeout(struct dib8000_state *state, u32 delay, enum timeout_mode mode)
2792{
2793        if (mode == SYMBOL_DEPENDENT_ON)
2794                return systime() + (delay * state->symbol_duration);
2795        else
2796                return systime() + delay;
2797}
2798
2799static s32 dib8000_get_status(struct dvb_frontend *fe)
2800{
2801        struct dib8000_state *state = fe->demodulator_priv;
2802        return state->status;
2803}
2804
2805enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
2806{
2807        struct dib8000_state *state = fe->demodulator_priv;
2808        return state->tune_state;
2809}
2810EXPORT_SYMBOL(dib8000_get_tune_state);
2811
2812int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
2813{
2814        struct dib8000_state *state = fe->demodulator_priv;
2815
2816        state->tune_state = tune_state;
2817        return 0;
2818}
2819EXPORT_SYMBOL(dib8000_set_tune_state);
2820
2821static int dib8000_tune_restart_from_demod(struct dvb_frontend *fe)
2822{
2823        struct dib8000_state *state = fe->demodulator_priv;
2824
2825        state->status = FE_STATUS_TUNE_PENDING;
2826        state->tune_state = CT_DEMOD_START;
2827        return 0;
2828}
2829
2830static u16 dib8000_read_lock(struct dvb_frontend *fe)
2831{
2832        struct dib8000_state *state = fe->demodulator_priv;
2833
2834        if (state->revision == 0x8090)
2835                return dib8000_read_word(state, 570);
2836        return dib8000_read_word(state, 568);
2837}
2838
2839static int dib8090p_init_sdram(struct dib8000_state *state)
2840{
2841        u16 reg = 0;
2842        dprintk("init sdram");
2843
2844        reg = dib8000_read_word(state, 274) & 0xfff0;
2845        dib8000_write_word(state, 274, reg | 0x7); /* P_dintlv_delay_ram = 7 because of MobileSdram */
2846
2847        dib8000_write_word(state, 1803, (7 << 2));
2848
2849        reg = dib8000_read_word(state, 1280);
2850        dib8000_write_word(state, 1280,  reg | (1 << 2)); /* force restart P_restart_sdram */
2851        dib8000_write_word(state, 1280,  reg); /* release restart P_restart_sdram */
2852
2853        return 0;
2854}
2855
2856static int dib8000_tune(struct dvb_frontend *fe)
2857{
2858        struct dib8000_state *state = fe->demodulator_priv;
2859        struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
2860        enum frontend_tune_state *tune_state = &state->tune_state;
2861
2862        u16 locks, deeper_interleaver = 0, i;
2863        int ret = 1; /* 1 symbol duration (in 100us unit) delay most of the time */
2864
2865        u32 *timeout = &state->timeout;
2866        u32 now = systime();
2867#ifdef DIB8000_AGC_FREEZE
2868        u16 agc1, agc2;
2869#endif
2870
2871        u32 corm[4] = {0, 0, 0, 0};
2872        u8 find_index, max_value;
2873
2874#if 0
2875        if (*tune_state < CT_DEMOD_STOP)
2876                dprintk("IN: context status = %d, TUNE_STATE %d autosearch step = %u systime = %u", state->channel_parameters_set, *tune_state, state->autosearch_state, now);
2877#endif
2878
2879        switch (*tune_state) {
2880        case CT_DEMOD_START: /* 30 */
2881                        if (state->revision == 0x8090)
2882                                dib8090p_init_sdram(state);
2883                        state->status = FE_STATUS_TUNE_PENDING;
2884                        if ((c->delivery_system != SYS_ISDBT) ||
2885                                        (c->inversion == INVERSION_AUTO) ||
2886                                        (c->transmission_mode == TRANSMISSION_MODE_AUTO) ||
2887                                        (c->guard_interval == GUARD_INTERVAL_AUTO) ||
2888                                        (((c->isdbt_layer_enabled & (1 << 0)) != 0) &&
2889                                         (c->layer[0].segment_count != 0xff) &&
2890                                         (c->layer[0].segment_count != 0) &&
2891                                         ((c->layer[0].modulation == QAM_AUTO) ||
2892                                          (c->layer[0].fec == FEC_AUTO))) ||
2893                                        (((c->isdbt_layer_enabled & (1 << 1)) != 0) &&
2894                                         (c->layer[1].segment_count != 0xff) &&
2895                                         (c->layer[1].segment_count != 0) &&
2896                                         ((c->layer[1].modulation == QAM_AUTO) ||
2897                                          (c->layer[1].fec == FEC_AUTO))) ||
2898                                        (((c->isdbt_layer_enabled & (1 << 2)) != 0) &&
2899                                         (c->layer[2].segment_count != 0xff) &&
2900                                         (c->layer[2].segment_count != 0) &&
2901                                         ((c->layer[2].modulation == QAM_AUTO) ||
2902                                          (c->layer[2].fec == FEC_AUTO))) ||
2903                                        (((c->layer[0].segment_count == 0) ||
2904                                          ((c->isdbt_layer_enabled & (1 << 0)) == 0)) &&
2905                                         ((c->layer[1].segment_count == 0) ||
2906                                          ((c->isdbt_layer_enabled & (2 << 0)) == 0)) &&
2907                                         ((c->layer[2].segment_count == 0) || ((c->isdbt_layer_enabled & (3 << 0)) == 0))))
2908                                state->channel_parameters_set = 0; /* auto search */
2909                        else
2910                                state->channel_parameters_set = 1; /* channel parameters are known */
2911
2912                        dib8000_viterbi_state(state, 0); /* force chan dec in restart */
2913
2914                        /* Layer monit */
2915                        dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
2916
2917                        dib8000_set_frequency_offset(state);
2918                        dib8000_set_bandwidth(fe, c->bandwidth_hz / 1000);
2919
2920                        if (state->channel_parameters_set == 0) { /* The channel struct is unknown, search it ! */
2921#ifdef DIB8000_AGC_FREEZE
2922                                if (state->revision != 0x8090) {
2923                                        state->agc1_max = dib8000_read_word(state, 108);
2924                                        state->agc1_min = dib8000_read_word(state, 109);
2925                                        state->agc2_max = dib8000_read_word(state, 110);
2926                                        state->agc2_min = dib8000_read_word(state, 111);
2927                                        agc1 = dib8000_read_word(state, 388);
2928                                        agc2 = dib8000_read_word(state, 389);
2929                                        dib8000_write_word(state, 108, agc1);
2930                                        dib8000_write_word(state, 109, agc1);
2931                                        dib8000_write_word(state, 110, agc2);
2932                                        dib8000_write_word(state, 111, agc2);
2933                                }
2934#endif
2935                                state->autosearch_state = AS_SEARCHING_FFT;
2936                                state->found_nfft = TRANSMISSION_MODE_AUTO;
2937                                state->found_guard = GUARD_INTERVAL_AUTO;
2938                                *tune_state = CT_DEMOD_SEARCH_NEXT;
2939                        } else { /* we already know the channel struct so TUNE only ! */
2940                                state->autosearch_state = AS_DONE;
2941                                *tune_state = CT_DEMOD_STEP_3;
2942                        }
2943                        state->symbol_duration = dib8000_get_symbol_duration(state);
2944                        break;
2945
2946        case CT_DEMOD_SEARCH_NEXT: /* 51 */
2947                        dib8000_autosearch_start(fe);
2948                        if (state->revision == 0x8090)
2949                                ret = 50;
2950                        else
2951                                ret = 15;
2952                        *tune_state = CT_DEMOD_STEP_1;
2953                        break;
2954
2955        case CT_DEMOD_STEP_1: /* 31 */
2956                        switch (dib8000_autosearch_irq(fe)) {
2957                        case 1: /* fail */
2958                                        state->status = FE_STATUS_TUNE_FAILED;
2959                                        state->autosearch_state = AS_DONE;
2960                                        *tune_state = CT_DEMOD_STOP; /* else we are done here */
2961                                        break;
2962                        case 2: /* Succes */
2963                                        state->status = FE_STATUS_FFT_SUCCESS; /* signal to the upper layer, that there was a channel found and the parameters can be read */
2964                                        *tune_state = CT_DEMOD_STEP_3;
2965                                        if (state->autosearch_state == AS_SEARCHING_GUARD)
2966                                                *tune_state = CT_DEMOD_STEP_2;
2967                                        else
2968                                                state->autosearch_state = AS_DONE;
2969                                        break;
2970                        case 3: /* Autosearch FFT max correlation endded */
2971                                        *tune_state = CT_DEMOD_STEP_2;
2972                                        break;
2973                        }
2974                        break;
2975
2976        case CT_DEMOD_STEP_2:
2977                        switch (state->autosearch_state) {
2978                        case AS_SEARCHING_FFT:
2979                                        /* searching for the correct FFT */
2980                                if (state->revision == 0x8090) {
2981                                        corm[2] = (dib8000_read_word(state, 596) << 16) | (dib8000_read_word(state, 597));
2982                                        corm[1] = (dib8000_read_word(state, 598) << 16) | (dib8000_read_word(state, 599));
2983                                        corm[0] = (dib8000_read_word(state, 600) << 16) | (dib8000_read_word(state, 601));
2984                                } else {
2985                                        corm[2] = (dib8000_read_word(state, 594) << 16) | (dib8000_read_word(state, 595));
2986                                        corm[1] = (dib8000_read_word(state, 596) << 16) | (dib8000_read_word(state, 597));
2987                                        corm[0] = (dib8000_read_word(state, 598) << 16) | (dib8000_read_word(state, 599));
2988                                }
2989                                        /* dprintk("corm fft: %u %u %u", corm[0], corm[1], corm[2]); */
2990
2991                                        max_value = 0;
2992                                        for (find_index = 1 ; find_index < 3 ; find_index++) {
2993                                                if (corm[max_value] < corm[find_index])
2994                                                        max_value = find_index ;
2995                                        }
2996
2997                                        switch (max_value) {
2998                                        case 0:
2999                                                        state->found_nfft = TRANSMISSION_MODE_2K;
3000                                                        break;
3001                                        case 1:
3002                                                        state->found_nfft = TRANSMISSION_MODE_4K;
3003                                                        break;
3004                                        case 2:
3005                                        default:
3006                                                        state->found_nfft = TRANSMISSION_MODE_8K;
3007                                                        break;
3008                                        }
3009                                        /* dprintk("Autosearch FFT has found Mode %d", max_value + 1); */
3010
3011                                        *tune_state = CT_DEMOD_SEARCH_NEXT;
3012                                        state->autosearch_state = AS_SEARCHING_GUARD;
3013                                        if (state->revision == 0x8090)
3014                                                ret = 50;
3015                                        else
3016                                                ret = 10;
3017                                        break;
3018                        case AS_SEARCHING_GUARD:
3019                                        /* searching for the correct guard interval */
3020                                        if (state->revision == 0x8090)
3021                                                state->found_guard = dib8000_read_word(state, 572) & 0x3;
3022                                        else
3023                                                state->found_guard = dib8000_read_word(state, 570) & 0x3;
3024                                        /* dprintk("guard interval found=%i", state->found_guard); */
3025
3026                                        *tune_state = CT_DEMOD_STEP_3;
3027                                        break;
3028                        default:
3029                                        /* the demod should never be in this state */
3030                                        state->status = FE_STATUS_TUNE_FAILED;
3031                                        state->autosearch_state = AS_DONE;
3032                                        *tune_state = CT_DEMOD_STOP; /* else we are done here */
3033                                        break;
3034                        }
3035                        break;
3036
3037        case CT_DEMOD_STEP_3: /* 33 */
3038                        state->symbol_duration = dib8000_get_symbol_duration(state);
3039                        dib8000_set_isdbt_loop_params(state, LOOP_TUNE_1);
3040                        dib8000_set_isdbt_common_channel(state, 0, 0);/* setting the known channel parameters here */
3041                        *tune_state = CT_DEMOD_STEP_4;
3042                        break;
3043
3044        case CT_DEMOD_STEP_4: /* (34) */
3045                        dib8000_demod_restart(state);
3046
3047                        dib8000_set_sync_wait(state);
3048                        dib8000_set_diversity_in(state->fe[0], state->diversity_onoff);
3049
3050                        locks = (dib8000_read_word(state, 180) >> 6) & 0x3f; /* P_coff_winlen ? */
3051                        /* coff should lock over P_coff_winlen ofdm symbols : give 3 times this lenght to lock */
3052                        *timeout = dib8000_get_timeout(state, 2 * locks, SYMBOL_DEPENDENT_ON);
3053                        *tune_state = CT_DEMOD_STEP_5;
3054                        break;
3055
3056        case CT_DEMOD_STEP_5: /* (35) */
3057                        locks = dib8000_read_lock(fe);
3058                        if (locks & (0x3 << 11)) { /* coff-lock and off_cpil_lock achieved */
3059                                dib8000_update_timf(state); /* we achieved a coff_cpil_lock - it's time to update the timf */
3060                                if (!state->differential_constellation) {
3061                                        /* 2 times lmod4_win_len + 10 symbols (pipe delay after coff + nb to compute a 1st correlation) */
3062                                        *timeout = dib8000_get_timeout(state, (20 * ((dib8000_read_word(state, 188)>>5)&0x1f)), SYMBOL_DEPENDENT_ON);
3063                                        *tune_state = CT_DEMOD_STEP_7;
3064                                } else {
3065                                        *tune_state = CT_DEMOD_STEP_8;
3066                                }
3067                        } else if (now > *timeout) {
3068                                *tune_state = CT_DEMOD_STEP_6; /* goto check for diversity input connection */
3069                        }
3070                        break;
3071
3072        case CT_DEMOD_STEP_6: /* (36)  if there is an input (diversity) */
3073                        if ((state->fe[1] != NULL) && (state->output_mode != OUTMODE_DIVERSITY)) {
3074                                /* if there is a diversity fe in input and this fe is has not already failled : wait here until this this fe has succedeed or failled */
3075                                if (dib8000_get_status(state->fe[1]) <= FE_STATUS_STD_SUCCESS) /* Something is locked on the input fe */
3076                                        *tune_state = CT_DEMOD_STEP_8; /* go for mpeg */
3077                                else if (dib8000_get_status(state->fe[1]) >= FE_STATUS_TUNE_TIME_TOO_SHORT) { /* fe in input failled also, break the current one */
3078                                        *tune_state = CT_DEMOD_STOP; /* else we are done here ; step 8 will close the loops and exit */
3079                                        dib8000_viterbi_state(state, 1); /* start viterbi chandec */
3080                                        dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2);
3081                                        state->status = FE_STATUS_TUNE_FAILED;
3082                                }
3083                        } else {
3084                                dib8000_viterbi_state(state, 1); /* start viterbi chandec */
3085                                dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2);
3086                                *tune_state = CT_DEMOD_STOP; /* else we are done here ; step 8 will close the loops and exit */
3087                                state->status = FE_STATUS_TUNE_FAILED;
3088                        }
3089                        break;
3090
3091        case CT_DEMOD_STEP_7: /* 37 */
3092                        locks = dib8000_read_lock(fe);
3093                        if (locks & (1<<10)) { /* lmod4_lock */
3094                                ret = 14; /* wait for 14 symbols */
3095                                *tune_state = CT_DEMOD_STEP_8;
3096                        } else if (now > *timeout)
3097                                *tune_state = CT_DEMOD_STEP_6; /* goto check for diversity input connection */
3098                        break;
3099
3100        case CT_DEMOD_STEP_8: /* 38 */
3101                        dib8000_viterbi_state(state, 1); /* start viterbi chandec */
3102                        dib8000_set_isdbt_loop_params(state, LOOP_TUNE_2);
3103
3104                        /* mpeg will never lock on this condition because init_prbs is not set : search for it !*/
3105                        if (c->isdbt_sb_mode
3106                            && c->isdbt_sb_subchannel < 14
3107                            && !state->differential_constellation) {
3108                                state->subchannel = 0;
3109                                *tune_state = CT_DEMOD_STEP_11;
3110                        } else {
3111                                *tune_state = CT_DEMOD_STEP_9;
3112                                state->status = FE_STATUS_LOCKED;
3113                        }
3114                        break;
3115
3116        case CT_DEMOD_STEP_9: /* 39 */
3117                        if ((state->revision == 0x8090) || ((dib8000_read_word(state, 1291) >> 9) & 0x1)) { /* fe capable of deinterleaving : esram */
3118                                /* defines timeout for mpeg lock depending on interleaver lenght of longest layer */
3119                                for (i = 0; i < 3; i++) {
3120                                        if (c->layer[i].interleaving >= deeper_interleaver) {
3121                                                dprintk("layer%i: time interleaver = %d ", i, c->layer[i].interleaving);
3122                                                if (c->layer[i].segment_count > 0) { /* valid layer */
3123                                                        deeper_interleaver = c->layer[0].interleaving;
3124                                                        state->longest_intlv_layer = i;
3125                                                }
3126                                        }
3127                                }
3128
3129                                if (deeper_interleaver == 0)
3130                                        locks = 2; /* locks is the tmp local variable name */
3131                                else if (deeper_interleaver == 3)
3132                                        locks = 8;
3133                                else
3134                                        locks = 2 * deeper_interleaver;
3135
3136                                if (state->diversity_onoff != 0) /* because of diversity sync */
3137                                        locks *= 2;
3138
3139                                *timeout = now + (2000 * locks); /* give the mpeg lock 800ms if sram is present */
3140                                dprintk("Deeper interleaver mode = %d on layer %d : timeout mult factor = %d => will use timeout = %d", deeper_interleaver, state->longest_intlv_layer, locks, *timeout);
3141
3142                                *tune_state = CT_DEMOD_STEP_10;
3143                        } else
3144                                *tune_state = CT_DEMOD_STOP;
3145                        break;
3146
3147        case CT_DEMOD_STEP_10: /* 40 */
3148                        locks = dib8000_read_lock(fe);
3149                        if (locks&(1<<(7-state->longest_intlv_layer))) { /* mpeg lock : check the longest one */
3150                                dprintk("Mpeg locks [ L0 : %d | L1 : %d | L2 : %d ]", (locks>>7)&0x1, (locks>>6)&0x1, (locks>>5)&0x1);
3151                                if (c->isdbt_sb_mode
3152                                    && c->isdbt_sb_subchannel < 14
3153                                    && !state->differential_constellation)
3154                                        /* signal to the upper layer, that there was a channel found and the parameters can be read */
3155                                        state->status = FE_STATUS_DEMOD_SUCCESS;
3156                                else
3157                                        state->status = FE_STATUS_DATA_LOCKED;
3158                                *tune_state = CT_DEMOD_STOP;
3159                        } else if (now > *timeout) {
3160                                if (c->isdbt_sb_mode
3161                                    && c->isdbt_sb_subchannel < 14
3162                                    && !state->differential_constellation) { /* continue to try init prbs autosearch */
3163                                        state->subchannel += 3;
3164                                        *tune_state = CT_DEMOD_STEP_11;
3165                                } else { /* we are done mpeg of the longest interleaver xas not locking but let's try if an other layer has locked in the same time */
3166                                        if (locks & (0x7<<5)) {
3167                                                dprintk("Mpeg locks [ L0 : %d | L1 : %d | L2 : %d ]", (locks>>7)&0x1, (locks>>6)&0x1, (locks>>5)&0x1);
3168                                                state->status = FE_STATUS_DATA_LOCKED;
3169                                        } else
3170                                                state->status = FE_STATUS_TUNE_FAILED;
3171                                        *tune_state = CT_DEMOD_STOP;
3172                                }
3173                        }
3174                        break;
3175
3176        case CT_DEMOD_STEP_11:  /* 41 : init prbs autosearch */
3177                        if (state->subchannel <= 41) {
3178                                dib8000_set_subchannel_prbs(state, dib8000_get_init_prbs(state, state->subchannel));
3179                                *tune_state = CT_DEMOD_STEP_9;
3180                        } else {
3181                                *tune_state = CT_DEMOD_STOP;
3182                                state->status = FE_STATUS_TUNE_FAILED;
3183                        }
3184                        break;
3185
3186        default:
3187                        break;
3188        }
3189
3190        /* tuning is finished - cleanup the demod */
3191        switch (*tune_state) {
3192        case CT_DEMOD_STOP: /* (42) */
3193#ifdef DIB8000_AGC_FREEZE
3194                        if ((state->revision != 0x8090) && (state->agc1_max != 0)) {
3195                                dib8000_write_word(state, 108, state->agc1_max);
3196                                dib8000_write_word(state, 109, state->agc1_min);
3197                                dib8000_write_word(state, 110, state->agc2_max);
3198                                dib8000_write_word(state, 111, state->agc2_min);
3199                                state->agc1_max = 0;
3200                                state->agc1_min = 0;
3201                                state->agc2_max = 0;
3202                                state->agc2_min = 0;
3203                        }
3204#endif
3205                        ret = FE_CALLBACK_TIME_NEVER;
3206                        break;
3207        default:
3208                        break;
3209        }
3210
3211        if ((ret > 0) && (*tune_state > CT_DEMOD_STEP_3))
3212                return ret * state->symbol_duration;
3213        if ((ret > 0) && (ret < state->symbol_duration))
3214                return state->symbol_duration; /* at least one symbol */
3215        return ret;
3216}
3217
3218static int dib8000_wakeup(struct dvb_frontend *fe)
3219{
3220        struct dib8000_state *state = fe->demodulator_priv;
3221        u8 index_frontend;
3222        int ret;
3223
3224        dib8000_set_power_mode(state, DIB8000_POWER_ALL);
3225        dib8000_set_adc_state(state, DIBX000_ADC_ON);
3226        if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
3227                dprintk("could not start Slow ADC");
3228
3229        if (state->revision == 0x8090)
3230                dib8000_sad_calib(state);
3231
3232        for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3233                ret = state->fe[index_frontend]->ops.init(state->fe[index_frontend]);
3234                if (ret < 0)
3235                        return ret;
3236        }
3237
3238        return 0;
3239}
3240
3241static int dib8000_sleep(struct dvb_frontend *fe)
3242{
3243        struct dib8000_state *state = fe->demodulator_priv;
3244        u8 index_frontend;
3245        int ret;
3246
3247        for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3248                ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
3249                if (ret < 0)
3250                        return ret;
3251        }
3252
3253        if (state->revision != 0x8090)
3254                dib8000_set_output_mode(fe, OUTMODE_HIGH_Z);
3255        dib8000_set_power_mode(state, DIB8000_POWER_INTERFACE_ONLY);
3256        return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF);
3257}
3258
3259static int dib8000_get_frontend(struct dvb_frontend *fe)
3260{
3261        struct dib8000_state *state = fe->demodulator_priv;
3262        u16 i, val = 0;
3263        fe_status_t stat;
3264        u8 index_frontend, sub_index_frontend;
3265
3266        fe->dtv_property_cache.bandwidth_hz = 6000000;
3267
3268        for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3269                state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
3270                if (stat&FE_HAS_SYNC) {
3271                        dprintk("TMCC lock on the slave%i", index_frontend);
3272                        /* synchronize the cache with the other frontends */
3273                        state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend]);
3274                        for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL); sub_index_frontend++) {
3275                                if (sub_index_frontend != index_frontend) {
3276                                        state->fe[sub_index_frontend]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode;
3277                                        state->fe[sub_index_frontend]->dtv_property_cache.inversion = state->fe[index_frontend]->dtv_property_cache.inversion;
3278                                        state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode = state->fe[index_frontend]->dtv_property_cache.transmission_mode;
3279                                        state->fe[sub_index_frontend]->dtv_property_cache.guard_interval = state->fe[index_frontend]->dtv_property_cache.guard_interval;
3280                                        state->fe[sub_index_frontend]->dtv_property_cache.isdbt_partial_reception = state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception;
3281                                        for (i = 0; i < 3; i++) {
3282                                                state->fe[sub_index_frontend]->dtv_property_cache.layer[i].segment_count = state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count;
3283                                                state->fe[sub_index_frontend]->dtv_property_cache.layer[i].interleaving = state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving;
3284                                                state->fe[sub_index_frontend]->dtv_property_cache.layer[i].fec = state->fe[index_frontend]->dtv_property_cache.layer[i].fec;
3285                                                state->fe[sub_index_frontend]->dtv_property_cache.layer[i].modulation = state->fe[index_frontend]->dtv_property_cache.layer[i].modulation;
3286                                        }
3287                                }
3288                        }
3289                        return 0;
3290                }
3291        }
3292
3293        fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1;
3294
3295        if (state->revision == 0x8090)
3296                val = dib8000_read_word(state, 572);
3297        else
3298                val = dib8000_read_word(state, 570);
3299        fe->dtv_property_cache.inversion = (val & 0x40) >> 6;
3300        switch ((val & 0x30) >> 4) {
3301        case 1:
3302                fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
3303                break;
3304        case 3:
3305        default:
3306                fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
3307                break;
3308        }
3309
3310        switch (val & 0x3) {
3311        case 0:
3312                fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
3313                dprintk("dib8000_get_frontend GI = 1/32 ");
3314                break;
3315        case 1:
3316                fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
3317                dprintk("dib8000_get_frontend GI = 1/16 ");
3318                break;
3319        case 2:
3320                dprintk("dib8000_get_frontend GI = 1/8 ");
3321                fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
3322                break;
3323        case 3:
3324                dprintk("dib8000_get_frontend GI = 1/4 ");
3325                fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
3326                break;
3327        }
3328
3329        val = dib8000_read_word(state, 505);
3330        fe->dtv_property_cache.isdbt_partial_reception = val & 1;
3331        dprintk("dib8000_get_frontend : partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception);
3332
3333        for (i = 0; i < 3; i++) {
3334                val = dib8000_read_word(state, 493 + i);
3335                fe->dtv_property_cache.layer[i].segment_count = val & 0x0F;
3336                dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count);
3337
3338                val = dib8000_read_word(state, 499 + i);
3339                fe->dtv_property_cache.layer[i].interleaving = val & 0x3;
3340                dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ", i, fe->dtv_property_cache.layer[i].interleaving);
3341
3342                val = dib8000_read_word(state, 481 + i);
3343                switch (val & 0x7) {
3344                case 1:
3345                        fe->dtv_property_cache.layer[i].fec = FEC_1_2;
3346                        dprintk("dib8000_get_frontend : Layer %d Code Rate = 1/2 ", i);
3347                        break;
3348                case 2:
3349                        fe->dtv_property_cache.layer[i].fec = FEC_2_3;
3350                        dprintk("dib8000_get_frontend : Layer %d Code Rate = 2/3 ", i);
3351                        break;
3352                case 3:
3353                        fe->dtv_property_cache.layer[i].fec = FEC_3_4;
3354                        dprintk("dib8000_get_frontend : Layer %d Code Rate = 3/4 ", i);
3355                        break;
3356                case 5:
3357                        fe->dtv_property_cache.layer[i].fec = FEC_5_6;
3358                        dprintk("dib8000_get_frontend : Layer %d Code Rate = 5/6 ", i);
3359                        break;
3360                default:
3361                        fe->dtv_property_cache.layer[i].fec = FEC_7_8;
3362                        dprintk("dib8000_get_frontend : Layer %d Code Rate = 7/8 ", i);
3363                        break;
3364                }
3365
3366                val = dib8000_read_word(state, 487 + i);
3367                switch (val & 0x3) {
3368                case 0:
3369                        dprintk("dib8000_get_frontend : Layer %d DQPSK ", i);
3370                        fe->dtv_property_cache.layer[i].modulation = DQPSK;
3371                        break;
3372                case 1:
3373                        fe->dtv_property_cache.layer[i].modulation = QPSK;
3374                        dprintk("dib8000_get_frontend : Layer %d QPSK ", i);
3375                        break;
3376                case 2:
3377                        fe->dtv_property_cache.layer[i].modulation = QAM_16;
3378                        dprintk("dib8000_get_frontend : Layer %d QAM16 ", i);
3379                        break;
3380                case 3:
3381                default:
3382                        dprintk("dib8000_get_frontend : Layer %d QAM64 ", i);
3383                        fe->dtv_property_cache.layer[i].modulation = QAM_64;
3384                        break;
3385                }
3386        }
3387
3388        /* synchronize the cache with the other frontends */
3389        for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3390                state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode = fe->dtv_property_cache.isdbt_sb_mode;
3391                state->fe[index_frontend]->dtv_property_cache.inversion = fe->dtv_property_cache.inversion;
3392                state->fe[index_frontend]->dtv_property_cache.transmission_mode = fe->dtv_property_cache.transmission_mode;
3393                state->fe[index_frontend]->dtv_property_cache.guard_interval = fe->dtv_property_cache.guard_interval;
3394                state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception = fe->dtv_property_cache.isdbt_partial_reception;
3395                for (i = 0; i < 3; i++) {
3396                        state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count = fe->dtv_property_cache.layer[i].segment_count;
3397                        state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving = fe->dtv_property_cache.layer[i].interleaving;
3398                        state->fe[index_frontend]->dtv_property_cache.layer[i].fec = fe->dtv_property_cache.layer[i].fec;
3399                        state->fe[index_frontend]->dtv_property_cache.layer[i].modulation = fe->dtv_property_cache.layer[i].modulation;
3400                }
3401        }
3402        return 0;
3403}
3404
3405static int dib8000_set_frontend(struct dvb_frontend *fe)
3406{
3407        struct dib8000_state *state = fe->demodulator_priv;
3408        struct dtv_frontend_properties *c = &state->fe[0]->dtv_property_cache;
3409        int l, i, active, time, time_slave = FE_CALLBACK_TIME_NEVER;
3410        u8 exit_condition, index_frontend;
3411        u32 delay, callback_time;
3412
3413        if (c->frequency == 0) {
3414                dprintk("dib8000: must at least specify frequency ");
3415                return 0;
3416        }
3417
3418        if (c->bandwidth_hz == 0) {
3419                dprintk("dib8000: no bandwidth specified, set to default ");
3420                c->bandwidth_hz = 6000000;
3421        }
3422
3423        for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3424                /* synchronization of the cache */
3425                state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT;
3426                memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));
3427
3428                /* set output mode and diversity input */
3429                if (state->revision != 0x8090) {
3430                        dib8000_set_diversity_in(state->fe[index_frontend], 1);
3431                        if (index_frontend != 0)
3432                                dib8000_set_output_mode(state->fe[index_frontend],
3433                                                OUTMODE_DIVERSITY);
3434                        else
3435                                dib8000_set_output_mode(state->fe[0], OUTMODE_HIGH_Z);
3436                } else {
3437                        dib8096p_set_diversity_in(state->fe[index_frontend], 1);
3438                        if (index_frontend != 0)
3439                                dib8096p_set_output_mode(state->fe[index_frontend],
3440                                                OUTMODE_DIVERSITY);
3441                        else
3442                                dib8096p_set_output_mode(state->fe[0], OUTMODE_HIGH_Z);
3443                }
3444
3445                /* tune the tuner */
3446                if (state->fe[index_frontend]->ops.tuner_ops.set_params)
3447                        state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend]);
3448
3449                dib8000_set_tune_state(state->fe[index_frontend], CT_AGC_START);
3450        }
3451
3452        /* turn off the diversity of the last chip */
3453        if (state->revision != 0x8090)
3454                dib8000_set_diversity_in(state->fe[index_frontend - 1], 0);
3455        else
3456                dib8096p_set_diversity_in(state->fe[index_frontend - 1], 0);
3457
3458        /* start up the AGC */
3459        do {
3460                time = dib8000_agc_startup(state->fe[0]);
3461                for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3462                        time_slave = dib8000_agc_startup(state->fe[index_frontend]);
3463                        if (time == FE_CALLBACK_TIME_NEVER)
3464                                time = time_slave;
3465                        else if ((time_slave != FE_CALLBACK_TIME_NEVER) && (time_slave > time))
3466                                time = time_slave;
3467                }
3468                if (time != FE_CALLBACK_TIME_NEVER)
3469                        msleep(time / 10);
3470                else
3471                        break;
3472                exit_condition = 1;
3473                for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3474                        if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_AGC_STOP) {
3475                                exit_condition = 0;
3476                                break;
3477                        }
3478                }
3479        } while (exit_condition == 0);
3480
3481        for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
3482                dib8000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
3483
3484        active = 1;
3485        do {
3486                callback_time = FE_CALLBACK_TIME_NEVER;
3487                for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3488                        delay = dib8000_tune(state->fe[index_frontend]);
3489                        if (delay != FE_CALLBACK_TIME_NEVER)
3490                                delay += systime();
3491
3492                        /* we are in autosearch */
3493                        if (state->channel_parameters_set == 0) { /* searching */
3494                                if ((dib8000_get_status(state->fe[index_frontend]) == FE_STATUS_DEMOD_SUCCESS) || (dib8000_get_status(state->fe[index_frontend]) == FE_STATUS_FFT_SUCCESS)) {
3495                                        dprintk("autosearch succeeded on fe%i", index_frontend);
3496                                        dib8000_get_frontend(state->fe[index_frontend]); /* we read the channel parameters from the frontend which was successful */
3497                                        state->channel_parameters_set = 1;
3498
3499                                        for (l = 0; (l < MAX_NUMBER_OF_FRONTENDS) && (state->fe[l] != NULL); l++) {
3500                                                if (l != index_frontend) { /* and for all frontend except the successful one */
3501                                                        dib8000_tune_restart_from_demod(state->fe[l]);
3502
3503                                                        state->fe[l]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode;
3504                                                        state->fe[l]->dtv_property_cache.inversion = state->fe[index_frontend]->dtv_property_cache.inversion;
3505                                                        state->fe[l]->dtv_property_cache.transmission_mode = state->fe[index_frontend]->dtv_property_cache.transmission_mode;
3506                                                        state->fe[l]->dtv_property_cache.guard_interval = state->fe[index_frontend]->dtv_property_cache.guard_interval;
3507                                                        state->fe[l]->dtv_property_cache.isdbt_partial_reception = state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception;
3508                                                        for (i = 0; i < 3; i++) {
3509                                                                state->fe[l]->dtv_property_cache.layer[i].segment_count = state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count;
3510                                                                state->fe[l]->dtv_property_cache.layer[i].interleaving = state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving;
3511                                                                state->fe[l]->dtv_property_cache.layer[i].fec = state->fe[index_frontend]->dtv_property_cache.layer[i].fec;
3512                                                                state->fe[l]->dtv_property_cache.layer[i].modulation = state->fe[index_frontend]->dtv_property_cache.layer[i].modulation;
3513                                                        }
3514
3515                                                }
3516                                        }
3517                                }
3518                        }
3519                        if (delay < callback_time)
3520                                callback_time = delay;
3521                }
3522                /* tuning is done when the master frontend is done (failed or success) */
3523                if (dib8000_get_status(state->fe[0]) == FE_STATUS_TUNE_FAILED ||
3524                                dib8000_get_status(state->fe[0]) == FE_STATUS_LOCKED ||
3525                                dib8000_get_status(state->fe[0]) == FE_STATUS_DATA_LOCKED) {
3526                        active = 0;
3527                        /* we need to wait for all frontends to be finished */
3528                        for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3529                                if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_DEMOD_STOP)
3530                                        active = 1;
3531                        }
3532                        if (active == 0)
3533                                dprintk("tuning done with status %d", dib8000_get_status(state->fe[0]));
3534                }
3535
3536                if ((active == 1) && (callback_time == FE_CALLBACK_TIME_NEVER)) {
3537                        dprintk("strange callback time something went wrong");
3538                        active = 0;
3539                }
3540
3541                while ((active == 1) && (systime() < callback_time))
3542                        msleep(100);
3543        } while (active);
3544
3545        /* set output mode */
3546        if (state->revision != 0x8090)
3547                dib8000_set_output_mode(state->fe[0], state->cfg.output_mode);
3548        else {
3549                dib8096p_set_output_mode(state->fe[0], state->cfg.output_mode);
3550                if (state->cfg.enMpegOutput == 0) {
3551                        dib8096p_setDibTxMux(state, MPEG_ON_DIBTX);
3552                        dib8096p_setHostBusMux(state, DIBTX_ON_HOSTBUS);
3553                }
3554        }
3555
3556        return 0;
3557}
3558
3559static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
3560{
3561        struct dib8000_state *state = fe->demodulator_priv;
3562        u16 lock_slave = 0, lock;
3563        u8 index_frontend;
3564
3565        lock = dib8000_read_lock(fe);
3566        for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
3567                lock_slave |= dib8000_read_lock(state->fe[index_frontend]);
3568
3569        *stat = 0;
3570
3571        if (((lock >> 13) & 1) || ((lock_slave >> 13) & 1))
3572                *stat |= FE_HAS_SIGNAL;
3573
3574        if (((lock >> 8) & 1) || ((lock_slave >> 8) & 1)) /* Equal */
3575                *stat |= FE_HAS_CARRIER;
3576
3577        if ((((lock >> 1) & 0xf) == 0xf) || (((lock_slave >> 1) & 0xf) == 0xf)) /* TMCC_SYNC */
3578                *stat |= FE_HAS_SYNC;
3579
3580        if ((((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) && ((lock >> 5) & 7)) /* FEC MPEG */
3581                *stat |= FE_HAS_LOCK;
3582
3583        if (((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) {
3584                lock = dib8000_read_word(state, 554); /* Viterbi Layer A */
3585                if (lock & 0x01)
3586                        *stat |= FE_HAS_VITERBI;
3587
3588                lock = dib8000_read_word(state, 555); /* Viterbi Layer B */
3589                if (lock & 0x01)
3590                        *stat |= FE_HAS_VITERBI;
3591
3592                lock = dib8000_read_word(state, 556); /* Viterbi Layer C */
3593                if (lock & 0x01)
3594                        *stat |= FE_HAS_VITERBI;
3595        }
3596
3597        return 0;
3598}
3599
3600static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber)
3601{
3602        struct dib8000_state *state = fe->demodulator_priv;
3603
3604        /* 13 segments */
3605        if (state->revision == 0x8090)
3606                *ber = (dib8000_read_word(state, 562) << 16) |
3607                        dib8000_read_word(state, 563);
3608        else
3609                *ber = (dib8000_read_word(state, 560) << 16) |
3610                        dib8000_read_word(state, 561);
3611        return 0;
3612}
3613
3614static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
3615{
3616        struct dib8000_state *state = fe->demodulator_priv;
3617
3618        /* packet error on 13 seg */
3619        if (state->revision == 0x8090)
3620                *unc = dib8000_read_word(state, 567);
3621        else
3622                *unc = dib8000_read_word(state, 565);
3623        return 0;
3624}
3625
3626static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
3627{
3628        struct dib8000_state *state = fe->demodulator_priv;
3629        u8 index_frontend;
3630        u16 val;
3631
3632        *strength = 0;
3633        for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
3634                state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
3635                if (val > 65535 - *strength)
3636                        *strength = 65535;
3637                else
3638                        *strength += val;
3639        }
3640
3641        val = 65535 - dib8000_read_word(state, 390);
3642        if (val > 65535 - *strength)
3643                *strength = 65535;
3644        else
3645                *strength += val;
3646        return 0;
3647}
3648
3649static u32 dib8000_get_snr(struct dvb_frontend *fe)
3650{
3651        struct dib8000_state *state = fe->demodulator_priv;
3652        u32 n, s, exp;
3653        u16 val;
3654
3655        if (state->revision != 0x8090)
3656                val = dib8000_read_word(state, 542);
3657        else
3658                val = dib8000_read_word(state, 544);
3659        n = (val >> 6) & 0xff;
3660        exp = (val & 0x3f);
3661        if ((exp & 0x20) != 0)
3662                exp -= 0x40;
3663        n <<= exp+16;
3664
3665        if (state->revision != 0x8090)
3666                val = dib8000_read_word(state, 543);
3667        else
3668                val = dib8000_read_word(state, 545);
3669        s = (val >> 6) & 0xff;
3670        exp = (val & 0x3f);
3671        if ((exp & 0x20) != 0)
3672                exp -= 0x40;
3673        s <<= exp+16;
3674
3675        if (n > 0) {
3676                u32 t = (s/n) << 16;
3677                return t + ((s << 16) - n*t) / n;
3678        }
3679        return 0xffffffff;
3680}
3681
3682static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
3683{
3684        struct dib8000_state *state = fe->demodulator_priv;
3685        u8 index_frontend;
3686        u32 snr_master;
3687
3688        snr_master = dib8000_get_snr(fe);
3689        for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
3690                snr_master += dib8000_get_snr(state->fe[index_frontend]);
3691
3692        if ((snr_master >> 16) != 0) {
3693                snr_master = 10*intlog10(snr_master>>16);
3694                *snr = snr_master / ((1 << 24) / 10);
3695        }
3696        else
3697                *snr = 0;
3698
3699        return 0;
3700}
3701
3702int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
3703{
3704        struct dib8000_state *state = fe->demodulator_priv;
3705        u8 index_frontend = 1;
3706
3707        while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
3708                index_frontend++;
3709        if (index_frontend < MAX_NUMBER_OF_FRONTENDS) {
3710                dprintk("set slave fe %p to index %i", fe_slave, index_frontend);
3711                state->fe[index_frontend] = fe_slave;
3712                return 0;
3713        }
3714
3715        dprintk("too many slave frontend");
3716        return -ENOMEM;
3717}
3718EXPORT_SYMBOL(dib8000_set_slave_frontend);
3719
3720int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
3721{
3722        struct dib8000_state *state = fe->demodulator_priv;
3723        u8 index_frontend = 1;
3724
3725        while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
3726                index_frontend++;
3727        if (index_frontend != 1) {
3728                dprintk("remove slave fe %p (index %i)", state->fe[index_frontend-1], index_frontend-1);
3729                state->fe[index_frontend] = NULL;
3730                return 0;
3731        }
3732
3733        dprintk("no frontend to be removed");
3734        return -ENODEV;
3735}
3736EXPORT_SYMBOL(dib8000_remove_slave_frontend);
3737
3738struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
3739{
3740        struct dib8000_state *state = fe->demodulator_priv;
3741
3742        if (slave_index >= MAX_NUMBER_OF_FRONTENDS)
3743                return NULL;
3744        return state->fe[slave_index];
3745}
3746EXPORT_SYMBOL(dib8000_get_slave_frontend);
3747
3748
3749int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods,
3750                u8 default_addr, u8 first_addr, u8 is_dib8096p)
3751{
3752        int k = 0, ret = 0;
3753        u8 new_addr = 0;
3754        struct i2c_device client = {.adap = host };
3755
3756        client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
3757        if (!client.i2c_write_buffer) {
3758                dprintk("%s: not enough memory", __func__);
3759                return -ENOMEM;
3760        }
3761        client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
3762        if (!client.i2c_read_buffer) {
3763                dprintk("%s: not enough memory", __func__);
3764                ret = -ENOMEM;
3765                goto error_memory_read;
3766        }
3767        client.i2c_buffer_lock = kzalloc(sizeof(struct mutex), GFP_KERNEL);
3768        if (!client.i2c_buffer_lock) {
3769                dprintk("%s: not enough memory", __func__);
3770                ret = -ENOMEM;
3771                goto error_memory_lock;
3772        }
3773        mutex_init(client.i2c_buffer_lock);
3774
3775        for (k = no_of_demods - 1; k >= 0; k--) {
3776                /* designated i2c address */
3777                new_addr = first_addr + (k << 1);
3778
3779                client.addr = new_addr;
3780                if (!is_dib8096p)
3781                        dib8000_i2c_write16(&client, 1287, 0x0003);     /* sram lead in, rdy */
3782                if (dib8000_identify(&client) == 0) {
3783                        /* sram lead in, rdy */
3784                        if (!is_dib8096p)
3785                                dib8000_i2c_write16(&client, 1287, 0x0003);
3786                        client.addr = default_addr;
3787                        if (dib8000_identify(&client) == 0) {
3788                                dprintk("#%d: not identified", k);
3789                                ret  = -EINVAL;
3790                                goto error;
3791                        }
3792                }
3793
3794                /* start diversity to pull_down div_str - just for i2c-enumeration */
3795                dib8000_i2c_write16(&client, 1286, (1 << 10) | (4 << 6));
3796
3797                /* set new i2c address and force divstart */
3798                dib8000_i2c_write16(&client, 1285, (new_addr << 2) | 0x2);
3799                client.addr = new_addr;
3800                dib8000_identify(&client);
3801
3802                dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
3803        }
3804
3805        for (k = 0; k < no_of_demods; k++) {
3806                new_addr = first_addr | (k << 1);
3807                client.addr = new_addr;
3808
3809                // unforce divstr
3810                dib8000_i2c_write16(&client, 1285, new_addr << 2);
3811
3812                /* deactivate div - it was just for i2c-enumeration */
3813                dib8000_i2c_write16(&client, 1286, 0);
3814        }
3815
3816error:
3817        kfree(client.i2c_buffer_lock);
3818error_memory_lock:
3819        kfree(client.i2c_read_buffer);
3820error_memory_read:
3821        kfree(client.i2c_write_buffer);
3822
3823        return ret;
3824}
3825
3826EXPORT_SYMBOL(dib8000_i2c_enumeration);
3827static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
3828{
3829        tune->min_delay_ms = 1000;
3830        tune->step_size = 0;
3831        tune->max_drift = 0;
3832        return 0;
3833}
3834
3835static void dib8000_release(struct dvb_frontend *fe)
3836{
3837        struct dib8000_state *st = fe->demodulator_priv;
3838        u8 index_frontend;
3839
3840        for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++)
3841                dvb_frontend_detach(st->fe[index_frontend]);
3842
3843        dibx000_exit_i2c_master(&st->i2c_master);
3844        i2c_del_adapter(&st->dib8096p_tuner_adap);
3845        kfree(st->fe[0]);
3846        kfree(st);
3847}
3848
3849struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
3850{
3851        struct dib8000_state *st = fe->demodulator_priv;
3852        return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
3853}
3854
3855EXPORT_SYMBOL(dib8000_get_i2c_master);
3856
3857int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
3858{
3859        struct dib8000_state *st = fe->demodulator_priv;
3860        u16 val = dib8000_read_word(st, 299) & 0xffef;
3861        val |= (onoff & 0x1) << 4;
3862
3863        dprintk("pid filter enabled %d", onoff);
3864        return dib8000_write_word(st, 299, val);
3865}
3866EXPORT_SYMBOL(dib8000_pid_filter_ctrl);
3867
3868int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
3869{
3870        struct dib8000_state *st = fe->demodulator_priv;
3871        dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
3872        return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0);
3873}
3874EXPORT_SYMBOL(dib8000_pid_filter);
3875
3876static const struct dvb_frontend_ops dib8000_ops = {
3877        .delsys = { SYS_ISDBT },
3878        .info = {
3879                 .name = "DiBcom 8000 ISDB-T",
3880                 .frequency_min = 44250000,
3881                 .frequency_max = 867250000,
3882                 .frequency_stepsize = 62500,
3883                 .caps = FE_CAN_INVERSION_AUTO |
3884                 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
3885                 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
3886                 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
3887                 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
3888                 },
3889
3890        .release = dib8000_release,
3891
3892        .init = dib8000_wakeup,
3893        .sleep = dib8000_sleep,
3894
3895        .set_frontend = dib8000_set_frontend,
3896        .get_tune_settings = dib8000_fe_get_tune_settings,
3897        .get_frontend = dib8000_get_frontend,
3898
3899        .read_status = dib8000_read_status,
3900        .read_ber = dib8000_read_ber,
3901        .read_signal_strength = dib8000_read_signal_strength,
3902        .read_snr = dib8000_read_snr,
3903        .read_ucblocks = dib8000_read_unc_blocks,
3904};
3905
3906struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
3907{
3908        struct dvb_frontend *fe;
3909        struct dib8000_state *state;
3910
3911        dprintk("dib8000_attach");
3912
3913        state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL);
3914        if (state == NULL)
3915                return NULL;
3916        fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);
3917        if (fe == NULL)
3918                goto error;
3919
3920        memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
3921        state->i2c.adap = i2c_adap;
3922        state->i2c.addr = i2c_addr;
3923        state->i2c.i2c_write_buffer = state->i2c_write_buffer;
3924        state->i2c.i2c_read_buffer = state->i2c_read_buffer;
3925        mutex_init(&state->i2c_buffer_lock);
3926        state->i2c.i2c_buffer_lock = &state->i2c_buffer_lock;
3927        state->gpio_val = cfg->gpio_val;
3928        state->gpio_dir = cfg->gpio_dir;
3929
3930        /* Ensure the output mode remains at the previous default if it's
3931         * not specifically set by the caller.
3932         */
3933        if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
3934                state->cfg.output_mode = OUTMODE_MPEG2_FIFO;
3935
3936        state->fe[0] = fe;
3937        fe->demodulator_priv = state;
3938        memcpy(&state->fe[0]->ops, &dib8000_ops, sizeof(struct dvb_frontend_ops));
3939
3940        state->timf_default = cfg->pll->timf;
3941
3942        if (dib8000_identify(&state->i2c) == 0)
3943                goto error;
3944
3945        dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr);
3946
3947        /* init 8096p tuner adapter */
3948        strncpy(state->dib8096p_tuner_adap.name, "DiB8096P tuner interface",
3949                        sizeof(state->dib8096p_tuner_adap.name));
3950        state->dib8096p_tuner_adap.algo = &dib8096p_tuner_xfer_algo;
3951        state->dib8096p_tuner_adap.algo_data = NULL;
3952        state->dib8096p_tuner_adap.dev.parent = state->i2c.adap->dev.parent;
3953        i2c_set_adapdata(&state->dib8096p_tuner_adap, state);
3954        i2c_add_adapter(&state->dib8096p_tuner_adap);
3955
3956        dib8000_reset(fe);
3957
3958        dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5));     /* ber_rs_len = 3 */
3959        state->current_demod_bw = 6000;
3960
3961        return fe;
3962
3963error:
3964        kfree(state);
3965        return NULL;
3966}
3967
3968EXPORT_SYMBOL(dib8000_attach);
3969
3970MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@dibcom.fr, " "Patrick Boettcher <pboettcher@dibcom.fr>");
3971MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator");
3972MODULE_LICENSE("GPL");
3973