linux/drivers/media/dvb-frontends/dib3000mc.c
<<
>>
Prefs
   1/*
   2 * Driver for DiBcom DiB3000MC/P-demodulator.
   3 *
   4 * Copyright (C) 2004-7 DiBcom (http://www.dibcom.fr/)
   5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de)
   6 *
   7 * This code is partially based on the previous dib3000mc.c .
   8 *
   9 * This program is free software; you can redistribute it and/or
  10 *      modify it under the terms of the GNU General Public License as
  11 *      published by the Free Software Foundation, version 2.
  12 */
  13
  14#include <linux/kernel.h>
  15#include <linux/slab.h>
  16#include <linux/i2c.h>
  17
  18#include "dvb_frontend.h"
  19
  20#include "dib3000mc.h"
  21
  22static int debug;
  23module_param(debug, int, 0644);
  24MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
  25
  26static int buggy_sfn_workaround;
  27module_param(buggy_sfn_workaround, int, 0644);
  28MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)");
  29
  30#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); printk("\n"); } } while (0)
  31
  32struct dib3000mc_state {
  33        struct dvb_frontend demod;
  34        struct dib3000mc_config *cfg;
  35
  36        u8 i2c_addr;
  37        struct i2c_adapter *i2c_adap;
  38
  39        struct dibx000_i2c_master i2c_master;
  40
  41        u32 timf;
  42
  43        u32 current_bandwidth;
  44
  45        u16 dev_id;
  46
  47        u8 sfn_workaround_active :1;
  48};
  49
  50static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
  51{
  52        u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
  53        u8 rb[2];
  54        struct i2c_msg msg[2] = {
  55                { .addr = state->i2c_addr >> 1, .flags = 0,        .buf = wb, .len = 2 },
  56                { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
  57        };
  58
  59        if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
  60                dprintk("i2c read error on %d\n",reg);
  61
  62        return (rb[0] << 8) | rb[1];
  63}
  64
  65static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
  66{
  67        u8 b[4] = {
  68                (reg >> 8) & 0xff, reg & 0xff,
  69                (val >> 8) & 0xff, val & 0xff,
  70        };
  71        struct i2c_msg msg = {
  72                .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
  73        };
  74        return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
  75}
  76
  77static int dib3000mc_identify(struct dib3000mc_state *state)
  78{
  79        u16 value;
  80        if ((value = dib3000mc_read_word(state, 1025)) != 0x01b3) {
  81                dprintk("-E-  DiB3000MC/P: wrong Vendor ID (read=0x%x)\n",value);
  82                return -EREMOTEIO;
  83        }
  84
  85        value = dib3000mc_read_word(state, 1026);
  86        if (value != 0x3001 && value != 0x3002) {
  87                dprintk("-E-  DiB3000MC/P: wrong Device ID (%x)\n",value);
  88                return -EREMOTEIO;
  89        }
  90        state->dev_id = value;
  91
  92        dprintk("-I-  found DiB3000MC/P: %x\n",state->dev_id);
  93
  94        return 0;
  95}
  96
  97static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u32 bw, u8 update_offset)
  98{
  99        u32 timf;
 100
 101        if (state->timf == 0) {
 102                timf = 1384402; // default value for 8MHz
 103                if (update_offset)
 104                        msleep(200); // first time we do an update
 105        } else
 106                timf = state->timf;
 107
 108        timf *= (bw / 1000);
 109
 110        if (update_offset) {
 111                s16 tim_offs = dib3000mc_read_word(state, 416);
 112
 113                if (tim_offs &  0x2000)
 114                        tim_offs -= 0x4000;
 115
 116                if (nfft == TRANSMISSION_MODE_2K)
 117                        tim_offs *= 4;
 118
 119                timf += tim_offs;
 120                state->timf = timf / (bw / 1000);
 121        }
 122
 123        dprintk("timf: %d\n", timf);
 124
 125        dib3000mc_write_word(state, 23, (u16) (timf >> 16));
 126        dib3000mc_write_word(state, 24, (u16) (timf      ) & 0xffff);
 127
 128        return 0;
 129}
 130
 131static int dib3000mc_setup_pwm_state(struct dib3000mc_state *state)
 132{
 133        u16 reg_51, reg_52 = state->cfg->agc->setup & 0xfefb;
 134        if (state->cfg->pwm3_inversion) {
 135                reg_51 =  (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
 136                reg_52 |= (1 << 2);
 137        } else {
 138                reg_51 = (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0);
 139                reg_52 |= (1 << 8);
 140        }
 141        dib3000mc_write_word(state, 51, reg_51);
 142        dib3000mc_write_word(state, 52, reg_52);
 143
 144        if (state->cfg->use_pwm3)
 145                dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0));
 146        else
 147                dib3000mc_write_word(state, 245, 0);
 148
 149        dib3000mc_write_word(state, 1040, 0x3);
 150        return 0;
 151}
 152
 153static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode)
 154{
 155        int    ret = 0;
 156        u16 fifo_threshold = 1792;
 157        u16 outreg = 0;
 158        u16 outmode = 0;
 159        u16 elecout = 1;
 160        u16 smo_reg = dib3000mc_read_word(state, 206) & 0x0010; /* keep the pid_parse bit */
 161
 162        dprintk("-I-  Setting output mode for demod %p to %d\n",
 163                        &state->demod, mode);
 164
 165        switch (mode) {
 166                case OUTMODE_HIGH_Z:  // disable
 167                        elecout = 0;
 168                        break;
 169                case OUTMODE_MPEG2_PAR_GATED_CLK:   // STBs with parallel gated clock
 170                        outmode = 0;
 171                        break;
 172                case OUTMODE_MPEG2_PAR_CONT_CLK:    // STBs with parallel continues clock
 173                        outmode = 1;
 174                        break;
 175                case OUTMODE_MPEG2_SERIAL:          // STBs with serial input
 176                        outmode = 2;
 177                        break;
 178                case OUTMODE_MPEG2_FIFO:            // e.g. USB feeding
 179                        elecout = 3;
 180                        /*ADDR @ 206 :
 181                        P_smo_error_discard  [1;6:6] = 0
 182                        P_smo_rs_discard     [1;5:5] = 0
 183                        P_smo_pid_parse      [1;4:4] = 0
 184                        P_smo_fifo_flush     [1;3:3] = 0
 185                        P_smo_mode           [2;2:1] = 11
 186                        P_smo_ovf_prot       [1;0:0] = 0
 187                        */
 188                        smo_reg |= 3 << 1;
 189                        fifo_threshold = 512;
 190                        outmode = 5;
 191                        break;
 192                case OUTMODE_DIVERSITY:
 193                        outmode = 4;
 194                        elecout = 1;
 195                        break;
 196                default:
 197                        dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod);
 198                        outmode = 0;
 199                        break;
 200        }
 201
 202        if ((state->cfg->output_mpeg2_in_188_bytes))
 203                smo_reg |= (1 << 5); // P_smo_rs_discard     [1;5:5] = 1
 204
 205        outreg = dib3000mc_read_word(state, 244) & 0x07FF;
 206        outreg |= (outmode << 11);
 207        ret |= dib3000mc_write_word(state,  244, outreg);
 208        ret |= dib3000mc_write_word(state,  206, smo_reg);   /*smo_ mode*/
 209        ret |= dib3000mc_write_word(state,  207, fifo_threshold); /* synchronous fread */
 210        ret |= dib3000mc_write_word(state, 1040, elecout);         /* P_out_cfg */
 211        return ret;
 212}
 213
 214static int dib3000mc_set_bandwidth(struct dib3000mc_state *state, u32 bw)
 215{
 216        u16 bw_cfg[6] = { 0 };
 217        u16 imp_bw_cfg[3] = { 0 };
 218        u16 reg;
 219
 220/* settings here are for 27.7MHz */
 221        switch (bw) {
 222                case 8000:
 223                        bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20;
 224                        imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7;
 225                        break;
 226
 227                case 7000:
 228                        bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7;
 229                        imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0;
 230                        break;
 231
 232                case 6000:
 233                        bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5;
 234                        imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089;
 235                        break;
 236
 237                case 5000:
 238                        bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500;
 239                        imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072;
 240                        break;
 241
 242                default: return -EINVAL;
 243        }
 244
 245        for (reg = 6; reg < 12; reg++)
 246                dib3000mc_write_word(state, reg, bw_cfg[reg - 6]);
 247        dib3000mc_write_word(state, 12, 0x0000);
 248        dib3000mc_write_word(state, 13, 0x03e8);
 249        dib3000mc_write_word(state, 14, 0x0000);
 250        dib3000mc_write_word(state, 15, 0x03f2);
 251        dib3000mc_write_word(state, 16, 0x0001);
 252        dib3000mc_write_word(state, 17, 0xb0d0);
 253        // P_sec_len
 254        dib3000mc_write_word(state, 18, 0x0393);
 255        dib3000mc_write_word(state, 19, 0x8700);
 256
 257        for (reg = 55; reg < 58; reg++)
 258                dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]);
 259
 260        // Timing configuration
 261        dib3000mc_set_timing(state, TRANSMISSION_MODE_2K, bw, 0);
 262
 263        return 0;
 264}
 265
 266static u16 impulse_noise_val[29] =
 267
 268{
 269        0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, 0x3ffe, 0x7f3,
 270        0x2d94, 0x76, 0x53d, 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, 0x3feb, 0x7d2,
 271        0x365e, 0x76, 0x48c, 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0000, 0xd
 272};
 273
 274static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft)
 275{
 276        u16 i;
 277        for (i = 58; i < 87; i++)
 278                dib3000mc_write_word(state, i, impulse_noise_val[i-58]);
 279
 280        if (nfft == TRANSMISSION_MODE_8K) {
 281                dib3000mc_write_word(state, 58, 0x3b);
 282                dib3000mc_write_word(state, 84, 0x00);
 283                dib3000mc_write_word(state, 85, 0x8200);
 284        }
 285
 286        dib3000mc_write_word(state, 34, 0x1294);
 287        dib3000mc_write_word(state, 35, 0x1ff8);
 288        if (mode == 1)
 289                dib3000mc_write_word(state, 55, dib3000mc_read_word(state, 55) | (1 << 10));
 290}
 291
 292static int dib3000mc_init(struct dvb_frontend *demod)
 293{
 294        struct dib3000mc_state *state = demod->demodulator_priv;
 295        struct dibx000_agc_config *agc = state->cfg->agc;
 296
 297        // Restart Configuration
 298        dib3000mc_write_word(state, 1027, 0x8000);
 299        dib3000mc_write_word(state, 1027, 0x0000);
 300
 301        // power up the demod + mobility configuration
 302        dib3000mc_write_word(state, 140, 0x0000);
 303        dib3000mc_write_word(state, 1031, 0);
 304
 305        if (state->cfg->mobile_mode) {
 306                dib3000mc_write_word(state, 139,  0x0000);
 307                dib3000mc_write_word(state, 141,  0x0000);
 308                dib3000mc_write_word(state, 175,  0x0002);
 309                dib3000mc_write_word(state, 1032, 0x0000);
 310        } else {
 311                dib3000mc_write_word(state, 139,  0x0001);
 312                dib3000mc_write_word(state, 141,  0x0000);
 313                dib3000mc_write_word(state, 175,  0x0000);
 314                dib3000mc_write_word(state, 1032, 0x012C);
 315        }
 316        dib3000mc_write_word(state, 1033, 0x0000);
 317
 318        // P_clk_cfg
 319        dib3000mc_write_word(state, 1037, 0x3130);
 320
 321        // other configurations
 322
 323        // P_ctrl_sfreq
 324        dib3000mc_write_word(state, 33, (5 << 0));
 325        dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0));
 326
 327        // Phase noise control
 328        // P_fft_phacor_inh, P_fft_phacor_cpe, P_fft_powrange
 329        dib3000mc_write_word(state, 99, (1 << 9) | (0x20 << 0));
 330
 331        if (state->cfg->phase_noise_mode == 0)
 332                dib3000mc_write_word(state, 111, 0x00);
 333        else
 334                dib3000mc_write_word(state, 111, 0x02);
 335
 336        // P_agc_global
 337        dib3000mc_write_word(state, 50, 0x8000);
 338
 339        // agc setup misc
 340        dib3000mc_setup_pwm_state(state);
 341
 342        // P_agc_counter_lock
 343        dib3000mc_write_word(state, 53, 0x87);
 344        // P_agc_counter_unlock
 345        dib3000mc_write_word(state, 54, 0x87);
 346
 347        /* agc */
 348        dib3000mc_write_word(state, 36, state->cfg->max_time);
 349        dib3000mc_write_word(state, 37, (state->cfg->agc_command1 << 13) | (state->cfg->agc_command2 << 12) | (0x1d << 0));
 350        dib3000mc_write_word(state, 38, state->cfg->pwm3_value);
 351        dib3000mc_write_word(state, 39, state->cfg->ln_adc_level);
 352
 353        // set_agc_loop_Bw
 354        dib3000mc_write_word(state, 40, 0x0179);
 355        dib3000mc_write_word(state, 41, 0x03f0);
 356
 357        dib3000mc_write_word(state, 42, agc->agc1_max);
 358        dib3000mc_write_word(state, 43, agc->agc1_min);
 359        dib3000mc_write_word(state, 44, agc->agc2_max);
 360        dib3000mc_write_word(state, 45, agc->agc2_min);
 361        dib3000mc_write_word(state, 46, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
 362        dib3000mc_write_word(state, 47, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
 363        dib3000mc_write_word(state, 48, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
 364        dib3000mc_write_word(state, 49, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
 365
 366// Begin: TimeOut registers
 367        // P_pha3_thres
 368        dib3000mc_write_word(state, 110, 3277);
 369        // P_timf_alpha = 6, P_corm_alpha = 6, P_corm_thres = 0x80
 370        dib3000mc_write_word(state,  26, 0x6680);
 371        // lock_mask0
 372        dib3000mc_write_word(state, 1, 4);
 373        // lock_mask1
 374        dib3000mc_write_word(state, 2, 4);
 375        // lock_mask2
 376        dib3000mc_write_word(state, 3, 0x1000);
 377        // P_search_maxtrial=1
 378        dib3000mc_write_word(state, 5, 1);
 379
 380        dib3000mc_set_bandwidth(state, 8000);
 381
 382        // div_lock_mask
 383        dib3000mc_write_word(state,  4, 0x814);
 384
 385        dib3000mc_write_word(state, 21, (1 << 9) | 0x164);
 386        dib3000mc_write_word(state, 22, 0x463d);
 387
 388        // Spurious rm cfg
 389        // P_cspu_regul, P_cspu_win_cut
 390        dib3000mc_write_word(state, 120, 0x200f);
 391        // P_adp_selec_monit
 392        dib3000mc_write_word(state, 134, 0);
 393
 394        // Fec cfg
 395        dib3000mc_write_word(state, 195, 0x10);
 396
 397        // diversity register: P_dvsy_sync_wait..
 398        dib3000mc_write_word(state, 180, 0x2FF0);
 399
 400        // Impulse noise configuration
 401        dib3000mc_set_impulse_noise(state, 0, TRANSMISSION_MODE_8K);
 402
 403        // output mode set-up
 404        dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
 405
 406        /* close the i2c-gate */
 407        dib3000mc_write_word(state, 769, (1 << 7) );
 408
 409        return 0;
 410}
 411
 412static int dib3000mc_sleep(struct dvb_frontend *demod)
 413{
 414        struct dib3000mc_state *state = demod->demodulator_priv;
 415
 416        dib3000mc_write_word(state, 1031, 0xFFFF);
 417        dib3000mc_write_word(state, 1032, 0xFFFF);
 418        dib3000mc_write_word(state, 1033, 0xFFF0);
 419
 420        return 0;
 421}
 422
 423static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
 424{
 425        u16 cfg[4] = { 0 },reg;
 426        switch (qam) {
 427                case QPSK:
 428                        cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0;
 429                        break;
 430                case QAM_16:
 431                        cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0;
 432                        break;
 433                case QAM_64:
 434                        cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8;
 435                        break;
 436        }
 437        for (reg = 129; reg < 133; reg++)
 438                dib3000mc_write_word(state, reg, cfg[reg - 129]);
 439}
 440
 441static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state,
 442                                      struct dtv_frontend_properties *ch, u16 seq)
 443{
 444        u16 value;
 445        u32 bw = BANDWIDTH_TO_KHZ(ch->bandwidth_hz);
 446
 447        dib3000mc_set_bandwidth(state, bw);
 448        dib3000mc_set_timing(state, ch->transmission_mode, bw, 0);
 449
 450#if 1
 451        dib3000mc_write_word(state, 100, (16 << 6) + 9);
 452#else
 453        if (boost)
 454                dib3000mc_write_word(state, 100, (11 << 6) + 6);
 455        else
 456                dib3000mc_write_word(state, 100, (16 << 6) + 9);
 457#endif
 458
 459        dib3000mc_write_word(state, 1027, 0x0800);
 460        dib3000mc_write_word(state, 1027, 0x0000);
 461
 462        //Default cfg isi offset adp
 463        dib3000mc_write_word(state, 26,  0x6680);
 464        dib3000mc_write_word(state, 29,  0x1273);
 465        dib3000mc_write_word(state, 33,       5);
 466        dib3000mc_set_adp_cfg(state, QAM_16);
 467        dib3000mc_write_word(state, 133,  15564);
 468
 469        dib3000mc_write_word(state, 12 , 0x0);
 470        dib3000mc_write_word(state, 13 , 0x3e8);
 471        dib3000mc_write_word(state, 14 , 0x0);
 472        dib3000mc_write_word(state, 15 , 0x3f2);
 473
 474        dib3000mc_write_word(state, 93,0);
 475        dib3000mc_write_word(state, 94,0);
 476        dib3000mc_write_word(state, 95,0);
 477        dib3000mc_write_word(state, 96,0);
 478        dib3000mc_write_word(state, 97,0);
 479        dib3000mc_write_word(state, 98,0);
 480
 481        dib3000mc_set_impulse_noise(state, 0, ch->transmission_mode);
 482
 483        value = 0;
 484        switch (ch->transmission_mode) {
 485                case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
 486                default:
 487                case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
 488        }
 489        switch (ch->guard_interval) {
 490                case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
 491                case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
 492                case GUARD_INTERVAL_1_4:  value |= (3 << 5); break;
 493                default:
 494                case GUARD_INTERVAL_1_8:  value |= (2 << 5); break;
 495        }
 496        switch (ch->modulation) {
 497                case QPSK:  value |= (0 << 3); break;
 498                case QAM_16: value |= (1 << 3); break;
 499                default:
 500                case QAM_64: value |= (2 << 3); break;
 501        }
 502        switch (HIERARCHY_1) {
 503                case HIERARCHY_2: value |= 2; break;
 504                case HIERARCHY_4: value |= 4; break;
 505                default:
 506                case HIERARCHY_1: value |= 1; break;
 507        }
 508        dib3000mc_write_word(state, 0, value);
 509        dib3000mc_write_word(state, 5, (1 << 8) | ((seq & 0xf) << 4));
 510
 511        value = 0;
 512        if (ch->hierarchy == 1)
 513                value |= (1 << 4);
 514        if (1 == 1)
 515                value |= 1;
 516        switch ((ch->hierarchy == 0 || 1 == 1) ? ch->code_rate_HP : ch->code_rate_LP) {
 517                case FEC_2_3: value |= (2 << 1); break;
 518                case FEC_3_4: value |= (3 << 1); break;
 519                case FEC_5_6: value |= (5 << 1); break;
 520                case FEC_7_8: value |= (7 << 1); break;
 521                default:
 522                case FEC_1_2: value |= (1 << 1); break;
 523        }
 524        dib3000mc_write_word(state, 181, value);
 525
 526        // diversity synchro delay add 50% SFN margin
 527        switch (ch->transmission_mode) {
 528                case TRANSMISSION_MODE_8K: value = 256; break;
 529                case TRANSMISSION_MODE_2K:
 530                default: value = 64; break;
 531        }
 532        switch (ch->guard_interval) {
 533                case GUARD_INTERVAL_1_16: value *= 2; break;
 534                case GUARD_INTERVAL_1_8:  value *= 4; break;
 535                case GUARD_INTERVAL_1_4:  value *= 8; break;
 536                default:
 537                case GUARD_INTERVAL_1_32: value *= 1; break;
 538        }
 539        value <<= 4;
 540        value |= dib3000mc_read_word(state, 180) & 0x000f;
 541        dib3000mc_write_word(state, 180, value);
 542
 543        // restart demod
 544        value = dib3000mc_read_word(state, 0);
 545        dib3000mc_write_word(state, 0, value | (1 << 9));
 546        dib3000mc_write_word(state, 0, value);
 547
 548        msleep(30);
 549
 550        dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, ch->transmission_mode);
 551}
 552
 553static int dib3000mc_autosearch_start(struct dvb_frontend *demod)
 554{
 555        struct dtv_frontend_properties *chan = &demod->dtv_property_cache;
 556        struct dib3000mc_state *state = demod->demodulator_priv;
 557        u16 reg;
 558//      u32 val;
 559        struct dtv_frontend_properties schan;
 560
 561        schan = *chan;
 562
 563        /* TODO what is that ? */
 564
 565        /* a channel for autosearch */
 566        schan.transmission_mode = TRANSMISSION_MODE_8K;
 567        schan.guard_interval = GUARD_INTERVAL_1_32;
 568        schan.modulation = QAM_64;
 569        schan.code_rate_HP = FEC_2_3;
 570        schan.code_rate_LP = FEC_2_3;
 571        schan.hierarchy = 0;
 572
 573        dib3000mc_set_channel_cfg(state, &schan, 11);
 574
 575        reg = dib3000mc_read_word(state, 0);
 576        dib3000mc_write_word(state, 0, reg | (1 << 8));
 577        dib3000mc_read_word(state, 511);
 578        dib3000mc_write_word(state, 0, reg);
 579
 580        return 0;
 581}
 582
 583static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod)
 584{
 585        struct dib3000mc_state *state = demod->demodulator_priv;
 586        u16 irq_pending = dib3000mc_read_word(state, 511);
 587
 588        if (irq_pending & 0x1) // failed
 589                return 1;
 590
 591        if (irq_pending & 0x2) // succeeded
 592                return 2;
 593
 594        return 0; // still pending
 595}
 596
 597static int dib3000mc_tune(struct dvb_frontend *demod)
 598{
 599        struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
 600        struct dib3000mc_state *state = demod->demodulator_priv;
 601
 602        // ** configure demod **
 603        dib3000mc_set_channel_cfg(state, ch, 0);
 604
 605        // activates isi
 606        if (state->sfn_workaround_active) {
 607                dprintk("SFN workaround is active\n");
 608                dib3000mc_write_word(state, 29, 0x1273);
 609                dib3000mc_write_word(state, 108, 0x4000); // P_pha3_force_pha_shift
 610        } else {
 611                dib3000mc_write_word(state, 29, 0x1073);
 612                dib3000mc_write_word(state, 108, 0x0000); // P_pha3_force_pha_shift
 613        }
 614
 615        dib3000mc_set_adp_cfg(state, (u8)ch->modulation);
 616        if (ch->transmission_mode == TRANSMISSION_MODE_8K) {
 617                dib3000mc_write_word(state, 26, 38528);
 618                dib3000mc_write_word(state, 33, 8);
 619        } else {
 620                dib3000mc_write_word(state, 26, 30336);
 621                dib3000mc_write_word(state, 33, 6);
 622        }
 623
 624        if (dib3000mc_read_word(state, 509) & 0x80)
 625                dib3000mc_set_timing(state, ch->transmission_mode,
 626                                     BANDWIDTH_TO_KHZ(ch->bandwidth_hz), 1);
 627
 628        return 0;
 629}
 630
 631struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating)
 632{
 633        struct dib3000mc_state *st = demod->demodulator_priv;
 634        return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating);
 635}
 636
 637EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master);
 638
 639static int dib3000mc_get_frontend(struct dvb_frontend* fe,
 640                                  struct dtv_frontend_properties *fep)
 641{
 642        struct dib3000mc_state *state = fe->demodulator_priv;
 643        u16 tps = dib3000mc_read_word(state,458);
 644
 645        fep->inversion = INVERSION_AUTO;
 646
 647        fep->bandwidth_hz = state->current_bandwidth;
 648
 649        switch ((tps >> 8) & 0x1) {
 650                case 0: fep->transmission_mode = TRANSMISSION_MODE_2K; break;
 651                case 1: fep->transmission_mode = TRANSMISSION_MODE_8K; break;
 652        }
 653
 654        switch (tps & 0x3) {
 655                case 0: fep->guard_interval = GUARD_INTERVAL_1_32; break;
 656                case 1: fep->guard_interval = GUARD_INTERVAL_1_16; break;
 657                case 2: fep->guard_interval = GUARD_INTERVAL_1_8; break;
 658                case 3: fep->guard_interval = GUARD_INTERVAL_1_4; break;
 659        }
 660
 661        switch ((tps >> 13) & 0x3) {
 662                case 0: fep->modulation = QPSK; break;
 663                case 1: fep->modulation = QAM_16; break;
 664                case 2:
 665                default: fep->modulation = QAM_64; break;
 666        }
 667
 668        /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
 669        /* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */
 670
 671        fep->hierarchy = HIERARCHY_NONE;
 672        switch ((tps >> 5) & 0x7) {
 673                case 1: fep->code_rate_HP = FEC_1_2; break;
 674                case 2: fep->code_rate_HP = FEC_2_3; break;
 675                case 3: fep->code_rate_HP = FEC_3_4; break;
 676                case 5: fep->code_rate_HP = FEC_5_6; break;
 677                case 7:
 678                default: fep->code_rate_HP = FEC_7_8; break;
 679
 680        }
 681
 682        switch ((tps >> 2) & 0x7) {
 683                case 1: fep->code_rate_LP = FEC_1_2; break;
 684                case 2: fep->code_rate_LP = FEC_2_3; break;
 685                case 3: fep->code_rate_LP = FEC_3_4; break;
 686                case 5: fep->code_rate_LP = FEC_5_6; break;
 687                case 7:
 688                default: fep->code_rate_LP = FEC_7_8; break;
 689        }
 690
 691        return 0;
 692}
 693
 694static int dib3000mc_set_frontend(struct dvb_frontend *fe)
 695{
 696        struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
 697        struct dib3000mc_state *state = fe->demodulator_priv;
 698        int ret;
 699
 700        dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
 701
 702        state->current_bandwidth = fep->bandwidth_hz;
 703        dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->bandwidth_hz));
 704
 705        /* maybe the parameter has been changed */
 706        state->sfn_workaround_active = buggy_sfn_workaround;
 707
 708        if (fe->ops.tuner_ops.set_params) {
 709                fe->ops.tuner_ops.set_params(fe);
 710                msleep(100);
 711        }
 712
 713        if (fep->transmission_mode  == TRANSMISSION_MODE_AUTO ||
 714            fep->guard_interval == GUARD_INTERVAL_AUTO ||
 715            fep->modulation     == QAM_AUTO ||
 716            fep->code_rate_HP   == FEC_AUTO) {
 717                int i = 1000, found;
 718
 719                dib3000mc_autosearch_start(fe);
 720                do {
 721                        msleep(1);
 722                        found = dib3000mc_autosearch_is_irq(fe);
 723                } while (found == 0 && i--);
 724
 725                dprintk("autosearch returns: %d\n",found);
 726                if (found == 0 || found == 1)
 727                        return 0; // no channel found
 728
 729                dib3000mc_get_frontend(fe, fep);
 730        }
 731
 732        ret = dib3000mc_tune(fe);
 733
 734        /* make this a config parameter */
 735        dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
 736        return ret;
 737}
 738
 739static int dib3000mc_read_status(struct dvb_frontend *fe, enum fe_status *stat)
 740{
 741        struct dib3000mc_state *state = fe->demodulator_priv;
 742        u16 lock = dib3000mc_read_word(state, 509);
 743
 744        *stat = 0;
 745
 746        if (lock & 0x8000)
 747                *stat |= FE_HAS_SIGNAL;
 748        if (lock & 0x3000)
 749                *stat |= FE_HAS_CARRIER;
 750        if (lock & 0x0100)
 751                *stat |= FE_HAS_VITERBI;
 752        if (lock & 0x0010)
 753                *stat |= FE_HAS_SYNC;
 754        if (lock & 0x0008)
 755                *stat |= FE_HAS_LOCK;
 756
 757        return 0;
 758}
 759
 760static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber)
 761{
 762        struct dib3000mc_state *state = fe->demodulator_priv;
 763        *ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501);
 764        return 0;
 765}
 766
 767static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
 768{
 769        struct dib3000mc_state *state = fe->demodulator_priv;
 770        *unc = dib3000mc_read_word(state, 508);
 771        return 0;
 772}
 773
 774static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
 775{
 776        struct dib3000mc_state *state = fe->demodulator_priv;
 777        u16 val = dib3000mc_read_word(state, 392);
 778        *strength = 65535 - val;
 779        return 0;
 780}
 781
 782static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
 783{
 784        *snr = 0x0000;
 785        return 0;
 786}
 787
 788static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
 789{
 790        tune->min_delay_ms = 1000;
 791        return 0;
 792}
 793
 794static void dib3000mc_release(struct dvb_frontend *fe)
 795{
 796        struct dib3000mc_state *state = fe->demodulator_priv;
 797        dibx000_exit_i2c_master(&state->i2c_master);
 798        kfree(state);
 799}
 800
 801int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff)
 802{
 803        struct dib3000mc_state *state = fe->demodulator_priv;
 804        dib3000mc_write_word(state, 212 + index,  onoff ? (1 << 13) | pid : 0);
 805        return 0;
 806}
 807EXPORT_SYMBOL(dib3000mc_pid_control);
 808
 809int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
 810{
 811        struct dib3000mc_state *state = fe->demodulator_priv;
 812        u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4);
 813        tmp |= (onoff << 4);
 814        return dib3000mc_write_word(state, 206, tmp);
 815}
 816EXPORT_SYMBOL(dib3000mc_pid_parse);
 817
 818void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg)
 819{
 820        struct dib3000mc_state *state = fe->demodulator_priv;
 821        state->cfg = cfg;
 822}
 823EXPORT_SYMBOL(dib3000mc_set_config);
 824
 825int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[])
 826{
 827        struct dib3000mc_state *dmcst;
 828        int k;
 829        u8 new_addr;
 830
 831        static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
 832
 833        dmcst = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
 834        if (dmcst == NULL)
 835                return -ENOMEM;
 836
 837        dmcst->i2c_adap = i2c;
 838
 839        for (k = no_of_demods-1; k >= 0; k--) {
 840                dmcst->cfg = &cfg[k];
 841
 842                /* designated i2c address */
 843                new_addr          = DIB3000MC_I2C_ADDRESS[k];
 844                dmcst->i2c_addr = new_addr;
 845                if (dib3000mc_identify(dmcst) != 0) {
 846                        dmcst->i2c_addr = default_addr;
 847                        if (dib3000mc_identify(dmcst) != 0) {
 848                                dprintk("-E-  DiB3000P/MC #%d: not identified\n", k);
 849                                kfree(dmcst);
 850                                return -ENODEV;
 851                        }
 852                }
 853
 854                dib3000mc_set_output_mode(dmcst, OUTMODE_MPEG2_PAR_CONT_CLK);
 855
 856                // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
 857                dib3000mc_write_word(dmcst, 1024, (new_addr << 3) | 0x1);
 858                dmcst->i2c_addr = new_addr;
 859        }
 860
 861        for (k = 0; k < no_of_demods; k++) {
 862                dmcst->cfg = &cfg[k];
 863                dmcst->i2c_addr = DIB3000MC_I2C_ADDRESS[k];
 864
 865                dib3000mc_write_word(dmcst, 1024, dmcst->i2c_addr << 3);
 866
 867                /* turn off data output */
 868                dib3000mc_set_output_mode(dmcst, OUTMODE_HIGH_Z);
 869        }
 870
 871        kfree(dmcst);
 872        return 0;
 873}
 874EXPORT_SYMBOL(dib3000mc_i2c_enumeration);
 875
 876static struct dvb_frontend_ops dib3000mc_ops;
 877
 878struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
 879{
 880        struct dvb_frontend *demod;
 881        struct dib3000mc_state *st;
 882        st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
 883        if (st == NULL)
 884                return NULL;
 885
 886        st->cfg = cfg;
 887        st->i2c_adap = i2c_adap;
 888        st->i2c_addr = i2c_addr;
 889
 890        demod                   = &st->demod;
 891        demod->demodulator_priv = st;
 892        memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
 893
 894        if (dib3000mc_identify(st) != 0)
 895                goto error;
 896
 897        dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
 898
 899        dib3000mc_write_word(st, 1037, 0x3130);
 900
 901        return demod;
 902
 903error:
 904        kfree(st);
 905        return NULL;
 906}
 907EXPORT_SYMBOL(dib3000mc_attach);
 908
 909static struct dvb_frontend_ops dib3000mc_ops = {
 910        .delsys = { SYS_DVBT },
 911        .info = {
 912                .name = "DiBcom 3000MC/P",
 913                .frequency_min      = 44250000,
 914                .frequency_max      = 867250000,
 915                .frequency_stepsize = 62500,
 916                .caps = FE_CAN_INVERSION_AUTO |
 917                        FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
 918                        FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
 919                        FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
 920                        FE_CAN_TRANSMISSION_MODE_AUTO |
 921                        FE_CAN_GUARD_INTERVAL_AUTO |
 922                        FE_CAN_RECOVER |
 923                        FE_CAN_HIERARCHY_AUTO,
 924        },
 925
 926        .release              = dib3000mc_release,
 927
 928        .init                 = dib3000mc_init,
 929        .sleep                = dib3000mc_sleep,
 930
 931        .set_frontend         = dib3000mc_set_frontend,
 932        .get_tune_settings    = dib3000mc_fe_get_tune_settings,
 933        .get_frontend         = dib3000mc_get_frontend,
 934
 935        .read_status          = dib3000mc_read_status,
 936        .read_ber             = dib3000mc_read_ber,
 937        .read_signal_strength = dib3000mc_read_signal_strength,
 938        .read_snr             = dib3000mc_read_snr,
 939        .read_ucblocks        = dib3000mc_read_unc_blocks,
 940};
 941
 942MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
 943MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator");
 944MODULE_LICENSE("GPL");
 945