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