Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Linux-DVB Driver for DiBcom's DiB7000M and
0004  *              first generation DiB7000P-demodulator-family.
0005  *
0006  * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/)
0007  */
0008 
0009 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0010 
0011 #include <linux/kernel.h>
0012 #include <linux/slab.h>
0013 #include <linux/i2c.h>
0014 #include <linux/mutex.h>
0015 
0016 #include <media/dvb_frontend.h>
0017 
0018 #include "dib7000m.h"
0019 
0020 static int debug;
0021 module_param(debug, int, 0644);
0022 MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
0023 
0024 #define dprintk(fmt, arg...) do {                   \
0025     if (debug)                          \
0026         printk(KERN_DEBUG pr_fmt("%s: " fmt),           \
0027                __func__, ##arg);                \
0028 } while (0)
0029 
0030 struct dib7000m_state {
0031     struct dvb_frontend demod;
0032     struct dib7000m_config cfg;
0033 
0034     u8 i2c_addr;
0035     struct i2c_adapter   *i2c_adap;
0036 
0037     struct dibx000_i2c_master i2c_master;
0038 
0039 /* offset is 1 in case of the 7000MC */
0040     u8 reg_offs;
0041 
0042     u16 wbd_ref;
0043 
0044     u8 current_band;
0045     u32 current_bandwidth;
0046     struct dibx000_agc_config *current_agc;
0047     u32 timf;
0048     u32 timf_default;
0049     u32 internal_clk;
0050 
0051     u8 div_force_off : 1;
0052     u8 div_state : 1;
0053     u16 div_sync_wait;
0054 
0055     u16 revision;
0056 
0057     u8 agc_state;
0058 
0059     /* for the I2C transfer */
0060     struct i2c_msg msg[2];
0061     u8 i2c_write_buffer[4];
0062     u8 i2c_read_buffer[2];
0063     struct mutex i2c_buffer_lock;
0064 };
0065 
0066 enum dib7000m_power_mode {
0067     DIB7000M_POWER_ALL = 0,
0068 
0069     DIB7000M_POWER_NO,
0070     DIB7000M_POWER_INTERF_ANALOG_AGC,
0071     DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD,
0072     DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD,
0073     DIB7000M_POWER_INTERFACE_ONLY,
0074 };
0075 
0076 static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg)
0077 {
0078     u16 ret;
0079 
0080     if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
0081         dprintk("could not acquire lock\n");
0082         return 0;
0083     }
0084 
0085     state->i2c_write_buffer[0] = (reg >> 8) | 0x80;
0086     state->i2c_write_buffer[1] = reg & 0xff;
0087 
0088     memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
0089     state->msg[0].addr = state->i2c_addr >> 1;
0090     state->msg[0].flags = 0;
0091     state->msg[0].buf = state->i2c_write_buffer;
0092     state->msg[0].len = 2;
0093     state->msg[1].addr = state->i2c_addr >> 1;
0094     state->msg[1].flags = I2C_M_RD;
0095     state->msg[1].buf = state->i2c_read_buffer;
0096     state->msg[1].len = 2;
0097 
0098     if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
0099         dprintk("i2c read error on %d\n", reg);
0100 
0101     ret = (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
0102     mutex_unlock(&state->i2c_buffer_lock);
0103 
0104     return ret;
0105 }
0106 
0107 static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val)
0108 {
0109     int ret;
0110 
0111     if (mutex_lock_interruptible(&state->i2c_buffer_lock) < 0) {
0112         dprintk("could not acquire lock\n");
0113         return -EINVAL;
0114     }
0115 
0116     state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
0117     state->i2c_write_buffer[1] = reg & 0xff;
0118     state->i2c_write_buffer[2] = (val >> 8) & 0xff;
0119     state->i2c_write_buffer[3] = val & 0xff;
0120 
0121     memset(&state->msg[0], 0, sizeof(struct i2c_msg));
0122     state->msg[0].addr = state->i2c_addr >> 1;
0123     state->msg[0].flags = 0;
0124     state->msg[0].buf = state->i2c_write_buffer;
0125     state->msg[0].len = 4;
0126 
0127     ret = (i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ?
0128             -EREMOTEIO : 0);
0129     mutex_unlock(&state->i2c_buffer_lock);
0130     return ret;
0131 }
0132 static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf)
0133 {
0134     u16 l = 0, r, *n;
0135     n = buf;
0136     l = *n++;
0137     while (l) {
0138         r = *n++;
0139 
0140         if (state->reg_offs && (r >= 112 && r <= 331)) // compensate for 7000MC
0141             r++;
0142 
0143         do {
0144             dib7000m_write_word(state, r, *n++);
0145             r++;
0146         } while (--l);
0147         l = *n++;
0148     }
0149 }
0150 
0151 static int dib7000m_set_output_mode(struct dib7000m_state *state, int mode)
0152 {
0153     int    ret = 0;
0154     u16 outreg, fifo_threshold, smo_mode,
0155         sram = 0x0005; /* by default SRAM output is disabled */
0156 
0157     outreg = 0;
0158     fifo_threshold = 1792;
0159     smo_mode = (dib7000m_read_word(state, 294 + state->reg_offs) & 0x0010) | (1 << 1);
0160 
0161     dprintk("setting output mode for demod %p to %d\n", &state->demod, mode);
0162 
0163     switch (mode) {
0164         case OUTMODE_MPEG2_PAR_GATED_CLK:   // STBs with parallel gated clock
0165             outreg = (1 << 10);  /* 0x0400 */
0166             break;
0167         case OUTMODE_MPEG2_PAR_CONT_CLK:    // STBs with parallel continues clock
0168             outreg = (1 << 10) | (1 << 6); /* 0x0440 */
0169             break;
0170         case OUTMODE_MPEG2_SERIAL:          // STBs with serial input
0171             outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
0172             break;
0173         case OUTMODE_DIVERSITY:
0174             if (state->cfg.hostbus_diversity)
0175                 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
0176             else
0177                 sram   |= 0x0c00;
0178             break;
0179         case OUTMODE_MPEG2_FIFO:            // e.g. USB feeding
0180             smo_mode |= (3 << 1);
0181             fifo_threshold = 512;
0182             outreg = (1 << 10) | (5 << 6);
0183             break;
0184         case OUTMODE_HIGH_Z:  // disable
0185             outreg = 0;
0186             break;
0187         default:
0188             dprintk("Unhandled output_mode passed to be set for demod %p\n", &state->demod);
0189             break;
0190     }
0191 
0192     if (state->cfg.output_mpeg2_in_188_bytes)
0193         smo_mode |= (1 << 5) ;
0194 
0195     ret |= dib7000m_write_word(state,  294 + state->reg_offs, smo_mode);
0196     ret |= dib7000m_write_word(state,  295 + state->reg_offs, fifo_threshold); /* synchronous fread */
0197     ret |= dib7000m_write_word(state, 1795, outreg);
0198     ret |= dib7000m_write_word(state, 1805, sram);
0199 
0200     if (state->revision == 0x4003) {
0201         u16 clk_cfg1 = dib7000m_read_word(state, 909) & 0xfffd;
0202         if (mode == OUTMODE_DIVERSITY)
0203             clk_cfg1 |= (1 << 1); // P_O_CLK_en
0204         dib7000m_write_word(state, 909, clk_cfg1);
0205     }
0206     return ret;
0207 }
0208 
0209 static void dib7000m_set_power_mode(struct dib7000m_state *state, enum dib7000m_power_mode mode)
0210 {
0211     /* by default everything is going to be powered off */
0212     u16 reg_903 = 0xffff, reg_904 = 0xffff, reg_905 = 0xffff, reg_906  = 0x3fff;
0213     u8  offset = 0;
0214 
0215     /* now, depending on the requested mode, we power on */
0216     switch (mode) {
0217         /* power up everything in the demod */
0218         case DIB7000M_POWER_ALL:
0219             reg_903 = 0x0000; reg_904 = 0x0000; reg_905 = 0x0000; reg_906 = 0x0000;
0220             break;
0221 
0222         /* just leave power on the control-interfaces: GPIO and (I2C or SDIO or SRAM) */
0223         case DIB7000M_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C or SRAM */
0224             reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 2));
0225             break;
0226 
0227         case DIB7000M_POWER_INTERF_ANALOG_AGC:
0228             reg_903 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10));
0229             reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 2));
0230             reg_906 &= ~((1 << 0));
0231             break;
0232 
0233         case DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD:
0234             reg_903 = 0x0000; reg_904 = 0x801f; reg_905 = 0x0000; reg_906 = 0x0000;
0235             break;
0236 
0237         case DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD:
0238             reg_903 = 0x0000; reg_904 = 0x8000; reg_905 = 0x010b; reg_906 = 0x0000;
0239             break;
0240         case DIB7000M_POWER_NO:
0241             break;
0242     }
0243 
0244     /* always power down unused parts */
0245     if (!state->cfg.mobile_mode)
0246         reg_904 |= (1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) | (1 << 1);
0247 
0248     /* P_sdio_select_clk = 0 on MC and after*/
0249     if (state->revision != 0x4000)
0250         reg_906 <<= 1;
0251 
0252     if (state->revision == 0x4003)
0253         offset = 1;
0254 
0255     dib7000m_write_word(state, 903 + offset, reg_903);
0256     dib7000m_write_word(state, 904 + offset, reg_904);
0257     dib7000m_write_word(state, 905 + offset, reg_905);
0258     dib7000m_write_word(state, 906 + offset, reg_906);
0259 }
0260 
0261 static int dib7000m_set_adc_state(struct dib7000m_state *state, enum dibx000_adc_states no)
0262 {
0263     int ret = 0;
0264     u16 reg_913 = dib7000m_read_word(state, 913),
0265            reg_914 = dib7000m_read_word(state, 914);
0266 
0267     switch (no) {
0268         case DIBX000_SLOW_ADC_ON:
0269             reg_914 |= (1 << 1) | (1 << 0);
0270             ret |= dib7000m_write_word(state, 914, reg_914);
0271             reg_914 &= ~(1 << 1);
0272             break;
0273 
0274         case DIBX000_SLOW_ADC_OFF:
0275             reg_914 |=  (1 << 1) | (1 << 0);
0276             break;
0277 
0278         case DIBX000_ADC_ON:
0279             if (state->revision == 0x4000) { // workaround for PA/MA
0280                 // power-up ADC
0281                 dib7000m_write_word(state, 913, 0);
0282                 dib7000m_write_word(state, 914, reg_914 & 0x3);
0283                 // power-down bandgag
0284                 dib7000m_write_word(state, 913, (1 << 15));
0285                 dib7000m_write_word(state, 914, reg_914 & 0x3);
0286             }
0287 
0288             reg_913 &= 0x0fff;
0289             reg_914 &= 0x0003;
0290             break;
0291 
0292         case DIBX000_ADC_OFF: // leave the VBG voltage on
0293             reg_913 |= (1 << 14) | (1 << 13) | (1 << 12);
0294             reg_914 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
0295             break;
0296 
0297         case DIBX000_VBG_ENABLE:
0298             reg_913 &= ~(1 << 15);
0299             break;
0300 
0301         case DIBX000_VBG_DISABLE:
0302             reg_913 |= (1 << 15);
0303             break;
0304 
0305         default:
0306             break;
0307     }
0308 
0309 //  dprintk("913: %x, 914: %x\n", reg_913, reg_914);
0310     ret |= dib7000m_write_word(state, 913, reg_913);
0311     ret |= dib7000m_write_word(state, 914, reg_914);
0312 
0313     return ret;
0314 }
0315 
0316 static int dib7000m_set_bandwidth(struct dib7000m_state *state, u32 bw)
0317 {
0318     u32 timf;
0319 
0320     if (!bw)
0321         bw = 8000;
0322 
0323     // store the current bandwidth for later use
0324     state->current_bandwidth = bw;
0325 
0326     if (state->timf == 0) {
0327         dprintk("using default timf\n");
0328         timf = state->timf_default;
0329     } else {
0330         dprintk("using updated timf\n");
0331         timf = state->timf;
0332     }
0333 
0334     timf = timf * (bw / 50) / 160;
0335 
0336     dib7000m_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
0337     dib7000m_write_word(state, 24, (u16) ((timf      ) & 0xffff));
0338 
0339     return 0;
0340 }
0341 
0342 static int dib7000m_set_diversity_in(struct dvb_frontend *demod, int onoff)
0343 {
0344     struct dib7000m_state *state = demod->demodulator_priv;
0345 
0346     if (state->div_force_off) {
0347         dprintk("diversity combination deactivated - forced by COFDM parameters\n");
0348         onoff = 0;
0349     }
0350     state->div_state = (u8)onoff;
0351 
0352     if (onoff) {
0353         dib7000m_write_word(state, 263 + state->reg_offs, 6);
0354         dib7000m_write_word(state, 264 + state->reg_offs, 6);
0355         dib7000m_write_word(state, 266 + state->reg_offs, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
0356     } else {
0357         dib7000m_write_word(state, 263 + state->reg_offs, 1);
0358         dib7000m_write_word(state, 264 + state->reg_offs, 0);
0359         dib7000m_write_word(state, 266 + state->reg_offs, 0);
0360     }
0361 
0362     return 0;
0363 }
0364 
0365 static int dib7000m_sad_calib(struct dib7000m_state *state)
0366 {
0367 
0368 /* internal */
0369 //  dib7000m_write_word(state, 928, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writing in set_bandwidth
0370     dib7000m_write_word(state, 929, (0 << 1) | (0 << 0));
0371     dib7000m_write_word(state, 930, 776); // 0.625*3.3 / 4096
0372 
0373     /* do the calibration */
0374     dib7000m_write_word(state, 929, (1 << 0));
0375     dib7000m_write_word(state, 929, (0 << 0));
0376 
0377     msleep(1);
0378 
0379     return 0;
0380 }
0381 
0382 static void dib7000m_reset_pll_common(struct dib7000m_state *state, const struct dibx000_bandwidth_config *bw)
0383 {
0384     dib7000m_write_word(state, 18, (u16) (((bw->internal*1000) >> 16) & 0xffff));
0385     dib7000m_write_word(state, 19, (u16) ( (bw->internal*1000)        & 0xffff));
0386     dib7000m_write_word(state, 21, (u16) ( (bw->ifreq          >> 16) & 0xffff));
0387     dib7000m_write_word(state, 22, (u16) (  bw->ifreq                 & 0xffff));
0388 
0389     dib7000m_write_word(state, 928, bw->sad_cfg);
0390 }
0391 
0392 static void dib7000m_reset_pll(struct dib7000m_state *state)
0393 {
0394     const struct dibx000_bandwidth_config *bw = state->cfg.bw;
0395     u16 reg_907,reg_910;
0396 
0397     /* default */
0398     reg_907 = (bw->pll_bypass << 15) | (bw->modulo << 7) |
0399         (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) |
0400         (bw->enable_refdiv << 1) | (0 << 0);
0401     reg_910 = (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset;
0402 
0403     // for this oscillator frequency should be 30 MHz for the Master (default values in the board_parameters give that value)
0404     // this is only working only for 30 MHz crystals
0405     if (!state->cfg.quartz_direct) {
0406         reg_910 |= (1 << 5);  // forcing the predivider to 1
0407 
0408         // if the previous front-end is baseband, its output frequency is 15 MHz (prev freq divided by 2)
0409         if(state->cfg.input_clk_is_div_2)
0410             reg_907 |= (16 << 9);
0411         else // otherwise the previous front-end puts out its input (default 30MHz) - no extra division necessary
0412             reg_907 |= (8 << 9);
0413     } else {
0414         reg_907 |= (bw->pll_ratio & 0x3f) << 9;
0415         reg_910 |= (bw->pll_prediv << 5);
0416     }
0417 
0418     dib7000m_write_word(state, 910, reg_910); // pll cfg
0419     dib7000m_write_word(state, 907, reg_907); // clk cfg0
0420     dib7000m_write_word(state, 908, 0x0006);  // clk_cfg1
0421 
0422     dib7000m_reset_pll_common(state, bw);
0423 }
0424 
0425 static void dib7000mc_reset_pll(struct dib7000m_state *state)
0426 {
0427     const struct dibx000_bandwidth_config *bw = state->cfg.bw;
0428     u16 clk_cfg1;
0429 
0430     // clk_cfg0
0431     dib7000m_write_word(state, 907, (bw->pll_prediv << 8) | (bw->pll_ratio << 0));
0432 
0433     // clk_cfg1
0434     //dib7000m_write_word(state, 908, (1 << 14) | (3 << 12) |(0 << 11) |
0435     clk_cfg1 = (0 << 14) | (3 << 12) |(0 << 11) |
0436             (bw->IO_CLK_en_core << 10) | (bw->bypclk_div << 5) | (bw->enable_refdiv << 4) |
0437             (1 << 3) | (bw->pll_range << 1) | (bw->pll_reset << 0);
0438     dib7000m_write_word(state, 908, clk_cfg1);
0439     clk_cfg1 = (clk_cfg1 & 0xfff7) | (bw->pll_bypass << 3);
0440     dib7000m_write_word(state, 908, clk_cfg1);
0441 
0442     // smpl_cfg
0443     dib7000m_write_word(state, 910, (1 << 12) | (2 << 10) | (bw->modulo << 8) | (bw->ADClkSrc << 7));
0444 
0445     dib7000m_reset_pll_common(state, bw);
0446 }
0447 
0448 static int dib7000m_reset_gpio(struct dib7000m_state *st)
0449 {
0450     /* reset the GPIOs */
0451     dib7000m_write_word(st, 773, st->cfg.gpio_dir);
0452     dib7000m_write_word(st, 774, st->cfg.gpio_val);
0453 
0454     /* TODO 782 is P_gpio_od */
0455 
0456     dib7000m_write_word(st, 775, st->cfg.gpio_pwm_pos);
0457 
0458     dib7000m_write_word(st, 780, st->cfg.pwm_freq_div);
0459     return 0;
0460 }
0461 
0462 static u16 dib7000m_defaults_common[] =
0463 
0464 {
0465     // auto search configuration
0466     3, 2,
0467         0x0004,
0468         0x1000,
0469         0x0814,
0470 
0471     12, 6,
0472         0x001b,
0473         0x7740,
0474         0x005b,
0475         0x8d80,
0476         0x01c9,
0477         0xc380,
0478         0x0000,
0479         0x0080,
0480         0x0000,
0481         0x0090,
0482         0x0001,
0483         0xd4c0,
0484 
0485     1, 26,
0486         0x6680, // P_corm_thres Lock algorithms configuration
0487 
0488     1, 170,
0489         0x0410, // P_palf_alpha_regul, P_palf_filter_freeze, P_palf_filter_on
0490 
0491     8, 173,
0492         0,
0493         0,
0494         0,
0495         0,
0496         0,
0497         0,
0498         0,
0499         0,
0500 
0501     1, 182,
0502         8192, // P_fft_nb_to_cut
0503 
0504     2, 195,
0505         0x0ccd, // P_pha3_thres
0506         0,      // P_cti_use_cpe, P_cti_use_prog
0507 
0508     1, 205,
0509         0x200f, // P_cspu_regul, P_cspu_win_cut
0510 
0511     5, 214,
0512         0x023d, // P_adp_regul_cnt
0513         0x00a4, // P_adp_noise_cnt
0514         0x00a4, // P_adp_regul_ext
0515         0x7ff0, // P_adp_noise_ext
0516         0x3ccc, // P_adp_fil
0517 
0518     1, 226,
0519         0, // P_2d_byp_ti_num
0520 
0521     1, 255,
0522         0x800, // P_equal_thres_wgn
0523 
0524     1, 263,
0525         0x0001,
0526 
0527     1, 281,
0528         0x0010, // P_fec_*
0529 
0530     1, 294,
0531         0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
0532 
0533     0
0534 };
0535 
0536 static u16 dib7000m_defaults[] =
0537 
0538 {
0539     /* set ADC level to -16 */
0540     11, 76,
0541         (1 << 13) - 825 - 117,
0542         (1 << 13) - 837 - 117,
0543         (1 << 13) - 811 - 117,
0544         (1 << 13) - 766 - 117,
0545         (1 << 13) - 737 - 117,
0546         (1 << 13) - 693 - 117,
0547         (1 << 13) - 648 - 117,
0548         (1 << 13) - 619 - 117,
0549         (1 << 13) - 575 - 117,
0550         (1 << 13) - 531 - 117,
0551         (1 << 13) - 501 - 117,
0552 
0553     // Tuner IO bank: max drive (14mA)
0554     1, 912,
0555         0x2c8a,
0556 
0557     1, 1817,
0558         1,
0559 
0560     0,
0561 };
0562 
0563 static int dib7000m_demod_reset(struct dib7000m_state *state)
0564 {
0565     dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
0566 
0567     /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
0568     dib7000m_set_adc_state(state, DIBX000_VBG_ENABLE);
0569 
0570     /* restart all parts */
0571     dib7000m_write_word(state,  898, 0xffff);
0572     dib7000m_write_word(state,  899, 0xffff);
0573     dib7000m_write_word(state,  900, 0xff0f);
0574     dib7000m_write_word(state,  901, 0xfffc);
0575 
0576     dib7000m_write_word(state,  898, 0);
0577     dib7000m_write_word(state,  899, 0);
0578     dib7000m_write_word(state,  900, 0);
0579     dib7000m_write_word(state,  901, 0);
0580 
0581     if (state->revision == 0x4000)
0582         dib7000m_reset_pll(state);
0583     else
0584         dib7000mc_reset_pll(state);
0585 
0586     if (dib7000m_reset_gpio(state) != 0)
0587         dprintk("GPIO reset was not successful.\n");
0588 
0589     if (dib7000m_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
0590         dprintk("OUTPUT_MODE could not be reset.\n");
0591 
0592     /* unforce divstr regardless whether i2c enumeration was done or not */
0593     dib7000m_write_word(state, 1794, dib7000m_read_word(state, 1794) & ~(1 << 1) );
0594 
0595     dib7000m_set_bandwidth(state, 8000);
0596 
0597     dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON);
0598     dib7000m_sad_calib(state);
0599     dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
0600 
0601     if (state->cfg.dvbt_mode)
0602         dib7000m_write_word(state, 1796, 0x0); // select DVB-T output
0603 
0604     if (state->cfg.mobile_mode)
0605         dib7000m_write_word(state, 261 + state->reg_offs, 2);
0606     else
0607         dib7000m_write_word(state, 224 + state->reg_offs, 1);
0608 
0609     // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
0610     if(state->cfg.tuner_is_baseband)
0611         dib7000m_write_word(state, 36, 0x0755);
0612     else
0613         dib7000m_write_word(state, 36, 0x1f55);
0614 
0615     // P_divclksel=3 P_divbitsel=1
0616     if (state->revision == 0x4000)
0617         dib7000m_write_word(state, 909, (3 << 10) | (1 << 6));
0618     else
0619         dib7000m_write_word(state, 909, (3 << 4) | 1);
0620 
0621     dib7000m_write_tab(state, dib7000m_defaults_common);
0622     dib7000m_write_tab(state, dib7000m_defaults);
0623 
0624     dib7000m_set_power_mode(state, DIB7000M_POWER_INTERFACE_ONLY);
0625 
0626     state->internal_clk = state->cfg.bw->internal;
0627 
0628     return 0;
0629 }
0630 
0631 static void dib7000m_restart_agc(struct dib7000m_state *state)
0632 {
0633     // P_restart_iqc & P_restart_agc
0634     dib7000m_write_word(state, 898, 0x0c00);
0635     dib7000m_write_word(state, 898, 0x0000);
0636 }
0637 
0638 static int dib7000m_agc_soft_split(struct dib7000m_state *state)
0639 {
0640     u16 agc,split_offset;
0641 
0642     if(!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
0643         return 0;
0644 
0645     // n_agc_global
0646     agc = dib7000m_read_word(state, 390);
0647 
0648     if (agc > state->current_agc->split.min_thres)
0649         split_offset = state->current_agc->split.min;
0650     else if (agc < state->current_agc->split.max_thres)
0651         split_offset = state->current_agc->split.max;
0652     else
0653         split_offset = state->current_agc->split.max *
0654             (agc - state->current_agc->split.min_thres) /
0655             (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
0656 
0657     dprintk("AGC split_offset: %d\n", split_offset);
0658 
0659     // P_agc_force_split and P_agc_split_offset
0660     return dib7000m_write_word(state, 103, (dib7000m_read_word(state, 103) & 0xff00) | split_offset);
0661 }
0662 
0663 static int dib7000m_update_lna(struct dib7000m_state *state)
0664 {
0665     u16 dyn_gain;
0666 
0667     if (state->cfg.update_lna) {
0668         // read dyn_gain here (because it is demod-dependent and not fe)
0669         dyn_gain = dib7000m_read_word(state, 390);
0670 
0671         if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed
0672             dib7000m_restart_agc(state);
0673             return 1;
0674         }
0675     }
0676     return 0;
0677 }
0678 
0679 static int dib7000m_set_agc_config(struct dib7000m_state *state, u8 band)
0680 {
0681     struct dibx000_agc_config *agc = NULL;
0682     int i;
0683     if (state->current_band == band && state->current_agc != NULL)
0684         return 0;
0685     state->current_band = band;
0686 
0687     for (i = 0; i < state->cfg.agc_config_count; i++)
0688         if (state->cfg.agc[i].band_caps & band) {
0689             agc = &state->cfg.agc[i];
0690             break;
0691         }
0692 
0693     if (agc == NULL) {
0694         dprintk("no valid AGC configuration found for band 0x%02x\n", band);
0695         return -EINVAL;
0696     }
0697 
0698     state->current_agc = agc;
0699 
0700     /* AGC */
0701     dib7000m_write_word(state, 72 ,  agc->setup);
0702     dib7000m_write_word(state, 73 ,  agc->inv_gain);
0703     dib7000m_write_word(state, 74 ,  agc->time_stabiliz);
0704     dib7000m_write_word(state, 97 , (agc->alpha_level << 12) | agc->thlock);
0705 
0706     // Demod AGC loop configuration
0707     dib7000m_write_word(state, 98, (agc->alpha_mant << 5) | agc->alpha_exp);
0708     dib7000m_write_word(state, 99, (agc->beta_mant  << 6) | agc->beta_exp);
0709 
0710     dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d\n",
0711         state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
0712 
0713     /* AGC continued */
0714     if (state->wbd_ref != 0)
0715         dib7000m_write_word(state, 102, state->wbd_ref);
0716     else // use default
0717         dib7000m_write_word(state, 102, agc->wbd_ref);
0718 
0719     dib7000m_write_word(state, 103, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8) );
0720     dib7000m_write_word(state, 104,  agc->agc1_max);
0721     dib7000m_write_word(state, 105,  agc->agc1_min);
0722     dib7000m_write_word(state, 106,  agc->agc2_max);
0723     dib7000m_write_word(state, 107,  agc->agc2_min);
0724     dib7000m_write_word(state, 108, (agc->agc1_pt1 << 8) | agc->agc1_pt2 );
0725     dib7000m_write_word(state, 109, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
0726     dib7000m_write_word(state, 110, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
0727     dib7000m_write_word(state, 111, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
0728 
0729     if (state->revision > 0x4000) { // settings for the MC
0730         dib7000m_write_word(state, 71,   agc->agc1_pt3);
0731 //      dprintk("929: %x %d %d\n",
0732 //          (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2), agc->wbd_inv, agc->wbd_sel);
0733         dib7000m_write_word(state, 929, (dib7000m_read_word(state, 929) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2));
0734     } else {
0735         // wrong default values
0736         u16 b[9] = { 676, 696, 717, 737, 758, 778, 799, 819, 840 };
0737         for (i = 0; i < 9; i++)
0738             dib7000m_write_word(state, 88 + i, b[i]);
0739     }
0740     return 0;
0741 }
0742 
0743 static void dib7000m_update_timf(struct dib7000m_state *state)
0744 {
0745     u32 timf = (dib7000m_read_word(state, 436) << 16) | dib7000m_read_word(state, 437);
0746     state->timf = timf * 160 / (state->current_bandwidth / 50);
0747     dib7000m_write_word(state, 23, (u16) (timf >> 16));
0748     dib7000m_write_word(state, 24, (u16) (timf & 0xffff));
0749     dprintk("updated timf_frequency: %d (default: %d)\n", state->timf, state->timf_default);
0750 }
0751 
0752 static int dib7000m_agc_startup(struct dvb_frontend *demod)
0753 {
0754     struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
0755     struct dib7000m_state *state = demod->demodulator_priv;
0756     u16 cfg_72 = dib7000m_read_word(state, 72);
0757     int ret = -1;
0758     u8 *agc_state = &state->agc_state;
0759     u8 agc_split;
0760 
0761     switch (state->agc_state) {
0762         case 0:
0763             // set power-up level: interf+analog+AGC
0764             dib7000m_set_power_mode(state, DIB7000M_POWER_INTERF_ANALOG_AGC);
0765             dib7000m_set_adc_state(state, DIBX000_ADC_ON);
0766 
0767             if (dib7000m_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0)
0768                 return -1;
0769 
0770             ret = 7; /* ADC power up */
0771             (*agc_state)++;
0772             break;
0773 
0774         case 1:
0775             /* AGC initialization */
0776             if (state->cfg.agc_control)
0777                 state->cfg.agc_control(&state->demod, 1);
0778 
0779             dib7000m_write_word(state, 75, 32768);
0780             if (!state->current_agc->perform_agc_softsplit) {
0781                 /* we are using the wbd - so slow AGC startup */
0782                 dib7000m_write_word(state, 103, 1 << 8); /* force 0 split on WBD and restart AGC */
0783                 (*agc_state)++;
0784                 ret = 5;
0785             } else {
0786                 /* default AGC startup */
0787                 (*agc_state) = 4;
0788                 /* wait AGC rough lock time */
0789                 ret = 7;
0790             }
0791 
0792             dib7000m_restart_agc(state);
0793             break;
0794 
0795         case 2: /* fast split search path after 5sec */
0796             dib7000m_write_word(state,  72, cfg_72 | (1 << 4)); /* freeze AGC loop */
0797             dib7000m_write_word(state, 103, 2 << 9);            /* fast split search 0.25kHz */
0798             (*agc_state)++;
0799             ret = 14;
0800             break;
0801 
0802     case 3: /* split search ended */
0803             agc_split = (u8)dib7000m_read_word(state, 392); /* store the split value for the next time */
0804             dib7000m_write_word(state, 75, dib7000m_read_word(state, 390)); /* set AGC gain start value */
0805 
0806             dib7000m_write_word(state, 72,  cfg_72 & ~(1 << 4));   /* std AGC loop */
0807             dib7000m_write_word(state, 103, (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
0808 
0809             dib7000m_restart_agc(state);
0810 
0811             dprintk("SPLIT %p: %u\n", demod, agc_split);
0812 
0813             (*agc_state)++;
0814             ret = 5;
0815             break;
0816 
0817         case 4: /* LNA startup */
0818             /* wait AGC accurate lock time */
0819             ret = 7;
0820 
0821             if (dib7000m_update_lna(state))
0822                 // wait only AGC rough lock time
0823                 ret = 5;
0824             else
0825                 (*agc_state)++;
0826             break;
0827 
0828         case 5:
0829             dib7000m_agc_soft_split(state);
0830 
0831             if (state->cfg.agc_control)
0832                 state->cfg.agc_control(&state->demod, 0);
0833 
0834             (*agc_state)++;
0835             break;
0836 
0837         default:
0838             break;
0839     }
0840     return ret;
0841 }
0842 
0843 static void dib7000m_set_channel(struct dib7000m_state *state, struct dtv_frontend_properties *ch,
0844                  u8 seq)
0845 {
0846     u16 value, est[4];
0847 
0848     dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
0849 
0850     /* nfft, guard, qam, alpha */
0851     value = 0;
0852     switch (ch->transmission_mode) {
0853         case TRANSMISSION_MODE_2K: value |= (0 << 7); break;
0854         case TRANSMISSION_MODE_4K: value |= (2 << 7); break;
0855         default:
0856         case TRANSMISSION_MODE_8K: value |= (1 << 7); break;
0857     }
0858     switch (ch->guard_interval) {
0859         case GUARD_INTERVAL_1_32: value |= (0 << 5); break;
0860         case GUARD_INTERVAL_1_16: value |= (1 << 5); break;
0861         case GUARD_INTERVAL_1_4:  value |= (3 << 5); break;
0862         default:
0863         case GUARD_INTERVAL_1_8:  value |= (2 << 5); break;
0864     }
0865     switch (ch->modulation) {
0866         case QPSK:  value |= (0 << 3); break;
0867         case QAM_16: value |= (1 << 3); break;
0868         default:
0869         case QAM_64: value |= (2 << 3); break;
0870     }
0871     switch (HIERARCHY_1) {
0872         case HIERARCHY_2: value |= 2; break;
0873         case HIERARCHY_4: value |= 4; break;
0874         default:
0875         case HIERARCHY_1: value |= 1; break;
0876     }
0877     dib7000m_write_word(state, 0, value);
0878     dib7000m_write_word(state, 5, (seq << 4));
0879 
0880     /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
0881     value = 0;
0882     if (1 != 0)
0883         value |= (1 << 6);
0884     if (ch->hierarchy == 1)
0885         value |= (1 << 4);
0886     if (1 == 1)
0887         value |= 1;
0888     switch ((ch->hierarchy == 0 || 1 == 1) ? ch->code_rate_HP : ch->code_rate_LP) {
0889         case FEC_2_3: value |= (2 << 1); break;
0890         case FEC_3_4: value |= (3 << 1); break;
0891         case FEC_5_6: value |= (5 << 1); break;
0892         case FEC_7_8: value |= (7 << 1); break;
0893         default:
0894         case FEC_1_2: value |= (1 << 1); break;
0895     }
0896     dib7000m_write_word(state, 267 + state->reg_offs, value);
0897 
0898     /* offset loop parameters */
0899 
0900     /* P_timf_alpha = 6, P_corm_alpha=6, P_corm_thres=0x80 */
0901     dib7000m_write_word(state, 26, (6 << 12) | (6 << 8) | 0x80);
0902 
0903     /* 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 */
0904     dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (1 << 9) | (3 << 5) | (1 << 4) | (0x3));
0905 
0906     /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max=3 */
0907     dib7000m_write_word(state, 32, (0 << 4) | 0x3);
0908 
0909     /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step=5 */
0910     dib7000m_write_word(state, 33, (0 << 4) | 0x5);
0911 
0912     /* P_dvsy_sync_wait */
0913     switch (ch->transmission_mode) {
0914         case TRANSMISSION_MODE_8K: value = 256; break;
0915         case TRANSMISSION_MODE_4K: value = 128; break;
0916         case TRANSMISSION_MODE_2K:
0917         default: value = 64; break;
0918     }
0919     switch (ch->guard_interval) {
0920         case GUARD_INTERVAL_1_16: value *= 2; break;
0921         case GUARD_INTERVAL_1_8:  value *= 4; break;
0922         case GUARD_INTERVAL_1_4:  value *= 8; break;
0923         default:
0924         case GUARD_INTERVAL_1_32: value *= 1; break;
0925     }
0926     state->div_sync_wait = (value * 3) / 2 + 32; // add 50% SFN margin + compensate for one DVSY-fifo TODO
0927 
0928     /* deactivate the possibility of diversity reception if extended interleave - not for 7000MC */
0929     /* P_dvsy_sync_mode = 0, P_dvsy_sync_enable=1, P_dvcb_comb_mode=2 */
0930     if (1 == 1 || state->revision > 0x4000)
0931         state->div_force_off = 0;
0932     else
0933         state->div_force_off = 1;
0934     dib7000m_set_diversity_in(&state->demod, state->div_state);
0935 
0936     /* channel estimation fine configuration */
0937     switch (ch->modulation) {
0938         case QAM_64:
0939             est[0] = 0x0148;       /* P_adp_regul_cnt 0.04 */
0940             est[1] = 0xfff0;       /* P_adp_noise_cnt -0.002 */
0941             est[2] = 0x00a4;       /* P_adp_regul_ext 0.02 */
0942             est[3] = 0xfff8;       /* P_adp_noise_ext -0.001 */
0943             break;
0944         case QAM_16:
0945             est[0] = 0x023d;       /* P_adp_regul_cnt 0.07 */
0946             est[1] = 0xffdf;       /* P_adp_noise_cnt -0.004 */
0947             est[2] = 0x00a4;       /* P_adp_regul_ext 0.02 */
0948             est[3] = 0xfff0;       /* P_adp_noise_ext -0.002 */
0949             break;
0950         default:
0951             est[0] = 0x099a;       /* P_adp_regul_cnt 0.3 */
0952             est[1] = 0xffae;       /* P_adp_noise_cnt -0.01 */
0953             est[2] = 0x0333;       /* P_adp_regul_ext 0.1 */
0954             est[3] = 0xfff8;       /* P_adp_noise_ext -0.002 */
0955             break;
0956     }
0957     for (value = 0; value < 4; value++)
0958         dib7000m_write_word(state, 214 + value + state->reg_offs, est[value]);
0959 
0960     // set power-up level: autosearch
0961     dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD);
0962 }
0963 
0964 static int dib7000m_autosearch_start(struct dvb_frontend *demod)
0965 {
0966     struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
0967     struct dib7000m_state *state = demod->demodulator_priv;
0968     struct dtv_frontend_properties schan;
0969     int ret = 0;
0970     u32 value, factor;
0971 
0972     schan = *ch;
0973 
0974     schan.modulation = QAM_64;
0975     schan.guard_interval        = GUARD_INTERVAL_1_32;
0976     schan.transmission_mode         = TRANSMISSION_MODE_8K;
0977     schan.code_rate_HP = FEC_2_3;
0978     schan.code_rate_LP = FEC_3_4;
0979     schan.hierarchy    = 0;
0980 
0981     dib7000m_set_channel(state, &schan, 7);
0982 
0983     factor = BANDWIDTH_TO_KHZ(schan.bandwidth_hz);
0984     if (factor >= 5000)
0985         factor = 1;
0986     else
0987         factor = 6;
0988 
0989     // always use the setting for 8MHz here lock_time for 7,6 MHz are longer
0990     value = 30 * state->internal_clk * factor;
0991     ret |= dib7000m_write_word(state, 6,  (u16) ((value >> 16) & 0xffff)); // lock0 wait time
0992     ret |= dib7000m_write_word(state, 7,  (u16)  (value        & 0xffff)); // lock0 wait time
0993     value = 100 * state->internal_clk * factor;
0994     ret |= dib7000m_write_word(state, 8,  (u16) ((value >> 16) & 0xffff)); // lock1 wait time
0995     ret |= dib7000m_write_word(state, 9,  (u16)  (value        & 0xffff)); // lock1 wait time
0996     value = 500 * state->internal_clk * factor;
0997     ret |= dib7000m_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
0998     ret |= dib7000m_write_word(state, 11, (u16)  (value        & 0xffff)); // lock2 wait time
0999 
1000     // start search
1001     value = dib7000m_read_word(state, 0);
1002     ret |= dib7000m_write_word(state, 0, (u16) (value | (1 << 9)));
1003 
1004     /* clear n_irq_pending */
1005     if (state->revision == 0x4000)
1006         dib7000m_write_word(state, 1793, 0);
1007     else
1008         dib7000m_read_word(state, 537);
1009 
1010     ret |= dib7000m_write_word(state, 0, (u16) value);
1011 
1012     return ret;
1013 }
1014 
1015 static int dib7000m_autosearch_irq(struct dib7000m_state *state, u16 reg)
1016 {
1017     u16 irq_pending = dib7000m_read_word(state, reg);
1018 
1019     if (irq_pending & 0x1) { // failed
1020         dprintk("autosearch failed\n");
1021         return 1;
1022     }
1023 
1024     if (irq_pending & 0x2) { // succeeded
1025         dprintk("autosearch succeeded\n");
1026         return 2;
1027     }
1028     return 0; // still pending
1029 }
1030 
1031 static int dib7000m_autosearch_is_irq(struct dvb_frontend *demod)
1032 {
1033     struct dib7000m_state *state = demod->demodulator_priv;
1034     if (state->revision == 0x4000)
1035         return dib7000m_autosearch_irq(state, 1793);
1036     else
1037         return dib7000m_autosearch_irq(state, 537);
1038 }
1039 
1040 static int dib7000m_tune(struct dvb_frontend *demod)
1041 {
1042     struct dtv_frontend_properties *ch = &demod->dtv_property_cache;
1043     struct dib7000m_state *state = demod->demodulator_priv;
1044     int ret = 0;
1045     u16 value;
1046 
1047     // we are already tuned - just resuming from suspend
1048     dib7000m_set_channel(state, ch, 0);
1049 
1050     // restart demod
1051     ret |= dib7000m_write_word(state, 898, 0x4000);
1052     ret |= dib7000m_write_word(state, 898, 0x0000);
1053     msleep(45);
1054 
1055     dib7000m_set_power_mode(state, DIB7000M_POWER_COR4_CRY_ESRAM_MOUT_NUD);
1056     /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */
1057     ret |= dib7000m_write_word(state, 29, (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3));
1058 
1059     // never achieved a lock before - wait for timfreq to update
1060     if (state->timf == 0)
1061         msleep(200);
1062 
1063     //dump_reg(state);
1064     /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
1065     value = (6 << 8) | 0x80;
1066     switch (ch->transmission_mode) {
1067         case TRANSMISSION_MODE_2K: value |= (7 << 12); break;
1068         case TRANSMISSION_MODE_4K: value |= (8 << 12); break;
1069         default:
1070         case TRANSMISSION_MODE_8K: value |= (9 << 12); break;
1071     }
1072     ret |= dib7000m_write_word(state, 26, value);
1073 
1074     /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1075     value = (0 << 4);
1076     switch (ch->transmission_mode) {
1077         case TRANSMISSION_MODE_2K: value |= 0x6; break;
1078         case TRANSMISSION_MODE_4K: value |= 0x7; break;
1079         default:
1080         case TRANSMISSION_MODE_8K: value |= 0x8; break;
1081     }
1082     ret |= dib7000m_write_word(state, 32, value);
1083 
1084     /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1085     value = (0 << 4);
1086     switch (ch->transmission_mode) {
1087         case TRANSMISSION_MODE_2K: value |= 0x6; break;
1088         case TRANSMISSION_MODE_4K: value |= 0x7; break;
1089         default:
1090         case TRANSMISSION_MODE_8K: value |= 0x8; break;
1091     }
1092     ret |= dib7000m_write_word(state, 33,  value);
1093 
1094     // we achieved a lock - it's time to update the timf freq
1095     if ((dib7000m_read_word(state, 535) >> 6)  & 0x1)
1096         dib7000m_update_timf(state);
1097 
1098     dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->bandwidth_hz));
1099     return ret;
1100 }
1101 
1102 static int dib7000m_wakeup(struct dvb_frontend *demod)
1103 {
1104     struct dib7000m_state *state = demod->demodulator_priv;
1105 
1106     dib7000m_set_power_mode(state, DIB7000M_POWER_ALL);
1107 
1108     if (dib7000m_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
1109         dprintk("could not start Slow ADC\n");
1110 
1111     return 0;
1112 }
1113 
1114 static int dib7000m_sleep(struct dvb_frontend *demod)
1115 {
1116     struct dib7000m_state *st = demod->demodulator_priv;
1117     dib7000m_set_output_mode(st, OUTMODE_HIGH_Z);
1118     dib7000m_set_power_mode(st, DIB7000M_POWER_INTERFACE_ONLY);
1119     return dib7000m_set_adc_state(st, DIBX000_SLOW_ADC_OFF) |
1120         dib7000m_set_adc_state(st, DIBX000_ADC_OFF);
1121 }
1122 
1123 static int dib7000m_identify(struct dib7000m_state *state)
1124 {
1125     u16 value;
1126 
1127     if ((value = dib7000m_read_word(state, 896)) != 0x01b3) {
1128         dprintk("wrong Vendor ID (0x%x)\n", value);
1129         return -EREMOTEIO;
1130     }
1131 
1132     state->revision = dib7000m_read_word(state, 897);
1133     if (state->revision != 0x4000 &&
1134         state->revision != 0x4001 &&
1135         state->revision != 0x4002 &&
1136         state->revision != 0x4003) {
1137         dprintk("wrong Device ID (0x%x)\n", value);
1138         return -EREMOTEIO;
1139     }
1140 
1141     /* protect this driver to be used with 7000PC */
1142     if (state->revision == 0x4000 && dib7000m_read_word(state, 769) == 0x4000) {
1143         dprintk("this driver does not work with DiB7000PC\n");
1144         return -EREMOTEIO;
1145     }
1146 
1147     switch (state->revision) {
1148     case 0x4000: dprintk("found DiB7000MA/PA/MB/PB\n"); break;
1149     case 0x4001: state->reg_offs = 1; dprintk("found DiB7000HC\n"); break;
1150     case 0x4002: state->reg_offs = 1; dprintk("found DiB7000MC\n"); break;
1151     case 0x4003: state->reg_offs = 1; dprintk("found DiB9000\n"); break;
1152     }
1153 
1154     return 0;
1155 }
1156 
1157 
1158 static int dib7000m_get_frontend(struct dvb_frontend* fe,
1159                  struct dtv_frontend_properties *fep)
1160 {
1161     struct dib7000m_state *state = fe->demodulator_priv;
1162     u16 tps = dib7000m_read_word(state,480);
1163 
1164     fep->inversion = INVERSION_AUTO;
1165 
1166     fep->bandwidth_hz = BANDWIDTH_TO_HZ(state->current_bandwidth);
1167 
1168     switch ((tps >> 8) & 0x3) {
1169         case 0: fep->transmission_mode = TRANSMISSION_MODE_2K; break;
1170         case 1: fep->transmission_mode = TRANSMISSION_MODE_8K; break;
1171         /* case 2: fep->transmission_mode = TRANSMISSION_MODE_4K; break; */
1172     }
1173 
1174     switch (tps & 0x3) {
1175         case 0: fep->guard_interval = GUARD_INTERVAL_1_32; break;
1176         case 1: fep->guard_interval = GUARD_INTERVAL_1_16; break;
1177         case 2: fep->guard_interval = GUARD_INTERVAL_1_8; break;
1178         case 3: fep->guard_interval = GUARD_INTERVAL_1_4; break;
1179     }
1180 
1181     switch ((tps >> 14) & 0x3) {
1182         case 0: fep->modulation = QPSK; break;
1183         case 1: fep->modulation = QAM_16; break;
1184         case 2:
1185         default: fep->modulation = QAM_64; break;
1186     }
1187 
1188     /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
1189     /* (tps >> 13) & 0x1 == hrch is used, (tps >> 10) & 0x7 == alpha */
1190 
1191     fep->hierarchy = HIERARCHY_NONE;
1192     switch ((tps >> 5) & 0x7) {
1193         case 1: fep->code_rate_HP = FEC_1_2; break;
1194         case 2: fep->code_rate_HP = FEC_2_3; break;
1195         case 3: fep->code_rate_HP = FEC_3_4; break;
1196         case 5: fep->code_rate_HP = FEC_5_6; break;
1197         case 7:
1198         default: fep->code_rate_HP = FEC_7_8; break;
1199 
1200     }
1201 
1202     switch ((tps >> 2) & 0x7) {
1203         case 1: fep->code_rate_LP = FEC_1_2; break;
1204         case 2: fep->code_rate_LP = FEC_2_3; break;
1205         case 3: fep->code_rate_LP = FEC_3_4; break;
1206         case 5: fep->code_rate_LP = FEC_5_6; break;
1207         case 7:
1208         default: fep->code_rate_LP = FEC_7_8; break;
1209     }
1210 
1211     /* native interleaver: (dib7000m_read_word(state, 481) >>  5) & 0x1 */
1212 
1213     return 0;
1214 }
1215 
1216 static int dib7000m_set_frontend(struct dvb_frontend *fe)
1217 {
1218     struct dtv_frontend_properties *fep = &fe->dtv_property_cache;
1219     struct dib7000m_state *state = fe->demodulator_priv;
1220     int time, ret;
1221 
1222     dib7000m_set_output_mode(state, OUTMODE_HIGH_Z);
1223 
1224     dib7000m_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->bandwidth_hz));
1225 
1226     if (fe->ops.tuner_ops.set_params)
1227         fe->ops.tuner_ops.set_params(fe);
1228 
1229     /* start up the AGC */
1230     state->agc_state = 0;
1231     do {
1232         time = dib7000m_agc_startup(fe);
1233         if (time != -1)
1234             msleep(time);
1235     } while (time != -1);
1236 
1237     if (fep->transmission_mode == TRANSMISSION_MODE_AUTO ||
1238         fep->guard_interval    == GUARD_INTERVAL_AUTO ||
1239         fep->modulation        == QAM_AUTO ||
1240         fep->code_rate_HP      == FEC_AUTO) {
1241         int i = 800, found;
1242 
1243         dib7000m_autosearch_start(fe);
1244         do {
1245             msleep(1);
1246             found = dib7000m_autosearch_is_irq(fe);
1247         } while (found == 0 && i--);
1248 
1249         dprintk("autosearch returns: %d\n", found);
1250         if (found == 0 || found == 1)
1251             return 0; // no channel found
1252 
1253         dib7000m_get_frontend(fe, fep);
1254     }
1255 
1256     ret = dib7000m_tune(fe);
1257 
1258     /* make this a config parameter */
1259     dib7000m_set_output_mode(state, OUTMODE_MPEG2_FIFO);
1260     return ret;
1261 }
1262 
1263 static int dib7000m_read_status(struct dvb_frontend *fe, enum fe_status *stat)
1264 {
1265     struct dib7000m_state *state = fe->demodulator_priv;
1266     u16 lock = dib7000m_read_word(state, 535);
1267 
1268     *stat = 0;
1269 
1270     if (lock & 0x8000)
1271         *stat |= FE_HAS_SIGNAL;
1272     if (lock & 0x3000)
1273         *stat |= FE_HAS_CARRIER;
1274     if (lock & 0x0100)
1275         *stat |= FE_HAS_VITERBI;
1276     if (lock & 0x0010)
1277         *stat |= FE_HAS_SYNC;
1278     if (lock & 0x0008)
1279         *stat |= FE_HAS_LOCK;
1280 
1281     return 0;
1282 }
1283 
1284 static int dib7000m_read_ber(struct dvb_frontend *fe, u32 *ber)
1285 {
1286     struct dib7000m_state *state = fe->demodulator_priv;
1287     *ber = (dib7000m_read_word(state, 526) << 16) | dib7000m_read_word(state, 527);
1288     return 0;
1289 }
1290 
1291 static int dib7000m_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
1292 {
1293     struct dib7000m_state *state = fe->demodulator_priv;
1294     *unc = dib7000m_read_word(state, 534);
1295     return 0;
1296 }
1297 
1298 static int dib7000m_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1299 {
1300     struct dib7000m_state *state = fe->demodulator_priv;
1301     u16 val = dib7000m_read_word(state, 390);
1302     *strength = 65535 - val;
1303     return 0;
1304 }
1305 
1306 static int dib7000m_read_snr(struct dvb_frontend* fe, u16 *snr)
1307 {
1308     *snr = 0x0000;
1309     return 0;
1310 }
1311 
1312 static int dib7000m_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
1313 {
1314     tune->min_delay_ms = 1000;
1315     return 0;
1316 }
1317 
1318 static void dib7000m_release(struct dvb_frontend *demod)
1319 {
1320     struct dib7000m_state *st = demod->demodulator_priv;
1321     dibx000_exit_i2c_master(&st->i2c_master);
1322     kfree(st);
1323 }
1324 
1325 struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
1326 {
1327     struct dib7000m_state *st = demod->demodulator_priv;
1328     return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1329 }
1330 EXPORT_SYMBOL(dib7000m_get_i2c_master);
1331 
1332 int dib7000m_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1333 {
1334     struct dib7000m_state *state = fe->demodulator_priv;
1335     u16 val = dib7000m_read_word(state, 294 + state->reg_offs) & 0xffef;
1336     val |= (onoff & 0x1) << 4;
1337     dprintk("PID filter enabled %d\n", onoff);
1338     return dib7000m_write_word(state, 294 + state->reg_offs, val);
1339 }
1340 EXPORT_SYMBOL(dib7000m_pid_filter_ctrl);
1341 
1342 int dib7000m_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1343 {
1344     struct dib7000m_state *state = fe->demodulator_priv;
1345     dprintk("PID filter: index %x, PID %d, OnOff %d\n", id, pid, onoff);
1346     return dib7000m_write_word(state, 300 + state->reg_offs + id,
1347             onoff ? (1 << 13) | pid : 0);
1348 }
1349 EXPORT_SYMBOL(dib7000m_pid_filter);
1350 
1351 #if 0
1352 /* used with some prototype boards */
1353 int dib7000m_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods,
1354         u8 default_addr, struct dib7000m_config cfg[])
1355 {
1356     struct dib7000m_state st = { .i2c_adap = i2c };
1357     int k = 0;
1358     u8 new_addr = 0;
1359 
1360     for (k = no_of_demods-1; k >= 0; k--) {
1361         st.cfg = cfg[k];
1362 
1363         /* designated i2c address */
1364         new_addr          = (0x40 + k) << 1;
1365         st.i2c_addr = new_addr;
1366         if (dib7000m_identify(&st) != 0) {
1367             st.i2c_addr = default_addr;
1368             if (dib7000m_identify(&st) != 0) {
1369                 dprintk("DiB7000M #%d: not identified\n", k);
1370                 return -EIO;
1371             }
1372         }
1373 
1374         /* start diversity to pull_down div_str - just for i2c-enumeration */
1375         dib7000m_set_output_mode(&st, OUTMODE_DIVERSITY);
1376 
1377         dib7000m_write_word(&st, 1796, 0x0); // select DVB-T output
1378 
1379         /* set new i2c address and force divstart */
1380         dib7000m_write_word(&st, 1794, (new_addr << 2) | 0x2);
1381 
1382         dprintk("IC %d initialized (to i2c_address 0x%x)\n", k, new_addr);
1383     }
1384 
1385     for (k = 0; k < no_of_demods; k++) {
1386         st.cfg = cfg[k];
1387         st.i2c_addr = (0x40 + k) << 1;
1388 
1389         // unforce divstr
1390         dib7000m_write_word(&st,1794, st.i2c_addr << 2);
1391 
1392         /* deactivate div - it was just for i2c-enumeration */
1393         dib7000m_set_output_mode(&st, OUTMODE_HIGH_Z);
1394     }
1395 
1396     return 0;
1397 }
1398 EXPORT_SYMBOL(dib7000m_i2c_enumeration);
1399 #endif
1400 
1401 static const struct dvb_frontend_ops dib7000m_ops;
1402 struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg)
1403 {
1404     struct dvb_frontend *demod;
1405     struct dib7000m_state *st;
1406     st = kzalloc(sizeof(struct dib7000m_state), GFP_KERNEL);
1407     if (st == NULL)
1408         return NULL;
1409 
1410     memcpy(&st->cfg, cfg, sizeof(struct dib7000m_config));
1411     st->i2c_adap = i2c_adap;
1412     st->i2c_addr = i2c_addr;
1413 
1414     demod                   = &st->demod;
1415     demod->demodulator_priv = st;
1416     memcpy(&st->demod.ops, &dib7000m_ops, sizeof(struct dvb_frontend_ops));
1417     mutex_init(&st->i2c_buffer_lock);
1418 
1419     st->timf_default = cfg->bw->timf;
1420 
1421     if (dib7000m_identify(st) != 0)
1422         goto error;
1423 
1424     if (st->revision == 0x4000)
1425         dibx000_init_i2c_master(&st->i2c_master, DIB7000, st->i2c_adap, st->i2c_addr);
1426     else
1427         dibx000_init_i2c_master(&st->i2c_master, DIB7000MC, st->i2c_adap, st->i2c_addr);
1428 
1429     dib7000m_demod_reset(st);
1430 
1431     return demod;
1432 
1433 error:
1434     kfree(st);
1435     return NULL;
1436 }
1437 EXPORT_SYMBOL(dib7000m_attach);
1438 
1439 static const struct dvb_frontend_ops dib7000m_ops = {
1440     .delsys = { SYS_DVBT },
1441     .info = {
1442         .name = "DiBcom 7000MA/MB/PA/PB/MC",
1443         .frequency_min_hz      =  44250 * kHz,
1444         .frequency_max_hz      = 867250 * kHz,
1445         .frequency_stepsize_hz = 62500,
1446         .caps = FE_CAN_INVERSION_AUTO |
1447             FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1448             FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1449             FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1450             FE_CAN_TRANSMISSION_MODE_AUTO |
1451             FE_CAN_GUARD_INTERVAL_AUTO |
1452             FE_CAN_RECOVER |
1453             FE_CAN_HIERARCHY_AUTO,
1454     },
1455 
1456     .release              = dib7000m_release,
1457 
1458     .init                 = dib7000m_wakeup,
1459     .sleep                = dib7000m_sleep,
1460 
1461     .set_frontend         = dib7000m_set_frontend,
1462     .get_tune_settings    = dib7000m_fe_get_tune_settings,
1463     .get_frontend         = dib7000m_get_frontend,
1464 
1465     .read_status          = dib7000m_read_status,
1466     .read_ber             = dib7000m_read_ber,
1467     .read_signal_strength = dib7000m_read_signal_strength,
1468     .read_snr             = dib7000m_read_snr,
1469     .read_ucblocks        = dib7000m_read_unc_blocks,
1470 };
1471 
1472 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
1473 MODULE_DESCRIPTION("Driver for the DiBcom 7000MA/MB/PA/PB/MC COFDM demodulator");
1474 MODULE_LICENSE("GPL");