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/i2c.h>
  12#include "dvb_math.h"
  13
  14#include "dvb_frontend.h"
  15
  16#include "dib8000.h"
  17
  18#define LAYER_ALL -1
  19#define LAYER_A   1
  20#define LAYER_B   2
  21#define LAYER_C   3
  22
  23#define FE_CALLBACK_TIME_NEVER 0xffffffff
  24
  25static int debug;
  26module_param(debug, int, 0644);
  27MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
  28
  29#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0)
  30
  31enum frontend_tune_state {
  32        CT_AGC_START = 20,
  33        CT_AGC_STEP_0,
  34        CT_AGC_STEP_1,
  35        CT_AGC_STEP_2,
  36        CT_AGC_STEP_3,
  37        CT_AGC_STEP_4,
  38        CT_AGC_STOP,
  39
  40        CT_DEMOD_START = 30,
  41};
  42
  43#define FE_STATUS_TUNE_FAILED 0
  44
  45struct i2c_device {
  46        struct i2c_adapter *adap;
  47        u8 addr;
  48};
  49
  50struct dib8000_state {
  51        struct dvb_frontend fe;
  52        struct dib8000_config cfg;
  53
  54        struct i2c_device i2c;
  55
  56        struct dibx000_i2c_master i2c_master;
  57
  58        u16 wbd_ref;
  59
  60        u8 current_band;
  61        u32 current_bandwidth;
  62        struct dibx000_agc_config *current_agc;
  63        u32 timf;
  64        u32 timf_default;
  65
  66        u8 div_force_off:1;
  67        u8 div_state:1;
  68        u16 div_sync_wait;
  69
  70        u8 agc_state;
  71        u8 differential_constellation;
  72        u8 diversity_onoff;
  73
  74        s16 ber_monitored_layer;
  75        u16 gpio_dir;
  76        u16 gpio_val;
  77
  78        u16 revision;
  79        u8 isdbt_cfg_loaded;
  80        enum frontend_tune_state tune_state;
  81        u32 status;
  82};
  83
  84enum dib8000_power_mode {
  85        DIB8000M_POWER_ALL = 0,
  86        DIB8000M_POWER_INTERFACE_ONLY,
  87};
  88
  89static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
  90{
  91        u8 wb[2] = { reg >> 8, reg & 0xff };
  92        u8 rb[2];
  93        struct i2c_msg msg[2] = {
  94                {.addr = i2c->addr >> 1,.flags = 0,.buf = wb,.len = 2},
  95                {.addr = i2c->addr >> 1,.flags = I2C_M_RD,.buf = rb,.len = 2},
  96        };
  97
  98        if (i2c_transfer(i2c->adap, msg, 2) != 2)
  99                dprintk("i2c read error on %d", reg);
 100
 101        return (rb[0] << 8) | rb[1];
 102}
 103
 104static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
 105{
 106        return dib8000_i2c_read16(&state->i2c, reg);
 107}
 108
 109static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
 110{
 111        u16 rw[2];
 112
 113        rw[0] = dib8000_read_word(state, reg + 0);
 114        rw[1] = dib8000_read_word(state, reg + 1);
 115
 116        return ((rw[0] << 16) | (rw[1]));
 117}
 118
 119static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
 120{
 121        u8 b[4] = {
 122                (reg >> 8) & 0xff, reg & 0xff,
 123                (val >> 8) & 0xff, val & 0xff,
 124        };
 125        struct i2c_msg msg = {
 126                .addr = i2c->addr >> 1,.flags = 0,.buf = b,.len = 4
 127        };
 128        return i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
 129}
 130
 131static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
 132{
 133        return dib8000_i2c_write16(&state->i2c, reg, val);
 134}
 135
 136const int16_t coeff_2k_sb_1seg_dqpsk[8] = {
 137        (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
 138            (920 << 5) | 0x09
 139};
 140
 141const int16_t coeff_2k_sb_1seg[8] = {
 142        (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
 143};
 144
 145const int16_t coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
 146        (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
 147            (-931 << 5) | 0x0f
 148};
 149
 150const int16_t coeff_2k_sb_3seg_0dqpsk[8] = {
 151        (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
 152            (982 << 5) | 0x0c
 153};
 154
 155const int16_t coeff_2k_sb_3seg_1dqpsk[8] = {
 156        (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
 157            (-720 << 5) | 0x0d
 158};
 159
 160const int16_t coeff_2k_sb_3seg[8] = {
 161        (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
 162            (-610 << 5) | 0x0a
 163};
 164
 165const int16_t coeff_4k_sb_1seg_dqpsk[8] = {
 166        (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
 167            (-922 << 5) | 0x0d
 168};
 169
 170const int16_t coeff_4k_sb_1seg[8] = {
 171        (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
 172            (-655 << 5) | 0x0a
 173};
 174
 175const int16_t coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
 176        (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
 177            (-958 << 5) | 0x13
 178};
 179
 180const int16_t coeff_4k_sb_3seg_0dqpsk[8] = {
 181        (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
 182            (-568 << 5) | 0x0f
 183};
 184
 185const int16_t coeff_4k_sb_3seg_1dqpsk[8] = {
 186        (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
 187            (-848 << 5) | 0x13
 188};
 189
 190const int16_t coeff_4k_sb_3seg[8] = {
 191        (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
 192            (-869 << 5) | 0x13
 193};
 194
 195const int16_t coeff_8k_sb_1seg_dqpsk[8] = {
 196        (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
 197            (-598 << 5) | 0x10
 198};
 199
 200const int16_t coeff_8k_sb_1seg[8] = {
 201        (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
 202            (585 << 5) | 0x0f
 203};
 204
 205const int16_t coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
 206        (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
 207            (0 << 5) | 0x14
 208};
 209
 210const int16_t coeff_8k_sb_3seg_0dqpsk[8] = {
 211        (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
 212            (-877 << 5) | 0x15
 213};
 214
 215const int16_t coeff_8k_sb_3seg_1dqpsk[8] = {
 216        (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
 217            (-921 << 5) | 0x14
 218};
 219
 220const int16_t coeff_8k_sb_3seg[8] = {
 221        (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
 222            (690 << 5) | 0x14
 223};
 224
 225const int16_t ana_fe_coeff_3seg[24] = {
 226        81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
 227};
 228
 229const int16_t ana_fe_coeff_1seg[24] = {
 230        249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
 231};
 232
 233const int16_t ana_fe_coeff_13seg[24] = {
 234        396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
 235};
 236
 237static u16 fft_to_mode(struct dib8000_state *state)
 238{
 239        u16 mode;
 240        switch (state->fe.dtv_property_cache.transmission_mode) {
 241        case TRANSMISSION_MODE_2K:
 242                mode = 1;
 243                break;
 244        case TRANSMISSION_MODE_4K:
 245                mode = 2;
 246                break;
 247        default:
 248        case TRANSMISSION_MODE_AUTO:
 249        case TRANSMISSION_MODE_8K:
 250                mode = 3;
 251                break;
 252        }
 253        return mode;
 254}
 255
 256static void dib8000_set_acquisition_mode(struct dib8000_state *state)
 257{
 258        u16 nud = dib8000_read_word(state, 298);
 259        nud |= (1 << 3) | (1 << 0);
 260        dprintk("acquisition mode activated");
 261        dib8000_write_word(state, 298, nud);
 262}
 263
 264static int dib8000_set_output_mode(struct dib8000_state *state, int mode)
 265{
 266        u16 outreg, fifo_threshold, smo_mode, sram = 0x0205;    /* by default SDRAM deintlv is enabled */
 267
 268        outreg = 0;
 269        fifo_threshold = 1792;
 270        smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
 271
 272        dprintk("-I-  Setting output mode for demod %p to %d", &state->fe, mode);
 273
 274        switch (mode) {
 275        case OUTMODE_MPEG2_PAR_GATED_CLK:       // STBs with parallel gated clock
 276                outreg = (1 << 10);     /* 0x0400 */
 277                break;
 278        case OUTMODE_MPEG2_PAR_CONT_CLK:        // STBs with parallel continues clock
 279                outreg = (1 << 10) | (1 << 6);  /* 0x0440 */
 280                break;
 281        case OUTMODE_MPEG2_SERIAL:      // STBs with serial input
 282                outreg = (1 << 10) | (2 << 6) | (0 << 1);       /* 0x0482 */
 283                break;
 284        case OUTMODE_DIVERSITY:
 285                if (state->cfg.hostbus_diversity) {
 286                        outreg = (1 << 10) | (4 << 6);  /* 0x0500 */
 287                        sram &= 0xfdff;
 288                } else
 289                        sram |= 0x0c00;
 290                break;
 291        case OUTMODE_MPEG2_FIFO:        // e.g. USB feeding
 292                smo_mode |= (3 << 1);
 293                fifo_threshold = 512;
 294                outreg = (1 << 10) | (5 << 6);
 295                break;
 296        case OUTMODE_HIGH_Z:    // disable
 297                outreg = 0;
 298                break;
 299
 300        case OUTMODE_ANALOG_ADC:
 301                outreg = (1 << 10) | (3 << 6);
 302                dib8000_set_acquisition_mode(state);
 303                break;
 304
 305        default:
 306                dprintk("Unhandled output_mode passed to be set for demod %p", &state->fe);
 307                return -EINVAL;
 308        }
 309
 310        if (state->cfg.output_mpeg2_in_188_bytes)
 311                smo_mode |= (1 << 5);
 312
 313        dib8000_write_word(state, 299, smo_mode);
 314        dib8000_write_word(state, 300, fifo_threshold); /* synchronous fread */
 315        dib8000_write_word(state, 1286, outreg);
 316        dib8000_write_word(state, 1291, sram);
 317
 318        return 0;
 319}
 320
 321static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff)
 322{
 323        struct dib8000_state *state = fe->demodulator_priv;
 324        u16 sync_wait = dib8000_read_word(state, 273) & 0xfff0;
 325
 326        if (!state->differential_constellation) {
 327                dib8000_write_word(state, 272, 1 << 9); //dvsy_off_lmod4 = 1
 328                dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2);       // sync_enable = 1; comb_mode = 2
 329        } else {
 330                dib8000_write_word(state, 272, 0);      //dvsy_off_lmod4 = 0
 331                dib8000_write_word(state, 273, sync_wait);      // sync_enable = 0; comb_mode = 0
 332        }
 333        state->diversity_onoff = onoff;
 334
 335        switch (onoff) {
 336        case 0:         /* only use the internal way - not the diversity input */
 337                dib8000_write_word(state, 270, 1);
 338                dib8000_write_word(state, 271, 0);
 339                break;
 340        case 1:         /* both ways */
 341                dib8000_write_word(state, 270, 6);
 342                dib8000_write_word(state, 271, 6);
 343                break;
 344        case 2:         /* only the diversity input */
 345                dib8000_write_word(state, 270, 0);
 346                dib8000_write_word(state, 271, 1);
 347                break;
 348        }
 349        return 0;
 350}
 351
 352static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_power_mode mode)
 353{
 354        /* by default everything is going to be powered off */
 355        u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
 356            reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3, reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
 357
 358        /* now, depending on the requested mode, we power on */
 359        switch (mode) {
 360                /* power up everything in the demod */
 361        case DIB8000M_POWER_ALL:
 362                reg_774 = 0x0000;
 363                reg_775 = 0x0000;
 364                reg_776 = 0x0000;
 365                reg_900 &= 0xfffc;
 366                reg_1280 &= 0x00ff;
 367                break;
 368        case DIB8000M_POWER_INTERFACE_ONLY:
 369                reg_1280 &= 0x00ff;
 370                break;
 371        }
 372
 373        dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x", reg_774, reg_775, reg_776, reg_900, reg_1280);
 374        dib8000_write_word(state, 774, reg_774);
 375        dib8000_write_word(state, 775, reg_775);
 376        dib8000_write_word(state, 776, reg_776);
 377        dib8000_write_word(state, 900, reg_900);
 378        dib8000_write_word(state, 1280, reg_1280);
 379}
 380
 381static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no)
 382{
 383        int ret = 0;
 384        u16 reg_907 = dib8000_read_word(state, 907), reg_908 = dib8000_read_word(state, 908);
 385
 386        switch (no) {
 387        case DIBX000_SLOW_ADC_ON:
 388                reg_908 |= (1 << 1) | (1 << 0);
 389                ret |= dib8000_write_word(state, 908, reg_908);
 390                reg_908 &= ~(1 << 1);
 391                break;
 392
 393        case DIBX000_SLOW_ADC_OFF:
 394                reg_908 |= (1 << 1) | (1 << 0);
 395                break;
 396
 397        case DIBX000_ADC_ON:
 398                reg_907 &= 0x0fff;
 399                reg_908 &= 0x0003;
 400                break;
 401
 402        case DIBX000_ADC_OFF:   // leave the VBG voltage on
 403                reg_907 |= (1 << 14) | (1 << 13) | (1 << 12);
 404                reg_908 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
 405                break;
 406
 407        case DIBX000_VBG_ENABLE:
 408                reg_907 &= ~(1 << 15);
 409                break;
 410
 411        case DIBX000_VBG_DISABLE:
 412                reg_907 |= (1 << 15);
 413                break;
 414
 415        default:
 416                break;
 417        }
 418
 419        ret |= dib8000_write_word(state, 907, reg_907);
 420        ret |= dib8000_write_word(state, 908, reg_908);
 421
 422        return ret;
 423}
 424
 425static int dib8000_set_bandwidth(struct dib8000_state *state, u32 bw)
 426{
 427        u32 timf;
 428
 429        if (bw == 0)
 430                bw = 6000;
 431
 432        if (state->timf == 0) {
 433                dprintk("using default timf");
 434                timf = state->timf_default;
 435        } else {
 436                dprintk("using updated timf");
 437                timf = state->timf;
 438        }
 439
 440        dib8000_write_word(state, 29, (u16) ((timf >> 16) & 0xffff));
 441        dib8000_write_word(state, 30, (u16) ((timf) & 0xffff));
 442
 443        return 0;
 444}
 445
 446static int dib8000_sad_calib(struct dib8000_state *state)
 447{
 448/* internal */
 449        dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
 450        dib8000_write_word(state, 924, 776);    // 0.625*3.3 / 4096
 451
 452        /* do the calibration */
 453        dib8000_write_word(state, 923, (1 << 0));
 454        dib8000_write_word(state, 923, (0 << 0));
 455
 456        msleep(1);
 457        return 0;
 458}
 459
 460int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
 461{
 462        struct dib8000_state *state = fe->demodulator_priv;
 463        if (value > 4095)
 464                value = 4095;
 465        state->wbd_ref = value;
 466        return dib8000_write_word(state, 106, value);
 467}
 468
 469EXPORT_SYMBOL(dib8000_set_wbd_ref);
 470static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
 471{
 472        dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25);
 473        dib8000_write_word(state, 23, (u16) (((bw->internal * 1000) >> 16) & 0xffff));  /* P_sec_len */
 474        dib8000_write_word(state, 24, (u16) ((bw->internal * 1000) & 0xffff));
 475        dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff));
 476        dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff));
 477        dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003));
 478
 479        dib8000_write_word(state, 922, bw->sad_cfg);
 480}
 481
 482static void dib8000_reset_pll(struct dib8000_state *state)
 483{
 484        const struct dibx000_bandwidth_config *pll = state->cfg.pll;
 485        u16 clk_cfg1;
 486
 487        // clk_cfg0
 488        dib8000_write_word(state, 901, (pll->pll_prediv << 8) | (pll->pll_ratio << 0));
 489
 490        // clk_cfg1
 491        clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
 492            (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) | (pll->pll_range << 1) | (pll->pll_reset << 0);
 493
 494        dib8000_write_word(state, 902, clk_cfg1);
 495        clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
 496        dib8000_write_word(state, 902, clk_cfg1);
 497
 498        dprintk("clk_cfg1: 0x%04x", clk_cfg1);  /* 0x507 1 0 1 000 0 0 11 1 */
 499
 500        /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
 501        if (state->cfg.pll->ADClkSrc == 0)
 502                dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
 503        else if (state->cfg.refclksel != 0)
 504                dib8000_write_word(state, 904,
 505                                   (0 << 15) | (1 << 12) | ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) | (pll->
 506                                                                                                                        ADClkSrc << 7) | (0 << 1));
 507        else
 508                dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
 509
 510        dib8000_reset_pll_common(state, pll);
 511}
 512
 513static int dib8000_reset_gpio(struct dib8000_state *st)
 514{
 515        /* reset the GPIOs */
 516        dib8000_write_word(st, 1029, st->cfg.gpio_dir);
 517        dib8000_write_word(st, 1030, st->cfg.gpio_val);
 518
 519        /* TODO 782 is P_gpio_od */
 520
 521        dib8000_write_word(st, 1032, st->cfg.gpio_pwm_pos);
 522
 523        dib8000_write_word(st, 1037, st->cfg.pwm_freq_div);
 524        return 0;
 525}
 526
 527static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val)
 528{
 529        st->cfg.gpio_dir = dib8000_read_word(st, 1029);
 530        st->cfg.gpio_dir &= ~(1 << num);        /* reset the direction bit */
 531        st->cfg.gpio_dir |= (dir & 0x1) << num; /* set the new direction */
 532        dib8000_write_word(st, 1029, st->cfg.gpio_dir);
 533
 534        st->cfg.gpio_val = dib8000_read_word(st, 1030);
 535        st->cfg.gpio_val &= ~(1 << num);        /* reset the direction bit */
 536        st->cfg.gpio_val |= (val & 0x01) << num;        /* set the new value */
 537        dib8000_write_word(st, 1030, st->cfg.gpio_val);
 538
 539        dprintk("gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val);
 540
 541        return 0;
 542}
 543
 544int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
 545{
 546        struct dib8000_state *state = fe->demodulator_priv;
 547        return dib8000_cfg_gpio(state, num, dir, val);
 548}
 549
 550EXPORT_SYMBOL(dib8000_set_gpio);
 551static const u16 dib8000_defaults[] = {
 552        /* auto search configuration - lock0 by default waiting
 553         * for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */
 554        3, 7,
 555        0x0004,
 556        0x0400,
 557        0x0814,
 558
 559        12, 11,
 560        0x001b,
 561        0x7740,
 562        0x005b,
 563        0x8d80,
 564        0x01c9,
 565        0xc380,
 566        0x0000,
 567        0x0080,
 568        0x0000,
 569        0x0090,
 570        0x0001,
 571        0xd4c0,
 572
 573        /*1, 32,
 574           0x6680 // P_corm_thres Lock algorithms configuration */
 575
 576        11, 80,                 /* set ADC level to -16 */
 577        (1 << 13) - 825 - 117,
 578        (1 << 13) - 837 - 117,
 579        (1 << 13) - 811 - 117,
 580        (1 << 13) - 766 - 117,
 581        (1 << 13) - 737 - 117,
 582        (1 << 13) - 693 - 117,
 583        (1 << 13) - 648 - 117,
 584        (1 << 13) - 619 - 117,
 585        (1 << 13) - 575 - 117,
 586        (1 << 13) - 531 - 117,
 587        (1 << 13) - 501 - 117,
 588
 589        4, 108,
 590        0,
 591        0,
 592        0,
 593        0,
 594
 595        1, 175,
 596        0x0410,
 597        1, 179,
 598        8192,                   // P_fft_nb_to_cut
 599
 600        6, 181,
 601        0x2800,                 // P_coff_corthres_ ( 2k 4k 8k ) 0x2800
 602        0x2800,
 603        0x2800,
 604        0x2800,                 // P_coff_cpilthres_ ( 2k 4k 8k ) 0x2800
 605        0x2800,
 606        0x2800,
 607
 608        2, 193,
 609        0x0666,                 // P_pha3_thres
 610        0x0000,                 // P_cti_use_cpe, P_cti_use_prog
 611
 612        2, 205,
 613        0x200f,                 // P_cspu_regul, P_cspu_win_cut
 614        0x000f,                 // P_des_shift_work
 615
 616        5, 215,
 617        0x023d,                 // P_adp_regul_cnt
 618        0x00a4,                 // P_adp_noise_cnt
 619        0x00a4,                 // P_adp_regul_ext
 620        0x7ff0,                 // P_adp_noise_ext
 621        0x3ccc,                 // P_adp_fil
 622
 623        1, 230,
 624        0x0000,                 // P_2d_byp_ti_num
 625
 626        1, 263,
 627        0x800,                  //P_equal_thres_wgn
 628
 629        1, 268,
 630        (2 << 9) | 39,          // P_equal_ctrl_synchro, P_equal_speedmode
 631
 632        1, 270,
 633        0x0001,                 // P_div_lock0_wait
 634        1, 285,
 635        0x0020,                 //p_fec_
 636        1, 299,
 637        0x0062,                 // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
 638
 639        1, 338,
 640        (1 << 12) |             // P_ctrl_corm_thres4pre_freq_inh=1
 641            (1 << 10) |         // P_ctrl_pre_freq_mode_sat=1
 642            (0 << 9) |          // P_ctrl_pre_freq_inh=0
 643            (3 << 5) |          // P_ctrl_pre_freq_step=3
 644            (1 << 0),           // P_pre_freq_win_len=1
 645
 646        1, 903,
 647        (0 << 4) | 2,           // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW)
 648
 649        0,
 650};
 651
 652static u16 dib8000_identify(struct i2c_device *client)
 653{
 654        u16 value;
 655
 656        //because of glitches sometimes
 657        value = dib8000_i2c_read16(client, 896);
 658
 659        if ((value = dib8000_i2c_read16(client, 896)) != 0x01b3) {
 660                dprintk("wrong Vendor ID (read=0x%x)", value);
 661                return 0;
 662        }
 663
 664        value = dib8000_i2c_read16(client, 897);
 665        if (value != 0x8000 && value != 0x8001 && value != 0x8002) {
 666                dprintk("wrong Device ID (%x)", value);
 667                return 0;
 668        }
 669
 670        switch (value) {
 671        case 0x8000:
 672                dprintk("found DiB8000A");
 673                break;
 674        case 0x8001:
 675                dprintk("found DiB8000B");
 676                break;
 677        case 0x8002:
 678                dprintk("found DiB8000C");
 679                break;
 680        }
 681        return value;
 682}
 683
 684static int dib8000_reset(struct dvb_frontend *fe)
 685{
 686        struct dib8000_state *state = fe->demodulator_priv;
 687
 688        dib8000_write_word(state, 1287, 0x0003);        /* sram lead in, rdy */
 689
 690        if ((state->revision = dib8000_identify(&state->i2c)) == 0)
 691                return -EINVAL;
 692
 693        if (state->revision == 0x8000)
 694                dprintk("error : dib8000 MA not supported");
 695
 696        dibx000_reset_i2c_master(&state->i2c_master);
 697
 698        dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
 699
 700        /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
 701        dib8000_set_adc_state(state, DIBX000_VBG_ENABLE);
 702
 703        /* restart all parts */
 704        dib8000_write_word(state, 770, 0xffff);
 705        dib8000_write_word(state, 771, 0xffff);
 706        dib8000_write_word(state, 772, 0xfffc);
 707        dib8000_write_word(state, 898, 0x000c); // sad
 708        dib8000_write_word(state, 1280, 0x004d);
 709        dib8000_write_word(state, 1281, 0x000c);
 710
 711        dib8000_write_word(state, 770, 0x0000);
 712        dib8000_write_word(state, 771, 0x0000);
 713        dib8000_write_word(state, 772, 0x0000);
 714        dib8000_write_word(state, 898, 0x0004); // sad
 715        dib8000_write_word(state, 1280, 0x0000);
 716        dib8000_write_word(state, 1281, 0x0000);
 717
 718        /* drives */
 719        if (state->cfg.drives)
 720                dib8000_write_word(state, 906, state->cfg.drives);
 721        else {
 722                dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.");
 723                dib8000_write_word(state, 906, 0x2d98); // min drive SDRAM - not optimal - adjust
 724        }
 725
 726        dib8000_reset_pll(state);
 727
 728        if (dib8000_reset_gpio(state) != 0)
 729                dprintk("GPIO reset was not successful.");
 730
 731        if (dib8000_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
 732                dprintk("OUTPUT_MODE could not be resetted.");
 733
 734        state->current_agc = NULL;
 735
 736        // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
 737        /* P_iqc_ca2 = 0; P_iqc_impnc_on = 0; P_iqc_mode = 0; */
 738        if (state->cfg.pll->ifreq == 0)
 739                dib8000_write_word(state, 40, 0x0755);  /* P_iqc_corr_inh = 0 enable IQcorr block */
 740        else
 741                dib8000_write_word(state, 40, 0x1f55);  /* P_iqc_corr_inh = 1 disable IQcorr block */
 742
 743        {
 744                u16 l = 0, r;
 745                const u16 *n;
 746                n = dib8000_defaults;
 747                l = *n++;
 748                while (l) {
 749                        r = *n++;
 750                        do {
 751                                dib8000_write_word(state, r, *n++);
 752                                r++;
 753                        } while (--l);
 754                        l = *n++;
 755                }
 756        }
 757        state->isdbt_cfg_loaded = 0;
 758
 759        //div_cfg override for special configs
 760        if (state->cfg.div_cfg != 0)
 761                dib8000_write_word(state, 903, state->cfg.div_cfg);
 762
 763        /* unforce divstr regardless whether i2c enumeration was done or not */
 764        dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1));
 765
 766        dib8000_set_bandwidth(state, 6000);
 767
 768        dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
 769        dib8000_sad_calib(state);
 770        dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
 771
 772        dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY);
 773
 774        return 0;
 775}
 776
 777static void dib8000_restart_agc(struct dib8000_state *state)
 778{
 779        // P_restart_iqc & P_restart_agc
 780        dib8000_write_word(state, 770, 0x0a00);
 781        dib8000_write_word(state, 770, 0x0000);
 782}
 783
 784static int dib8000_update_lna(struct dib8000_state *state)
 785{
 786        u16 dyn_gain;
 787
 788        if (state->cfg.update_lna) {
 789                // read dyn_gain here (because it is demod-dependent and not tuner)
 790                dyn_gain = dib8000_read_word(state, 390);
 791
 792                if (state->cfg.update_lna(&state->fe, dyn_gain)) {      // LNA has changed
 793                        dib8000_restart_agc(state);
 794                        return 1;
 795                }
 796        }
 797        return 0;
 798}
 799
 800static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
 801{
 802        struct dibx000_agc_config *agc = NULL;
 803        int i;
 804        if (state->current_band == band && state->current_agc != NULL)
 805                return 0;
 806        state->current_band = band;
 807
 808        for (i = 0; i < state->cfg.agc_config_count; i++)
 809                if (state->cfg.agc[i].band_caps & band) {
 810                        agc = &state->cfg.agc[i];
 811                        break;
 812                }
 813
 814        if (agc == NULL) {
 815                dprintk("no valid AGC configuration found for band 0x%02x", band);
 816                return -EINVAL;
 817        }
 818
 819        state->current_agc = agc;
 820
 821        /* AGC */
 822        dib8000_write_word(state, 76, agc->setup);
 823        dib8000_write_word(state, 77, agc->inv_gain);
 824        dib8000_write_word(state, 78, agc->time_stabiliz);
 825        dib8000_write_word(state, 101, (agc->alpha_level << 12) | agc->thlock);
 826
 827        // Demod AGC loop configuration
 828        dib8000_write_word(state, 102, (agc->alpha_mant << 5) | agc->alpha_exp);
 829        dib8000_write_word(state, 103, (agc->beta_mant << 6) | agc->beta_exp);
 830
 831        dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
 832                state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
 833
 834        /* AGC continued */
 835        if (state->wbd_ref != 0)
 836                dib8000_write_word(state, 106, state->wbd_ref);
 837        else                    // use default
 838                dib8000_write_word(state, 106, agc->wbd_ref);
 839        dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
 840        dib8000_write_word(state, 108, agc->agc1_max);
 841        dib8000_write_word(state, 109, agc->agc1_min);
 842        dib8000_write_word(state, 110, agc->agc2_max);
 843        dib8000_write_word(state, 111, agc->agc2_min);
 844        dib8000_write_word(state, 112, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
 845        dib8000_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
 846        dib8000_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
 847        dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
 848
 849        dib8000_write_word(state, 75, agc->agc1_pt3);
 850        dib8000_write_word(state, 923, (dib8000_read_word(state, 923) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2));   /*LB : 929 -> 923 */
 851
 852        return 0;
 853}
 854
 855static int dib8000_agc_soft_split(struct dib8000_state *state)
 856{
 857        u16 agc, split_offset;
 858
 859        if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
 860                return FE_CALLBACK_TIME_NEVER;
 861
 862        // n_agc_global
 863        agc = dib8000_read_word(state, 390);
 864
 865        if (agc > state->current_agc->split.min_thres)
 866                split_offset = state->current_agc->split.min;
 867        else if (agc < state->current_agc->split.max_thres)
 868                split_offset = state->current_agc->split.max;
 869        else
 870                split_offset = state->current_agc->split.max *
 871                    (agc - state->current_agc->split.min_thres) / (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
 872
 873        dprintk("AGC split_offset: %d", split_offset);
 874
 875        // P_agc_force_split and P_agc_split_offset
 876        dib8000_write_word(state, 107, (dib8000_read_word(state, 107) & 0xff00) | split_offset);
 877        return 5000;
 878}
 879
 880static int dib8000_agc_startup(struct dvb_frontend *fe)
 881{
 882        struct dib8000_state *state = fe->demodulator_priv;
 883        enum frontend_tune_state *tune_state = &state->tune_state;
 884
 885        int ret = 0;
 886
 887        switch (*tune_state) {
 888        case CT_AGC_START:
 889                // set power-up level: interf+analog+AGC
 890
 891                dib8000_set_adc_state(state, DIBX000_ADC_ON);
 892
 893                if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) {
 894                        *tune_state = CT_AGC_STOP;
 895                        state->status = FE_STATUS_TUNE_FAILED;
 896                        break;
 897                }
 898
 899                ret = 70;
 900                *tune_state = CT_AGC_STEP_0;
 901                break;
 902
 903        case CT_AGC_STEP_0:
 904                //AGC initialization
 905                if (state->cfg.agc_control)
 906                        state->cfg.agc_control(&state->fe, 1);
 907
 908                dib8000_restart_agc(state);
 909
 910                // wait AGC rough lock time
 911                ret = 50;
 912                *tune_state = CT_AGC_STEP_1;
 913                break;
 914
 915        case CT_AGC_STEP_1:
 916                // wait AGC accurate lock time
 917                ret = 70;
 918
 919                if (dib8000_update_lna(state))
 920                        // wait only AGC rough lock time
 921                        ret = 50;
 922                else
 923                        *tune_state = CT_AGC_STEP_2;
 924                break;
 925
 926        case CT_AGC_STEP_2:
 927                dib8000_agc_soft_split(state);
 928
 929                if (state->cfg.agc_control)
 930                        state->cfg.agc_control(&state->fe, 0);
 931
 932                *tune_state = CT_AGC_STOP;
 933                break;
 934        default:
 935                ret = dib8000_agc_soft_split(state);
 936                break;
 937        }
 938        return ret;
 939
 940}
 941
 942static void dib8000_update_timf(struct dib8000_state *state)
 943{
 944        u32 timf = state->timf = dib8000_read32(state, 435);
 945
 946        dib8000_write_word(state, 29, (u16) (timf >> 16));
 947        dib8000_write_word(state, 30, (u16) (timf & 0xffff));
 948        dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
 949}
 950
 951static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
 952{
 953        u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
 954        u8 guard, crate, constellation, timeI;
 955        u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
 956        u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff;        // All 13 segments enabled
 957        const s16 *ncoeff, *ana_fe;
 958        u16 tmcc_pow = 0;
 959        u16 coff_pow = 0x2800;
 960        u16 init_prbs = 0xfff;
 961        u16 ana_gain = 0;
 962        u16 adc_target_16dB[11] = {
 963                (1 << 13) - 825 - 117,
 964                (1 << 13) - 837 - 117,
 965                (1 << 13) - 811 - 117,
 966                (1 << 13) - 766 - 117,
 967                (1 << 13) - 737 - 117,
 968                (1 << 13) - 693 - 117,
 969                (1 << 13) - 648 - 117,
 970                (1 << 13) - 619 - 117,
 971                (1 << 13) - 575 - 117,
 972                (1 << 13) - 531 - 117,
 973                (1 << 13) - 501 - 117
 974        };
 975
 976        if (state->ber_monitored_layer != LAYER_ALL)
 977                dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
 978        else
 979                dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
 980
 981        i = dib8000_read_word(state, 26) & 1;   // P_dds_invspec
 982        dib8000_write_word(state, 26, state->fe.dtv_property_cache.inversion ^ i);
 983
 984        if (state->fe.dtv_property_cache.isdbt_sb_mode) {
 985                //compute new dds_freq for the seg and adjust prbs
 986                int seg_offset =
 987                    state->fe.dtv_property_cache.isdbt_sb_segment_idx - (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) -
 988                    (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2);
 989                int clk = state->cfg.pll->internal;
 990                u32 segtodds = ((u32) (430 << 23) / clk) << 3;  // segtodds = SegBW / Fclk * pow(2,26)
 991                int dds_offset = seg_offset * segtodds;
 992                int new_dds, sub_channel;
 993                if ((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0)     // if even
 994                        dds_offset -= (int)(segtodds / 2);
 995
 996                if (state->cfg.pll->ifreq == 0) {
 997                        if ((state->fe.dtv_property_cache.inversion ^ i) == 0) {
 998                                dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
 999                                new_dds = dds_offset;
1000                        } else
1001                                new_dds = dds_offset;
1002
1003                        // We shift tuning frequency if the wanted segment is :
1004                        //  - the segment of center frequency with an odd total number of segments
1005                        //  - the segment to the left of center frequency with an even total number of segments
1006                        //  - the segment to the right of center frequency with an even total number of segments
1007                        if ((state->fe.dtv_property_cache.delivery_system == SYS_ISDBT) && (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
1008                            &&
1009                            (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2)
1010                              && (state->fe.dtv_property_cache.isdbt_sb_segment_idx ==
1011                                  ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1012                             || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1013                                 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx == (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2)))
1014                             || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1015                                 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx ==
1016                                     ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1017                            )) {
1018                                new_dds -= ((u32) (850 << 22) / clk) << 4;      // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26)
1019                        }
1020                } else {
1021                        if ((state->fe.dtv_property_cache.inversion ^ i) == 0)
1022                                new_dds = state->cfg.pll->ifreq - dds_offset;
1023                        else
1024                                new_dds = state->cfg.pll->ifreq + dds_offset;
1025                }
1026                dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff));
1027                dib8000_write_word(state, 28, (u16) (new_dds & 0xffff));
1028                if (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2)    // if odd
1029                        sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3;
1030                else            // if even
1031                        sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3;
1032                sub_channel -= 6;
1033
1034                if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K
1035                    || state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) {
1036                        dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1);    //adp_pass =1
1037                        dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14));    //pha3_force_pha_shift = 1
1038                } else {
1039                        dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); //adp_pass =0
1040                        dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0
1041                }
1042
1043                switch (state->fe.dtv_property_cache.transmission_mode) {
1044                case TRANSMISSION_MODE_2K:
1045                        switch (sub_channel) {
1046                        case -6:
1047                                init_prbs = 0x0;
1048                                break;  // 41, 0, 1
1049                        case -5:
1050                                init_prbs = 0x423;
1051                                break;  // 02~04
1052                        case -4:
1053                                init_prbs = 0x9;
1054                                break;  // 05~07
1055                        case -3:
1056                                init_prbs = 0x5C7;
1057                                break;  // 08~10
1058                        case -2:
1059                                init_prbs = 0x7A6;
1060                                break;  // 11~13
1061                        case -1:
1062                                init_prbs = 0x3D8;
1063                                break;  // 14~16
1064                        case 0:
1065                                init_prbs = 0x527;
1066                                break;  // 17~19
1067                        case 1:
1068                                init_prbs = 0x7FF;
1069                                break;  // 20~22
1070                        case 2:
1071                                init_prbs = 0x79B;
1072                                break;  // 23~25
1073                        case 3:
1074                                init_prbs = 0x3D6;
1075                                break;  // 26~28
1076                        case 4:
1077                                init_prbs = 0x3A2;
1078                                break;  // 29~31
1079                        case 5:
1080                                init_prbs = 0x53B;
1081                                break;  // 32~34
1082                        case 6:
1083                                init_prbs = 0x2F4;
1084                                break;  // 35~37
1085                        default:
1086                        case 7:
1087                                init_prbs = 0x213;
1088                                break;  // 38~40
1089                        }
1090                        break;
1091
1092                case TRANSMISSION_MODE_4K:
1093                        switch (sub_channel) {
1094                        case -6:
1095                                init_prbs = 0x0;
1096                                break;  // 41, 0, 1
1097                        case -5:
1098                                init_prbs = 0x208;
1099                                break;  // 02~04
1100                        case -4:
1101                                init_prbs = 0xC3;
1102                                break;  // 05~07
1103                        case -3:
1104                                init_prbs = 0x7B9;
1105                                break;  // 08~10
1106                        case -2:
1107                                init_prbs = 0x423;
1108                                break;  // 11~13
1109                        case -1:
1110                                init_prbs = 0x5C7;
1111                                break;  // 14~16
1112                        case 0:
1113                                init_prbs = 0x3D8;
1114                                break;  // 17~19
1115                        case 1:
1116                                init_prbs = 0x7FF;
1117                                break;  // 20~22
1118                        case 2:
1119                                init_prbs = 0x3D6;
1120                                break;  // 23~25
1121                        case 3:
1122                                init_prbs = 0x53B;
1123                                break;  // 26~28
1124                        case 4:
1125                                init_prbs = 0x213;
1126                                break;  // 29~31
1127                        case 5:
1128                                init_prbs = 0x29;
1129                                break;  // 32~34
1130                        case 6:
1131                                init_prbs = 0xD0;
1132                                break;  // 35~37
1133                        default:
1134                        case 7:
1135                                init_prbs = 0x48E;
1136                                break;  // 38~40
1137                        }
1138                        break;
1139
1140                default:
1141                case TRANSMISSION_MODE_8K:
1142                        switch (sub_channel) {
1143                        case -6:
1144                                init_prbs = 0x0;
1145                                break;  // 41, 0, 1
1146                        case -5:
1147                                init_prbs = 0x740;
1148                                break;  // 02~04
1149                        case -4:
1150                                init_prbs = 0x069;
1151                                break;  // 05~07
1152                        case -3:
1153                                init_prbs = 0x7DD;
1154                                break;  // 08~10
1155                        case -2:
1156                                init_prbs = 0x208;
1157                                break;  // 11~13
1158                        case -1:
1159                                init_prbs = 0x7B9;
1160                                break;  // 14~16
1161                        case 0:
1162                                init_prbs = 0x5C7;
1163                                break;  // 17~19
1164                        case 1:
1165                                init_prbs = 0x7FF;
1166                                break;  // 20~22
1167                        case 2:
1168                                init_prbs = 0x53B;
1169                                break;  // 23~25
1170                        case 3:
1171                                init_prbs = 0x29;
1172                                break;  // 26~28
1173                        case 4:
1174                                init_prbs = 0x48E;
1175                                break;  // 29~31
1176                        case 5:
1177                                init_prbs = 0x4C4;
1178                                break;  // 32~34
1179                        case 6:
1180                                init_prbs = 0x367;
1181                                break;  // 33~37
1182                        default:
1183                        case 7:
1184                                init_prbs = 0x684;
1185                                break;  // 38~40
1186                        }
1187                        break;
1188                }
1189        } else {                // if not state->fe.dtv_property_cache.isdbt_sb_mode
1190                dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff));
1191                dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff));
1192                dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003));
1193        }
1194        /*P_mode == ?? */
1195        dib8000_write_word(state, 10, (seq << 4));
1196        //  dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000);
1197
1198        switch (state->fe.dtv_property_cache.guard_interval) {
1199        case GUARD_INTERVAL_1_32:
1200                guard = 0;
1201                break;
1202        case GUARD_INTERVAL_1_16:
1203                guard = 1;
1204                break;
1205        case GUARD_INTERVAL_1_8:
1206                guard = 2;
1207                break;
1208        case GUARD_INTERVAL_1_4:
1209        default:
1210                guard = 3;
1211                break;
1212        }
1213
1214        dib8000_write_word(state, 1, (init_prbs << 2) | (guard & 0x3)); // ADDR 1
1215
1216        max_constellation = DQPSK;
1217        for (i = 0; i < 3; i++) {
1218                switch (state->fe.dtv_property_cache.layer[i].modulation) {
1219                case DQPSK:
1220                        constellation = 0;
1221                        break;
1222                case QPSK:
1223                        constellation = 1;
1224                        break;
1225                case QAM_16:
1226                        constellation = 2;
1227                        break;
1228                case QAM_64:
1229                default:
1230                        constellation = 3;
1231                        break;
1232                }
1233
1234                switch (state->fe.dtv_property_cache.layer[i].fec) {
1235                case FEC_1_2:
1236                        crate = 1;
1237                        break;
1238                case FEC_2_3:
1239                        crate = 2;
1240                        break;
1241                case FEC_3_4:
1242                        crate = 3;
1243                        break;
1244                case FEC_5_6:
1245                        crate = 5;
1246                        break;
1247                case FEC_7_8:
1248                default:
1249                        crate = 7;
1250                        break;
1251                }
1252
1253                if ((state->fe.dtv_property_cache.layer[i].interleaving > 0) &&
1254                    ((state->fe.dtv_property_cache.layer[i].interleaving <= 3) ||
1255                     (state->fe.dtv_property_cache.layer[i].interleaving == 4 && state->fe.dtv_property_cache.isdbt_sb_mode == 1))
1256                    )
1257                        timeI = state->fe.dtv_property_cache.layer[i].interleaving;
1258                else
1259                        timeI = 0;
1260                dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe.dtv_property_cache.layer[i].segment_count & 0xf) << 6) |
1261                                   (crate << 3) | timeI);
1262                if (state->fe.dtv_property_cache.layer[i].segment_count > 0) {
1263                        switch (max_constellation) {
1264                        case DQPSK:
1265                        case QPSK:
1266                                if (state->fe.dtv_property_cache.layer[i].modulation == QAM_16 ||
1267                                    state->fe.dtv_property_cache.layer[i].modulation == QAM_64)
1268                                        max_constellation = state->fe.dtv_property_cache.layer[i].modulation;
1269                                break;
1270                        case QAM_16:
1271                                if (state->fe.dtv_property_cache.layer[i].modulation == QAM_64)
1272                                        max_constellation = state->fe.dtv_property_cache.layer[i].modulation;
1273                                break;
1274                        }
1275                }
1276        }
1277
1278        mode = fft_to_mode(state);
1279
1280        //dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/
1281
1282        dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) |
1283                           ((state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe.dtv_property_cache.
1284                                                                                                 isdbt_sb_mode & 1) << 4));
1285
1286        dprintk("mode = %d ; guard = %d", mode, state->fe.dtv_property_cache.guard_interval);
1287
1288        /* signal optimization parameter */
1289
1290        if (state->fe.dtv_property_cache.isdbt_partial_reception) {
1291                seg_diff_mask = (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0];
1292                for (i = 1; i < 3; i++)
1293                        nbseg_diff +=
1294                            (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count;
1295                for (i = 0; i < nbseg_diff; i++)
1296                        seg_diff_mask |= 1 << permu_seg[i + 1];
1297        } else {
1298                for (i = 0; i < 3; i++)
1299                        nbseg_diff +=
1300                            (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count;
1301                for (i = 0; i < nbseg_diff; i++)
1302                        seg_diff_mask |= 1 << permu_seg[i];
1303        }
1304        dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask);
1305
1306        state->differential_constellation = (seg_diff_mask != 0);
1307        dib8000_set_diversity_in(&state->fe, state->diversity_onoff);
1308
1309        if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {  // ISDB-Tsb
1310                if (state->fe.dtv_property_cache.isdbt_partial_reception == 1)  // 3-segments
1311                        seg_mask13 = 0x00E0;
1312                else            // 1-segment
1313                        seg_mask13 = 0x0040;
1314        } else
1315                seg_mask13 = 0x1fff;
1316
1317        // WRITE: Mode & Diff mask
1318        dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask);
1319
1320        if ((seg_diff_mask) || (state->fe.dtv_property_cache.isdbt_sb_mode))
1321                dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
1322        else
1323                dib8000_write_word(state, 268, (2 << 9) | 39);  //init value
1324
1325        // ---- SMALL ----
1326        // P_small_seg_diff
1327        dib8000_write_word(state, 352, seg_diff_mask);  // ADDR 352
1328
1329        dib8000_write_word(state, 353, seg_mask13);     // ADDR 353
1330
1331/*     // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */
1332        // dib8000_write_word(state, 351, (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5 );
1333
1334        // ---- SMALL ----
1335        if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1336                switch (state->fe.dtv_property_cache.transmission_mode) {
1337                case TRANSMISSION_MODE_2K:
1338                        if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) {        // 1-seg
1339                                if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK)  // DQPSK
1340                                        ncoeff = coeff_2k_sb_1seg_dqpsk;
1341                                else    // QPSK or QAM
1342                                        ncoeff = coeff_2k_sb_1seg;
1343                        } else {        // 3-segments
1344                                if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) {        // DQPSK on central segment
1345                                        if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK)  // DQPSK on external segments
1346                                                ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
1347                                        else    // QPSK or QAM on external segments
1348                                                ncoeff = coeff_2k_sb_3seg_0dqpsk;
1349                                } else {        // QPSK or QAM on central segment
1350                                        if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK)  // DQPSK on external segments
1351                                                ncoeff = coeff_2k_sb_3seg_1dqpsk;
1352                                        else    // QPSK or QAM on external segments
1353                                                ncoeff = coeff_2k_sb_3seg;
1354                                }
1355                        }
1356                        break;
1357
1358                case TRANSMISSION_MODE_4K:
1359                        if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) {        // 1-seg
1360                                if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK)  // DQPSK
1361                                        ncoeff = coeff_4k_sb_1seg_dqpsk;
1362                                else    // QPSK or QAM
1363                                        ncoeff = coeff_4k_sb_1seg;
1364                        } else {        // 3-segments
1365                                if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) {        // DQPSK on central segment
1366                                        if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) {        // DQPSK on external segments
1367                                                ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
1368                                        } else {        // QPSK or QAM on external segments
1369                                                ncoeff = coeff_4k_sb_3seg_0dqpsk;
1370                                        }
1371                                } else {        // QPSK or QAM on central segment
1372                                        if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) {        // DQPSK on external segments
1373                                                ncoeff = coeff_4k_sb_3seg_1dqpsk;
1374                                        } else  // QPSK or QAM on external segments
1375                                                ncoeff = coeff_4k_sb_3seg;
1376                                }
1377                        }
1378                        break;
1379
1380                case TRANSMISSION_MODE_AUTO:
1381                case TRANSMISSION_MODE_8K:
1382                default:
1383                        if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) {        // 1-seg
1384                                if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK)  // DQPSK
1385                                        ncoeff = coeff_8k_sb_1seg_dqpsk;
1386                                else    // QPSK or QAM
1387                                        ncoeff = coeff_8k_sb_1seg;
1388                        } else {        // 3-segments
1389                                if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) {        // DQPSK on central segment
1390                                        if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) {        // DQPSK on external segments
1391                                                ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
1392                                        } else {        // QPSK or QAM on external segments
1393                                                ncoeff = coeff_8k_sb_3seg_0dqpsk;
1394                                        }
1395                                } else {        // QPSK or QAM on central segment
1396                                        if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) {        // DQPSK on external segments
1397                                                ncoeff = coeff_8k_sb_3seg_1dqpsk;
1398                                        } else  // QPSK or QAM on external segments
1399                                                ncoeff = coeff_8k_sb_3seg;
1400                                }
1401                        }
1402                        break;
1403                }
1404        }
1405        if (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
1406                for (i = 0; i < 8; i++)
1407                        dib8000_write_word(state, 343 + i, ncoeff[i]);
1408
1409        // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5
1410        dib8000_write_word(state, 351,
1411                           (state->fe.dtv_property_cache.isdbt_sb_mode << 9) | (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5);
1412
1413        // ---- COFF ----
1414        // Carloff, the most robust
1415        if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {  // Sound Broadcasting mode - use both TMCC and AC pilots
1416
1417                // P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64
1418                // 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
1419                dib8000_write_word(state, 187,
1420                                   (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 2)
1421                                   | 0x3);
1422
1423/*             // P_small_coef_ext_enable = 1 */
1424/*             dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */
1425
1426                if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) {        // Sound Broadcasting mode 1 seg
1427
1428                        // 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)
1429                        if (mode == 3)
1430                                dib8000_write_word(state, 180, 0x1fcf | ((mode - 1) << 14));
1431                        else
1432                                dib8000_write_word(state, 180, 0x0fcf | ((mode - 1) << 14));
1433                        // P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1,
1434                        // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4
1435                        dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
1436                        // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
1437                        dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
1438                        // P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
1439                        dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1440
1441                        // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
1442                        dib8000_write_word(state, 181, 300);
1443                        dib8000_write_word(state, 182, 150);
1444                        dib8000_write_word(state, 183, 80);
1445                        dib8000_write_word(state, 184, 300);
1446                        dib8000_write_word(state, 185, 150);
1447                        dib8000_write_word(state, 186, 80);
1448                } else {        // Sound Broadcasting mode 3 seg
1449                        // P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15
1450                        /*                 if (mode == 3) */
1451                        /*                     dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */
1452                        /*                 else */
1453                        /*                     dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */
1454                        dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
1455
1456                        // P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1,
1457                        // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4
1458                        dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
1459                        // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
1460                        dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
1461                        //P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
1462                        dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1463
1464                        // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
1465                        dib8000_write_word(state, 181, 350);
1466                        dib8000_write_word(state, 182, 300);
1467                        dib8000_write_word(state, 183, 250);
1468                        dib8000_write_word(state, 184, 350);
1469                        dib8000_write_word(state, 185, 300);
1470                        dib8000_write_word(state, 186, 250);
1471                }
1472
1473        } else if (state->isdbt_cfg_loaded == 0) {      // if not Sound Broadcasting mode : put default values for 13 segments
1474                dib8000_write_word(state, 180, (16 << 6) | 9);
1475                dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2);
1476                coff_pow = 0x2800;
1477                for (i = 0; i < 6; i++)
1478                        dib8000_write_word(state, 181 + i, coff_pow);
1479
1480                // P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1,
1481                // 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
1482                dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1);
1483
1484                // P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6
1485                dib8000_write_word(state, 340, (8 << 6) | (6 << 0));
1486                // P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1
1487                dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1488        }
1489        // ---- FFT ----
1490        if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 && state->fe.dtv_property_cache.isdbt_partial_reception == 0)       // 1-seg
1491                dib8000_write_word(state, 178, 64);     // P_fft_powrange=64
1492        else
1493                dib8000_write_word(state, 178, 32);     // P_fft_powrange=32
1494
1495        /* make the cpil_coff_lock more robust but slower p_coff_winlen
1496         * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
1497         */
1498        /* if ( ( nbseg_diff>0)&&(nbseg_diff<13))
1499           dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */
1500
1501        dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask);    /* P_lmod4_seg_inh       */
1502        dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask);    /* P_pha3_seg_inh        */
1503        dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask);    /* P_tac_seg_inh         */
1504        if ((!state->fe.dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0))
1505                dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40);     /* P_equal_noise_seg_inh */
1506        else
1507                dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask);    /* P_equal_noise_seg_inh */
1508        dib8000_write_word(state, 287, ~seg_mask13 | 0x1000);   /* P_tmcc_seg_inh        */
1509        //dib8000_write_word(state, 288, ~seg_mask13 | seg_diff_mask); /* P_tmcc_seg_eq_inh */
1510        if (!autosearching)
1511                dib8000_write_word(state, 288, (~seg_mask13 | seg_diff_mask) & 0x1fff); /* P_tmcc_seg_eq_inh */
1512        else
1513                dib8000_write_word(state, 288, 0x1fff); //disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels.
1514        dprintk("287 = %X (%d)", ~seg_mask13 | 0x1000, ~seg_mask13 | 0x1000);
1515
1516        dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask));  /* P_des_seg_enabled     */
1517
1518        /* offset loop parameters */
1519        if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1520                if (state->fe.dtv_property_cache.isdbt_partial_reception == 0)  // Sound Broadcasting mode 1 seg
1521                        /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1522                        dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40);
1523
1524                else            // Sound Broadcasting mode 3 seg
1525                        /* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1526                        dib8000_write_word(state, 32, ((10 - mode) << 12) | (6 << 8) | 0x60);
1527        } else
1528                // TODO in 13 seg, timf_alpha can always be the same or not ?
1529                /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
1530                dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80);
1531
1532        if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1533                if (state->fe.dtv_property_cache.isdbt_partial_reception == 0)  // Sound Broadcasting mode 1 seg
1534                        /* P_ctrl_pha_off_max=3   P_ctrl_sfreq_inh =0  P_ctrl_sfreq_step = (11-P_mode)  */
1535                        dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode));
1536
1537                else            // Sound Broadcasting mode 3 seg
1538                        /* P_ctrl_pha_off_max=3   P_ctrl_sfreq_inh =0  P_ctrl_sfreq_step = (10-P_mode)  */
1539                        dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (9 - mode));
1540        } else
1541                /* P_ctrl_pha_off_max=3   P_ctrl_sfreq_inh =0  P_ctrl_sfreq_step = 9  */
1542                dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode));
1543
1544        /* P_dvsy_sync_wait - reuse mode */
1545        switch (state->fe.dtv_property_cache.transmission_mode) {
1546        case TRANSMISSION_MODE_8K:
1547                mode = 256;
1548                break;
1549        case TRANSMISSION_MODE_4K:
1550                mode = 128;
1551                break;
1552        default:
1553        case TRANSMISSION_MODE_2K:
1554                mode = 64;
1555                break;
1556        }
1557        if (state->cfg.diversity_delay == 0)
1558                mode = (mode * (1 << (guard)) * 3) / 2 + 48;    // add 50% SFN margin + compensate for one DVSY-fifo
1559        else
1560                mode = (mode * (1 << (guard)) * 3) / 2 + state->cfg.diversity_delay;    // add 50% SFN margin + compensate for DVSY-fifo
1561        mode <<= 4;
1562        dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | mode);
1563
1564        /* channel estimation fine configuration */
1565        switch (max_constellation) {
1566        case QAM_64:
1567                ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
1568                coeff[0] = 0x0148;      /* P_adp_regul_cnt 0.04 */
1569                coeff[1] = 0xfff0;      /* P_adp_noise_cnt -0.002 */
1570                coeff[2] = 0x00a4;      /* P_adp_regul_ext 0.02 */
1571                coeff[3] = 0xfff8;      /* P_adp_noise_ext -0.001 */
1572                //if (!state->cfg.hostbus_diversity) //if diversity, we should prehaps use the configuration of the max_constallation -1
1573                break;
1574        case QAM_16:
1575                ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
1576                coeff[0] = 0x023d;      /* P_adp_regul_cnt 0.07 */
1577                coeff[1] = 0xffdf;      /* P_adp_noise_cnt -0.004 */
1578                coeff[2] = 0x00a4;      /* P_adp_regul_ext 0.02 */
1579                coeff[3] = 0xfff0;      /* P_adp_noise_ext -0.002 */
1580                //if (!((state->cfg.hostbus_diversity) && (max_constellation == QAM_16)))
1581                break;
1582        default:
1583                ana_gain = 0;   // 0 : goes along with ADC target at -22dB to keep good mobile performance and lock at sensitivity level
1584                coeff[0] = 0x099a;      /* P_adp_regul_cnt 0.3 */
1585                coeff[1] = 0xffae;      /* P_adp_noise_cnt -0.01 */
1586                coeff[2] = 0x0333;      /* P_adp_regul_ext 0.1 */
1587                coeff[3] = 0xfff8;      /* P_adp_noise_ext -0.002 */
1588                break;
1589        }
1590        for (mode = 0; mode < 4; mode++)
1591                dib8000_write_word(state, 215 + mode, coeff[mode]);
1592
1593        // update ana_gain depending on max constellation
1594        dib8000_write_word(state, 116, ana_gain);
1595        // update ADC target depending on ana_gain
1596        if (ana_gain) {         // set -16dB ADC target for ana_gain=-1
1597                for (i = 0; i < 10; i++)
1598                        dib8000_write_word(state, 80 + i, adc_target_16dB[i]);
1599        } else {                // set -22dB ADC target for ana_gain=0
1600                for (i = 0; i < 10; i++)
1601                        dib8000_write_word(state, 80 + i, adc_target_16dB[i] - 355);
1602        }
1603
1604        // ---- ANA_FE ----
1605        if (state->fe.dtv_property_cache.isdbt_sb_mode) {
1606                if (state->fe.dtv_property_cache.isdbt_partial_reception == 1)  // 3-segments
1607                        ana_fe = ana_fe_coeff_3seg;
1608                else            // 1-segment
1609                        ana_fe = ana_fe_coeff_1seg;
1610        } else
1611                ana_fe = ana_fe_coeff_13seg;
1612
1613        if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0)
1614                for (mode = 0; mode < 24; mode++)
1615                        dib8000_write_word(state, 117 + mode, ana_fe[mode]);
1616
1617        // ---- CHAN_BLK ----
1618        for (i = 0; i < 13; i++) {
1619                if ((((~seg_diff_mask) >> i) & 1) == 1) {
1620                        P_cfr_left_edge += (1 << i) * ((i == 0) || ((((seg_mask13 & (~seg_diff_mask)) >> (i - 1)) & 1) == 0));
1621                        P_cfr_right_edge += (1 << i) * ((i == 12) || ((((seg_mask13 & (~seg_diff_mask)) >> (i + 1)) & 1) == 0));
1622                }
1623        }
1624        dib8000_write_word(state, 222, P_cfr_left_edge);        // P_cfr_left_edge
1625        dib8000_write_word(state, 223, P_cfr_right_edge);       // P_cfr_right_edge
1626        // "P_cspu_left_edge"  not used => do not care
1627        // "P_cspu_right_edge" not used => do not care
1628
1629        if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {  // ISDB-Tsb
1630                dib8000_write_word(state, 228, 1);      // P_2d_mode_byp=1
1631                dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); // P_cspu_win_cut = 0
1632                if (state->fe.dtv_property_cache.isdbt_partial_reception == 0   // 1-segment
1633                    && state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) {
1634                        //dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0
1635                        dib8000_write_word(state, 265, 15);     // P_equal_noise_sel = 15
1636                }
1637        } else if (state->isdbt_cfg_loaded == 0) {
1638                dib8000_write_word(state, 228, 0);      // default value
1639                dib8000_write_word(state, 265, 31);     // default value
1640                dib8000_write_word(state, 205, 0x200f); // init value
1641        }
1642        // ---- TMCC ----
1643        for (i = 0; i < 3; i++)
1644                tmcc_pow +=
1645                    (((state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe.dtv_property_cache.layer[i].segment_count);
1646        // Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9);
1647        // Threshold is set at 1/4 of max power.
1648        tmcc_pow *= (1 << (9 - 2));
1649
1650        dib8000_write_word(state, 290, tmcc_pow);       // P_tmcc_dec_thres_2k
1651        dib8000_write_word(state, 291, tmcc_pow);       // P_tmcc_dec_thres_4k
1652        dib8000_write_word(state, 292, tmcc_pow);       // P_tmcc_dec_thres_8k
1653        //dib8000_write_word(state, 287, (1 << 13) | 0x1000 );
1654        // ---- PHA3 ----
1655
1656        if (state->isdbt_cfg_loaded == 0)
1657                dib8000_write_word(state, 250, 3285);   /*p_2d_hspeed_thr0 */
1658
1659        if (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
1660                state->isdbt_cfg_loaded = 0;
1661        else
1662                state->isdbt_cfg_loaded = 1;
1663
1664}
1665
1666static int dib8000_autosearch_start(struct dvb_frontend *fe)
1667{
1668        u8 factor;
1669        u32 value;
1670        struct dib8000_state *state = fe->demodulator_priv;
1671
1672        int slist = 0;
1673
1674        state->fe.dtv_property_cache.inversion = 0;
1675        if (!state->fe.dtv_property_cache.isdbt_sb_mode)
1676                state->fe.dtv_property_cache.layer[0].segment_count = 13;
1677        state->fe.dtv_property_cache.layer[0].modulation = QAM_64;
1678        state->fe.dtv_property_cache.layer[0].fec = FEC_2_3;
1679        state->fe.dtv_property_cache.layer[0].interleaving = 0;
1680
1681        //choose the right list, in sb, always do everything
1682        if (state->fe.dtv_property_cache.isdbt_sb_mode) {
1683                state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1684                state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1685                slist = 7;
1686                dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));
1687        } else {
1688                if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) {
1689                        if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1690                                slist = 7;
1691                                dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));       // P_mode = 1 to have autosearch start ok with mode2
1692                        } else
1693                                slist = 3;
1694                } else {
1695                        if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1696                                slist = 2;
1697                                dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));       // P_mode = 1
1698                        } else
1699                                slist = 0;
1700                }
1701
1702                if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO)
1703                        state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1704                if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO)
1705                        state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1706
1707                dprintk("using list for autosearch : %d", slist);
1708                dib8000_set_channel(state, (unsigned char)slist, 1);
1709                //dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));  // P_mode = 1
1710
1711                factor = 1;
1712
1713                //set lock_mask values
1714                dib8000_write_word(state, 6, 0x4);
1715                dib8000_write_word(state, 7, 0x8);
1716                dib8000_write_word(state, 8, 0x1000);
1717
1718                //set lock_mask wait time values
1719                value = 50 * state->cfg.pll->internal * factor;
1720                dib8000_write_word(state, 11, (u16) ((value >> 16) & 0xffff));  // lock0 wait time
1721                dib8000_write_word(state, 12, (u16) (value & 0xffff));  // lock0 wait time
1722                value = 100 * state->cfg.pll->internal * factor;
1723                dib8000_write_word(state, 13, (u16) ((value >> 16) & 0xffff));  // lock1 wait time
1724                dib8000_write_word(state, 14, (u16) (value & 0xffff));  // lock1 wait time
1725                value = 1000 * state->cfg.pll->internal * factor;
1726                dib8000_write_word(state, 15, (u16) ((value >> 16) & 0xffff));  // lock2 wait time
1727                dib8000_write_word(state, 16, (u16) (value & 0xffff));  // lock2 wait time
1728
1729                value = dib8000_read_word(state, 0);
1730                dib8000_write_word(state, 0, (u16) ((1 << 15) | value));
1731                dib8000_read_word(state, 1284); // reset the INT. n_irq_pending
1732                dib8000_write_word(state, 0, (u16) value);
1733
1734        }
1735
1736        return 0;
1737}
1738
1739static int dib8000_autosearch_irq(struct dvb_frontend *fe)
1740{
1741        struct dib8000_state *state = fe->demodulator_priv;
1742        u16 irq_pending = dib8000_read_word(state, 1284);
1743
1744        if (irq_pending & 0x1) {        // failed
1745                dprintk("dib8000_autosearch_irq failed");
1746                return 1;
1747        }
1748
1749        if (irq_pending & 0x2) {        // succeeded
1750                dprintk("dib8000_autosearch_irq succeeded");
1751                return 2;
1752        }
1753
1754        return 0;               // still pending
1755}
1756
1757static int dib8000_tune(struct dvb_frontend *fe)
1758{
1759        struct dib8000_state *state = fe->demodulator_priv;
1760        int ret = 0;
1761        u16 value, mode = fft_to_mode(state);
1762
1763        // we are already tuned - just resuming from suspend
1764        if (state == NULL)
1765                return -EINVAL;
1766
1767        dib8000_set_bandwidth(state, state->fe.dtv_property_cache.bandwidth_hz / 1000);
1768        dib8000_set_channel(state, 0, 0);
1769
1770        // restart demod
1771        ret |= dib8000_write_word(state, 770, 0x4000);
1772        ret |= dib8000_write_word(state, 770, 0x0000);
1773        msleep(45);
1774
1775        /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3 */
1776        /*  ret |= dib8000_write_word(state, 29, (0 << 9) | (4 << 5) | (0 << 4) | (3 << 0) );  workaround inh_isi stays at 1 */
1777
1778        // never achieved a lock before - wait for timfreq to update
1779        if (state->timf == 0) {
1780                if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1781                        if (state->fe.dtv_property_cache.isdbt_partial_reception == 0)  // Sound Broadcasting mode 1 seg
1782                                msleep(300);
1783                        else    // Sound Broadcasting mode 3 seg
1784                                msleep(500);
1785                } else          // 13 seg
1786                        msleep(200);
1787        }
1788        //dump_reg(state);
1789        if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1790                if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) {        // Sound Broadcasting mode 1 seg
1791
1792                        /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40  alpha to check on board */
1793                        dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40);
1794                        //dib8000_write_word(state, 32, (8 << 12) | (6 << 8) | 0x80);
1795
1796                        /*  P_ctrl_sfreq_step= (12-P_mode)   P_ctrl_sfreq_inh =0     P_ctrl_pha_off_max  */
1797                        ret |= dib8000_write_word(state, 37, (12 - mode) | ((5 + mode) << 5));
1798
1799                } else {        // Sound Broadcasting mode 3 seg
1800
1801                        /* P_timf_alpha = (12-P_mode) , P_corm_alpha=6, P_corm_thres=0x60  alpha to check on board */
1802                        dib8000_write_word(state, 32, ((12 - mode) << 12) | (6 << 8) | 0x60);
1803
1804                        ret |= dib8000_write_word(state, 37, (11 - mode) | ((5 + mode) << 5));
1805                }
1806
1807        } else {                // 13 seg
1808                /* P_timf_alpha = 8 , P_corm_alpha=6, P_corm_thres=0x80  alpha to check on board */
1809                dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x80);
1810
1811                ret |= dib8000_write_word(state, 37, (10 - mode) | ((5 + mode) << 5));
1812
1813        }
1814
1815        // we achieved a coff_cpil_lock - it's time to update the timf
1816        if ((dib8000_read_word(state, 568) >> 11) & 0x1)
1817                dib8000_update_timf(state);
1818
1819        //now that tune is finished, lock0 should lock on fec_mpeg to output this lock on MP_LOCK. It's changed in autosearch start
1820        dib8000_write_word(state, 6, 0x200);
1821
1822        if (state->revision == 0x8002) {
1823                value = dib8000_read_word(state, 903);
1824                dib8000_write_word(state, 903, value & ~(1 << 3));
1825                msleep(1);
1826                dib8000_write_word(state, 903, value | (1 << 3));
1827        }
1828
1829        return ret;
1830}
1831
1832static int dib8000_wakeup(struct dvb_frontend *fe)
1833{
1834        struct dib8000_state *state = fe->demodulator_priv;
1835
1836        dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
1837        dib8000_set_adc_state(state, DIBX000_ADC_ON);
1838        if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
1839                dprintk("could not start Slow ADC");
1840
1841        return 0;
1842}
1843
1844static int dib8000_sleep(struct dvb_frontend *fe)
1845{
1846        struct dib8000_state *st = fe->demodulator_priv;
1847        if (1) {
1848                dib8000_set_output_mode(st, OUTMODE_HIGH_Z);
1849                dib8000_set_power_mode(st, DIB8000M_POWER_INTERFACE_ONLY);
1850                return dib8000_set_adc_state(st, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(st, DIBX000_ADC_OFF);
1851        } else {
1852
1853                return 0;
1854        }
1855}
1856
1857static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1858{
1859        struct dib8000_state *state = fe->demodulator_priv;
1860        u16 i, val = 0;
1861
1862        fe->dtv_property_cache.bandwidth_hz = 6000000;
1863
1864        fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1;
1865
1866        val = dib8000_read_word(state, 570);
1867        fe->dtv_property_cache.inversion = (val & 0x40) >> 6;
1868        switch ((val & 0x30) >> 4) {
1869        case 1:
1870                fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
1871                break;
1872        case 3:
1873        default:
1874                fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1875                break;
1876        }
1877
1878        switch (val & 0x3) {
1879        case 0:
1880                fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
1881                dprintk("dib8000_get_frontend GI = 1/32 ");
1882                break;
1883        case 1:
1884                fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
1885                dprintk("dib8000_get_frontend GI = 1/16 ");
1886                break;
1887        case 2:
1888                dprintk("dib8000_get_frontend GI = 1/8 ");
1889                fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1890                break;
1891        case 3:
1892                dprintk("dib8000_get_frontend GI = 1/4 ");
1893                fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
1894                break;
1895        }
1896
1897        val = dib8000_read_word(state, 505);
1898        fe->dtv_property_cache.isdbt_partial_reception = val & 1;
1899        dprintk("dib8000_get_frontend : partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception);
1900
1901        for (i = 0; i < 3; i++) {
1902                val = dib8000_read_word(state, 493 + i);
1903                fe->dtv_property_cache.layer[i].segment_count = val & 0x0F;
1904                dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count);
1905
1906                val = dib8000_read_word(state, 499 + i);
1907                fe->dtv_property_cache.layer[i].interleaving = val & 0x3;
1908                dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ", i, fe->dtv_property_cache.layer[i].interleaving);
1909
1910                val = dib8000_read_word(state, 481 + i);
1911                switch (val & 0x7) {
1912                case 1:
1913                        fe->dtv_property_cache.layer[i].fec = FEC_1_2;
1914                        dprintk("dib8000_get_frontend : Layer %d Code Rate = 1/2 ", i);
1915                        break;
1916                case 2:
1917                        fe->dtv_property_cache.layer[i].fec = FEC_2_3;
1918                        dprintk("dib8000_get_frontend : Layer %d Code Rate = 2/3 ", i);
1919                        break;
1920                case 3:
1921                        fe->dtv_property_cache.layer[i].fec = FEC_3_4;
1922                        dprintk("dib8000_get_frontend : Layer %d Code Rate = 3/4 ", i);
1923                        break;
1924                case 5:
1925                        fe->dtv_property_cache.layer[i].fec = FEC_5_6;
1926                        dprintk("dib8000_get_frontend : Layer %d Code Rate = 5/6 ", i);
1927                        break;
1928                default:
1929                        fe->dtv_property_cache.layer[i].fec = FEC_7_8;
1930                        dprintk("dib8000_get_frontend : Layer %d Code Rate = 7/8 ", i);
1931                        break;
1932                }
1933
1934                val = dib8000_read_word(state, 487 + i);
1935                switch (val & 0x3) {
1936                case 0:
1937                        dprintk("dib8000_get_frontend : Layer %d DQPSK ", i);
1938                        fe->dtv_property_cache.layer[i].modulation = DQPSK;
1939                        break;
1940                case 1:
1941                        fe->dtv_property_cache.layer[i].modulation = QPSK;
1942                        dprintk("dib8000_get_frontend : Layer %d QPSK ", i);
1943                        break;
1944                case 2:
1945                        fe->dtv_property_cache.layer[i].modulation = QAM_16;
1946                        dprintk("dib8000_get_frontend : Layer %d QAM16 ", i);
1947                        break;
1948                case 3:
1949                default:
1950                        dprintk("dib8000_get_frontend : Layer %d QAM64 ", i);
1951                        fe->dtv_property_cache.layer[i].modulation = QAM_64;
1952                        break;
1953                }
1954        }
1955        return 0;
1956}
1957
1958static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1959{
1960        struct dib8000_state *state = fe->demodulator_priv;
1961        int time, ret;
1962
1963        dib8000_set_output_mode(state, OUTMODE_HIGH_Z);
1964
1965        if (fe->ops.tuner_ops.set_params)
1966                fe->ops.tuner_ops.set_params(fe, fep);
1967
1968        /* start up the AGC */
1969        state->tune_state = CT_AGC_START;
1970        do {
1971                time = dib8000_agc_startup(fe);
1972                if (time != FE_CALLBACK_TIME_NEVER)
1973                        msleep(time / 10);
1974                else
1975                        break;
1976        } while (state->tune_state != CT_AGC_STOP);
1977
1978        if (state->fe.dtv_property_cache.frequency == 0) {
1979                dprintk("dib8000: must at least specify frequency ");
1980                return 0;
1981        }
1982
1983        if (state->fe.dtv_property_cache.bandwidth_hz == 0) {
1984                dprintk("dib8000: no bandwidth specified, set to default ");
1985                state->fe.dtv_property_cache.bandwidth_hz = 6000000;
1986        }
1987
1988        state->tune_state = CT_DEMOD_START;
1989
1990        if ((state->fe.dtv_property_cache.delivery_system != SYS_ISDBT) ||
1991            (state->fe.dtv_property_cache.inversion == INVERSION_AUTO) ||
1992            (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) ||
1993            (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) ||
1994            (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) &&
1995             (state->fe.dtv_property_cache.layer[0].segment_count != 0xff) &&
1996             (state->fe.dtv_property_cache.layer[0].segment_count != 0) &&
1997             ((state->fe.dtv_property_cache.layer[0].modulation == QAM_AUTO) ||
1998              (state->fe.dtv_property_cache.layer[0].fec == FEC_AUTO))) ||
1999            (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) &&
2000             (state->fe.dtv_property_cache.layer[1].segment_count != 0xff) &&
2001             (state->fe.dtv_property_cache.layer[1].segment_count != 0) &&
2002             ((state->fe.dtv_property_cache.layer[1].modulation == QAM_AUTO) ||
2003              (state->fe.dtv_property_cache.layer[1].fec == FEC_AUTO))) ||
2004            (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) &&
2005             (state->fe.dtv_property_cache.layer[2].segment_count != 0xff) &&
2006             (state->fe.dtv_property_cache.layer[2].segment_count != 0) &&
2007             ((state->fe.dtv_property_cache.layer[2].modulation == QAM_AUTO) ||
2008              (state->fe.dtv_property_cache.layer[2].fec == FEC_AUTO))) ||
2009            (((state->fe.dtv_property_cache.layer[0].segment_count == 0) ||
2010              ((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) &&
2011             ((state->fe.dtv_property_cache.layer[1].segment_count == 0) ||
2012              ((state->fe.dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) &&
2013             ((state->fe.dtv_property_cache.layer[2].segment_count == 0) || ((state->fe.dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) {
2014                int i = 800, found;
2015
2016                dib8000_set_bandwidth(state, fe->dtv_property_cache.bandwidth_hz / 1000);
2017                dib8000_autosearch_start(fe);
2018                do {
2019                        msleep(10);
2020                        found = dib8000_autosearch_irq(fe);
2021                } while (found == 0 && i--);
2022
2023                dprintk("Frequency %d Hz, autosearch returns: %d", fep->frequency, found);
2024
2025                if (found == 0 || found == 1)
2026                        return 0;       // no channel found
2027
2028                dib8000_get_frontend(fe, fep);
2029        }
2030
2031        ret = dib8000_tune(fe);
2032
2033        /* make this a config parameter */
2034        dib8000_set_output_mode(state, state->cfg.output_mode);
2035
2036        return ret;
2037}
2038
2039static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
2040{
2041        struct dib8000_state *state = fe->demodulator_priv;
2042        u16 lock = dib8000_read_word(state, 568);
2043
2044        *stat = 0;
2045
2046        if ((lock >> 14) & 1)   // AGC
2047                *stat |= FE_HAS_SIGNAL;
2048
2049        if ((lock >> 8) & 1)    // Equal
2050                *stat |= FE_HAS_CARRIER;
2051
2052        if ((lock >> 3) & 1)    // TMCC_SYNC
2053                *stat |= FE_HAS_SYNC;
2054
2055        if ((lock >> 5) & 7)    // FEC MPEG
2056                *stat |= FE_HAS_LOCK;
2057
2058        lock = dib8000_read_word(state, 554);   // Viterbi Layer A
2059        if (lock & 0x01)
2060                *stat |= FE_HAS_VITERBI;
2061
2062        lock = dib8000_read_word(state, 555);   // Viterbi Layer B
2063        if (lock & 0x01)
2064                *stat |= FE_HAS_VITERBI;
2065
2066        lock = dib8000_read_word(state, 556);   // Viterbi Layer C
2067        if (lock & 0x01)
2068                *stat |= FE_HAS_VITERBI;
2069
2070        return 0;
2071}
2072
2073static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber)
2074{
2075        struct dib8000_state *state = fe->demodulator_priv;
2076        *ber = (dib8000_read_word(state, 560) << 16) | dib8000_read_word(state, 561);   // 13 segments
2077        return 0;
2078}
2079
2080static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
2081{
2082        struct dib8000_state *state = fe->demodulator_priv;
2083        *unc = dib8000_read_word(state, 565);   // packet error on 13 seg
2084        return 0;
2085}
2086
2087static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2088{
2089        struct dib8000_state *state = fe->demodulator_priv;
2090        u16 val = dib8000_read_word(state, 390);
2091        *strength = 65535 - val;
2092        return 0;
2093}
2094
2095static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
2096{
2097        struct dib8000_state *state = fe->demodulator_priv;
2098        u16 val;
2099        s32 signal_mant, signal_exp, noise_mant, noise_exp;
2100        u32 result = 0;
2101
2102        val = dib8000_read_word(state, 542);
2103        noise_mant = (val >> 6) & 0xff;
2104        noise_exp = (val & 0x3f);
2105
2106        val = dib8000_read_word(state, 543);
2107        signal_mant = (val >> 6) & 0xff;
2108        signal_exp = (val & 0x3f);
2109
2110        if ((noise_exp & 0x20) != 0)
2111                noise_exp -= 0x40;
2112        if ((signal_exp & 0x20) != 0)
2113                signal_exp -= 0x40;
2114
2115        if (signal_mant != 0)
2116                result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
2117        else
2118                result = intlog10(2) * 10 * signal_exp - 100;
2119        if (noise_mant != 0)
2120                result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
2121        else
2122                result -= intlog10(2) * 10 * noise_exp - 100;
2123
2124        *snr = result / (1 << 24);
2125        return 0;
2126}
2127
2128int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
2129{
2130        int k = 0;
2131        u8 new_addr = 0;
2132        struct i2c_device client = {.adap = host };
2133
2134        for (k = no_of_demods - 1; k >= 0; k--) {
2135                /* designated i2c address */
2136                new_addr = first_addr + (k << 1);
2137
2138                client.addr = new_addr;
2139                dib8000_i2c_write16(&client, 1287, 0x0003);     /* sram lead in, rdy */
2140                if (dib8000_identify(&client) == 0) {
2141                        dib8000_i2c_write16(&client, 1287, 0x0003);     /* sram lead in, rdy */
2142                        client.addr = default_addr;
2143                        if (dib8000_identify(&client) == 0) {
2144                                dprintk("#%d: not identified", k);
2145                                return -EINVAL;
2146                        }
2147                }
2148
2149                /* start diversity to pull_down div_str - just for i2c-enumeration */
2150                dib8000_i2c_write16(&client, 1286, (1 << 10) | (4 << 6));
2151
2152                /* set new i2c address and force divstart */
2153                dib8000_i2c_write16(&client, 1285, (new_addr << 2) | 0x2);
2154                client.addr = new_addr;
2155                dib8000_identify(&client);
2156
2157                dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
2158        }
2159
2160        for (k = 0; k < no_of_demods; k++) {
2161                new_addr = first_addr | (k << 1);
2162                client.addr = new_addr;
2163
2164                // unforce divstr
2165                dib8000_i2c_write16(&client, 1285, new_addr << 2);
2166
2167                /* deactivate div - it was just for i2c-enumeration */
2168                dib8000_i2c_write16(&client, 1286, 0);
2169        }
2170
2171        return 0;
2172}
2173
2174EXPORT_SYMBOL(dib8000_i2c_enumeration);
2175static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
2176{
2177        tune->min_delay_ms = 1000;
2178        tune->step_size = 0;
2179        tune->max_drift = 0;
2180        return 0;
2181}
2182
2183static void dib8000_release(struct dvb_frontend *fe)
2184{
2185        struct dib8000_state *st = fe->demodulator_priv;
2186        dibx000_exit_i2c_master(&st->i2c_master);
2187        kfree(st);
2188}
2189
2190struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
2191{
2192        struct dib8000_state *st = fe->demodulator_priv;
2193        return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
2194}
2195
2196EXPORT_SYMBOL(dib8000_get_i2c_master);
2197
2198static const struct dvb_frontend_ops dib8000_ops = {
2199        .info = {
2200                 .name = "DiBcom 8000 ISDB-T",
2201                 .type = FE_OFDM,
2202                 .frequency_min = 44250000,
2203                 .frequency_max = 867250000,
2204                 .frequency_stepsize = 62500,
2205                 .caps = FE_CAN_INVERSION_AUTO |
2206                 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2207                 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2208                 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2209                 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2210                 },
2211
2212        .release = dib8000_release,
2213
2214        .init = dib8000_wakeup,
2215        .sleep = dib8000_sleep,
2216
2217        .set_frontend = dib8000_set_frontend,
2218        .get_tune_settings = dib8000_fe_get_tune_settings,
2219        .get_frontend = dib8000_get_frontend,
2220
2221        .read_status = dib8000_read_status,
2222        .read_ber = dib8000_read_ber,
2223        .read_signal_strength = dib8000_read_signal_strength,
2224        .read_snr = dib8000_read_snr,
2225        .read_ucblocks = dib8000_read_unc_blocks,
2226};
2227
2228struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
2229{
2230        struct dvb_frontend *fe;
2231        struct dib8000_state *state;
2232
2233        dprintk("dib8000_attach");
2234
2235        state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL);
2236        if (state == NULL)
2237                return NULL;
2238
2239        memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
2240        state->i2c.adap = i2c_adap;
2241        state->i2c.addr = i2c_addr;
2242        state->gpio_val = cfg->gpio_val;
2243        state->gpio_dir = cfg->gpio_dir;
2244
2245        /* Ensure the output mode remains at the previous default if it's
2246         * not specifically set by the caller.
2247         */
2248        if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2249                state->cfg.output_mode = OUTMODE_MPEG2_FIFO;
2250
2251        fe = &state->fe;
2252        fe->demodulator_priv = state;
2253        memcpy(&state->fe.ops, &dib8000_ops, sizeof(struct dvb_frontend_ops));
2254
2255        state->timf_default = cfg->pll->timf;
2256
2257        if (dib8000_identify(&state->i2c) == 0)
2258                goto error;
2259
2260        dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr);
2261
2262        dib8000_reset(fe);
2263
2264        dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5));     /* ber_rs_len = 3 */
2265
2266        return fe;
2267
2268 error:
2269        kfree(state);
2270        return NULL;
2271}
2272
2273EXPORT_SYMBOL(dib8000_attach);
2274
2275MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@dibcom.fr, " "Patrick Boettcher <pboettcher@dibcom.fr>");
2276MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator");
2277MODULE_LICENSE("GPL");
2278