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