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        dib7000m_set_channel(state, ch, 0);
1045
1046        // restart demod
1047        ret |= dib7000m_write_word(state, 898, 0x4000);
1048        ret |= dib7000m_write_word(state, 898, 0x0000);
1049        msleep(45);
1050
1051        dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD);
1052        /* 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 */
1053        ret |= dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3));
1054
1055        // never achieved a lock before - wait for timfreq to update
1056        if (state->timf == 0)
1057                msleep(200);
1058
1059        //dump_reg(state);
1060        /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
1061        value = (6 << 8) | 0x80;
1062        switch (ch->transmission_mode) {
1063                case TRANSMISSION_MODE_2K: value |= (7 << 12); break;
1064                case TRANSMISSION_MODE_4K: value |= (8 << 12); break;
1065                default:
1066                case TRANSMISSION_MODE_8K: value |= (9 << 12); break;
1067        }
1068        ret |= dib7000m_write_word(state, 26, value);
1069
1070        /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1071        value = (0 << 4);
1072        switch (ch->transmission_mode) {
1073                case TRANSMISSION_MODE_2K: value |= 0x6; break;
1074                case TRANSMISSION_MODE_4K: value |= 0x7; break;
1075                default:
1076                case TRANSMISSION_MODE_8K: value |= 0x8; break;
1077        }
1078        ret |= dib7000m_write_word(state, 32, value);
1079
1080        /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1081        value = (0 << 4);
1082        switch (ch->transmission_mode) {
1083                case TRANSMISSION_MODE_2K: value |= 0x6; break;
1084                case TRANSMISSION_MODE_4K: value |= 0x7; break;
1085                default:
1086                case TRANSMISSION_MODE_8K: value |= 0x8; break;
1087        }
1088        ret |= dib7000m_write_word(state, 33,  value);
1089
1090        // we achieved a lock - it's time to update the timf freq
1091        if ((dib7000m_read_word(state, 535) >> 6)  & 0x1)
1092                dib7000m_update_timf(state);
1093
1094        dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
1095        return ret;
1096}
1097
1098static int dib7000m_wakeup(struct dvb_frontend *demod)
1099{
1100        struct dib7000m_state *state = demod->demodulator_priv;
1101
1102        dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
1103
1104        if (dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
1105                dprintk( "could not start Slow ADC");
1106
1107        return 0;
1108}
1109
1110static int dib7000m_sleep(struct dvb_frontend *demod)
1111{
1112        struct dib7000m_state *st = demod->demodulator_priv;
1113        dib7000m_set_output_mode(st, OUTMODE_HIGH_Z);
1114        dib7000m_set_power_mode(st, DIB7000M_POWER_INTERFACE_ONLY);
1115        return dib7000m_set_adc_state(st, DIBX000_SLOW_ADC_OFF) |
1116                dib7000m_set_adc_state(st, DIBX000_ADC_OFF);
1117}
1118
1119static int dib7000m_identify(struct dib7000m_state *state)
1120{
1121        u16 value;
1122
1123        if ((value = dib7000m_read_word(state, 896)) != 0x01b3) {
1124                dprintk( "wrong Vendor ID (0x%x)",value);
1125                return -EREMOTEIO;
1126        }
1127
1128        state->revision = dib7000m_read_word(state, 897);
1129        if (state->revision != 0x4000 &&
1130                state->revision != 0x4001 &&
1131                state->revision != 0x4002 &&
1132                state->revision != 0x4003) {
1133                dprintk( "wrong Device ID (0x%x)",value);
1134                return -EREMOTEIO;
1135        }
1136
1137        /* protect this driver to be used with 7000PC */
1138        if (state->revision == 0x4000 && dib7000m_read_word(state, 769) == 0x4000) {
1139                dprintk( "this driver does not work with DiB7000PC");
1140                return -EREMOTEIO;
1141        }
1142
1143        switch (state->revision) {
1144                case 0x4000: dprintk( "found DiB7000MA/PA/MB/PB"); break;
1145                case 0x4001: state->reg_offs = 1; dprintk( "found DiB7000HC"); break;
1146                case 0x4002: state->reg_offs = 1; dprintk( "found DiB7000MC"); break;
1147                case 0x4003: state->reg_offs = 1; dprintk( "found DiB9000"); break;
1148        }
1149
1150        return 0;
1151}
1152
1153
1154static int dib7000m_get_frontend(struct dvb_frontend* fe)
1155{
1156        struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
1157        struct dib7000m_state *state = fe->demodulator_priv;
1158        u16 tps = dib7000m_read_word(state,480);
1159
1160        fep->inversion = INVERSION_AUTO;
1161
1162        fep->bandwidth_hz = BANDWIDTH_TO_HZ(state->current_bandwidth);
1163
1164        switch ((tps >> 8) & 0x3) {
1165                case 0: fep->transmission_mode = TRANSMISSION_MODE_2K; break;
1166                case 1: fep->transmission_mode = TRANSMISSION_MODE_8K; break;
1167                /* case 2: fep->transmission_mode = TRANSMISSION_MODE_4K; break; */
1168        }
1169
1170        switch (tps & 0x3) {
1171                case 0: fep->guard_interval = GUARD_INTERVAL_1_32; break;
1172                case 1: fep->guard_interval = GUARD_INTERVAL_1_16; break;
1173                case 2: fep->guard_interval = GUARD_INTERVAL_1_8; break;
1174                case 3: fep->guard_interval = GUARD_INTERVAL_1_4; break;
1175        }
1176
1177        switch ((tps >> 14) & 0x3) {
1178                case 0: fep->modulation = QPSK; break;
1179                case 1: fep->modulation = QAM_16; break;
1180                case 2:
1181                default: fep->modulation = QAM_64; break;
1182        }
1183
1184        /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1185        /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1186
1187        fep->hierarchy = HIERARCHY_NONE;
1188        switch ((tps >> 5) & 0x7) {
1189                case 1: fep->code_rate_HP = FEC_1_2; break;
1190                case 2: fep->code_rate_HP = FEC_2_3; break;
1191                case 3: fep->code_rate_HP = FEC_3_4; break;
1192                case 5: fep->code_rate_HP = FEC_5_6; break;
1193                case 7:
1194                default: fep->code_rate_HP = FEC_7_8; break;
1195
1196        }
1197
1198        switch ((tps >> 2) & 0x7) {
1199                case 1: fep->code_rate_LP = FEC_1_2; break;
1200                case 2: fep->code_rate_LP = FEC_2_3; break;
1201                case 3: fep->code_rate_LP = FEC_3_4; break;
1202                case 5: fep->code_rate_LP = FEC_5_6; break;
1203                case 7:
1204                default: fep->code_rate_LP = FEC_7_8; break;
1205        }
1206
1207        /* native interleaver: (dib7000m_read_word(state, 481) >>  5) & 0x1 */
1208
1209        return 0;
1210}
1211
1212static int dib7000m_set_frontend(struct dvb_frontend *fe)
1213{
1214        struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
1215        struct dib7000m_state *state = fe->demodulator_priv;
1216        int time, ret;
1217
1218        dib7000m_set_output_mode(state, OUTMODE_HIGH_Z);
1219
1220        dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->bandwidth_hz));
1221
1222        if (fe->ops.tuner_ops.set_params)
1223                fe->ops.tuner_ops.set_params(fe);
1224
1225        /* start up the AGC */
1226        state->agc_state = 0;
1227        do {
1228                time = dib7000m_agc_startup(fe);
1229                if (time != -1)
1230                        msleep(time);
1231        } while (time != -1);
1232
1233        if (fep->transmission_mode == TRANSMISSION_MODE_AUTO ||
1234                fep->guard_interval    == GUARD_INTERVAL_AUTO ||
1235                fep->modulation        == QAM_AUTO ||
1236                fep->code_rate_HP      == FEC_AUTO) {
1237                int i = 800, found;
1238
1239                dib7000m_autosearch_start(fe);
1240                do {
1241                        msleep(1);
1242                        found = dib7000m_autosearch_is_irq(fe);
1243                } while (found == 0 && i--);
1244
1245                dprintk("autosearch returns: %d",found);
1246                if (found == 0 || found == 1)
1247                        return 0; // no channel found
1248
1249                dib7000m_get_frontend(fe);
1250        }
1251
1252        ret = dib7000m_tune(fe);
1253
1254        /* make this a config parameter */
1255        dib7000m_set_output_mode(state, OUTMODE_MPEG2_FIFO);
1256        return ret;
1257}
1258
1259static int dib7000m_read_status(struct dvb_frontend *fe, fe_status_t *stat)
1260{
1261        struct dib7000m_state *state = fe->demodulator_priv;
1262        u16 lock = dib7000m_read_word(state, 535);
1263
1264        *stat = 0;
1265
1266        if (lock & 0x8000)
1267                *stat |= FE_HAS_SIGNAL;
1268        if (lock & 0x3000)
1269                *stat |= FE_HAS_CARRIER;
1270        if (lock & 0x0100)
1271                *stat |= FE_HAS_VITERBI;
1272        if (lock & 0x0010)
1273                *stat |= FE_HAS_SYNC;
1274        if (lock & 0x0008)
1275                *stat |= FE_HAS_LOCK;
1276
1277        return 0;
1278}
1279
1280static int dib7000m_read_ber(struct dvb_frontend *fe, u32 *ber)
1281{
1282        struct dib7000m_state *state = fe->demodulator_priv;
1283        *ber = (dib7000m_read_word(state, 526) << 16) | dib7000m_read_word(state, 527);
1284        return 0;
1285}
1286
1287static int dib7000m_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
1288{
1289        struct dib7000m_state *state = fe->demodulator_priv;
1290        *unc = dib7000m_read_word(state, 534);
1291        return 0;
1292}
1293
1294static int dib7000m_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1295{
1296        struct dib7000m_state *state = fe->demodulator_priv;
1297        u16 val = dib7000m_read_word(state, 390);
1298        *strength = 65535 - val;
1299        return 0;
1300}
1301
1302static int dib7000m_read_snr(struct dvb_frontend* fe, u16 *snr)
1303{
1304        *snr = 0x0000;
1305        return 0;
1306}
1307
1308static int dib7000m_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
1309{
1310        tune->min_delay_ms = 1000;
1311        return 0;
1312}
1313
1314static void dib7000m_release(struct dvb_frontend *demod)
1315{
1316        struct dib7000m_state *st = demod->demodulator_priv;
1317        dibx000_exit_i2c_master(&st->i2c_master);
1318        kfree(st);
1319}
1320
1321struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
1322{
1323        struct dib7000m_state *st = demod->demodulator_priv;
1324        return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1325}
1326EXPORT_SYMBOL(dib7000m_get_i2c_master);
1327
1328int dib7000m_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1329{
1330        struct dib7000m_state *state = fe->demodulator_priv;
1331        u16 val = dib7000m_read_word(state, 294 + state->reg_offs) & 0xffef;
1332        val |= (onoff & 0x1) << 4;
1333        dprintk("PID filter enabled %d", onoff);
1334        return dib7000m_write_word(state, 294 + state->reg_offs, val);
1335}
1336EXPORT_SYMBOL(dib7000m_pid_filter_ctrl);
1337
1338int dib7000m_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1339{
1340        struct dib7000m_state *state = fe->demodulator_priv;
1341        dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
1342        return dib7000m_write_word(state, 300 + state->reg_offs + id,
1343                        onoff ? (1 << 13) | pid : 0);
1344}
1345EXPORT_SYMBOL(dib7000m_pid_filter);
1346
1347#if 0
1348/* used with some prototype boards */
1349int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods,
1350                u8 default_addr, struct dib7000m_config cfg[])
1351{
1352        struct dib7000m_state st = { .i2c_adap = i2c };
1353        int k = 0;
1354        u8 new_addr = 0;
1355
1356        for (k = no_of_demods-1; k >= 0; k--) {
1357                st.cfg = cfg[k];
1358
1359                /* designated i2c address */
1360                new_addr          = (0x40 + k) << 1;
1361                st.i2c_addr = new_addr;
1362                if (dib7000m_identify(&st) != 0) {
1363                        st.i2c_addr = default_addr;
1364                        if (dib7000m_identify(&st) != 0) {
1365                                dprintk("DiB7000M #%d: not identified", k);
1366                                return -EIO;
1367                        }
1368                }
1369
1370                /* start diversity to pull_down div_str - just for i2c-enumeration */
1371                dib7000m_set_output_mode(&st, OUTMODE_DIVERSITY);
1372
1373                dib7000m_write_word(&st, 1796, 0x0); // select DVB-T output
1374
1375                /* set new i2c address and force divstart */
1376                dib7000m_write_word(&st, 1794, (new_addr << 2) | 0x2);
1377
1378                dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
1379        }
1380
1381        for (k = 0; k < no_of_demods; k++) {
1382                st.cfg = cfg[k];
1383                st.i2c_addr = (0x40 + k) << 1;
1384
1385                // unforce divstr
1386                dib7000m_write_word(&st,1794, st.i2c_addr << 2);
1387
1388                /* deactivate div - it was just for i2c-enumeration */
1389                dib7000m_set_output_mode(&st, OUTMODE_HIGH_Z);
1390        }
1391
1392        return 0;
1393}
1394EXPORT_SYMBOL(dib7000m_i2c_enumeration);
1395#endif
1396
1397static struct dvb_frontend_ops dib7000m_ops;
1398struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg)
1399{
1400        struct dvb_frontend *demod;
1401        struct dib7000m_state *st;
1402        st = kzalloc(sizeof(struct dib7000m_state), GFP_KERNEL);
1403        if (st == NULL)
1404                return NULL;
1405
1406        memcpy(&st->cfg, cfg, sizeof(struct dib7000m_config));
1407        st->i2c_adap = i2c_adap;
1408        st->i2c_addr = i2c_addr;
1409
1410        demod                   = &st->demod;
1411        demod->demodulator_priv = st;
1412        memcpy(&st->demod.ops, &dib7000m_ops, sizeof(struct dvb_frontend_ops));
1413        mutex_init(&st->i2c_buffer_lock);
1414
1415        st->timf_default = cfg->bw->timf;
1416
1417        if (dib7000m_identify(st) != 0)
1418                goto error;
1419
1420        if (st->revision == 0x4000)
1421                dibx000_init_i2c_master(&st->i2c_master, DIB7000, st->i2c_adap, st->i2c_addr);
1422        else
1423                dibx000_init_i2c_master(&st->i2c_master, DIB7000MC, st->i2c_adap, st->i2c_addr);
1424
1425        dib7000m_demod_reset(st);
1426
1427        return demod;
1428
1429error:
1430        kfree(st);
1431        return NULL;
1432}
1433EXPORT_SYMBOL(dib7000m_attach);
1434
1435static struct dvb_frontend_ops dib7000m_ops = {
1436        .delsys = { SYS_DVBT },
1437        .info = {
1438                .name = "DiBcom 7000MA/MB/PA/PB/MC",
1439                .frequency_min      = 44250000,
1440                .frequency_max      = 867250000,
1441                .frequency_stepsize = 62500,
1442                .caps = FE_CAN_INVERSION_AUTO |
1443                        FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1444                        FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1445                        FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1446                        FE_CAN_TRANSMISSION_MODE_AUTO |
1447                        FE_CAN_GUARD_INTERVAL_AUTO |
1448                        FE_CAN_RECOVER |
1449                        FE_CAN_HIERARCHY_AUTO,
1450        },
1451
1452        .release              = dib7000m_release,
1453
1454        .init                 = dib7000m_wakeup,
1455        .sleep                = dib7000m_sleep,
1456
1457        .set_frontend         = dib7000m_set_frontend,
1458        .get_tune_settings    = dib7000m_fe_get_tune_settings,
1459        .get_frontend         = dib7000m_get_frontend,
1460
1461        .read_status          = dib7000m_read_status,
1462        .read_ber             = dib7000m_read_ber,
1463        .read_signal_strength = dib7000m_read_signal_strength,
1464        .read_snr             = dib7000m_read_snr,
1465        .read_ucblocks        = dib7000m_read_unc_blocks,
1466};
1467
1468MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
1469MODULE_DESCRIPTION("Driver for the DiBcom 7000MA/MB/PA/PB/MC COFDM demodulator");
1470MODULE_LICENSE("GPL");
1471