linux/drivers/media/dvb/frontends/dib7000p.c
<<
>>
Prefs
   1/*
   2 * Linux-DVB Driver for DiBcom's second generation DiB7000P (PC).
   3 *
   4 * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 *      modify it under the terms of the GNU General Public License as
   8 *      published by the Free Software Foundation, version 2.
   9 */
  10#include <linux/kernel.h>
  11#include <linux/i2c.h>
  12
  13#include "dvb_math.h"
  14#include "dvb_frontend.h"
  15
  16#include "dib7000p.h"
  17
  18static int debug;
  19module_param(debug, int, 0644);
  20MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
  21
  22static int buggy_sfn_workaround;
  23module_param(buggy_sfn_workaround, int, 0644);
  24MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
  25
  26#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0)
  27
  28struct dib7000p_state {
  29        struct dvb_frontend demod;
  30    struct dib7000p_config cfg;
  31
  32        u8 i2c_addr;
  33        struct i2c_adapter   *i2c_adap;
  34
  35        struct dibx000_i2c_master i2c_master;
  36
  37        u16 wbd_ref;
  38
  39        u8  current_band;
  40        u32 current_bandwidth;
  41        struct dibx000_agc_config *current_agc;
  42        u32 timf;
  43
  44        u8 div_force_off : 1;
  45        u8 div_state : 1;
  46        u16 div_sync_wait;
  47
  48        u8 agc_state;
  49
  50        u16 gpio_dir;
  51        u16 gpio_val;
  52
  53        u8 sfn_workaround_active :1;
  54};
  55
  56enum dib7000p_power_mode {
  57        DIB7000P_POWER_ALL = 0,
  58        DIB7000P_POWER_ANALOG_ADC,
  59        DIB7000P_POWER_INTERFACE_ONLY,
  60};
  61
  62static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
  63{
  64        u8 wb[2] = { reg >> 8, reg & 0xff };
  65        u8 rb[2];
  66        struct i2c_msg msg[2] = {
  67                { .addr = state->i2c_addr >> 1, .flags = 0,        .buf = wb, .len = 2 },
  68                { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
  69        };
  70
  71        if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
  72                dprintk("i2c read error on %d",reg);
  73
  74        return (rb[0] << 8) | rb[1];
  75}
  76
  77static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
  78{
  79        u8 b[4] = {
  80                (reg >> 8) & 0xff, reg & 0xff,
  81                (val >> 8) & 0xff, val & 0xff,
  82        };
  83        struct i2c_msg msg = {
  84                .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
  85        };
  86        return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
  87}
  88static void dib7000p_write_tab(struct dib7000p_state *state, u16 *buf)
  89{
  90        u16 l = 0, r, *n;
  91        n = buf;
  92        l = *n++;
  93        while (l) {
  94                r = *n++;
  95
  96                do {
  97                        dib7000p_write_word(state, r, *n++);
  98                        r++;
  99                } while (--l);
 100                l = *n++;
 101        }
 102}
 103
 104static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
 105{
 106        int    ret = 0;
 107        u16 outreg, fifo_threshold, smo_mode;
 108
 109        outreg = 0;
 110        fifo_threshold = 1792;
 111        smo_mode = (dib7000p_read_word(state, 235) & 0x0010) | (1 << 1);
 112
 113        dprintk( "setting output mode for demod %p to %d",
 114                        &state->demod, mode);
 115
 116        switch (mode) {
 117                case OUTMODE_MPEG2_PAR_GATED_CLK:   // STBs with parallel gated clock
 118                        outreg = (1 << 10);  /* 0x0400 */
 119                        break;
 120                case OUTMODE_MPEG2_PAR_CONT_CLK:    // STBs with parallel continues clock
 121                        outreg = (1 << 10) | (1 << 6); /* 0x0440 */
 122                        break;
 123                case OUTMODE_MPEG2_SERIAL:          // STBs with serial input
 124                        outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */
 125                        break;
 126                case OUTMODE_DIVERSITY:
 127                        if (state->cfg.hostbus_diversity)
 128                                outreg = (1 << 10) | (4 << 6); /* 0x0500 */
 129                        else
 130                                outreg = (1 << 11);
 131                        break;
 132                case OUTMODE_MPEG2_FIFO:            // e.g. USB feeding
 133                        smo_mode |= (3 << 1);
 134                        fifo_threshold = 512;
 135                        outreg = (1 << 10) | (5 << 6);
 136                        break;
 137                case OUTMODE_ANALOG_ADC:
 138                        outreg = (1 << 10) | (3 << 6);
 139                        break;
 140                case OUTMODE_HIGH_Z:  // disable
 141                        outreg = 0;
 142                        break;
 143                default:
 144                        dprintk( "Unhandled output_mode passed to be set for demod %p",&state->demod);
 145                        break;
 146        }
 147
 148        if (state->cfg.output_mpeg2_in_188_bytes)
 149                smo_mode |= (1 << 5) ;
 150
 151        ret |= dib7000p_write_word(state,  235, smo_mode);
 152        ret |= dib7000p_write_word(state,  236, fifo_threshold); /* synchronous fread */
 153        ret |= dib7000p_write_word(state, 1286, outreg);         /* P_Div_active */
 154
 155        return ret;
 156}
 157
 158static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
 159{
 160        struct dib7000p_state *state = demod->demodulator_priv;
 161
 162        if (state->div_force_off) {
 163                dprintk( "diversity combination deactivated - forced by COFDM parameters");
 164                onoff = 0;
 165        }
 166        state->div_state = (u8)onoff;
 167
 168        if (onoff) {
 169                dib7000p_write_word(state, 204, 6);
 170                dib7000p_write_word(state, 205, 16);
 171                /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
 172                dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
 173        } else {
 174                dib7000p_write_word(state, 204, 1);
 175                dib7000p_write_word(state, 205, 0);
 176                dib7000p_write_word(state, 207, 0);
 177        }
 178
 179        return 0;
 180}
 181
 182static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode)
 183{
 184        /* by default everything is powered off */
 185        u16 reg_774 = 0xffff, reg_775 = 0xffff, reg_776 = 0x0007, reg_899  = 0x0003,
 186                reg_1280 = (0xfe00) | (dib7000p_read_word(state, 1280) & 0x01ff);
 187
 188        /* now, depending on the requested mode, we power on */
 189        switch (mode) {
 190                /* power up everything in the demod */
 191                case DIB7000P_POWER_ALL:
 192                        reg_774 = 0x0000; reg_775 = 0x0000; reg_776 = 0x0; reg_899 = 0x0; reg_1280 &= 0x01ff;
 193                        break;
 194
 195                case DIB7000P_POWER_ANALOG_ADC:
 196                        /* dem, cfg, iqc, sad, agc */
 197                        reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
 198                        /* nud */
 199                        reg_776 &= ~((1 << 0));
 200                        /* Dout */
 201                        reg_1280 &= ~((1 << 11));
 202                        /* fall through wanted to enable the interfaces */
 203
 204                /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
 205                case DIB7000P_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C */
 206                        reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
 207                        break;
 208
 209/* TODO following stuff is just converted from the dib7000-driver - check when is used what */
 210        }
 211
 212        dib7000p_write_word(state,  774,  reg_774);
 213        dib7000p_write_word(state,  775,  reg_775);
 214        dib7000p_write_word(state,  776,  reg_776);
 215        dib7000p_write_word(state,  899,  reg_899);
 216        dib7000p_write_word(state, 1280, reg_1280);
 217
 218        return 0;
 219}
 220
 221static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no)
 222{
 223        u16 reg_908 = dib7000p_read_word(state, 908),
 224               reg_909 = dib7000p_read_word(state, 909);
 225
 226        switch (no) {
 227                case DIBX000_SLOW_ADC_ON:
 228                        reg_909 |= (1 << 1) | (1 << 0);
 229                        dib7000p_write_word(state, 909, reg_909);
 230                        reg_909 &= ~(1 << 1);
 231                        break;
 232
 233                case DIBX000_SLOW_ADC_OFF:
 234                        reg_909 |=  (1 << 1) | (1 << 0);
 235                        break;
 236
 237                case DIBX000_ADC_ON:
 238                        reg_908 &= 0x0fff;
 239                        reg_909 &= 0x0003;
 240                        break;
 241
 242                case DIBX000_ADC_OFF: // leave the VBG voltage on
 243                        reg_908 |= (1 << 14) | (1 << 13) | (1 << 12);
 244                        reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
 245                        break;
 246
 247                case DIBX000_VBG_ENABLE:
 248                        reg_908 &= ~(1 << 15);
 249                        break;
 250
 251                case DIBX000_VBG_DISABLE:
 252                        reg_908 |= (1 << 15);
 253                        break;
 254
 255                default:
 256                        break;
 257        }
 258
 259//      dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
 260
 261        dib7000p_write_word(state, 908, reg_908);
 262        dib7000p_write_word(state, 909, reg_909);
 263}
 264
 265static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
 266{
 267        u32 timf;
 268
 269        // store the current bandwidth for later use
 270        state->current_bandwidth = bw;
 271
 272        if (state->timf == 0) {
 273                dprintk( "using default timf");
 274                timf = state->cfg.bw->timf;
 275        } else {
 276                dprintk( "using updated timf");
 277                timf = state->timf;
 278        }
 279
 280        timf = timf * (bw / 50) / 160;
 281
 282        dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
 283        dib7000p_write_word(state, 24, (u16) ((timf      ) & 0xffff));
 284
 285        return 0;
 286}
 287
 288static int dib7000p_sad_calib(struct dib7000p_state *state)
 289{
 290/* internal */
 291//      dib7000p_write_word(state, 72, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth
 292        dib7000p_write_word(state, 73, (0 << 1) | (0 << 0));
 293        dib7000p_write_word(state, 74, 776); // 0.625*3.3 / 4096
 294
 295        /* do the calibration */
 296        dib7000p_write_word(state, 73, (1 << 0));
 297        dib7000p_write_word(state, 73, (0 << 0));
 298
 299        msleep(1);
 300
 301        return 0;
 302}
 303
 304int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
 305{
 306        struct dib7000p_state *state = demod->demodulator_priv;
 307        if (value > 4095)
 308                value = 4095;
 309        state->wbd_ref = value;
 310        return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value);
 311}
 312
 313EXPORT_SYMBOL(dib7000p_set_wbd_ref);
 314static void dib7000p_reset_pll(struct dib7000p_state *state)
 315{
 316        struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
 317        u16 clk_cfg0;
 318
 319        /* force PLL bypass */
 320        clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) |
 321                (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) |
 322                (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0);
 323
 324        dib7000p_write_word(state, 900, clk_cfg0);
 325
 326        /* P_pll_cfg */
 327        dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset);
 328        clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff);
 329        dib7000p_write_word(state, 900, clk_cfg0);
 330
 331        dib7000p_write_word(state, 18, (u16) (((bw->internal*1000) >> 16) & 0xffff));
 332        dib7000p_write_word(state, 19, (u16) ( (bw->internal*1000       ) & 0xffff));
 333        dib7000p_write_word(state, 21, (u16) ( (bw->ifreq          >> 16) & 0xffff));
 334        dib7000p_write_word(state, 22, (u16) ( (bw->ifreq               ) & 0xffff));
 335
 336        dib7000p_write_word(state, 72, bw->sad_cfg);
 337}
 338
 339static int dib7000p_reset_gpio(struct dib7000p_state *st)
 340{
 341        /* reset the GPIOs */
 342        dprintk( "gpio dir: %x: val: %x, pwm_pos: %x",st->gpio_dir, st->gpio_val,st->cfg.gpio_pwm_pos);
 343
 344        dib7000p_write_word(st, 1029, st->gpio_dir);
 345        dib7000p_write_word(st, 1030, st->gpio_val);
 346
 347        /* TODO 1031 is P_gpio_od */
 348
 349        dib7000p_write_word(st, 1032, st->cfg.gpio_pwm_pos);
 350
 351        dib7000p_write_word(st, 1037, st->cfg.pwm_freq_div);
 352        return 0;
 353}
 354
 355static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val)
 356{
 357        st->gpio_dir = dib7000p_read_word(st, 1029);
 358        st->gpio_dir &= ~(1 << num);         /* reset the direction bit */
 359        st->gpio_dir |=  (dir & 0x1) << num; /* set the new direction */
 360        dib7000p_write_word(st, 1029, st->gpio_dir);
 361
 362        st->gpio_val = dib7000p_read_word(st, 1030);
 363        st->gpio_val &= ~(1 << num);          /* reset the direction bit */
 364        st->gpio_val |=  (val & 0x01) << num; /* set the new value */
 365        dib7000p_write_word(st, 1030, st->gpio_val);
 366
 367        return 0;
 368}
 369
 370int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val)
 371{
 372        struct dib7000p_state *state = demod->demodulator_priv;
 373        return dib7000p_cfg_gpio(state, num, dir, val);
 374}
 375
 376EXPORT_SYMBOL(dib7000p_set_gpio);
 377static u16 dib7000p_defaults[] =
 378
 379{
 380        // auto search configuration
 381        3, 2,
 382                0x0004,
 383                0x1000,
 384                0x0814, /* Equal Lock */
 385
 386        12, 6,
 387                0x001b,
 388                0x7740,
 389                0x005b,
 390                0x8d80,
 391                0x01c9,
 392                0xc380,
 393                0x0000,
 394                0x0080,
 395                0x0000,
 396                0x0090,
 397                0x0001,
 398                0xd4c0,
 399
 400        1, 26,
 401                0x6680, // P_timf_alpha=6, P_corm_alpha=6, P_corm_thres=128 default: 6,4,26
 402
 403        /* set ADC level to -16 */
 404        11, 79,
 405                (1 << 13) - 825 - 117,
 406                (1 << 13) - 837 - 117,
 407                (1 << 13) - 811 - 117,
 408                (1 << 13) - 766 - 117,
 409                (1 << 13) - 737 - 117,
 410                (1 << 13) - 693 - 117,
 411                (1 << 13) - 648 - 117,
 412                (1 << 13) - 619 - 117,
 413                (1 << 13) - 575 - 117,
 414                (1 << 13) - 531 - 117,
 415                (1 << 13) - 501 - 117,
 416
 417        1, 142,
 418                0x0410, // P_palf_filter_on=1, P_palf_filter_freeze=0, P_palf_alpha_regul=16
 419
 420        /* disable power smoothing */
 421        8, 145,
 422                0,
 423                0,
 424                0,
 425                0,
 426                0,
 427                0,
 428                0,
 429                0,
 430
 431        1, 154,
 432                1 << 13, // P_fft_freq_dir=1, P_fft_nb_to_cut=0
 433
 434        1, 168,
 435                0x0ccd, // P_pha3_thres, default 0x3000
 436
 437//      1, 169,
 438//              0x0010, // P_cti_use_cpe=0, P_cti_use_prog=0, P_cti_win_len=16, default: 0x0010
 439
 440        1, 183,
 441                0x200f, // P_cspu_regul=512, P_cspu_win_cut=15, default: 0x2005
 442
 443        5, 187,
 444                0x023d, // P_adp_regul_cnt=573, default: 410
 445                0x00a4, // P_adp_noise_cnt=
 446                0x00a4, // P_adp_regul_ext
 447                0x7ff0, // P_adp_noise_ext
 448                0x3ccc, // P_adp_fil
 449
 450        1, 198,
 451                0x800, // P_equal_thres_wgn
 452
 453        1, 222,
 454                0x0010, // P_fec_ber_rs_len=2
 455
 456        1, 235,
 457                0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
 458
 459        2, 901,
 460                0x0006, // P_clk_cfg1
 461                (3 << 10) | (1 << 6), // P_divclksel=3 P_divbitsel=1
 462
 463        1, 905,
 464                0x2c8e, // Tuner IO bank: max drive (14mA) + divout pads max drive
 465
 466        0,
 467};
 468
 469static int dib7000p_demod_reset(struct dib7000p_state *state)
 470{
 471        dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
 472
 473        dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE);
 474
 475        /* restart all parts */
 476        dib7000p_write_word(state,  770, 0xffff);
 477        dib7000p_write_word(state,  771, 0xffff);
 478        dib7000p_write_word(state,  772, 0x001f);
 479        dib7000p_write_word(state,  898, 0x0003);
 480        /* except i2c, sdio, gpio - control interfaces */
 481        dib7000p_write_word(state, 1280, 0x01fc - ((1 << 7) | (1 << 6) | (1 << 5)) );
 482
 483        dib7000p_write_word(state,  770, 0);
 484        dib7000p_write_word(state,  771, 0);
 485        dib7000p_write_word(state,  772, 0);
 486        dib7000p_write_word(state,  898, 0);
 487        dib7000p_write_word(state, 1280, 0);
 488
 489        /* default */
 490        dib7000p_reset_pll(state);
 491
 492        if (dib7000p_reset_gpio(state) != 0)
 493                dprintk( "GPIO reset was not successful.");
 494
 495        if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
 496                dprintk( "OUTPUT_MODE could not be reset.");
 497
 498        /* unforce divstr regardless whether i2c enumeration was done or not */
 499        dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1) );
 500
 501        dib7000p_set_bandwidth(state, 8000);
 502
 503        dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
 504        dib7000p_sad_calib(state);
 505        dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
 506
 507        // P_iqc_alpha_pha, P_iqc_alpha_amp_dcc_alpha, ...
 508        if(state->cfg.tuner_is_baseband)
 509                dib7000p_write_word(state, 36,0x0755);
 510        else
 511                dib7000p_write_word(state, 36,0x1f55);
 512
 513        dib7000p_write_tab(state, dib7000p_defaults);
 514
 515        dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
 516
 517
 518        return 0;
 519}
 520
 521static void dib7000p_pll_clk_cfg(struct dib7000p_state *state)
 522{
 523        u16 tmp = 0;
 524        tmp = dib7000p_read_word(state, 903);
 525        dib7000p_write_word(state, 903, (tmp | 0x1));   //pwr-up pll
 526        tmp = dib7000p_read_word(state, 900);
 527        dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6));     //use High freq clock
 528}
 529
 530static void dib7000p_restart_agc(struct dib7000p_state *state)
 531{
 532        // P_restart_iqc & P_restart_agc
 533        dib7000p_write_word(state, 770, (1 << 11) | (1 << 9));
 534        dib7000p_write_word(state, 770, 0x0000);
 535}
 536
 537static int dib7000p_update_lna(struct dib7000p_state *state)
 538{
 539        u16 dyn_gain;
 540
 541        // when there is no LNA to program return immediatly
 542        if (state->cfg.update_lna) {
 543                // read dyn_gain here (because it is demod-dependent and not fe)
 544                dyn_gain = dib7000p_read_word(state, 394);
 545                if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed
 546                        dib7000p_restart_agc(state);
 547                        return 1;
 548                }
 549        }
 550
 551        return 0;
 552}
 553
 554static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
 555{
 556        struct dibx000_agc_config *agc = NULL;
 557        int i;
 558        if (state->current_band == band && state->current_agc != NULL)
 559                return 0;
 560        state->current_band = band;
 561
 562        for (i = 0; i < state->cfg.agc_config_count; i++)
 563                if (state->cfg.agc[i].band_caps & band) {
 564                        agc = &state->cfg.agc[i];
 565                        break;
 566                }
 567
 568        if (agc == NULL) {
 569                dprintk( "no valid AGC configuration found for band 0x%02x",band);
 570                return -EINVAL;
 571        }
 572
 573        state->current_agc = agc;
 574
 575        /* AGC */
 576        dib7000p_write_word(state, 75 ,  agc->setup );
 577        dib7000p_write_word(state, 76 ,  agc->inv_gain );
 578        dib7000p_write_word(state, 77 ,  agc->time_stabiliz );
 579        dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);
 580
 581        // Demod AGC loop configuration
 582        dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);
 583        dib7000p_write_word(state, 102, (agc->beta_mant << 6)  | agc->beta_exp);
 584
 585        /* AGC continued */
 586        dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d",
 587                state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
 588
 589        if (state->wbd_ref != 0)
 590                dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | state->wbd_ref);
 591        else
 592                dib7000p_write_word(state, 105, (agc->wbd_inv << 12) | agc->wbd_ref);
 593
 594        dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
 595
 596        dib7000p_write_word(state, 107,  agc->agc1_max);
 597        dib7000p_write_word(state, 108,  agc->agc1_min);
 598        dib7000p_write_word(state, 109,  agc->agc2_max);
 599        dib7000p_write_word(state, 110,  agc->agc2_min);
 600        dib7000p_write_word(state, 111, (agc->agc1_pt1    << 8) | agc->agc1_pt2);
 601        dib7000p_write_word(state, 112,  agc->agc1_pt3);
 602        dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
 603        dib7000p_write_word(state, 114, (agc->agc2_pt1    << 8) | agc->agc2_pt2);
 604        dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
 605        return 0;
 606}
 607
 608static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
 609{
 610        struct dib7000p_state *state = demod->demodulator_priv;
 611        int ret = -1;
 612        u8 *agc_state = &state->agc_state;
 613        u8 agc_split;
 614
 615        switch (state->agc_state) {
 616                case 0:
 617                        // set power-up level: interf+analog+AGC
 618                        dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
 619                        dib7000p_set_adc_state(state, DIBX000_ADC_ON);
 620                        dib7000p_pll_clk_cfg(state);
 621
 622                        if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0)
 623                                return -1;
 624
 625                        ret = 7;
 626                        (*agc_state)++;
 627                        break;
 628
 629                case 1:
 630                        // AGC initialization
 631                        if (state->cfg.agc_control)
 632                                state->cfg.agc_control(&state->demod, 1);
 633
 634                        dib7000p_write_word(state, 78, 32768);
 635                        if (!state->current_agc->perform_agc_softsplit) {
 636                                /* we are using the wbd - so slow AGC startup */
 637                                /* force 0 split on WBD and restart AGC */
 638                                dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));
 639                                (*agc_state)++;
 640                                ret = 5;
 641                        } else {
 642                                /* default AGC startup */
 643                                (*agc_state) = 4;
 644                                /* wait AGC rough lock time */
 645                                ret = 7;
 646                        }
 647
 648                        dib7000p_restart_agc(state);
 649                        break;
 650
 651                case 2: /* fast split search path after 5sec */
 652                        dib7000p_write_word(state,  75, state->current_agc->setup | (1 << 4)); /* freeze AGC loop */
 653                        dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */
 654                        (*agc_state)++;
 655                        ret = 14;
 656                        break;
 657
 658        case 3: /* split search ended */
 659                        agc_split = (u8)dib7000p_read_word(state, 396); /* store the split value for the next time */
 660                        dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */
 661
 662                        dib7000p_write_word(state, 75,  state->current_agc->setup);   /* std AGC loop */
 663                        dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
 664
 665                        dib7000p_restart_agc(state);
 666
 667                        dprintk( "SPLIT %p: %hd", demod, agc_split);
 668
 669                        (*agc_state)++;
 670                        ret = 5;
 671                        break;
 672
 673                case 4: /* LNA startup */
 674                        // wait AGC accurate lock time
 675                        ret = 7;
 676
 677                        if (dib7000p_update_lna(state))
 678                                // wait only AGC rough lock time
 679                                ret = 5;
 680                        else // nothing was done, go to the next state
 681                                (*agc_state)++;
 682                        break;
 683
 684                case 5:
 685                        if (state->cfg.agc_control)
 686                                state->cfg.agc_control(&state->demod, 0);
 687                        (*agc_state)++;
 688                        break;
 689                default:
 690                        break;
 691        }
 692        return ret;
 693}
 694
 695static void dib7000p_update_timf(struct dib7000p_state *state)
 696{
 697        u32 timf = (dib7000p_read_word(state, 427) << 16) | dib7000p_read_word(state, 428);
 698        state->timf = timf * 160 / (state->current_bandwidth / 50);
 699        dib7000p_write_word(state, 23, (u16) (timf >> 16));
 700        dib7000p_write_word(state, 24, (u16) (timf & 0xffff));
 701        dprintk( "updated timf_frequency: %d (default: %d)",state->timf, state->cfg.bw->timf);
 702
 703}
 704
 705static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq)
 706{
 707        u16 value, est[4];
 708
 709    dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
 710
 711        /* nfft, guard, qam, alpha */
 712        value = 0;
 713        switch (ch->u.ofdm.transmission_mode) {
 714                case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
 715                case /* 4K MODE */ 255: value |= (2 << 7); break;
 716                default:
 717                case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
 718        }
 719        switch (ch->u.ofdm.guard_interval) {
 720                case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
 721                case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
 722                case GUARD_INTERVAL_1_4:  value |= (3 << 5); break;
 723                default:
 724                case GUARD_INTERVAL_1_8:  value |= (2 << 5); break;
 725        }
 726        switch (ch->u.ofdm.constellation) {
 727                case QPSK:  value |= (0 << 3); break;
 728                case QAM_16: value |= (1 << 3); break;
 729                default:
 730                case QAM_64: value |= (2 << 3); break;
 731        }
 732        switch (HIERARCHY_1) {
 733                case HIERARCHY_2: value |= 2; break;
 734                case HIERARCHY_4: value |= 4; break;
 735                default:
 736                case HIERARCHY_1: value |= 1; break;
 737        }
 738        dib7000p_write_word(state, 0, value);
 739        dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */
 740
 741        /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
 742        value = 0;
 743        if (1 != 0)
 744                value |= (1 << 6);
 745        if (ch->u.ofdm.hierarchy_information == 1)
 746                value |= (1 << 4);
 747        if (1 == 1)
 748                value |= 1;
 749        switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
 750                case FEC_2_3: value |= (2 << 1); break;
 751                case FEC_3_4: value |= (3 << 1); break;
 752                case FEC_5_6: value |= (5 << 1); break;
 753                case FEC_7_8: value |= (7 << 1); break;
 754                default:
 755                case FEC_1_2: value |= (1 << 1); break;
 756        }
 757        dib7000p_write_word(state, 208, value);
 758
 759        /* offset loop parameters */
 760        dib7000p_write_word(state, 26, 0x6680); // timf(6xxx)
 761        dib7000p_write_word(state, 32, 0x0003); // pha_off_max(xxx3)
 762        dib7000p_write_word(state, 29, 0x1273); // isi
 763        dib7000p_write_word(state, 33, 0x0005); // sfreq(xxx5)
 764
 765        /* P_dvsy_sync_wait */
 766        switch (ch->u.ofdm.transmission_mode) {
 767                case TRANSMISSION_MODE_8K: value = 256; break;
 768                case /* 4K MODE */ 255: value = 128; break;
 769                case TRANSMISSION_MODE_2K:
 770                default: value = 64; break;
 771        }
 772        switch (ch->u.ofdm.guard_interval) {
 773                case GUARD_INTERVAL_1_16: value *= 2; break;
 774                case GUARD_INTERVAL_1_8:  value *= 4; break;
 775                case GUARD_INTERVAL_1_4:  value *= 8; break;
 776                default:
 777                case GUARD_INTERVAL_1_32: value *= 1; break;
 778        }
 779        state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO
 780
 781        /* deactive the possibility of diversity reception if extended interleaver */
 782        state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K;
 783        dib7000p_set_diversity_in(&state->demod, state->div_state);
 784
 785        /* channel estimation fine configuration */
 786        switch (ch->u.ofdm.constellation) {
 787                case QAM_64:
 788                        est[0] = 0x0148;       /* P_adp_regul_cnt 0.04 */
 789                        est[1] = 0xfff0;       /* P_adp_noise_cnt -0.002 */
 790                        est[2] = 0x00a4;       /* P_adp_regul_ext 0.02 */
 791                        est[3] = 0xfff8;       /* P_adp_noise_ext -0.001 */
 792                        break;
 793                case QAM_16:
 794                        est[0] = 0x023d;       /* P_adp_regul_cnt 0.07 */
 795                        est[1] = 0xffdf;       /* P_adp_noise_cnt -0.004 */
 796                        est[2] = 0x00a4;       /* P_adp_regul_ext 0.02 */
 797                        est[3] = 0xfff0;       /* P_adp_noise_ext -0.002 */
 798                        break;
 799                default:
 800                        est[0] = 0x099a;       /* P_adp_regul_cnt 0.3 */
 801                        est[1] = 0xffae;       /* P_adp_noise_cnt -0.01 */
 802                        est[2] = 0x0333;       /* P_adp_regul_ext 0.1 */
 803                        est[3] = 0xfff8;       /* P_adp_noise_ext -0.002 */
 804                        break;
 805        }
 806        for (value = 0; value < 4; value++)
 807                dib7000p_write_word(state, 187 + value, est[value]);
 808}
 809
 810static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
 811{
 812        struct dib7000p_state *state = demod->demodulator_priv;
 813        struct dvb_frontend_parameters schan;
 814        u32 value, factor;
 815
 816        schan = *ch;
 817        schan.u.ofdm.constellation = QAM_64;
 818        schan.u.ofdm.guard_interval         = GUARD_INTERVAL_1_32;
 819        schan.u.ofdm.transmission_mode          = TRANSMISSION_MODE_8K;
 820        schan.u.ofdm.code_rate_HP  = FEC_2_3;
 821        schan.u.ofdm.code_rate_LP  = FEC_3_4;
 822        schan.u.ofdm.hierarchy_information          = 0;
 823
 824        dib7000p_set_channel(state, &schan, 7);
 825
 826        factor = BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth);
 827        if (factor >= 5000)
 828                factor = 1;
 829        else
 830                factor = 6;
 831
 832        // always use the setting for 8MHz here lock_time for 7,6 MHz are longer
 833        value = 30 * state->cfg.bw->internal * factor;
 834        dib7000p_write_word(state, 6,  (u16) ((value >> 16) & 0xffff)); // lock0 wait time
 835        dib7000p_write_word(state, 7,  (u16)  (value        & 0xffff)); // lock0 wait time
 836        value = 100 * state->cfg.bw->internal * factor;
 837        dib7000p_write_word(state, 8,  (u16) ((value >> 16) & 0xffff)); // lock1 wait time
 838        dib7000p_write_word(state, 9,  (u16)  (value        & 0xffff)); // lock1 wait time
 839        value = 500 * state->cfg.bw->internal * factor;
 840        dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
 841        dib7000p_write_word(state, 11, (u16)  (value        & 0xffff)); // lock2 wait time
 842
 843        value = dib7000p_read_word(state, 0);
 844        dib7000p_write_word(state, 0, (u16) ((1 << 9) | value));
 845        dib7000p_read_word(state, 1284);
 846        dib7000p_write_word(state, 0, (u16) value);
 847
 848        return 0;
 849}
 850
 851static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod)
 852{
 853        struct dib7000p_state *state = demod->demodulator_priv;
 854        u16 irq_pending = dib7000p_read_word(state, 1284);
 855
 856        if (irq_pending & 0x1) // failed
 857                return 1;
 858
 859        if (irq_pending & 0x2) // succeeded
 860                return 2;
 861
 862        return 0; // still pending
 863}
 864
 865static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw)
 866{
 867        static s16 notch[]={16143, 14402, 12238, 9713, 6902, 3888, 759, -2392};
 868        static u8 sine [] ={0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
 869        24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
 870        53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
 871        82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
 872        107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
 873        128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
 874        147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
 875        166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
 876        183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
 877        199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
 878        213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
 879        225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
 880        235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
 881        244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
 882        250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
 883        254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
 884        255, 255, 255, 255, 255, 255};
 885
 886        u32 xtal = state->cfg.bw->xtal_hz / 1000;
 887        int f_rel = DIV_ROUND_CLOSEST(rf_khz, xtal) * xtal - rf_khz;
 888        int k;
 889        int coef_re[8],coef_im[8];
 890        int bw_khz = bw;
 891        u32 pha;
 892
 893        dprintk( "relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal);
 894
 895
 896        if (f_rel < -bw_khz/2 || f_rel > bw_khz/2)
 897                return;
 898
 899        bw_khz /= 100;
 900
 901        dib7000p_write_word(state, 142 ,0x0610);
 902
 903        for (k = 0; k < 8; k++) {
 904                pha = ((f_rel * (k+1) * 112 * 80/bw_khz) /1000) & 0x3ff;
 905
 906                if (pha==0) {
 907                        coef_re[k] = 256;
 908                        coef_im[k] = 0;
 909                } else if(pha < 256) {
 910                        coef_re[k] = sine[256-(pha&0xff)];
 911                        coef_im[k] = sine[pha&0xff];
 912                } else if (pha == 256) {
 913                        coef_re[k] = 0;
 914                        coef_im[k] = 256;
 915                } else if (pha < 512) {
 916                        coef_re[k] = -sine[pha&0xff];
 917                        coef_im[k] = sine[256 - (pha&0xff)];
 918                } else if (pha == 512) {
 919                        coef_re[k] = -256;
 920                        coef_im[k] = 0;
 921                } else if (pha < 768) {
 922                        coef_re[k] = -sine[256-(pha&0xff)];
 923                        coef_im[k] = -sine[pha&0xff];
 924                } else if (pha == 768) {
 925                        coef_re[k] = 0;
 926                        coef_im[k] = -256;
 927                } else {
 928                        coef_re[k] = sine[pha&0xff];
 929                        coef_im[k] = -sine[256 - (pha&0xff)];
 930                }
 931
 932                coef_re[k] *= notch[k];
 933                coef_re[k] += (1<<14);
 934                if (coef_re[k] >= (1<<24))
 935                        coef_re[k]  = (1<<24) - 1;
 936                coef_re[k] /= (1<<15);
 937
 938                coef_im[k] *= notch[k];
 939                coef_im[k] += (1<<14);
 940                if (coef_im[k] >= (1<<24))
 941                        coef_im[k]  = (1<<24)-1;
 942                coef_im[k] /= (1<<15);
 943
 944                dprintk( "PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]);
 945
 946                dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
 947                dib7000p_write_word(state, 144, coef_im[k] & 0x3ff);
 948                dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
 949        }
 950        dib7000p_write_word(state,143 ,0);
 951}
 952
 953static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
 954{
 955        struct dib7000p_state *state = demod->demodulator_priv;
 956        u16 tmp = 0;
 957
 958        if (ch != NULL)
 959                dib7000p_set_channel(state, ch, 0);
 960        else
 961                return -EINVAL;
 962
 963        // restart demod
 964        dib7000p_write_word(state, 770, 0x4000);
 965        dib7000p_write_word(state, 770, 0x0000);
 966        msleep(45);
 967
 968        /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */
 969        tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
 970        if (state->sfn_workaround_active) {
 971                dprintk( "SFN workaround is active");
 972                tmp |= (1 << 9);
 973                dib7000p_write_word(state, 166, 0x4000); // P_pha3_force_pha_shift
 974        } else {
 975                dib7000p_write_word(state, 166, 0x0000); // P_pha3_force_pha_shift
 976        }
 977        dib7000p_write_word(state, 29, tmp);
 978
 979        // never achieved a lock with that bandwidth so far - wait for osc-freq to update
 980        if (state->timf == 0)
 981                msleep(200);
 982
 983        /* offset loop parameters */
 984
 985        /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
 986        tmp = (6 << 8) | 0x80;
 987        switch (ch->u.ofdm.transmission_mode) {
 988                case TRANSMISSION_MODE_2K: tmp |= (7 << 12); break;
 989                case /* 4K MODE */ 255: tmp |= (8 << 12); break;
 990                default:
 991                case TRANSMISSION_MODE_8K: tmp |= (9 << 12); break;
 992        }
 993        dib7000p_write_word(state, 26, tmp);  /* timf_a(6xxx) */
 994
 995        /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
 996        tmp = (0 << 4);
 997        switch (ch->u.ofdm.transmission_mode) {
 998                case TRANSMISSION_MODE_2K: tmp |= 0x6; break;
 999                case /* 4K MODE */ 255: tmp |= 0x7; break;
1000                default:
1001                case TRANSMISSION_MODE_8K: tmp |= 0x8; break;
1002        }
1003        dib7000p_write_word(state, 32,  tmp);
1004
1005        /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1006        tmp = (0 << 4);
1007        switch (ch->u.ofdm.transmission_mode) {
1008                case TRANSMISSION_MODE_2K: tmp |= 0x6; break;
1009                case /* 4K MODE */ 255: tmp |= 0x7; break;
1010                default:
1011                case TRANSMISSION_MODE_8K: tmp |= 0x8; break;
1012        }
1013        dib7000p_write_word(state, 33,  tmp);
1014
1015        tmp = dib7000p_read_word(state,509);
1016        if (!((tmp >> 6) & 0x1)) {
1017                /* restart the fec */
1018                tmp = dib7000p_read_word(state,771);
1019                dib7000p_write_word(state, 771, tmp | (1 << 1));
1020                dib7000p_write_word(state, 771, tmp);
1021                msleep(10);
1022                tmp = dib7000p_read_word(state,509);
1023        }
1024
1025        // we achieved a lock - it's time to update the osc freq
1026        if ((tmp >> 6) & 0x1)
1027                dib7000p_update_timf(state);
1028
1029        if (state->cfg.spur_protect)
1030                dib7000p_spur_protect(state, ch->frequency/1000, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1031
1032    dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1033        return 0;
1034}
1035
1036static int dib7000p_wakeup(struct dvb_frontend *demod)
1037{
1038        struct dib7000p_state *state = demod->demodulator_priv;
1039        dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
1040        dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
1041        return 0;
1042}
1043
1044static int dib7000p_sleep(struct dvb_frontend *demod)
1045{
1046        struct dib7000p_state *state = demod->demodulator_priv;
1047        return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1048}
1049
1050static int dib7000p_identify(struct dib7000p_state *st)
1051{
1052        u16 value;
1053        dprintk( "checking demod on I2C address: %d (%x)",
1054                st->i2c_addr, st->i2c_addr);
1055
1056        if ((value = dib7000p_read_word(st, 768)) != 0x01b3) {
1057                dprintk( "wrong Vendor ID (read=0x%x)",value);
1058                return -EREMOTEIO;
1059        }
1060
1061        if ((value = dib7000p_read_word(st, 769)) != 0x4000) {
1062                dprintk( "wrong Device ID (%x)",value);
1063                return -EREMOTEIO;
1064        }
1065
1066        return 0;
1067}
1068
1069
1070static int dib7000p_get_frontend(struct dvb_frontend* fe,
1071                                struct dvb_frontend_parameters *fep)
1072{
1073        struct dib7000p_state *state = fe->demodulator_priv;
1074        u16 tps = dib7000p_read_word(state,463);
1075
1076        fep->inversion = INVERSION_AUTO;
1077
1078        fep->u.ofdm.bandwidth = BANDWIDTH_TO_INDEX(state->current_bandwidth);
1079
1080        switch ((tps >> 8) & 0x3) {
1081                case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break;
1082                case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break;
1083                /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */
1084        }
1085
1086        switch (tps & 0x3) {
1087                case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break;
1088                case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break;
1089                case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break;
1090                case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break;
1091        }
1092
1093        switch ((tps >> 14) & 0x3) {
1094                case 0: fep->u.ofdm.constellation = QPSK; break;
1095                case 1: fep->u.ofdm.constellation = QAM_16; break;
1096                case 2:
1097                default: fep->u.ofdm.constellation = QAM_64; break;
1098        }
1099
1100        /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1101        /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1102
1103        fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
1104        switch ((tps >> 5) & 0x7) {
1105                case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break;
1106                case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break;
1107                case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break;
1108                case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break;
1109                case 7:
1110                default: fep->u.ofdm.code_rate_HP = FEC_7_8; break;
1111
1112        }
1113
1114        switch ((tps >> 2) & 0x7) {
1115                case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break;
1116                case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break;
1117                case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break;
1118                case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break;
1119                case 7:
1120                default: fep->u.ofdm.code_rate_LP = FEC_7_8; break;
1121        }
1122
1123        /* native interleaver: (dib7000p_read_word(state, 464) >>  5) & 0x1 */
1124
1125        return 0;
1126}
1127
1128static int dib7000p_set_frontend(struct dvb_frontend* fe,
1129                                struct dvb_frontend_parameters *fep)
1130{
1131        struct dib7000p_state *state = fe->demodulator_priv;
1132        int time, ret;
1133
1134        dib7000p_set_output_mode(state, OUTMODE_HIGH_Z);
1135
1136    /* maybe the parameter has been changed */
1137        state->sfn_workaround_active = buggy_sfn_workaround;
1138
1139        if (fe->ops.tuner_ops.set_params)
1140                fe->ops.tuner_ops.set_params(fe, fep);
1141
1142        /* start up the AGC */
1143        state->agc_state = 0;
1144        do {
1145                time = dib7000p_agc_startup(fe, fep);
1146                if (time != -1)
1147                        msleep(time);
1148        } while (time != -1);
1149
1150        if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
1151                fep->u.ofdm.guard_interval    == GUARD_INTERVAL_AUTO ||
1152                fep->u.ofdm.constellation     == QAM_AUTO ||
1153                fep->u.ofdm.code_rate_HP      == FEC_AUTO) {
1154                int i = 800, found;
1155
1156                dib7000p_autosearch_start(fe, fep);
1157                do {
1158                        msleep(1);
1159                        found = dib7000p_autosearch_is_irq(fe);
1160                } while (found == 0 && i--);
1161
1162                dprintk("autosearch returns: %d",found);
1163                if (found == 0 || found == 1)
1164                        return 0; // no channel found
1165
1166                dib7000p_get_frontend(fe, fep);
1167        }
1168
1169        ret = dib7000p_tune(fe, fep);
1170
1171        /* make this a config parameter */
1172        dib7000p_set_output_mode(state, state->cfg.output_mode);
1173    return ret;
1174}
1175
1176static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t *stat)
1177{
1178        struct dib7000p_state *state = fe->demodulator_priv;
1179        u16 lock = dib7000p_read_word(state, 509);
1180
1181        *stat = 0;
1182
1183        if (lock & 0x8000)
1184                *stat |= FE_HAS_SIGNAL;
1185        if (lock & 0x3000)
1186                *stat |= FE_HAS_CARRIER;
1187        if (lock & 0x0100)
1188                *stat |= FE_HAS_VITERBI;
1189        if (lock & 0x0010)
1190                *stat |= FE_HAS_SYNC;
1191        if (lock & 0x0008)
1192                *stat |= FE_HAS_LOCK;
1193
1194        return 0;
1195}
1196
1197static int dib7000p_read_ber(struct dvb_frontend *fe, u32 *ber)
1198{
1199        struct dib7000p_state *state = fe->demodulator_priv;
1200        *ber = (dib7000p_read_word(state, 500) << 16) | dib7000p_read_word(state, 501);
1201        return 0;
1202}
1203
1204static int dib7000p_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
1205{
1206        struct dib7000p_state *state = fe->demodulator_priv;
1207        *unc = dib7000p_read_word(state, 506);
1208        return 0;
1209}
1210
1211static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1212{
1213        struct dib7000p_state *state = fe->demodulator_priv;
1214        u16 val = dib7000p_read_word(state, 394);
1215        *strength = 65535 - val;
1216        return 0;
1217}
1218
1219static int dib7000p_read_snr(struct dvb_frontend* fe, u16 *snr)
1220{
1221        struct dib7000p_state *state = fe->demodulator_priv;
1222        u16 val;
1223        s32 signal_mant, signal_exp, noise_mant, noise_exp;
1224        u32 result = 0;
1225
1226        val = dib7000p_read_word(state, 479);
1227        noise_mant = (val >> 4) & 0xff;
1228        noise_exp = ((val & 0xf) << 2);
1229        val = dib7000p_read_word(state, 480);
1230        noise_exp += ((val >> 14) & 0x3);
1231        if ((noise_exp & 0x20) != 0)
1232                noise_exp -= 0x40;
1233
1234        signal_mant = (val >> 6) & 0xFF;
1235        signal_exp  = (val & 0x3F);
1236        if ((signal_exp & 0x20) != 0)
1237                signal_exp -= 0x40;
1238
1239        if (signal_mant != 0)
1240                result = intlog10(2) * 10 * signal_exp + 10 *
1241                        intlog10(signal_mant);
1242        else
1243                result = intlog10(2) * 10 * signal_exp - 100;
1244
1245        if (noise_mant != 0)
1246                result -= intlog10(2) * 10 * noise_exp + 10 *
1247                        intlog10(noise_mant);
1248        else
1249                result -= intlog10(2) * 10 * noise_exp - 100;
1250
1251        *snr = result / ((1 << 24) / 10);
1252        return 0;
1253}
1254
1255static int dib7000p_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
1256{
1257        tune->min_delay_ms = 1000;
1258        return 0;
1259}
1260
1261static void dib7000p_release(struct dvb_frontend *demod)
1262{
1263        struct dib7000p_state *st = demod->demodulator_priv;
1264        dibx000_exit_i2c_master(&st->i2c_master);
1265        kfree(st);
1266}
1267
1268int dib7000pc_detection(struct i2c_adapter *i2c_adap)
1269{
1270        u8 tx[2], rx[2];
1271        struct i2c_msg msg[2] = {
1272                { .addr = 18 >> 1, .flags = 0,        .buf = tx, .len = 2 },
1273                { .addr = 18 >> 1, .flags = I2C_M_RD, .buf = rx, .len = 2 },
1274        };
1275
1276        tx[0] = 0x03;
1277        tx[1] = 0x00;
1278
1279        if (i2c_transfer(i2c_adap, msg, 2) == 2)
1280                if (rx[0] == 0x01 && rx[1] == 0xb3) {
1281                        dprintk("-D-  DiB7000PC detected");
1282                        return 1;
1283                }
1284
1285        msg[0].addr = msg[1].addr = 0x40;
1286
1287        if (i2c_transfer(i2c_adap, msg, 2) == 2)
1288                if (rx[0] == 0x01 && rx[1] == 0xb3) {
1289                        dprintk("-D-  DiB7000PC detected");
1290                        return 1;
1291                }
1292
1293        dprintk("-D-  DiB7000PC not detected");
1294        return 0;
1295}
1296EXPORT_SYMBOL(dib7000pc_detection);
1297
1298struct i2c_adapter * dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
1299{
1300        struct dib7000p_state *st = demod->demodulator_priv;
1301        return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1302}
1303EXPORT_SYMBOL(dib7000p_get_i2c_master);
1304
1305int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
1306{
1307        struct dib7000p_state st = { .i2c_adap = i2c };
1308        int k = 0;
1309        u8 new_addr = 0;
1310
1311        for (k = no_of_demods-1; k >= 0; k--) {
1312                st.cfg = cfg[k];
1313
1314                /* designated i2c address */
1315                new_addr          = (0x40 + k) << 1;
1316                st.i2c_addr = new_addr;
1317                if (dib7000p_identify(&st) != 0) {
1318                        st.i2c_addr = default_addr;
1319                        if (dib7000p_identify(&st) != 0) {
1320                                dprintk("DiB7000P #%d: not identified\n", k);
1321                                return -EIO;
1322                        }
1323                }
1324
1325                /* start diversity to pull_down div_str - just for i2c-enumeration */
1326                dib7000p_set_output_mode(&st, OUTMODE_DIVERSITY);
1327
1328                /* set new i2c address and force divstart */
1329                dib7000p_write_word(&st, 1285, (new_addr << 2) | 0x2);
1330
1331                dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
1332        }
1333
1334        for (k = 0; k < no_of_demods; k++) {
1335                st.cfg = cfg[k];
1336                st.i2c_addr = (0x40 + k) << 1;
1337
1338                // unforce divstr
1339                dib7000p_write_word(&st, 1285, st.i2c_addr << 2);
1340
1341                /* deactivate div - it was just for i2c-enumeration */
1342                dib7000p_set_output_mode(&st, OUTMODE_HIGH_Z);
1343        }
1344
1345        return 0;
1346}
1347EXPORT_SYMBOL(dib7000p_i2c_enumeration);
1348
1349static struct dvb_frontend_ops dib7000p_ops;
1350struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
1351{
1352        struct dvb_frontend *demod;
1353        struct dib7000p_state *st;
1354        st = kzalloc(sizeof(struct dib7000p_state), GFP_KERNEL);
1355        if (st == NULL)
1356                return NULL;
1357
1358        memcpy(&st->cfg, cfg, sizeof(struct dib7000p_config));
1359        st->i2c_adap = i2c_adap;
1360        st->i2c_addr = i2c_addr;
1361        st->gpio_val = cfg->gpio_val;
1362        st->gpio_dir = cfg->gpio_dir;
1363
1364        /* Ensure the output mode remains at the previous default if it's
1365         * not specifically set by the caller.
1366         */
1367        if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) &&
1368            (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
1369                st->cfg.output_mode = OUTMODE_MPEG2_FIFO;
1370
1371        demod                   = &st->demod;
1372        demod->demodulator_priv = st;
1373        memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));
1374
1375        if (dib7000p_identify(st) != 0)
1376                goto error;
1377
1378        /* FIXME: make sure the dev.parent field is initialized, or else
1379        request_firmware() will hit an OOPS (this should be moved somewhere
1380        more common) */
1381        st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent;
1382
1383        dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr);
1384
1385        dib7000p_demod_reset(st);
1386
1387        return demod;
1388
1389error:
1390        kfree(st);
1391        return NULL;
1392}
1393EXPORT_SYMBOL(dib7000p_attach);
1394
1395static struct dvb_frontend_ops dib7000p_ops = {
1396        .info = {
1397                .name = "DiBcom 7000PC",
1398                .type = FE_OFDM,
1399                .frequency_min      = 44250000,
1400                .frequency_max      = 867250000,
1401                .frequency_stepsize = 62500,
1402                .caps = FE_CAN_INVERSION_AUTO |
1403                        FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1404                        FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1405                        FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1406                        FE_CAN_TRANSMISSION_MODE_AUTO |
1407                        FE_CAN_GUARD_INTERVAL_AUTO |
1408                        FE_CAN_RECOVER |
1409                        FE_CAN_HIERARCHY_AUTO,
1410        },
1411
1412        .release              = dib7000p_release,
1413
1414        .init                 = dib7000p_wakeup,
1415        .sleep                = dib7000p_sleep,
1416
1417        .set_frontend         = dib7000p_set_frontend,
1418        .get_tune_settings    = dib7000p_fe_get_tune_settings,
1419        .get_frontend         = dib7000p_get_frontend,
1420
1421        .read_status          = dib7000p_read_status,
1422        .read_ber             = dib7000p_read_ber,
1423        .read_signal_strength = dib7000p_read_signal_strength,
1424        .read_snr             = dib7000p_read_snr,
1425        .read_ucblocks        = dib7000p_read_unc_blocks,
1426};
1427
1428MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
1429MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
1430MODULE_LICENSE("GPL");
1431