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