cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

si2165.c (29840B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *  Driver for Silicon Labs Si2161 DVB-T and Si2165 DVB-C/-T Demodulator
      4 *
      5 *  Copyright (C) 2013-2017 Matthias Schwarzott <zzam@gentoo.org>
      6 *
      7 *  References:
      8 *  https://www.silabs.com/Support%20Documents/TechnicalDocs/Si2165-short.pdf
      9 */
     10
     11#include <linux/delay.h>
     12#include <linux/errno.h>
     13#include <linux/init.h>
     14#include <linux/kernel.h>
     15#include <linux/module.h>
     16#include <linux/string.h>
     17#include <linux/slab.h>
     18#include <linux/firmware.h>
     19#include <linux/regmap.h>
     20
     21#include <media/dvb_frontend.h>
     22#include <media/dvb_math.h>
     23#include "si2165_priv.h"
     24#include "si2165.h"
     25
     26/*
     27 * Hauppauge WinTV-HVR-930C-HD B130 / PCTV QuatroStick 521e 1113xx
     28 * uses 16 MHz xtal
     29 *
     30 * Hauppauge WinTV-HVR-930C-HD B131 / PCTV QuatroStick 522e 1114xx
     31 * uses 24 MHz clock provided by tuner
     32 */
     33
     34struct si2165_state {
     35	struct i2c_client *client;
     36
     37	struct regmap *regmap;
     38
     39	struct dvb_frontend fe;
     40
     41	struct si2165_config config;
     42
     43	u8 chip_revcode;
     44	u8 chip_type;
     45
     46	/* calculated by xtal and div settings */
     47	u32 fvco_hz;
     48	u32 sys_clk;
     49	u32 adc_clk;
     50
     51	/* DVBv3 stats */
     52	u64 ber_prev;
     53
     54	bool has_dvbc;
     55	bool has_dvbt;
     56	bool firmware_loaded;
     57};
     58
     59static int si2165_write(struct si2165_state *state, const u16 reg,
     60			const u8 *src, const int count)
     61{
     62	int ret;
     63
     64	dev_dbg(&state->client->dev, "i2c write: reg: 0x%04x, data: %*ph\n",
     65		reg, count, src);
     66
     67	ret = regmap_bulk_write(state->regmap, reg, src, count);
     68
     69	if (ret)
     70		dev_err(&state->client->dev, "%s: ret == %d\n", __func__, ret);
     71
     72	return ret;
     73}
     74
     75static int si2165_read(struct si2165_state *state,
     76		       const u16 reg, u8 *val, const int count)
     77{
     78	int ret = regmap_bulk_read(state->regmap, reg, val, count);
     79
     80	if (ret) {
     81		dev_err(&state->client->dev, "%s: error (addr %02x reg %04x error (ret == %i)\n",
     82			__func__, state->config.i2c_addr, reg, ret);
     83		return ret;
     84	}
     85
     86	dev_dbg(&state->client->dev, "i2c read: reg: 0x%04x, data: %*ph\n",
     87		reg, count, val);
     88
     89	return 0;
     90}
     91
     92static int si2165_readreg8(struct si2165_state *state,
     93			   const u16 reg, u8 *val)
     94{
     95	unsigned int val_tmp;
     96	int ret = regmap_read(state->regmap, reg, &val_tmp);
     97	*val = (u8)val_tmp;
     98	dev_dbg(&state->client->dev, "reg read: R(0x%04x)=0x%02x\n", reg, *val);
     99	return ret;
    100}
    101
    102static int si2165_readreg16(struct si2165_state *state,
    103			    const u16 reg, u16 *val)
    104{
    105	u8 buf[2];
    106
    107	int ret = si2165_read(state, reg, buf, 2);
    108	*val = buf[0] | buf[1] << 8;
    109	dev_dbg(&state->client->dev, "reg read: R(0x%04x)=0x%04x\n", reg, *val);
    110	return ret;
    111}
    112
    113static int si2165_readreg24(struct si2165_state *state,
    114			    const u16 reg, u32 *val)
    115{
    116	u8 buf[3];
    117
    118	int ret = si2165_read(state, reg, buf, 3);
    119	*val = buf[0] | buf[1] << 8 | buf[2] << 16;
    120	dev_dbg(&state->client->dev, "reg read: R(0x%04x)=0x%06x\n", reg, *val);
    121	return ret;
    122}
    123
    124static int si2165_writereg8(struct si2165_state *state, const u16 reg, u8 val)
    125{
    126	return regmap_write(state->regmap, reg, val);
    127}
    128
    129static int si2165_writereg16(struct si2165_state *state, const u16 reg, u16 val)
    130{
    131	u8 buf[2] = { val & 0xff, (val >> 8) & 0xff };
    132
    133	return si2165_write(state, reg, buf, 2);
    134}
    135
    136static int si2165_writereg24(struct si2165_state *state, const u16 reg, u32 val)
    137{
    138	u8 buf[3] = { val & 0xff, (val >> 8) & 0xff, (val >> 16) & 0xff };
    139
    140	return si2165_write(state, reg, buf, 3);
    141}
    142
    143static int si2165_writereg32(struct si2165_state *state, const u16 reg, u32 val)
    144{
    145	u8 buf[4] = {
    146		val & 0xff,
    147		(val >> 8) & 0xff,
    148		(val >> 16) & 0xff,
    149		(val >> 24) & 0xff
    150	};
    151	return si2165_write(state, reg, buf, 4);
    152}
    153
    154static int si2165_writereg_mask8(struct si2165_state *state, const u16 reg,
    155				 u8 val, u8 mask)
    156{
    157	if (mask != 0xff) {
    158		u8 tmp;
    159		int ret = si2165_readreg8(state, reg, &tmp);
    160
    161		if (ret < 0)
    162			return ret;
    163
    164		val &= mask;
    165		tmp &= ~mask;
    166		val |= tmp;
    167	}
    168	return si2165_writereg8(state, reg, val);
    169}
    170
    171#define REG16(reg, val) \
    172	{ (reg), (val) & 0xff }, \
    173	{ (reg) + 1, (val) >> 8 & 0xff }
    174struct si2165_reg_value_pair {
    175	u16 reg;
    176	u8 val;
    177};
    178
    179static int si2165_write_reg_list(struct si2165_state *state,
    180				 const struct si2165_reg_value_pair *regs,
    181				 int count)
    182{
    183	int i;
    184	int ret;
    185
    186	for (i = 0; i < count; i++) {
    187		ret = si2165_writereg8(state, regs[i].reg, regs[i].val);
    188		if (ret < 0)
    189			return ret;
    190	}
    191	return 0;
    192}
    193
    194static int si2165_get_tune_settings(struct dvb_frontend *fe,
    195				    struct dvb_frontend_tune_settings *s)
    196{
    197	s->min_delay_ms = 1000;
    198	return 0;
    199}
    200
    201static int si2165_init_pll(struct si2165_state *state)
    202{
    203	u32 ref_freq_hz = state->config.ref_freq_hz;
    204	u8 divr = 1; /* 1..7 */
    205	u8 divp = 1; /* only 1 or 4 */
    206	u8 divn = 56; /* 1..63 */
    207	u8 divm = 8;
    208	u8 divl = 12;
    209	u8 buf[4];
    210
    211	/*
    212	 * hardcoded values can be deleted if calculation is verified
    213	 * or it yields the same values as the windows driver
    214	 */
    215	switch (ref_freq_hz) {
    216	case 16000000u:
    217		divn = 56;
    218		break;
    219	case 24000000u:
    220		divr = 2;
    221		divp = 4;
    222		divn = 19;
    223		break;
    224	default:
    225		/* ref_freq / divr must be between 4 and 16 MHz */
    226		if (ref_freq_hz > 16000000u)
    227			divr = 2;
    228
    229		/*
    230		 * now select divn and divp such that
    231		 * fvco is in 1624..1824 MHz
    232		 */
    233		if (1624000000u * divr > ref_freq_hz * 2u * 63u)
    234			divp = 4;
    235
    236		/* is this already correct regarding rounding? */
    237		divn = 1624000000u * divr / (ref_freq_hz * 2u * divp);
    238		break;
    239	}
    240
    241	/* adc_clk and sys_clk depend on xtal and pll settings */
    242	state->fvco_hz = ref_freq_hz / divr
    243			* 2u * divn * divp;
    244	state->adc_clk = state->fvco_hz / (divm * 4u);
    245	state->sys_clk = state->fvco_hz / (divl * 2u);
    246
    247	/* write all 4 pll registers 0x00a0..0x00a3 at once */
    248	buf[0] = divl;
    249	buf[1] = divm;
    250	buf[2] = (divn & 0x3f) | ((divp == 1) ? 0x40 : 0x00) | 0x80;
    251	buf[3] = divr;
    252	return si2165_write(state, REG_PLL_DIVL, buf, 4);
    253}
    254
    255static int si2165_adjust_pll_divl(struct si2165_state *state, u8 divl)
    256{
    257	state->sys_clk = state->fvco_hz / (divl * 2u);
    258	return si2165_writereg8(state, REG_PLL_DIVL, divl);
    259}
    260
    261static u32 si2165_get_fe_clk(struct si2165_state *state)
    262{
    263	/* assume Oversampling mode Ovr4 is used */
    264	return state->adc_clk;
    265}
    266
    267static int si2165_wait_init_done(struct si2165_state *state)
    268{
    269	int ret;
    270	u8 val = 0;
    271	int i;
    272
    273	for (i = 0; i < 3; ++i) {
    274		ret = si2165_readreg8(state, REG_INIT_DONE, &val);
    275		if (ret < 0)
    276			return ret;
    277		if (val == 0x01)
    278			return 0;
    279		usleep_range(1000, 50000);
    280	}
    281	dev_err(&state->client->dev, "init_done was not set\n");
    282	return -EINVAL;
    283}
    284
    285static int si2165_upload_firmware_block(struct si2165_state *state,
    286					const u8 *data, u32 len, u32 *poffset,
    287					u32 block_count)
    288{
    289	int ret;
    290	u8 buf_ctrl[4] = { 0x00, 0x00, 0x00, 0xc0 };
    291	u8 wordcount;
    292	u32 cur_block = 0;
    293	u32 offset = poffset ? *poffset : 0;
    294
    295	if (len < 4)
    296		return -EINVAL;
    297	if (len % 4 != 0)
    298		return -EINVAL;
    299
    300	dev_dbg(&state->client->dev,
    301		"fw load: %s: called with len=0x%x offset=0x%x blockcount=0x%x\n",
    302		__func__, len, offset, block_count);
    303	while (offset + 12 <= len && cur_block < block_count) {
    304		dev_dbg(&state->client->dev,
    305			"fw load: %s: in while len=0x%x offset=0x%x cur_block=0x%x blockcount=0x%x\n",
    306			__func__, len, offset, cur_block, block_count);
    307		wordcount = data[offset];
    308		if (wordcount < 1 || data[offset + 1] ||
    309		    data[offset + 2] || data[offset + 3]) {
    310			dev_warn(&state->client->dev,
    311				 "bad fw data[0..3] = %*ph\n",
    312				 4, data);
    313			return -EINVAL;
    314		}
    315
    316		if (offset + 8 + wordcount * 4 > len) {
    317			dev_warn(&state->client->dev,
    318				 "len is too small for block len=%d, wordcount=%d\n",
    319				len, wordcount);
    320			return -EINVAL;
    321		}
    322
    323		buf_ctrl[0] = wordcount - 1;
    324
    325		ret = si2165_write(state, REG_DCOM_CONTROL_BYTE, buf_ctrl, 4);
    326		if (ret < 0)
    327			goto error;
    328		ret = si2165_write(state, REG_DCOM_ADDR, data + offset + 4, 4);
    329		if (ret < 0)
    330			goto error;
    331
    332		offset += 8;
    333
    334		while (wordcount > 0) {
    335			ret = si2165_write(state, REG_DCOM_DATA,
    336					   data + offset, 4);
    337			if (ret < 0)
    338				goto error;
    339			wordcount--;
    340			offset += 4;
    341		}
    342		cur_block++;
    343	}
    344
    345	dev_dbg(&state->client->dev,
    346		"fw load: %s: after while len=0x%x offset=0x%x cur_block=0x%x blockcount=0x%x\n",
    347		__func__, len, offset, cur_block, block_count);
    348
    349	if (poffset)
    350		*poffset = offset;
    351
    352	dev_dbg(&state->client->dev,
    353		"fw load: %s: returned offset=0x%x\n",
    354		__func__, offset);
    355
    356	return 0;
    357error:
    358	return ret;
    359}
    360
    361static int si2165_upload_firmware(struct si2165_state *state)
    362{
    363	/* int ret; */
    364	u8 val[3];
    365	u16 val16;
    366	int ret;
    367
    368	const struct firmware *fw = NULL;
    369	u8 *fw_file;
    370	const u8 *data;
    371	u32 len;
    372	u32 offset;
    373	u8 patch_version;
    374	u8 block_count;
    375	u16 crc_expected;
    376
    377	switch (state->chip_revcode) {
    378	case 0x03: /* revision D */
    379		fw_file = SI2165_FIRMWARE_REV_D;
    380		break;
    381	default:
    382		dev_info(&state->client->dev, "no firmware file for revision=%d\n",
    383			 state->chip_revcode);
    384		return 0;
    385	}
    386
    387	/* request the firmware, this will block and timeout */
    388	ret = request_firmware(&fw, fw_file, &state->client->dev);
    389	if (ret) {
    390		dev_warn(&state->client->dev, "firmware file '%s' not found\n",
    391			 fw_file);
    392		goto error;
    393	}
    394
    395	data = fw->data;
    396	len = fw->size;
    397
    398	dev_info(&state->client->dev, "downloading firmware from file '%s' size=%d\n",
    399		 fw_file, len);
    400
    401	if (len % 4 != 0) {
    402		dev_warn(&state->client->dev, "firmware size is not multiple of 4\n");
    403		ret = -EINVAL;
    404		goto error;
    405	}
    406
    407	/* check header (8 bytes) */
    408	if (len < 8) {
    409		dev_warn(&state->client->dev, "firmware header is missing\n");
    410		ret = -EINVAL;
    411		goto error;
    412	}
    413
    414	if (data[0] != 1 || data[1] != 0) {
    415		dev_warn(&state->client->dev, "firmware file version is wrong\n");
    416		ret = -EINVAL;
    417		goto error;
    418	}
    419
    420	patch_version = data[2];
    421	block_count = data[4];
    422	crc_expected = data[7] << 8 | data[6];
    423
    424	/* start uploading fw */
    425	/* boot/wdog status */
    426	ret = si2165_writereg8(state, REG_WDOG_AND_BOOT, 0x00);
    427	if (ret < 0)
    428		goto error;
    429	/* reset */
    430	ret = si2165_writereg8(state, REG_RST_ALL, 0x00);
    431	if (ret < 0)
    432		goto error;
    433	/* boot/wdog status */
    434	ret = si2165_readreg8(state, REG_WDOG_AND_BOOT, val);
    435	if (ret < 0)
    436		goto error;
    437
    438	/* enable reset on error */
    439	ret = si2165_readreg8(state, REG_EN_RST_ERROR, val);
    440	if (ret < 0)
    441		goto error;
    442	ret = si2165_readreg8(state, REG_EN_RST_ERROR, val);
    443	if (ret < 0)
    444		goto error;
    445	ret = si2165_writereg8(state, REG_EN_RST_ERROR, 0x02);
    446	if (ret < 0)
    447		goto error;
    448
    449	/* start right after the header */
    450	offset = 8;
    451
    452	dev_info(&state->client->dev, "%s: extracted patch_version=0x%02x, block_count=0x%02x, crc_expected=0x%04x\n",
    453		 __func__, patch_version, block_count, crc_expected);
    454
    455	ret = si2165_upload_firmware_block(state, data, len, &offset, 1);
    456	if (ret < 0)
    457		goto error;
    458
    459	ret = si2165_writereg8(state, REG_PATCH_VERSION, patch_version);
    460	if (ret < 0)
    461		goto error;
    462
    463	/* reset crc */
    464	ret = si2165_writereg8(state, REG_RST_CRC, 0x01);
    465	if (ret)
    466		goto error;
    467
    468	ret = si2165_upload_firmware_block(state, data, len,
    469					   &offset, block_count);
    470	if (ret < 0) {
    471		dev_err(&state->client->dev,
    472			"firmware could not be uploaded\n");
    473		goto error;
    474	}
    475
    476	/* read crc */
    477	ret = si2165_readreg16(state, REG_CRC, &val16);
    478	if (ret)
    479		goto error;
    480
    481	if (val16 != crc_expected) {
    482		dev_err(&state->client->dev,
    483			"firmware crc mismatch %04x != %04x\n",
    484			val16, crc_expected);
    485		ret = -EINVAL;
    486		goto error;
    487	}
    488
    489	ret = si2165_upload_firmware_block(state, data, len, &offset, 5);
    490	if (ret)
    491		goto error;
    492
    493	if (len != offset) {
    494		dev_err(&state->client->dev,
    495			"firmware len mismatch %04x != %04x\n",
    496			len, offset);
    497		ret = -EINVAL;
    498		goto error;
    499	}
    500
    501	/* reset watchdog error register */
    502	ret = si2165_writereg_mask8(state, REG_WDOG_AND_BOOT, 0x02, 0x02);
    503	if (ret < 0)
    504		goto error;
    505
    506	/* enable reset on error */
    507	ret = si2165_writereg_mask8(state, REG_EN_RST_ERROR, 0x01, 0x01);
    508	if (ret < 0)
    509		goto error;
    510
    511	dev_info(&state->client->dev, "fw load finished\n");
    512
    513	ret = 0;
    514	state->firmware_loaded = true;
    515error:
    516	if (fw) {
    517		release_firmware(fw);
    518		fw = NULL;
    519	}
    520
    521	return ret;
    522}
    523
    524static int si2165_init(struct dvb_frontend *fe)
    525{
    526	int ret = 0;
    527	struct si2165_state *state = fe->demodulator_priv;
    528	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
    529	u8 val;
    530	u8 patch_version = 0x00;
    531
    532	dev_dbg(&state->client->dev, "%s: called\n", __func__);
    533
    534	/* powerup */
    535	ret = si2165_writereg8(state, REG_CHIP_MODE, state->config.chip_mode);
    536	if (ret < 0)
    537		goto error;
    538	/* dsp_clock_enable */
    539	ret = si2165_writereg8(state, REG_DSP_CLOCK, 0x01);
    540	if (ret < 0)
    541		goto error;
    542	/* verify chip_mode */
    543	ret = si2165_readreg8(state, REG_CHIP_MODE, &val);
    544	if (ret < 0)
    545		goto error;
    546	if (val != state->config.chip_mode) {
    547		dev_err(&state->client->dev, "could not set chip_mode\n");
    548		return -EINVAL;
    549	}
    550
    551	/* agc */
    552	ret = si2165_writereg8(state, REG_AGC_IF_TRI, 0x00);
    553	if (ret < 0)
    554		goto error;
    555	ret = si2165_writereg8(state, REG_AGC_IF_SLR, 0x01);
    556	if (ret < 0)
    557		goto error;
    558	ret = si2165_writereg8(state, REG_AGC2_OUTPUT, 0x00);
    559	if (ret < 0)
    560		goto error;
    561	ret = si2165_writereg8(state, REG_AGC2_CLKDIV, 0x07);
    562	if (ret < 0)
    563		goto error;
    564	/* rssi pad */
    565	ret = si2165_writereg8(state, REG_RSSI_PAD_CTRL, 0x00);
    566	if (ret < 0)
    567		goto error;
    568	ret = si2165_writereg8(state, REG_RSSI_ENABLE, 0x00);
    569	if (ret < 0)
    570		goto error;
    571
    572	ret = si2165_init_pll(state);
    573	if (ret < 0)
    574		goto error;
    575
    576	/* enable chip_init */
    577	ret = si2165_writereg8(state, REG_CHIP_INIT, 0x01);
    578	if (ret < 0)
    579		goto error;
    580	/* set start_init */
    581	ret = si2165_writereg8(state, REG_START_INIT, 0x01);
    582	if (ret < 0)
    583		goto error;
    584	ret = si2165_wait_init_done(state);
    585	if (ret < 0)
    586		goto error;
    587
    588	/* disable chip_init */
    589	ret = si2165_writereg8(state, REG_CHIP_INIT, 0x00);
    590	if (ret < 0)
    591		goto error;
    592
    593	/* ber_pkt - default 65535 */
    594	ret = si2165_writereg16(state, REG_BER_PKT,
    595				STATISTICS_PERIOD_PKT_COUNT);
    596	if (ret < 0)
    597		goto error;
    598
    599	ret = si2165_readreg8(state, REG_PATCH_VERSION, &patch_version);
    600	if (ret < 0)
    601		goto error;
    602
    603	ret = si2165_writereg8(state, REG_AUTO_RESET, 0x00);
    604	if (ret < 0)
    605		goto error;
    606
    607	/* dsp_addr_jump */
    608	ret = si2165_writereg32(state, REG_ADDR_JUMP, 0xf4000000);
    609	if (ret < 0)
    610		goto error;
    611	/* boot/wdog status */
    612	ret = si2165_readreg8(state, REG_WDOG_AND_BOOT, &val);
    613	if (ret < 0)
    614		goto error;
    615
    616	if (patch_version == 0x00) {
    617		ret = si2165_upload_firmware(state);
    618		if (ret < 0)
    619			goto error;
    620	}
    621
    622	/* ts output config */
    623	ret = si2165_writereg8(state, REG_TS_DATA_MODE, 0x20);
    624	if (ret < 0)
    625		return ret;
    626	ret = si2165_writereg16(state, REG_TS_TRI, 0x00fe);
    627	if (ret < 0)
    628		return ret;
    629	ret = si2165_writereg24(state, REG_TS_SLR, 0x555555);
    630	if (ret < 0)
    631		return ret;
    632	ret = si2165_writereg8(state, REG_TS_CLK_MODE, 0x01);
    633	if (ret < 0)
    634		return ret;
    635	ret = si2165_writereg8(state, REG_TS_PARALLEL_MODE, 0x00);
    636	if (ret < 0)
    637		return ret;
    638
    639	c = &state->fe.dtv_property_cache;
    640	c->cnr.len = 1;
    641	c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
    642	c->post_bit_error.len = 1;
    643	c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
    644	c->post_bit_count.len = 1;
    645	c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
    646
    647	return 0;
    648error:
    649	return ret;
    650}
    651
    652static int si2165_sleep(struct dvb_frontend *fe)
    653{
    654	int ret;
    655	struct si2165_state *state = fe->demodulator_priv;
    656
    657	/* dsp clock disable */
    658	ret = si2165_writereg8(state, REG_DSP_CLOCK, 0x00);
    659	if (ret < 0)
    660		return ret;
    661	/* chip mode */
    662	ret = si2165_writereg8(state, REG_CHIP_MODE, SI2165_MODE_OFF);
    663	if (ret < 0)
    664		return ret;
    665	return 0;
    666}
    667
    668static int si2165_read_status(struct dvb_frontend *fe, enum fe_status *status)
    669{
    670	int ret;
    671	u8 u8tmp;
    672	u32 u32tmp;
    673	struct si2165_state *state = fe->demodulator_priv;
    674	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
    675	u32 delsys = c->delivery_system;
    676
    677	*status = 0;
    678
    679	switch (delsys) {
    680	case SYS_DVBT:
    681		/* check fast signal type */
    682		ret = si2165_readreg8(state, REG_CHECK_SIGNAL, &u8tmp);
    683		if (ret < 0)
    684			return ret;
    685		switch (u8tmp & 0x3) {
    686		case 0: /* searching */
    687		case 1: /* nothing */
    688			break;
    689		case 2: /* digital signal */
    690			*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
    691			break;
    692		}
    693		break;
    694	case SYS_DVBC_ANNEX_A:
    695		/* check packet sync lock */
    696		ret = si2165_readreg8(state, REG_PS_LOCK, &u8tmp);
    697		if (ret < 0)
    698			return ret;
    699		if (u8tmp & 0x01) {
    700			*status |= FE_HAS_SIGNAL;
    701			*status |= FE_HAS_CARRIER;
    702			*status |= FE_HAS_VITERBI;
    703			*status |= FE_HAS_SYNC;
    704		}
    705		break;
    706	}
    707
    708	/* check fec_lock */
    709	ret = si2165_readreg8(state, REG_FEC_LOCK, &u8tmp);
    710	if (ret < 0)
    711		return ret;
    712	if (u8tmp & 0x01) {
    713		*status |= FE_HAS_SIGNAL;
    714		*status |= FE_HAS_CARRIER;
    715		*status |= FE_HAS_VITERBI;
    716		*status |= FE_HAS_SYNC;
    717		*status |= FE_HAS_LOCK;
    718	}
    719
    720	/* CNR */
    721	if (delsys == SYS_DVBC_ANNEX_A && *status & FE_HAS_VITERBI) {
    722		ret = si2165_readreg24(state, REG_C_N, &u32tmp);
    723		if (ret < 0)
    724			return ret;
    725		/*
    726		 * svalue =
    727		 * 1000 * c_n/dB =
    728		 * 1000 * 10 * log10(2^24 / regval) =
    729		 * 1000 * 10 * (log10(2^24) - log10(regval)) =
    730		 * 1000 * 10 * (intlog10(2^24) - intlog10(regval)) / 2^24
    731		 *
    732		 * intlog10(x) = log10(x) * 2^24
    733		 * intlog10(2^24) = log10(2^24) * 2^24 = 121210686
    734		 */
    735		u32tmp = (1000 * 10 * (121210686 - (u64)intlog10(u32tmp)))
    736				>> 24;
    737		c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
    738		c->cnr.stat[0].svalue = u32tmp;
    739	} else
    740		c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
    741
    742	/* BER */
    743	if (*status & FE_HAS_VITERBI) {
    744		if (c->post_bit_error.stat[0].scale == FE_SCALE_NOT_AVAILABLE) {
    745			/* start new sampling period to get rid of old data*/
    746			ret = si2165_writereg8(state, REG_BER_RST, 0x01);
    747			if (ret < 0)
    748				return ret;
    749
    750			/* set scale to enter read code on next call */
    751			c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
    752			c->post_bit_count.stat[0].scale = FE_SCALE_COUNTER;
    753			c->post_bit_error.stat[0].uvalue = 0;
    754			c->post_bit_count.stat[0].uvalue = 0;
    755
    756			/*
    757			 * reset DVBv3 value to deliver a good result
    758			 * for the first call
    759			 */
    760			state->ber_prev = 0;
    761
    762		} else {
    763			ret = si2165_readreg8(state, REG_BER_AVAIL, &u8tmp);
    764			if (ret < 0)
    765				return ret;
    766
    767			if (u8tmp & 1) {
    768				u32 biterrcnt;
    769
    770				ret = si2165_readreg24(state, REG_BER_BIT,
    771							&biterrcnt);
    772				if (ret < 0)
    773					return ret;
    774
    775				c->post_bit_error.stat[0].uvalue +=
    776					biterrcnt;
    777				c->post_bit_count.stat[0].uvalue +=
    778					STATISTICS_PERIOD_BIT_COUNT;
    779
    780				/* start new sampling period */
    781				ret = si2165_writereg8(state,
    782							REG_BER_RST, 0x01);
    783				if (ret < 0)
    784					return ret;
    785
    786				dev_dbg(&state->client->dev,
    787					"post_bit_error=%u post_bit_count=%u\n",
    788					biterrcnt, STATISTICS_PERIOD_BIT_COUNT);
    789			}
    790		}
    791	} else {
    792		c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
    793		c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
    794	}
    795
    796	return 0;
    797}
    798
    799static int si2165_read_snr(struct dvb_frontend *fe, u16 *snr)
    800{
    801	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
    802
    803	if (c->cnr.stat[0].scale == FE_SCALE_DECIBEL)
    804		*snr = div_s64(c->cnr.stat[0].svalue, 100);
    805	else
    806		*snr = 0;
    807	return 0;
    808}
    809
    810static int si2165_read_ber(struct dvb_frontend *fe, u32 *ber)
    811{
    812	struct si2165_state *state = fe->demodulator_priv;
    813	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
    814
    815	if (c->post_bit_error.stat[0].scale != FE_SCALE_COUNTER) {
    816		*ber = 0;
    817		return 0;
    818	}
    819
    820	*ber = c->post_bit_error.stat[0].uvalue - state->ber_prev;
    821	state->ber_prev = c->post_bit_error.stat[0].uvalue;
    822
    823	return 0;
    824}
    825
    826static int si2165_set_oversamp(struct si2165_state *state, u32 dvb_rate)
    827{
    828	u64 oversamp;
    829	u32 reg_value;
    830
    831	if (!dvb_rate)
    832		return -EINVAL;
    833
    834	oversamp = si2165_get_fe_clk(state);
    835	oversamp <<= 23;
    836	do_div(oversamp, dvb_rate);
    837	reg_value = oversamp & 0x3fffffff;
    838
    839	dev_dbg(&state->client->dev, "Write oversamp=%#x\n", reg_value);
    840	return si2165_writereg32(state, REG_OVERSAMP, reg_value);
    841}
    842
    843static int si2165_set_if_freq_shift(struct si2165_state *state)
    844{
    845	struct dvb_frontend *fe = &state->fe;
    846	u64 if_freq_shift;
    847	s32 reg_value = 0;
    848	u32 fe_clk = si2165_get_fe_clk(state);
    849	u32 IF = 0;
    850
    851	if (!fe->ops.tuner_ops.get_if_frequency) {
    852		dev_err(&state->client->dev,
    853			"Error: get_if_frequency() not defined at tuner. Can't work without it!\n");
    854		return -EINVAL;
    855	}
    856
    857	if (!fe_clk)
    858		return -EINVAL;
    859
    860	fe->ops.tuner_ops.get_if_frequency(fe, &IF);
    861	if_freq_shift = IF;
    862	if_freq_shift <<= 29;
    863
    864	do_div(if_freq_shift, fe_clk);
    865	reg_value = (s32)if_freq_shift;
    866
    867	if (state->config.inversion)
    868		reg_value = -reg_value;
    869
    870	reg_value = reg_value & 0x1fffffff;
    871
    872	/* if_freq_shift, usbdump contained 0x023ee08f; */
    873	return si2165_writereg32(state, REG_IF_FREQ_SHIFT, reg_value);
    874}
    875
    876static const struct si2165_reg_value_pair dvbt_regs[] = {
    877	/* standard = DVB-T */
    878	{ REG_DVB_STANDARD, 0x01 },
    879	/* impulsive_noise_remover */
    880	{ REG_IMPULSIVE_NOISE_REM, 0x01 },
    881	{ REG_AUTO_RESET, 0x00 },
    882	/* agc2 */
    883	{ REG_AGC2_MIN, 0x41 },
    884	{ REG_AGC2_KACQ, 0x0e },
    885	{ REG_AGC2_KLOC, 0x10 },
    886	/* agc */
    887	{ REG_AGC_UNFREEZE_THR, 0x03 },
    888	{ REG_AGC_CRESTF_DBX8, 0x78 },
    889	/* agc */
    890	{ REG_AAF_CRESTF_DBX8, 0x78 },
    891	{ REG_ACI_CRESTF_DBX8, 0x68 },
    892	/* freq_sync_range */
    893	REG16(REG_FREQ_SYNC_RANGE, 0x0064),
    894	/* gp_reg0 */
    895	{ REG_GP_REG0_MSB, 0x00 }
    896};
    897
    898static int si2165_set_frontend_dvbt(struct dvb_frontend *fe)
    899{
    900	int ret;
    901	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
    902	struct si2165_state *state = fe->demodulator_priv;
    903	u32 dvb_rate = 0;
    904	u16 bw10k;
    905	u32 bw_hz = p->bandwidth_hz;
    906
    907	dev_dbg(&state->client->dev, "%s: called\n", __func__);
    908
    909	if (!state->has_dvbt)
    910		return -EINVAL;
    911
    912	/* no bandwidth auto-detection */
    913	if (bw_hz == 0)
    914		return -EINVAL;
    915
    916	dvb_rate = bw_hz * 8 / 7;
    917	bw10k = bw_hz / 10000;
    918
    919	ret = si2165_adjust_pll_divl(state, 12);
    920	if (ret < 0)
    921		return ret;
    922
    923	/* bandwidth in 10KHz steps */
    924	ret = si2165_writereg16(state, REG_T_BANDWIDTH, bw10k);
    925	if (ret < 0)
    926		return ret;
    927	ret = si2165_set_oversamp(state, dvb_rate);
    928	if (ret < 0)
    929		return ret;
    930
    931	ret = si2165_write_reg_list(state, dvbt_regs, ARRAY_SIZE(dvbt_regs));
    932	if (ret < 0)
    933		return ret;
    934
    935	return 0;
    936}
    937
    938static const struct si2165_reg_value_pair dvbc_regs[] = {
    939	/* standard = DVB-C */
    940	{ REG_DVB_STANDARD, 0x05 },
    941
    942	/* agc2 */
    943	{ REG_AGC2_MIN, 0x50 },
    944	{ REG_AGC2_KACQ, 0x0e },
    945	{ REG_AGC2_KLOC, 0x10 },
    946	/* agc */
    947	{ REG_AGC_UNFREEZE_THR, 0x03 },
    948	{ REG_AGC_CRESTF_DBX8, 0x68 },
    949	/* agc */
    950	{ REG_AAF_CRESTF_DBX8, 0x68 },
    951	{ REG_ACI_CRESTF_DBX8, 0x50 },
    952
    953	{ REG_EQ_AUTO_CONTROL, 0x0d },
    954
    955	{ REG_KP_LOCK, 0x05 },
    956	{ REG_CENTRAL_TAP, 0x09 },
    957	REG16(REG_UNKNOWN_350, 0x3e80),
    958
    959	{ REG_AUTO_RESET, 0x01 },
    960	REG16(REG_UNKNOWN_24C, 0x0000),
    961	REG16(REG_UNKNOWN_27C, 0x0000),
    962	{ REG_SWEEP_STEP, 0x03 },
    963	{ REG_AGC_IF_TRI, 0x00 },
    964};
    965
    966static int si2165_set_frontend_dvbc(struct dvb_frontend *fe)
    967{
    968	struct si2165_state *state = fe->demodulator_priv;
    969	int ret;
    970	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
    971	const u32 dvb_rate = p->symbol_rate;
    972	u8 u8tmp;
    973
    974	if (!state->has_dvbc)
    975		return -EINVAL;
    976
    977	if (dvb_rate == 0)
    978		return -EINVAL;
    979
    980	ret = si2165_adjust_pll_divl(state, 14);
    981	if (ret < 0)
    982		return ret;
    983
    984	/* Oversampling */
    985	ret = si2165_set_oversamp(state, dvb_rate);
    986	if (ret < 0)
    987		return ret;
    988
    989	switch (p->modulation) {
    990	case QPSK:
    991		u8tmp = 0x3;
    992		break;
    993	case QAM_16:
    994		u8tmp = 0x7;
    995		break;
    996	case QAM_32:
    997		u8tmp = 0x8;
    998		break;
    999	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
   1025static 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
   1033static 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
   1109static 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
   1147static 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
   1269nodev_error:
   1270	ret = -ENODEV;
   1271error:
   1272	kfree(state);
   1273	dev_dbg(&client->dev, "failed=%d\n", ret);
   1274	return ret;
   1275}
   1276
   1277static 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
   1287static const struct i2c_device_id si2165_id_table[] = {
   1288	{"si2165", 0},
   1289	{}
   1290};
   1291MODULE_DEVICE_TABLE(i2c, si2165_id_table);
   1292
   1293static 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
   1302module_i2c_driver(si2165_driver);
   1303
   1304MODULE_DESCRIPTION("Silicon Labs Si2165 DVB-C/-T Demodulator driver");
   1305MODULE_AUTHOR("Matthias Schwarzott <zzam@gentoo.org>");
   1306MODULE_LICENSE("GPL");
   1307MODULE_FIRMWARE(SI2165_FIRMWARE_REV_D);