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