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