Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  *  Driver for Silicon Labs Si2161 DVB-T and Si2165 DVB-C/-T Demodulator
0004  *
0005  *  Copyright (C) 2013-2017 Matthias Schwarzott <zzam@gentoo.org>
0006  *
0007  *  References:
0008  *  https://www.silabs.com/Support%20Documents/TechnicalDocs/Si2165-short.pdf
0009  */
0010 
0011 #include <linux/delay.h>
0012 #include <linux/errno.h>
0013 #include <linux/init.h>
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/string.h>
0017 #include <linux/slab.h>
0018 #include <linux/firmware.h>
0019 #include <linux/regmap.h>
0020 
0021 #include <media/dvb_frontend.h>
0022 #include <media/dvb_math.h>
0023 #include "si2165_priv.h"
0024 #include "si2165.h"
0025 
0026 /*
0027  * Hauppauge WinTV-HVR-930C-HD B130 / PCTV QuatroStick 521e 1113xx
0028  * uses 16 MHz xtal
0029  *
0030  * Hauppauge WinTV-HVR-930C-HD B131 / PCTV QuatroStick 522e 1114xx
0031  * uses 24 MHz clock provided by tuner
0032  */
0033 
0034 struct si2165_state {
0035     struct i2c_client *client;
0036 
0037     struct regmap *regmap;
0038 
0039     struct dvb_frontend fe;
0040 
0041     struct si2165_config config;
0042 
0043     u8 chip_revcode;
0044     u8 chip_type;
0045 
0046     /* calculated by xtal and div settings */
0047     u32 fvco_hz;
0048     u32 sys_clk;
0049     u32 adc_clk;
0050 
0051     /* DVBv3 stats */
0052     u64 ber_prev;
0053 
0054     bool has_dvbc;
0055     bool has_dvbt;
0056     bool firmware_loaded;
0057 };
0058 
0059 static int si2165_write(struct si2165_state *state, const u16 reg,
0060             const u8 *src, const int count)
0061 {
0062     int ret;
0063 
0064     dev_dbg(&state->client->dev, "i2c write: reg: 0x%04x, data: %*ph\n",
0065         reg, count, src);
0066 
0067     ret = regmap_bulk_write(state->regmap, reg, src, count);
0068 
0069     if (ret)
0070         dev_err(&state->client->dev, "%s: ret == %d\n", __func__, ret);
0071 
0072     return ret;
0073 }
0074 
0075 static int si2165_read(struct si2165_state *state,
0076                const u16 reg, u8 *val, const int count)
0077 {
0078     int ret = regmap_bulk_read(state->regmap, reg, val, count);
0079 
0080     if (ret) {
0081         dev_err(&state->client->dev, "%s: error (addr %02x reg %04x error (ret == %i)\n",
0082             __func__, state->config.i2c_addr, reg, ret);
0083         return ret;
0084     }
0085 
0086     dev_dbg(&state->client->dev, "i2c read: reg: 0x%04x, data: %*ph\n",
0087         reg, count, val);
0088 
0089     return 0;
0090 }
0091 
0092 static int si2165_readreg8(struct si2165_state *state,
0093                const u16 reg, u8 *val)
0094 {
0095     unsigned int val_tmp;
0096     int ret = regmap_read(state->regmap, reg, &val_tmp);
0097     *val = (u8)val_tmp;
0098     dev_dbg(&state->client->dev, "reg read: R(0x%04x)=0x%02x\n", reg, *val);
0099     return ret;
0100 }
0101 
0102 static int si2165_readreg16(struct si2165_state *state,
0103                 const u16 reg, u16 *val)
0104 {
0105     u8 buf[2];
0106 
0107     int ret = si2165_read(state, reg, buf, 2);
0108     *val = buf[0] | buf[1] << 8;
0109     dev_dbg(&state->client->dev, "reg read: R(0x%04x)=0x%04x\n", reg, *val);
0110     return ret;
0111 }
0112 
0113 static int si2165_readreg24(struct si2165_state *state,
0114                 const u16 reg, u32 *val)
0115 {
0116     u8 buf[3];
0117 
0118     int ret = si2165_read(state, reg, buf, 3);
0119     *val = buf[0] | buf[1] << 8 | buf[2] << 16;
0120     dev_dbg(&state->client->dev, "reg read: R(0x%04x)=0x%06x\n", reg, *val);
0121     return ret;
0122 }
0123 
0124 static int si2165_writereg8(struct si2165_state *state, const u16 reg, u8 val)
0125 {
0126     return regmap_write(state->regmap, reg, val);
0127 }
0128 
0129 static int si2165_writereg16(struct si2165_state *state, const u16 reg, u16 val)
0130 {
0131     u8 buf[2] = { val & 0xff, (val >> 8) & 0xff };
0132 
0133     return si2165_write(state, reg, buf, 2);
0134 }
0135 
0136 static int si2165_writereg24(struct si2165_state *state, const u16 reg, u32 val)
0137 {
0138     u8 buf[3] = { val & 0xff, (val >> 8) & 0xff, (val >> 16) & 0xff };
0139 
0140     return si2165_write(state, reg, buf, 3);
0141 }
0142 
0143 static int si2165_writereg32(struct si2165_state *state, const u16 reg, u32 val)
0144 {
0145     u8 buf[4] = {
0146         val & 0xff,
0147         (val >> 8) & 0xff,
0148         (val >> 16) & 0xff,
0149         (val >> 24) & 0xff
0150     };
0151     return si2165_write(state, reg, buf, 4);
0152 }
0153 
0154 static int si2165_writereg_mask8(struct si2165_state *state, const u16 reg,
0155                  u8 val, u8 mask)
0156 {
0157     if (mask != 0xff) {
0158         u8 tmp;
0159         int ret = si2165_readreg8(state, reg, &tmp);
0160 
0161         if (ret < 0)
0162             return ret;
0163 
0164         val &= mask;
0165         tmp &= ~mask;
0166         val |= tmp;
0167     }
0168     return si2165_writereg8(state, reg, val);
0169 }
0170 
0171 #define REG16(reg, val) \
0172     { (reg), (val) & 0xff }, \
0173     { (reg) + 1, (val) >> 8 & 0xff }
0174 struct si2165_reg_value_pair {
0175     u16 reg;
0176     u8 val;
0177 };
0178 
0179 static int si2165_write_reg_list(struct si2165_state *state,
0180                  const struct si2165_reg_value_pair *regs,
0181                  int count)
0182 {
0183     int i;
0184     int ret;
0185 
0186     for (i = 0; i < count; i++) {
0187         ret = si2165_writereg8(state, regs[i].reg, regs[i].val);
0188         if (ret < 0)
0189             return ret;
0190     }
0191     return 0;
0192 }
0193 
0194 static int si2165_get_tune_settings(struct dvb_frontend *fe,
0195                     struct dvb_frontend_tune_settings *s)
0196 {
0197     s->min_delay_ms = 1000;
0198     return 0;
0199 }
0200 
0201 static int si2165_init_pll(struct si2165_state *state)
0202 {
0203     u32 ref_freq_hz = state->config.ref_freq_hz;
0204     u8 divr = 1; /* 1..7 */
0205     u8 divp = 1; /* only 1 or 4 */
0206     u8 divn = 56; /* 1..63 */
0207     u8 divm = 8;
0208     u8 divl = 12;
0209     u8 buf[4];
0210 
0211     /*
0212      * hardcoded values can be deleted if calculation is verified
0213      * or it yields the same values as the windows driver
0214      */
0215     switch (ref_freq_hz) {
0216     case 16000000u:
0217         divn = 56;
0218         break;
0219     case 24000000u:
0220         divr = 2;
0221         divp = 4;
0222         divn = 19;
0223         break;
0224     default:
0225         /* ref_freq / divr must be between 4 and 16 MHz */
0226         if (ref_freq_hz > 16000000u)
0227             divr = 2;
0228 
0229         /*
0230          * now select divn and divp such that
0231          * fvco is in 1624..1824 MHz
0232          */
0233         if (1624000000u * divr > ref_freq_hz * 2u * 63u)
0234             divp = 4;
0235 
0236         /* is this already correct regarding rounding? */
0237         divn = 1624000000u * divr / (ref_freq_hz * 2u * divp);
0238         break;
0239     }
0240 
0241     /* adc_clk and sys_clk depend on xtal and pll settings */
0242     state->fvco_hz = ref_freq_hz / divr
0243             * 2u * divn * divp;
0244     state->adc_clk = state->fvco_hz / (divm * 4u);
0245     state->sys_clk = state->fvco_hz / (divl * 2u);
0246 
0247     /* write all 4 pll registers 0x00a0..0x00a3 at once */
0248     buf[0] = divl;
0249     buf[1] = divm;
0250     buf[2] = (divn & 0x3f) | ((divp == 1) ? 0x40 : 0x00) | 0x80;
0251     buf[3] = divr;
0252     return si2165_write(state, REG_PLL_DIVL, buf, 4);
0253 }
0254 
0255 static int si2165_adjust_pll_divl(struct si2165_state *state, u8 divl)
0256 {
0257     state->sys_clk = state->fvco_hz / (divl * 2u);
0258     return si2165_writereg8(state, REG_PLL_DIVL, divl);
0259 }
0260 
0261 static u32 si2165_get_fe_clk(struct si2165_state *state)
0262 {
0263     /* assume Oversampling mode Ovr4 is used */
0264     return state->adc_clk;
0265 }
0266 
0267 static int si2165_wait_init_done(struct si2165_state *state)
0268 {
0269     int ret;
0270     u8 val = 0;
0271     int i;
0272 
0273     for (i = 0; i < 3; ++i) {
0274         ret = si2165_readreg8(state, REG_INIT_DONE, &val);
0275         if (ret < 0)
0276             return ret;
0277         if (val == 0x01)
0278             return 0;
0279         usleep_range(1000, 50000);
0280     }
0281     dev_err(&state->client->dev, "init_done was not set\n");
0282     return -EINVAL;
0283 }
0284 
0285 static int si2165_upload_firmware_block(struct si2165_state *state,
0286                     const u8 *data, u32 len, u32 *poffset,
0287                     u32 block_count)
0288 {
0289     int ret;
0290     u8 buf_ctrl[4] = { 0x00, 0x00, 0x00, 0xc0 };
0291     u8 wordcount;
0292     u32 cur_block = 0;
0293     u32 offset = poffset ? *poffset : 0;
0294 
0295     if (len < 4)
0296         return -EINVAL;
0297     if (len % 4 != 0)
0298         return -EINVAL;
0299 
0300     dev_dbg(&state->client->dev,
0301         "fw load: %s: called with len=0x%x offset=0x%x blockcount=0x%x\n",
0302         __func__, len, offset, block_count);
0303     while (offset + 12 <= len && cur_block < block_count) {
0304         dev_dbg(&state->client->dev,
0305             "fw load: %s: in while len=0x%x offset=0x%x cur_block=0x%x blockcount=0x%x\n",
0306             __func__, len, offset, cur_block, block_count);
0307         wordcount = data[offset];
0308         if (wordcount < 1 || data[offset + 1] ||
0309             data[offset + 2] || data[offset + 3]) {
0310             dev_warn(&state->client->dev,
0311                  "bad fw data[0..3] = %*ph\n",
0312                  4, data);
0313             return -EINVAL;
0314         }
0315 
0316         if (offset + 8 + wordcount * 4 > len) {
0317             dev_warn(&state->client->dev,
0318                  "len is too small for block len=%d, wordcount=%d\n",
0319                 len, wordcount);
0320             return -EINVAL;
0321         }
0322 
0323         buf_ctrl[0] = wordcount - 1;
0324 
0325         ret = si2165_write(state, REG_DCOM_CONTROL_BYTE, buf_ctrl, 4);
0326         if (ret < 0)
0327             goto error;
0328         ret = si2165_write(state, REG_DCOM_ADDR, data + offset + 4, 4);
0329         if (ret < 0)
0330             goto error;
0331 
0332         offset += 8;
0333 
0334         while (wordcount > 0) {
0335             ret = si2165_write(state, REG_DCOM_DATA,
0336                        data + offset, 4);
0337             if (ret < 0)
0338                 goto error;
0339             wordcount--;
0340             offset += 4;
0341         }
0342         cur_block++;
0343     }
0344 
0345     dev_dbg(&state->client->dev,
0346         "fw load: %s: after while len=0x%x offset=0x%x cur_block=0x%x blockcount=0x%x\n",
0347         __func__, len, offset, cur_block, block_count);
0348 
0349     if (poffset)
0350         *poffset = offset;
0351 
0352     dev_dbg(&state->client->dev,
0353         "fw load: %s: returned offset=0x%x\n",
0354         __func__, offset);
0355 
0356     return 0;
0357 error:
0358     return ret;
0359 }
0360 
0361 static int si2165_upload_firmware(struct si2165_state *state)
0362 {
0363     /* int ret; */
0364     u8 val[3];
0365     u16 val16;
0366     int ret;
0367 
0368     const struct firmware *fw = NULL;
0369     u8 *fw_file;
0370     const u8 *data;
0371     u32 len;
0372     u32 offset;
0373     u8 patch_version;
0374     u8 block_count;
0375     u16 crc_expected;
0376 
0377     switch (state->chip_revcode) {
0378     case 0x03: /* revision D */
0379         fw_file = SI2165_FIRMWARE_REV_D;
0380         break;
0381     default:
0382         dev_info(&state->client->dev, "no firmware file for revision=%d\n",
0383              state->chip_revcode);
0384         return 0;
0385     }
0386 
0387     /* request the firmware, this will block and timeout */
0388     ret = request_firmware(&fw, fw_file, &state->client->dev);
0389     if (ret) {
0390         dev_warn(&state->client->dev, "firmware file '%s' not found\n",
0391              fw_file);
0392         goto error;
0393     }
0394 
0395     data = fw->data;
0396     len = fw->size;
0397 
0398     dev_info(&state->client->dev, "downloading firmware from file '%s' size=%d\n",
0399          fw_file, len);
0400 
0401     if (len % 4 != 0) {
0402         dev_warn(&state->client->dev, "firmware size is not multiple of 4\n");
0403         ret = -EINVAL;
0404         goto error;
0405     }
0406 
0407     /* check header (8 bytes) */
0408     if (len < 8) {
0409         dev_warn(&state->client->dev, "firmware header is missing\n");
0410         ret = -EINVAL;
0411         goto error;
0412     }
0413 
0414     if (data[0] != 1 || data[1] != 0) {
0415         dev_warn(&state->client->dev, "firmware file version is wrong\n");
0416         ret = -EINVAL;
0417         goto error;
0418     }
0419 
0420     patch_version = data[2];
0421     block_count = data[4];
0422     crc_expected = data[7] << 8 | data[6];
0423 
0424     /* start uploading fw */
0425     /* boot/wdog status */
0426     ret = si2165_writereg8(state, REG_WDOG_AND_BOOT, 0x00);
0427     if (ret < 0)
0428         goto error;
0429     /* reset */
0430     ret = si2165_writereg8(state, REG_RST_ALL, 0x00);
0431     if (ret < 0)
0432         goto error;
0433     /* boot/wdog status */
0434     ret = si2165_readreg8(state, REG_WDOG_AND_BOOT, val);
0435     if (ret < 0)
0436         goto error;
0437 
0438     /* enable reset on error */
0439     ret = si2165_readreg8(state, REG_EN_RST_ERROR, val);
0440     if (ret < 0)
0441         goto error;
0442     ret = si2165_readreg8(state, REG_EN_RST_ERROR, val);
0443     if (ret < 0)
0444         goto error;
0445     ret = si2165_writereg8(state, REG_EN_RST_ERROR, 0x02);
0446     if (ret < 0)
0447         goto error;
0448 
0449     /* start right after the header */
0450     offset = 8;
0451 
0452     dev_info(&state->client->dev, "%s: extracted patch_version=0x%02x, block_count=0x%02x, crc_expected=0x%04x\n",
0453          __func__, patch_version, block_count, crc_expected);
0454 
0455     ret = si2165_upload_firmware_block(state, data, len, &offset, 1);
0456     if (ret < 0)
0457         goto error;
0458 
0459     ret = si2165_writereg8(state, REG_PATCH_VERSION, patch_version);
0460     if (ret < 0)
0461         goto error;
0462 
0463     /* reset crc */
0464     ret = si2165_writereg8(state, REG_RST_CRC, 0x01);
0465     if (ret)
0466         goto error;
0467 
0468     ret = si2165_upload_firmware_block(state, data, len,
0469                        &offset, block_count);
0470     if (ret < 0) {
0471         dev_err(&state->client->dev,
0472             "firmware could not be uploaded\n");
0473         goto error;
0474     }
0475 
0476     /* read crc */
0477     ret = si2165_readreg16(state, REG_CRC, &val16);
0478     if (ret)
0479         goto error;
0480 
0481     if (val16 != crc_expected) {
0482         dev_err(&state->client->dev,
0483             "firmware crc mismatch %04x != %04x\n",
0484             val16, crc_expected);
0485         ret = -EINVAL;
0486         goto error;
0487     }
0488 
0489     ret = si2165_upload_firmware_block(state, data, len, &offset, 5);
0490     if (ret)
0491         goto error;
0492 
0493     if (len != offset) {
0494         dev_err(&state->client->dev,
0495             "firmware len mismatch %04x != %04x\n",
0496             len, offset);
0497         ret = -EINVAL;
0498         goto error;
0499     }
0500 
0501     /* reset watchdog error register */
0502     ret = si2165_writereg_mask8(state, REG_WDOG_AND_BOOT, 0x02, 0x02);
0503     if (ret < 0)
0504         goto error;
0505 
0506     /* enable reset on error */
0507     ret = si2165_writereg_mask8(state, REG_EN_RST_ERROR, 0x01, 0x01);
0508     if (ret < 0)
0509         goto error;
0510 
0511     dev_info(&state->client->dev, "fw load finished\n");
0512 
0513     ret = 0;
0514     state->firmware_loaded = true;
0515 error:
0516     if (fw) {
0517         release_firmware(fw);
0518         fw = NULL;
0519     }
0520 
0521     return ret;
0522 }
0523 
0524 static int si2165_init(struct dvb_frontend *fe)
0525 {
0526     int ret = 0;
0527     struct si2165_state *state = fe->demodulator_priv;
0528     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0529     u8 val;
0530     u8 patch_version = 0x00;
0531 
0532     dev_dbg(&state->client->dev, "%s: called\n", __func__);
0533 
0534     /* powerup */
0535     ret = si2165_writereg8(state, REG_CHIP_MODE, state->config.chip_mode);
0536     if (ret < 0)
0537         goto error;
0538     /* dsp_clock_enable */
0539     ret = si2165_writereg8(state, REG_DSP_CLOCK, 0x01);
0540     if (ret < 0)
0541         goto error;
0542     /* verify chip_mode */
0543     ret = si2165_readreg8(state, REG_CHIP_MODE, &val);
0544     if (ret < 0)
0545         goto error;
0546     if (val != state->config.chip_mode) {
0547         dev_err(&state->client->dev, "could not set chip_mode\n");
0548         return -EINVAL;
0549     }
0550 
0551     /* agc */
0552     ret = si2165_writereg8(state, REG_AGC_IF_TRI, 0x00);
0553     if (ret < 0)
0554         goto error;
0555     ret = si2165_writereg8(state, REG_AGC_IF_SLR, 0x01);
0556     if (ret < 0)
0557         goto error;
0558     ret = si2165_writereg8(state, REG_AGC2_OUTPUT, 0x00);
0559     if (ret < 0)
0560         goto error;
0561     ret = si2165_writereg8(state, REG_AGC2_CLKDIV, 0x07);
0562     if (ret < 0)
0563         goto error;
0564     /* rssi pad */
0565     ret = si2165_writereg8(state, REG_RSSI_PAD_CTRL, 0x00);
0566     if (ret < 0)
0567         goto error;
0568     ret = si2165_writereg8(state, REG_RSSI_ENABLE, 0x00);
0569     if (ret < 0)
0570         goto error;
0571 
0572     ret = si2165_init_pll(state);
0573     if (ret < 0)
0574         goto error;
0575 
0576     /* enable chip_init */
0577     ret = si2165_writereg8(state, REG_CHIP_INIT, 0x01);
0578     if (ret < 0)
0579         goto error;
0580     /* set start_init */
0581     ret = si2165_writereg8(state, REG_START_INIT, 0x01);
0582     if (ret < 0)
0583         goto error;
0584     ret = si2165_wait_init_done(state);
0585     if (ret < 0)
0586         goto error;
0587 
0588     /* disable chip_init */
0589     ret = si2165_writereg8(state, REG_CHIP_INIT, 0x00);
0590     if (ret < 0)
0591         goto error;
0592 
0593     /* ber_pkt - default 65535 */
0594     ret = si2165_writereg16(state, REG_BER_PKT,
0595                 STATISTICS_PERIOD_PKT_COUNT);
0596     if (ret < 0)
0597         goto error;
0598 
0599     ret = si2165_readreg8(state, REG_PATCH_VERSION, &patch_version);
0600     if (ret < 0)
0601         goto error;
0602 
0603     ret = si2165_writereg8(state, REG_AUTO_RESET, 0x00);
0604     if (ret < 0)
0605         goto error;
0606 
0607     /* dsp_addr_jump */
0608     ret = si2165_writereg32(state, REG_ADDR_JUMP, 0xf4000000);
0609     if (ret < 0)
0610         goto error;
0611     /* boot/wdog status */
0612     ret = si2165_readreg8(state, REG_WDOG_AND_BOOT, &val);
0613     if (ret < 0)
0614         goto error;
0615 
0616     if (patch_version == 0x00) {
0617         ret = si2165_upload_firmware(state);
0618         if (ret < 0)
0619             goto error;
0620     }
0621 
0622     /* ts output config */
0623     ret = si2165_writereg8(state, REG_TS_DATA_MODE, 0x20);
0624     if (ret < 0)
0625         return ret;
0626     ret = si2165_writereg16(state, REG_TS_TRI, 0x00fe);
0627     if (ret < 0)
0628         return ret;
0629     ret = si2165_writereg24(state, REG_TS_SLR, 0x555555);
0630     if (ret < 0)
0631         return ret;
0632     ret = si2165_writereg8(state, REG_TS_CLK_MODE, 0x01);
0633     if (ret < 0)
0634         return ret;
0635     ret = si2165_writereg8(state, REG_TS_PARALLEL_MODE, 0x00);
0636     if (ret < 0)
0637         return ret;
0638 
0639     c = &state->fe.dtv_property_cache;
0640     c->cnr.len = 1;
0641     c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0642     c->post_bit_error.len = 1;
0643     c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0644     c->post_bit_count.len = 1;
0645     c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0646 
0647     return 0;
0648 error:
0649     return ret;
0650 }
0651 
0652 static int si2165_sleep(struct dvb_frontend *fe)
0653 {
0654     int ret;
0655     struct si2165_state *state = fe->demodulator_priv;
0656 
0657     /* dsp clock disable */
0658     ret = si2165_writereg8(state, REG_DSP_CLOCK, 0x00);
0659     if (ret < 0)
0660         return ret;
0661     /* chip mode */
0662     ret = si2165_writereg8(state, REG_CHIP_MODE, SI2165_MODE_OFF);
0663     if (ret < 0)
0664         return ret;
0665     return 0;
0666 }
0667 
0668 static int si2165_read_status(struct dvb_frontend *fe, enum fe_status *status)
0669 {
0670     int ret;
0671     u8 u8tmp;
0672     u32 u32tmp;
0673     struct si2165_state *state = fe->demodulator_priv;
0674     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0675     u32 delsys = c->delivery_system;
0676 
0677     *status = 0;
0678 
0679     switch (delsys) {
0680     case SYS_DVBT:
0681         /* check fast signal type */
0682         ret = si2165_readreg8(state, REG_CHECK_SIGNAL, &u8tmp);
0683         if (ret < 0)
0684             return ret;
0685         switch (u8tmp & 0x3) {
0686         case 0: /* searching */
0687         case 1: /* nothing */
0688             break;
0689         case 2: /* digital signal */
0690             *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
0691             break;
0692         }
0693         break;
0694     case SYS_DVBC_ANNEX_A:
0695         /* check packet sync lock */
0696         ret = si2165_readreg8(state, REG_PS_LOCK, &u8tmp);
0697         if (ret < 0)
0698             return ret;
0699         if (u8tmp & 0x01) {
0700             *status |= FE_HAS_SIGNAL;
0701             *status |= FE_HAS_CARRIER;
0702             *status |= FE_HAS_VITERBI;
0703             *status |= FE_HAS_SYNC;
0704         }
0705         break;
0706     }
0707 
0708     /* check fec_lock */
0709     ret = si2165_readreg8(state, REG_FEC_LOCK, &u8tmp);
0710     if (ret < 0)
0711         return ret;
0712     if (u8tmp & 0x01) {
0713         *status |= FE_HAS_SIGNAL;
0714         *status |= FE_HAS_CARRIER;
0715         *status |= FE_HAS_VITERBI;
0716         *status |= FE_HAS_SYNC;
0717         *status |= FE_HAS_LOCK;
0718     }
0719 
0720     /* CNR */
0721     if (delsys == SYS_DVBC_ANNEX_A && *status & FE_HAS_VITERBI) {
0722         ret = si2165_readreg24(state, REG_C_N, &u32tmp);
0723         if (ret < 0)
0724             return ret;
0725         /*
0726          * svalue =
0727          * 1000 * c_n/dB =
0728          * 1000 * 10 * log10(2^24 / regval) =
0729          * 1000 * 10 * (log10(2^24) - log10(regval)) =
0730          * 1000 * 10 * (intlog10(2^24) - intlog10(regval)) / 2^24
0731          *
0732          * intlog10(x) = log10(x) * 2^24
0733          * intlog10(2^24) = log10(2^24) * 2^24 = 121210686
0734          */
0735         u32tmp = (1000 * 10 * (121210686 - (u64)intlog10(u32tmp)))
0736                 >> 24;
0737         c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
0738         c->cnr.stat[0].svalue = u32tmp;
0739     } else
0740         c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0741 
0742     /* BER */
0743     if (*status & FE_HAS_VITERBI) {
0744         if (c->post_bit_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
0745             /* start new sampling period to get rid of old data*/
0746             ret = si2165_writereg8(state, REG_BER_RST, 0x01);
0747             if (ret < 0)
0748                 return ret;
0749 
0750             /* set scale to enter read code on next call */
0751             c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
0752             c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
0753             c->post_bit_error.stat[0].uvalue = 0;
0754             c->post_bit_count.stat[0].uvalue = 0;
0755 
0756             /*
0757              * reset DVBv3 value to deliver a good result
0758              * for the first call
0759              */
0760             state->ber_prev = 0;
0761 
0762         } else {
0763             ret = si2165_readreg8(state, REG_BER_AVAIL, &u8tmp);
0764             if (ret < 0)
0765                 return ret;
0766 
0767             if (u8tmp & 1) {
0768                 u32 biterrcnt;
0769 
0770                 ret = si2165_readreg24(state, REG_BER_BIT,
0771                             &biterrcnt);
0772                 if (ret < 0)
0773                     return ret;
0774 
0775                 c->post_bit_error.stat[0].uvalue +=
0776                     biterrcnt;
0777                 c->post_bit_count.stat[0].uvalue +=
0778                     STATISTICS_PERIOD_BIT_COUNT;
0779 
0780                 /* start new sampling period */
0781                 ret = si2165_writereg8(state,
0782                             REG_BER_RST, 0x01);
0783                 if (ret < 0)
0784                     return ret;
0785 
0786                 dev_dbg(&state->client->dev,
0787                     "post_bit_error=%u post_bit_count=%u\n",
0788                     biterrcnt, STATISTICS_PERIOD_BIT_COUNT);
0789             }
0790         }
0791     } else {
0792         c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0793         c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0794     }
0795 
0796     return 0;
0797 }
0798 
0799 static int si2165_read_snr(struct dvb_frontend *fe, u16 *snr)
0800 {
0801     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0802 
0803     if (c->cnr.stat[0].scale == FE_SCALE_DECIBEL)
0804         *snr = div_s64(c->cnr.stat[0].svalue, 100);
0805     else
0806         *snr = 0;
0807     return 0;
0808 }
0809 
0810 static int si2165_read_ber(struct dvb_frontend *fe, u32 *ber)
0811 {
0812     struct si2165_state *state = fe->demodulator_priv;
0813     struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0814 
0815     if (c->post_bit_error.stat[0].scale != FE_SCALE_COUNTER) {
0816         *ber = 0;
0817         return 0;
0818     }
0819 
0820     *ber = c->post_bit_error.stat[0].uvalue - state->ber_prev;
0821     state->ber_prev = c->post_bit_error.stat[0].uvalue;
0822 
0823     return 0;
0824 }
0825 
0826 static int si2165_set_oversamp(struct si2165_state *state, u32 dvb_rate)
0827 {
0828     u64 oversamp;
0829     u32 reg_value;
0830 
0831     if (!dvb_rate)
0832         return -EINVAL;
0833 
0834     oversamp = si2165_get_fe_clk(state);
0835     oversamp <<= 23;
0836     do_div(oversamp, dvb_rate);
0837     reg_value = oversamp & 0x3fffffff;
0838 
0839     dev_dbg(&state->client->dev, "Write oversamp=%#x\n", reg_value);
0840     return si2165_writereg32(state, REG_OVERSAMP, reg_value);
0841 }
0842 
0843 static int si2165_set_if_freq_shift(struct si2165_state *state)
0844 {
0845     struct dvb_frontend *fe = &state->fe;
0846     u64 if_freq_shift;
0847     s32 reg_value = 0;
0848     u32 fe_clk = si2165_get_fe_clk(state);
0849     u32 IF = 0;
0850 
0851     if (!fe->ops.tuner_ops.get_if_frequency) {
0852         dev_err(&state->client->dev,
0853             "Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
0854         return -EINVAL;
0855     }
0856 
0857     if (!fe_clk)
0858         return -EINVAL;
0859 
0860     fe->ops.tuner_ops.get_if_frequency(fe, &IF);
0861     if_freq_shift = IF;
0862     if_freq_shift <<= 29;
0863 
0864     do_div(if_freq_shift, fe_clk);
0865     reg_value = (s32)if_freq_shift;
0866 
0867     if (state->config.inversion)
0868         reg_value = -reg_value;
0869 
0870     reg_value = reg_value & 0x1fffffff;
0871 
0872     /* if_freq_shift, usbdump contained 0x023ee08f; */
0873     return si2165_writereg32(state, REG_IF_FREQ_SHIFT, reg_value);
0874 }
0875 
0876 static const struct si2165_reg_value_pair dvbt_regs[] = {
0877     /* standard = DVB-T */
0878     { REG_DVB_STANDARD, 0x01 },
0879     /* impulsive_noise_remover */
0880     { REG_IMPULSIVE_NOISE_REM, 0x01 },
0881     { REG_AUTO_RESET, 0x00 },
0882     /* agc2 */
0883     { REG_AGC2_MIN, 0x41 },
0884     { REG_AGC2_KACQ, 0x0e },
0885     { REG_AGC2_KLOC, 0x10 },
0886     /* agc */
0887     { REG_AGC_UNFREEZE_THR, 0x03 },
0888     { REG_AGC_CRESTF_DBX8, 0x78 },
0889     /* agc */
0890     { REG_AAF_CRESTF_DBX8, 0x78 },
0891     { REG_ACI_CRESTF_DBX8, 0x68 },
0892     /* freq_sync_range */
0893     REG16(REG_FREQ_SYNC_RANGE, 0x0064),
0894     /* gp_reg0 */
0895     { REG_GP_REG0_MSB, 0x00 }
0896 };
0897 
0898 static int si2165_set_frontend_dvbt(struct dvb_frontend *fe)
0899 {
0900     int ret;
0901     struct dtv_frontend_properties *p = &fe->dtv_property_cache;
0902     struct si2165_state *state = fe->demodulator_priv;
0903     u32 dvb_rate = 0;
0904     u16 bw10k;
0905     u32 bw_hz = p->bandwidth_hz;
0906 
0907     dev_dbg(&state->client->dev, "%s: called\n", __func__);
0908 
0909     if (!state->has_dvbt)
0910         return -EINVAL;
0911 
0912     /* no bandwidth auto-detection */
0913     if (bw_hz == 0)
0914         return -EINVAL;
0915 
0916     dvb_rate = bw_hz * 8 / 7;
0917     bw10k = bw_hz / 10000;
0918 
0919     ret = si2165_adjust_pll_divl(state, 12);
0920     if (ret < 0)
0921         return ret;
0922 
0923     /* bandwidth in 10KHz steps */
0924     ret = si2165_writereg16(state, REG_T_BANDWIDTH, bw10k);
0925     if (ret < 0)
0926         return ret;
0927     ret = si2165_set_oversamp(state, dvb_rate);
0928     if (ret < 0)
0929         return ret;
0930 
0931     ret = si2165_write_reg_list(state, dvbt_regs, ARRAY_SIZE(dvbt_regs));
0932     if (ret < 0)
0933         return ret;
0934 
0935     return 0;
0936 }
0937 
0938 static const struct si2165_reg_value_pair dvbc_regs[] = {
0939     /* standard = DVB-C */
0940     { REG_DVB_STANDARD, 0x05 },
0941 
0942     /* agc2 */
0943     { REG_AGC2_MIN, 0x50 },
0944     { REG_AGC2_KACQ, 0x0e },
0945     { REG_AGC2_KLOC, 0x10 },
0946     /* agc */
0947     { REG_AGC_UNFREEZE_THR, 0x03 },
0948     { REG_AGC_CRESTF_DBX8, 0x68 },
0949     /* agc */
0950     { REG_AAF_CRESTF_DBX8, 0x68 },
0951     { REG_ACI_CRESTF_DBX8, 0x50 },
0952 
0953     { REG_EQ_AUTO_CONTROL, 0x0d },
0954 
0955     { REG_KP_LOCK, 0x05 },
0956     { REG_CENTRAL_TAP, 0x09 },
0957     REG16(REG_UNKNOWN_350, 0x3e80),
0958 
0959     { REG_AUTO_RESET, 0x01 },
0960     REG16(REG_UNKNOWN_24C, 0x0000),
0961     REG16(REG_UNKNOWN_27C, 0x0000),
0962     { REG_SWEEP_STEP, 0x03 },
0963     { REG_AGC_IF_TRI, 0x00 },
0964 };
0965 
0966 static int si2165_set_frontend_dvbc(struct dvb_frontend *fe)
0967 {
0968     struct si2165_state *state = fe->demodulator_priv;
0969     int ret;
0970     struct dtv_frontend_properties *p = &fe->dtv_property_cache;
0971     const u32 dvb_rate = p->symbol_rate;
0972     u8 u8tmp;
0973 
0974     if (!state->has_dvbc)
0975         return -EINVAL;
0976 
0977     if (dvb_rate == 0)
0978         return -EINVAL;
0979 
0980     ret = si2165_adjust_pll_divl(state, 14);
0981     if (ret < 0)
0982         return ret;
0983 
0984     /* Oversampling */
0985     ret = si2165_set_oversamp(state, dvb_rate);
0986     if (ret < 0)
0987         return ret;
0988 
0989     switch (p->modulation) {
0990     case QPSK:
0991         u8tmp = 0x3;
0992         break;
0993     case QAM_16:
0994         u8tmp = 0x7;
0995         break;
0996     case QAM_32:
0997         u8tmp = 0x8;
0998         break;
0999     case QAM_64:
1000         u8tmp = 0x9;
1001         break;
1002     case QAM_128:
1003         u8tmp = 0xa;
1004         break;
1005     case QAM_256:
1006     default:
1007         u8tmp = 0xb;
1008         break;
1009     }
1010     ret = si2165_writereg8(state, REG_REQ_CONSTELLATION, u8tmp);
1011     if (ret < 0)
1012         return ret;
1013 
1014     ret = si2165_writereg32(state, REG_LOCK_TIMEOUT, 0x007a1200);
1015     if (ret < 0)
1016         return ret;
1017 
1018     ret = si2165_write_reg_list(state, dvbc_regs, ARRAY_SIZE(dvbc_regs));
1019     if (ret < 0)
1020         return ret;
1021 
1022     return 0;
1023 }
1024 
1025 static const struct si2165_reg_value_pair adc_rewrite[] = {
1026     { REG_ADC_RI1, 0x46 },
1027     { REG_ADC_RI3, 0x00 },
1028     { REG_ADC_RI5, 0x0a },
1029     { REG_ADC_RI6, 0xff },
1030     { REG_ADC_RI8, 0x70 }
1031 };
1032 
1033 static int si2165_set_frontend(struct dvb_frontend *fe)
1034 {
1035     struct si2165_state *state = fe->demodulator_priv;
1036     struct dtv_frontend_properties *p = &fe->dtv_property_cache;
1037     u32 delsys = p->delivery_system;
1038     int ret;
1039     u8 val[3];
1040 
1041     /* initial setting of if freq shift */
1042     ret = si2165_set_if_freq_shift(state);
1043     if (ret < 0)
1044         return ret;
1045 
1046     switch (delsys) {
1047     case SYS_DVBT:
1048         ret = si2165_set_frontend_dvbt(fe);
1049         if (ret < 0)
1050             return ret;
1051         break;
1052     case SYS_DVBC_ANNEX_A:
1053         ret = si2165_set_frontend_dvbc(fe);
1054         if (ret < 0)
1055             return ret;
1056         break;
1057     default:
1058         return -EINVAL;
1059     }
1060 
1061     /* dsp_addr_jump */
1062     ret = si2165_writereg32(state, REG_ADDR_JUMP, 0xf4000000);
1063     if (ret < 0)
1064         return ret;
1065 
1066     if (fe->ops.tuner_ops.set_params)
1067         fe->ops.tuner_ops.set_params(fe);
1068 
1069     /* recalc if_freq_shift if IF might has changed */
1070     ret = si2165_set_if_freq_shift(state);
1071     if (ret < 0)
1072         return ret;
1073 
1074     /* boot/wdog status */
1075     ret = si2165_readreg8(state, REG_WDOG_AND_BOOT, val);
1076     if (ret < 0)
1077         return ret;
1078     ret = si2165_writereg8(state, REG_WDOG_AND_BOOT, 0x00);
1079     if (ret < 0)
1080         return ret;
1081 
1082     /* reset all */
1083     ret = si2165_writereg8(state, REG_RST_ALL, 0x00);
1084     if (ret < 0)
1085         return ret;
1086     /* gp_reg0 */
1087     ret = si2165_writereg32(state, REG_GP_REG0_LSB, 0x00000000);
1088     if (ret < 0)
1089         return ret;
1090 
1091     /* write adc values after each reset*/
1092     ret = si2165_write_reg_list(state, adc_rewrite,
1093                     ARRAY_SIZE(adc_rewrite));
1094     if (ret < 0)
1095         return ret;
1096 
1097     /* start_synchro */
1098     ret = si2165_writereg8(state, REG_START_SYNCHRO, 0x01);
1099     if (ret < 0)
1100         return ret;
1101     /* boot/wdog status */
1102     ret = si2165_readreg8(state, REG_WDOG_AND_BOOT, val);
1103     if (ret < 0)
1104         return ret;
1105 
1106     return 0;
1107 }
1108 
1109 static const struct dvb_frontend_ops si2165_ops = {
1110     .info = {
1111         .name = "Silicon Labs ",
1112          /* For DVB-C */
1113         .symbol_rate_min = 1000000,
1114         .symbol_rate_max = 7200000,
1115         /* For DVB-T */
1116         .frequency_stepsize_hz = 166667,
1117         .caps = FE_CAN_FEC_1_2 |
1118             FE_CAN_FEC_2_3 |
1119             FE_CAN_FEC_3_4 |
1120             FE_CAN_FEC_5_6 |
1121             FE_CAN_FEC_7_8 |
1122             FE_CAN_FEC_AUTO |
1123             FE_CAN_QPSK |
1124             FE_CAN_QAM_16 |
1125             FE_CAN_QAM_32 |
1126             FE_CAN_QAM_64 |
1127             FE_CAN_QAM_128 |
1128             FE_CAN_QAM_256 |
1129             FE_CAN_GUARD_INTERVAL_AUTO |
1130             FE_CAN_HIERARCHY_AUTO |
1131             FE_CAN_MUTE_TS |
1132             FE_CAN_TRANSMISSION_MODE_AUTO |
1133             FE_CAN_RECOVER
1134     },
1135 
1136     .get_tune_settings = si2165_get_tune_settings,
1137 
1138     .init = si2165_init,
1139     .sleep = si2165_sleep,
1140 
1141     .set_frontend      = si2165_set_frontend,
1142     .read_status       = si2165_read_status,
1143     .read_snr          = si2165_read_snr,
1144     .read_ber          = si2165_read_ber,
1145 };
1146 
1147 static int si2165_probe(struct i2c_client *client,
1148             const struct i2c_device_id *id)
1149 {
1150     struct si2165_state *state = NULL;
1151     struct si2165_platform_data *pdata = client->dev.platform_data;
1152     int n;
1153     int ret = 0;
1154     u8 val;
1155     char rev_char;
1156     const char *chip_name;
1157     static const struct regmap_config regmap_config = {
1158         .reg_bits = 16,
1159         .val_bits = 8,
1160         .max_register = 0x08ff,
1161     };
1162 
1163     /* allocate memory for the internal state */
1164     state = kzalloc(sizeof(*state), GFP_KERNEL);
1165     if (!state) {
1166         ret = -ENOMEM;
1167         goto error;
1168     }
1169 
1170     /* create regmap */
1171     state->regmap = devm_regmap_init_i2c(client, &regmap_config);
1172     if (IS_ERR(state->regmap)) {
1173         ret = PTR_ERR(state->regmap);
1174         goto error;
1175     }
1176 
1177     /* setup the state */
1178     state->client = client;
1179     state->config.i2c_addr = client->addr;
1180     state->config.chip_mode = pdata->chip_mode;
1181     state->config.ref_freq_hz = pdata->ref_freq_hz;
1182     state->config.inversion = pdata->inversion;
1183 
1184     if (state->config.ref_freq_hz < 4000000 ||
1185         state->config.ref_freq_hz > 27000000) {
1186         dev_err(&state->client->dev, "ref_freq of %d Hz not supported by this driver\n",
1187             state->config.ref_freq_hz);
1188         ret = -EINVAL;
1189         goto error;
1190     }
1191 
1192     /* create dvb_frontend */
1193     memcpy(&state->fe.ops, &si2165_ops,
1194            sizeof(struct dvb_frontend_ops));
1195     state->fe.ops.release = NULL;
1196     state->fe.demodulator_priv = state;
1197     i2c_set_clientdata(client, state);
1198 
1199     /* powerup */
1200     ret = si2165_writereg8(state, REG_CHIP_MODE, state->config.chip_mode);
1201     if (ret < 0)
1202         goto nodev_error;
1203 
1204     ret = si2165_readreg8(state, REG_CHIP_MODE, &val);
1205     if (ret < 0)
1206         goto nodev_error;
1207     if (val != state->config.chip_mode)
1208         goto nodev_error;
1209 
1210     ret = si2165_readreg8(state, REG_CHIP_REVCODE, &state->chip_revcode);
1211     if (ret < 0)
1212         goto nodev_error;
1213 
1214     ret = si2165_readreg8(state, REV_CHIP_TYPE, &state->chip_type);
1215     if (ret < 0)
1216         goto nodev_error;
1217 
1218     /* powerdown */
1219     ret = si2165_writereg8(state, REG_CHIP_MODE, SI2165_MODE_OFF);
1220     if (ret < 0)
1221         goto nodev_error;
1222 
1223     if (state->chip_revcode < 26)
1224         rev_char = 'A' + state->chip_revcode;
1225     else
1226         rev_char = '?';
1227 
1228     switch (state->chip_type) {
1229     case 0x06:
1230         chip_name = "Si2161";
1231         state->has_dvbt = true;
1232         break;
1233     case 0x07:
1234         chip_name = "Si2165";
1235         state->has_dvbt = true;
1236         state->has_dvbc = true;
1237         break;
1238     default:
1239         dev_err(&state->client->dev, "Unsupported Silicon Labs chip (type %d, rev %d)\n",
1240             state->chip_type, state->chip_revcode);
1241         goto nodev_error;
1242     }
1243 
1244     dev_info(&state->client->dev,
1245          "Detected Silicon Labs %s-%c (type %d, rev %d)\n",
1246         chip_name, rev_char, state->chip_type,
1247         state->chip_revcode);
1248 
1249     strlcat(state->fe.ops.info.name, chip_name,
1250         sizeof(state->fe.ops.info.name));
1251 
1252     n = 0;
1253     if (state->has_dvbt) {
1254         state->fe.ops.delsys[n++] = SYS_DVBT;
1255         strlcat(state->fe.ops.info.name, " DVB-T",
1256             sizeof(state->fe.ops.info.name));
1257     }
1258     if (state->has_dvbc) {
1259         state->fe.ops.delsys[n++] = SYS_DVBC_ANNEX_A;
1260         strlcat(state->fe.ops.info.name, " DVB-C",
1261             sizeof(state->fe.ops.info.name));
1262     }
1263 
1264     /* return fe pointer */
1265     *pdata->fe = &state->fe;
1266 
1267     return 0;
1268 
1269 nodev_error:
1270     ret = -ENODEV;
1271 error:
1272     kfree(state);
1273     dev_dbg(&client->dev, "failed=%d\n", ret);
1274     return ret;
1275 }
1276 
1277 static int si2165_remove(struct i2c_client *client)
1278 {
1279     struct si2165_state *state = i2c_get_clientdata(client);
1280 
1281     dev_dbg(&client->dev, "\n");
1282 
1283     kfree(state);
1284     return 0;
1285 }
1286 
1287 static const struct i2c_device_id si2165_id_table[] = {
1288     {"si2165", 0},
1289     {}
1290 };
1291 MODULE_DEVICE_TABLE(i2c, si2165_id_table);
1292 
1293 static struct i2c_driver si2165_driver = {
1294     .driver = {
1295         .name   = "si2165",
1296     },
1297     .probe      = si2165_probe,
1298     .remove     = si2165_remove,
1299     .id_table   = si2165_id_table,
1300 };
1301 
1302 module_i2c_driver(si2165_driver);
1303 
1304 MODULE_DESCRIPTION("Silicon Labs Si2165 DVB-C/-T Demodulator driver");
1305 MODULE_AUTHOR("Matthias Schwarzott <zzam@gentoo.org>");
1306 MODULE_LICENSE("GPL");
1307 MODULE_FIRMWARE(SI2165_FIRMWARE_REV_D);