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