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

si21xx.c (21010B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/* DVB compliant Linux driver for the DVB-S si2109/2110 demodulator
      3*
      4* Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
      5*/
      6#include <linux/init.h>
      7#include <linux/kernel.h>
      8#include <linux/module.h>
      9#include <linux/string.h>
     10#include <linux/slab.h>
     11#include <linux/jiffies.h>
     12#include <asm/div64.h>
     13
     14#include <media/dvb_frontend.h>
     15#include "si21xx.h"
     16
     17#define	REVISION_REG			0x00
     18#define	SYSTEM_MODE_REG			0x01
     19#define	TS_CTRL_REG_1			0x02
     20#define	TS_CTRL_REG_2			0x03
     21#define	PIN_CTRL_REG_1			0x04
     22#define	PIN_CTRL_REG_2			0x05
     23#define	LOCK_STATUS_REG_1		0x0f
     24#define	LOCK_STATUS_REG_2		0x10
     25#define	ACQ_STATUS_REG			0x11
     26#define	ACQ_CTRL_REG_1			0x13
     27#define	ACQ_CTRL_REG_2			0x14
     28#define	PLL_DIVISOR_REG			0x15
     29#define	COARSE_TUNE_REG			0x16
     30#define	FINE_TUNE_REG_L			0x17
     31#define	FINE_TUNE_REG_H			0x18
     32
     33#define	ANALOG_AGC_POWER_LEVEL_REG	0x28
     34#define	CFO_ESTIMATOR_CTRL_REG_1	0x29
     35#define	CFO_ESTIMATOR_CTRL_REG_2	0x2a
     36#define	CFO_ESTIMATOR_CTRL_REG_3	0x2b
     37
     38#define	SYM_RATE_ESTIMATE_REG_L		0x31
     39#define	SYM_RATE_ESTIMATE_REG_M		0x32
     40#define	SYM_RATE_ESTIMATE_REG_H		0x33
     41
     42#define	CFO_ESTIMATOR_OFFSET_REG_L	0x36
     43#define	CFO_ESTIMATOR_OFFSET_REG_H	0x37
     44#define	CFO_ERROR_REG_L			0x38
     45#define	CFO_ERROR_REG_H			0x39
     46#define	SYM_RATE_ESTIMATOR_CTRL_REG	0x3a
     47
     48#define	SYM_RATE_REG_L			0x3f
     49#define	SYM_RATE_REG_M			0x40
     50#define	SYM_RATE_REG_H			0x41
     51#define	SYM_RATE_ESTIMATOR_MAXIMUM_REG	0x42
     52#define	SYM_RATE_ESTIMATOR_MINIMUM_REG	0x43
     53
     54#define	C_N_ESTIMATOR_CTRL_REG		0x7c
     55#define	C_N_ESTIMATOR_THRSHLD_REG	0x7d
     56#define	C_N_ESTIMATOR_LEVEL_REG_L	0x7e
     57#define	C_N_ESTIMATOR_LEVEL_REG_H	0x7f
     58
     59#define	BLIND_SCAN_CTRL_REG		0x80
     60
     61#define	LSA_CTRL_REG_1			0x8D
     62#define	SPCTRM_TILT_CORR_THRSHLD_REG	0x8f
     63#define	ONE_DB_BNDWDTH_THRSHLD_REG	0x90
     64#define	TWO_DB_BNDWDTH_THRSHLD_REG	0x91
     65#define	THREE_DB_BNDWDTH_THRSHLD_REG	0x92
     66#define	INBAND_POWER_THRSHLD_REG	0x93
     67#define	REF_NOISE_LVL_MRGN_THRSHLD_REG	0x94
     68
     69#define	VIT_SRCH_CTRL_REG_1		0xa0
     70#define	VIT_SRCH_CTRL_REG_2		0xa1
     71#define	VIT_SRCH_CTRL_REG_3		0xa2
     72#define	VIT_SRCH_STATUS_REG		0xa3
     73#define	VITERBI_BER_COUNT_REG_L		0xab
     74#define	REED_SOLOMON_CTRL_REG		0xb0
     75#define	REED_SOLOMON_ERROR_COUNT_REG_L	0xb1
     76#define	PRBS_CTRL_REG			0xb5
     77
     78#define	LNB_CTRL_REG_1			0xc0
     79#define	LNB_CTRL_REG_2			0xc1
     80#define	LNB_CTRL_REG_3			0xc2
     81#define	LNB_CTRL_REG_4			0xc3
     82#define	LNB_CTRL_STATUS_REG		0xc4
     83#define	LNB_FIFO_REGS_0			0xc5
     84#define	LNB_FIFO_REGS_1			0xc6
     85#define	LNB_FIFO_REGS_2			0xc7
     86#define	LNB_FIFO_REGS_3			0xc8
     87#define	LNB_FIFO_REGS_4			0xc9
     88#define	LNB_FIFO_REGS_5			0xca
     89#define	LNB_SUPPLY_CTRL_REG_1		0xcb
     90#define	LNB_SUPPLY_CTRL_REG_2		0xcc
     91#define	LNB_SUPPLY_CTRL_REG_3		0xcd
     92#define	LNB_SUPPLY_CTRL_REG_4		0xce
     93#define	LNB_SUPPLY_STATUS_REG		0xcf
     94
     95#define FAIL	-1
     96#define PASS	0
     97
     98#define ALLOWABLE_FS_COUNT	10
     99#define STATUS_BER		0
    100#define STATUS_UCBLOCKS		1
    101
    102static int debug;
    103#define dprintk(args...) \
    104	do { \
    105		if (debug) \
    106			printk(KERN_DEBUG "si21xx: " args); \
    107	} while (0)
    108
    109enum {
    110	ACTIVE_HIGH,
    111	ACTIVE_LOW
    112};
    113enum {
    114	BYTE_WIDE,
    115	BIT_WIDE
    116};
    117enum {
    118	CLK_GAPPED_MODE,
    119	CLK_CONTINUOUS_MODE
    120};
    121enum {
    122	RISING_EDGE,
    123	FALLING_EDGE
    124};
    125enum {
    126	MSB_FIRST,
    127	LSB_FIRST
    128};
    129enum {
    130	SERIAL,
    131	PARALLEL
    132};
    133
    134struct si21xx_state {
    135	struct i2c_adapter *i2c;
    136	const struct si21xx_config *config;
    137	struct dvb_frontend frontend;
    138	u8 initialised:1;
    139	int errmode;
    140	int fs;			/*Sampling rate of the ADC in MHz*/
    141};
    142
    143/*	register default initialization */
    144static u8 serit_sp1511lhb_inittab[] = {
    145	0x01, 0x28,	/* set i2c_inc_disable */
    146	0x20, 0x03,
    147	0x27, 0x20,
    148	0xe0, 0x45,
    149	0xe1, 0x08,
    150	0xfe, 0x01,
    151	0x01, 0x28,
    152	0x89, 0x09,
    153	0x04, 0x80,
    154	0x05, 0x01,
    155	0x06, 0x00,
    156	0x20, 0x03,
    157	0x24, 0x88,
    158	0x29, 0x09,
    159	0x2a, 0x0f,
    160	0x2c, 0x10,
    161	0x2d, 0x19,
    162	0x2e, 0x08,
    163	0x2f, 0x10,
    164	0x30, 0x19,
    165	0x34, 0x20,
    166	0x35, 0x03,
    167	0x45, 0x02,
    168	0x46, 0x45,
    169	0x47, 0xd0,
    170	0x48, 0x00,
    171	0x49, 0x40,
    172	0x4a, 0x03,
    173	0x4c, 0xfd,
    174	0x4f, 0x2e,
    175	0x50, 0x2e,
    176	0x51, 0x10,
    177	0x52, 0x10,
    178	0x56, 0x92,
    179	0x59, 0x00,
    180	0x5a, 0x2d,
    181	0x5b, 0x33,
    182	0x5c, 0x1f,
    183	0x5f, 0x76,
    184	0x62, 0xc0,
    185	0x63, 0xc0,
    186	0x64, 0xf3,
    187	0x65, 0xf3,
    188	0x79, 0x40,
    189	0x6a, 0x40,
    190	0x6b, 0x0a,
    191	0x6c, 0x80,
    192	0x6d, 0x27,
    193	0x71, 0x06,
    194	0x75, 0x60,
    195	0x78, 0x00,
    196	0x79, 0xb5,
    197	0x7c, 0x05,
    198	0x7d, 0x1a,
    199	0x87, 0x55,
    200	0x88, 0x72,
    201	0x8f, 0x08,
    202	0x90, 0xe0,
    203	0x94, 0x40,
    204	0xa0, 0x3f,
    205	0xa1, 0xc0,
    206	0xa4, 0xcc,
    207	0xa5, 0x66,
    208	0xa6, 0x66,
    209	0xa7, 0x7b,
    210	0xa8, 0x7b,
    211	0xa9, 0x7b,
    212	0xaa, 0x9a,
    213	0xed, 0x04,
    214	0xad, 0x00,
    215	0xae, 0x03,
    216	0xcc, 0xab,
    217	0x01, 0x08,
    218	0xff, 0xff
    219};
    220
    221/*	low level read/writes */
    222static int si21_writeregs(struct si21xx_state *state, u8 reg1,
    223							u8 *data, int len)
    224{
    225	int ret;
    226	u8 buf[60];/* = { reg1, data };*/
    227	struct i2c_msg msg = {
    228				.addr = state->config->demod_address,
    229				.flags = 0,
    230				.buf = buf,
    231				.len = len + 1
    232	};
    233
    234	if (len > sizeof(buf) - 1)
    235		return -EINVAL;
    236
    237	msg.buf[0] =  reg1;
    238	memcpy(msg.buf + 1, data, len);
    239
    240	ret = i2c_transfer(state->i2c, &msg, 1);
    241
    242	if (ret != 1)
    243		dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, ret == %i)\n",
    244			__func__, reg1, data[0], ret);
    245
    246	return (ret != 1) ? -EREMOTEIO : 0;
    247}
    248
    249static int si21_writereg(struct si21xx_state *state, u8 reg, u8 data)
    250{
    251	int ret;
    252	u8 buf[] = { reg, data };
    253	struct i2c_msg msg = {
    254				.addr = state->config->demod_address,
    255				.flags = 0,
    256				.buf = buf,
    257				.len = 2
    258	};
    259
    260	ret = i2c_transfer(state->i2c, &msg, 1);
    261
    262	if (ret != 1)
    263		dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, ret == %i)\n",
    264			__func__, reg, data, ret);
    265
    266	return (ret != 1) ? -EREMOTEIO : 0;
    267}
    268
    269static int si21_write(struct dvb_frontend *fe, const u8 buf[], int len)
    270{
    271	struct si21xx_state *state = fe->demodulator_priv;
    272
    273	if (len != 2)
    274		return -EINVAL;
    275
    276	return si21_writereg(state, buf[0], buf[1]);
    277}
    278
    279static u8 si21_readreg(struct si21xx_state *state, u8 reg)
    280{
    281	int ret;
    282	u8 b0[] = { reg };
    283	u8 b1[] = { 0 };
    284	struct i2c_msg msg[] = {
    285		{
    286			.addr = state->config->demod_address,
    287			.flags = 0,
    288			.buf = b0,
    289			.len = 1
    290		}, {
    291			.addr = state->config->demod_address,
    292			.flags = I2C_M_RD,
    293			.buf = b1,
    294			.len = 1
    295		}
    296	};
    297
    298	ret = i2c_transfer(state->i2c, msg, 2);
    299
    300	if (ret != 2)
    301		dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
    302			__func__, reg, ret);
    303
    304	return b1[0];
    305}
    306
    307static int si21_readregs(struct si21xx_state *state, u8 reg1, u8 *b, u8 len)
    308{
    309	int ret;
    310	struct i2c_msg msg[] = {
    311		{
    312			.addr = state->config->demod_address,
    313			.flags = 0,
    314			.buf = &reg1,
    315			.len = 1
    316		}, {
    317			.addr = state->config->demod_address,
    318			.flags = I2C_M_RD,
    319			.buf = b,
    320			.len = len
    321		}
    322	};
    323
    324	ret = i2c_transfer(state->i2c, msg, 2);
    325
    326	if (ret != 2)
    327		dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
    328
    329	return ret == 2 ? 0 : -1;
    330}
    331
    332static int si21xx_wait_diseqc_idle(struct si21xx_state *state, int timeout)
    333{
    334	unsigned long start = jiffies;
    335
    336	dprintk("%s\n", __func__);
    337
    338	while ((si21_readreg(state, LNB_CTRL_REG_1) & 0x8) == 8) {
    339		if (time_is_before_jiffies(start + timeout)) {
    340			dprintk("%s: timeout!!\n", __func__);
    341			return -ETIMEDOUT;
    342		}
    343		msleep(10);
    344	}
    345
    346	return 0;
    347}
    348
    349static int si21xx_set_symbolrate(struct dvb_frontend *fe, u32 srate)
    350{
    351	struct si21xx_state *state = fe->demodulator_priv;
    352	u32 sym_rate, data_rate;
    353	int i;
    354	u8 sym_rate_bytes[3];
    355
    356	dprintk("%s : srate = %i\n", __func__ , srate);
    357
    358	if ((srate < 1000000) || (srate > 45000000))
    359		return -EINVAL;
    360
    361	data_rate = srate;
    362	sym_rate = 0;
    363
    364	for (i = 0; i < 4; ++i) {
    365		sym_rate /= 100;
    366		sym_rate = sym_rate + ((data_rate % 100) * 0x800000) /
    367								state->fs;
    368		data_rate /= 100;
    369	}
    370	for (i = 0; i < 3; ++i)
    371		sym_rate_bytes[i] = (u8)((sym_rate >> (i * 8)) & 0xff);
    372
    373	si21_writeregs(state, SYM_RATE_REG_L, sym_rate_bytes, 0x03);
    374
    375	return 0;
    376}
    377
    378static int si21xx_send_diseqc_msg(struct dvb_frontend *fe,
    379					struct dvb_diseqc_master_cmd *m)
    380{
    381	struct si21xx_state *state = fe->demodulator_priv;
    382	u8 lnb_status;
    383	u8 LNB_CTRL_1;
    384	int status;
    385
    386	dprintk("%s\n", __func__);
    387
    388	status = PASS;
    389	LNB_CTRL_1 = 0;
    390
    391	status |= si21_readregs(state, LNB_CTRL_STATUS_REG, &lnb_status, 0x01);
    392	status |= si21_readregs(state, LNB_CTRL_REG_1, &lnb_status, 0x01);
    393
    394	/*fill the FIFO*/
    395	status |= si21_writeregs(state, LNB_FIFO_REGS_0, m->msg, m->msg_len);
    396
    397	LNB_CTRL_1 = (lnb_status & 0x70);
    398	LNB_CTRL_1 |= m->msg_len;
    399
    400	LNB_CTRL_1 |= 0x80;	/* begin LNB signaling */
    401
    402	status |= si21_writeregs(state, LNB_CTRL_REG_1, &LNB_CTRL_1, 0x01);
    403
    404	return status;
    405}
    406
    407static int si21xx_send_diseqc_burst(struct dvb_frontend *fe,
    408				    enum fe_sec_mini_cmd burst)
    409{
    410	struct si21xx_state *state = fe->demodulator_priv;
    411	u8 val;
    412
    413	dprintk("%s\n", __func__);
    414
    415	if (si21xx_wait_diseqc_idle(state, 100) < 0)
    416		return -ETIMEDOUT;
    417
    418	val = (0x80 | si21_readreg(state, 0xc1));
    419	if (si21_writereg(state, LNB_CTRL_REG_1,
    420			burst == SEC_MINI_A ? (val & ~0x10) : (val | 0x10)))
    421		return -EREMOTEIO;
    422
    423	if (si21xx_wait_diseqc_idle(state, 100) < 0)
    424		return -ETIMEDOUT;
    425
    426	if (si21_writereg(state, LNB_CTRL_REG_1, val))
    427		return -EREMOTEIO;
    428
    429	return 0;
    430}
    431/*	30.06.2008 */
    432static int si21xx_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
    433{
    434	struct si21xx_state *state = fe->demodulator_priv;
    435	u8 val;
    436
    437	dprintk("%s\n", __func__);
    438	val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
    439
    440	switch (tone) {
    441	case SEC_TONE_ON:
    442		return si21_writereg(state, LNB_CTRL_REG_1, val | 0x20);
    443
    444	case SEC_TONE_OFF:
    445		return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x20));
    446
    447	default:
    448		return -EINVAL;
    449	}
    450}
    451
    452static int si21xx_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage volt)
    453{
    454	struct si21xx_state *state = fe->demodulator_priv;
    455
    456	u8 val;
    457	dprintk("%s: %s\n", __func__,
    458		volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
    459		volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
    460
    461
    462	val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
    463
    464	switch (volt) {
    465	case SEC_VOLTAGE_18:
    466		return si21_writereg(state, LNB_CTRL_REG_1, val | 0x40);
    467	case SEC_VOLTAGE_13:
    468		return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x40));
    469	default:
    470		return -EINVAL;
    471	}
    472}
    473
    474static int si21xx_init(struct dvb_frontend *fe)
    475{
    476	struct si21xx_state *state = fe->demodulator_priv;
    477	int i;
    478	int status = 0;
    479	u8 reg1;
    480	u8 val;
    481	u8 reg2[2];
    482
    483	dprintk("%s\n", __func__);
    484
    485	for (i = 0; ; i += 2) {
    486		reg1 = serit_sp1511lhb_inittab[i];
    487		val = serit_sp1511lhb_inittab[i+1];
    488		if (reg1 == 0xff && val == 0xff)
    489			break;
    490		si21_writeregs(state, reg1, &val, 1);
    491	}
    492
    493	/*DVB QPSK SYSTEM MODE REG*/
    494	reg1 = 0x08;
    495	si21_writeregs(state, SYSTEM_MODE_REG, &reg1, 0x01);
    496
    497	/*transport stream config*/
    498	/*
    499	mode = PARALLEL;
    500	sdata_form = LSB_FIRST;
    501	clk_edge = FALLING_EDGE;
    502	clk_mode = CLK_GAPPED_MODE;
    503	strt_len = BYTE_WIDE;
    504	sync_pol = ACTIVE_HIGH;
    505	val_pol = ACTIVE_HIGH;
    506	err_pol = ACTIVE_HIGH;
    507	sclk_rate = 0x00;
    508	parity = 0x00 ;
    509	data_delay = 0x00;
    510	clk_delay = 0x00;
    511	pclk_smooth = 0x00;
    512	*/
    513	reg2[0] =
    514		PARALLEL + (LSB_FIRST << 1)
    515		+ (FALLING_EDGE << 2) + (CLK_GAPPED_MODE << 3)
    516		+ (BYTE_WIDE << 4) + (ACTIVE_HIGH << 5)
    517		+ (ACTIVE_HIGH << 6) + (ACTIVE_HIGH << 7);
    518
    519	reg2[1] = 0;
    520	/*	sclk_rate + (parity << 2)
    521		+ (data_delay << 3) + (clk_delay << 4)
    522		+ (pclk_smooth << 5);
    523	*/
    524	status |= si21_writeregs(state, TS_CTRL_REG_1, reg2, 0x02);
    525	if (status != 0)
    526		dprintk(" %s : TS Set Error\n", __func__);
    527
    528	return 0;
    529
    530}
    531
    532static int si21_read_status(struct dvb_frontend *fe, enum fe_status *status)
    533{
    534	struct si21xx_state *state = fe->demodulator_priv;
    535	u8 regs_read[2];
    536	u8 reg_read;
    537	u8 i;
    538	u8 lock;
    539	u8 signal = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG);
    540
    541	si21_readregs(state, LOCK_STATUS_REG_1, regs_read, 0x02);
    542	reg_read = 0;
    543
    544	for (i = 0; i < 7; ++i)
    545		reg_read |= ((regs_read[0] >> i) & 0x01) << (6 - i);
    546
    547	lock = ((reg_read & 0x7f) | (regs_read[1] & 0x80));
    548
    549	dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, lock);
    550	*status = 0;
    551
    552	if (signal > 10)
    553		*status |= FE_HAS_SIGNAL;
    554
    555	if (lock & 0x2)
    556		*status |= FE_HAS_CARRIER;
    557
    558	if (lock & 0x20)
    559		*status |= FE_HAS_VITERBI;
    560
    561	if (lock & 0x40)
    562		*status |= FE_HAS_SYNC;
    563
    564	if ((lock & 0x7b) == 0x7b)
    565		*status |= FE_HAS_LOCK;
    566
    567	return 0;
    568}
    569
    570static int si21_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
    571{
    572	struct si21xx_state *state = fe->demodulator_priv;
    573
    574	/*status = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG,
    575						(u8*)agclevel, 0x01);*/
    576
    577	u16 signal = (3 * si21_readreg(state, 0x27) *
    578					si21_readreg(state, 0x28));
    579
    580	dprintk("%s : AGCPWR: 0x%02x%02x, signal=0x%04x\n", __func__,
    581		si21_readreg(state, 0x27),
    582		si21_readreg(state, 0x28), (int) signal);
    583
    584	signal  <<= 4;
    585	*strength = signal;
    586
    587	return 0;
    588}
    589
    590static int si21_read_ber(struct dvb_frontend *fe, u32 *ber)
    591{
    592	struct si21xx_state *state = fe->demodulator_priv;
    593
    594	dprintk("%s\n", __func__);
    595
    596	if (state->errmode != STATUS_BER)
    597		return 0;
    598
    599	*ber = (si21_readreg(state, 0x1d) << 8) |
    600				si21_readreg(state, 0x1e);
    601
    602	return 0;
    603}
    604
    605static int si21_read_snr(struct dvb_frontend *fe, u16 *snr)
    606{
    607	struct si21xx_state *state = fe->demodulator_priv;
    608
    609	s32 xsnr = 0xffff - ((si21_readreg(state, 0x24) << 8) |
    610					si21_readreg(state, 0x25));
    611	xsnr = 3 * (xsnr - 0xa100);
    612	*snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
    613
    614	dprintk("%s\n", __func__);
    615
    616	return 0;
    617}
    618
    619static int si21_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
    620{
    621	struct si21xx_state *state = fe->demodulator_priv;
    622
    623	dprintk("%s\n", __func__);
    624
    625	if (state->errmode != STATUS_UCBLOCKS)
    626		*ucblocks = 0;
    627	else
    628		*ucblocks = (si21_readreg(state, 0x1d) << 8) |
    629					si21_readreg(state, 0x1e);
    630
    631	return 0;
    632}
    633
    634/*	initiates a channel acquisition sequence
    635	using the specified symbol rate and code rate */
    636static int si21xx_setacquire(struct dvb_frontend *fe, int symbrate,
    637			     enum fe_code_rate crate)
    638{
    639
    640	struct si21xx_state *state = fe->demodulator_priv;
    641	u8 coderates[] = {
    642				0x0, 0x01, 0x02, 0x04, 0x00,
    643				0x8, 0x10, 0x20, 0x00, 0x3f
    644	};
    645
    646	u8 coderate_ptr;
    647	int status;
    648	u8 start_acq = 0x80;
    649	u8 reg, regs[3];
    650
    651	dprintk("%s\n", __func__);
    652
    653	status = PASS;
    654	coderate_ptr = coderates[crate];
    655
    656	si21xx_set_symbolrate(fe, symbrate);
    657
    658	/* write code rates to use in the Viterbi search */
    659	status |= si21_writeregs(state,
    660				VIT_SRCH_CTRL_REG_1,
    661				&coderate_ptr, 0x01);
    662
    663	/* clear acq_start bit */
    664	status |= si21_readregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
    665	reg &= ~start_acq;
    666	status |= si21_writeregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
    667
    668	/* use new Carrier Frequency Offset Estimator (QuickLock) */
    669	regs[0] = 0xCB;
    670	regs[1] = 0x40;
    671	regs[2] = 0xCB;
    672
    673	status |= si21_writeregs(state,
    674				TWO_DB_BNDWDTH_THRSHLD_REG,
    675				&regs[0], 0x03);
    676	reg = 0x56;
    677	status |= si21_writeregs(state,
    678				LSA_CTRL_REG_1, &reg, 1);
    679	reg = 0x05;
    680	status |= si21_writeregs(state,
    681				BLIND_SCAN_CTRL_REG, &reg, 1);
    682	/* start automatic acq */
    683	status |= si21_writeregs(state,
    684				ACQ_CTRL_REG_2, &start_acq, 0x01);
    685
    686	return status;
    687}
    688
    689static int si21xx_set_frontend(struct dvb_frontend *fe)
    690{
    691	struct si21xx_state *state = fe->demodulator_priv;
    692	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
    693
    694	/* freq		Channel carrier frequency in KHz (i.e. 1550000 KHz)
    695	 datarate	Channel symbol rate in Sps (i.e. 22500000 Sps)*/
    696
    697	/* in MHz */
    698	unsigned char coarse_tune_freq;
    699	int fine_tune_freq;
    700	unsigned char sample_rate = 0;
    701	/* boolean */
    702	bool inband_interferer_ind;
    703
    704	/* INTERMEDIATE VALUES */
    705	int icoarse_tune_freq; /* MHz */
    706	int ifine_tune_freq; /* MHz */
    707	unsigned int band_high;
    708	unsigned int band_low;
    709	unsigned int x1;
    710	unsigned int x2;
    711	int i;
    712	bool inband_interferer_div2[ALLOWABLE_FS_COUNT];
    713	bool inband_interferer_div4[ALLOWABLE_FS_COUNT];
    714	int status = 0;
    715
    716	/* allowable sample rates for ADC in MHz */
    717	int afs[ALLOWABLE_FS_COUNT] = { 200, 192, 193, 194, 195,
    718					196, 204, 205, 206, 207
    719	};
    720	/* in MHz */
    721	int if_limit_high;
    722	int if_limit_low;
    723	int lnb_lo;
    724	int lnb_uncertanity;
    725
    726	int rf_freq;
    727	int data_rate;
    728	unsigned char regs[4];
    729
    730	dprintk("%s : FE_SET_FRONTEND\n", __func__);
    731
    732	if (c->delivery_system != SYS_DVBS) {
    733			dprintk("%s: unsupported delivery system selected (%d)\n",
    734				__func__, c->delivery_system);
    735			return -EOPNOTSUPP;
    736	}
    737
    738	for (i = 0; i < ALLOWABLE_FS_COUNT; ++i)
    739		inband_interferer_div2[i] = inband_interferer_div4[i] = false;
    740
    741	if_limit_high = -700000;
    742	if_limit_low = -100000;
    743	/* in MHz */
    744	lnb_lo = 0;
    745	lnb_uncertanity = 0;
    746
    747	rf_freq = 10 * c->frequency ;
    748	data_rate = c->symbol_rate / 100;
    749
    750	band_low = (rf_freq - lnb_lo) - ((lnb_uncertanity * 200)
    751					+ (data_rate * 135)) / 200;
    752
    753	band_high = (rf_freq - lnb_lo) + ((lnb_uncertanity * 200)
    754					+ (data_rate * 135)) / 200;
    755
    756
    757	icoarse_tune_freq = 100000 *
    758				(((rf_freq - lnb_lo) -
    759					(if_limit_low + if_limit_high) / 2)
    760								/ 100000);
    761
    762	ifine_tune_freq = (rf_freq - lnb_lo) - icoarse_tune_freq ;
    763
    764	for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
    765		x1 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
    766					(afs[i] * 2500) + afs[i] * 2500;
    767
    768		x2 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
    769							(afs[i] * 2500);
    770
    771		if (((band_low < x1) && (x1 < band_high)) ||
    772					((band_low < x2) && (x2 < band_high)))
    773					inband_interferer_div4[i] = true;
    774
    775	}
    776
    777	for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
    778		x1 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
    779					(afs[i] * 5000) + afs[i] * 5000;
    780
    781		x2 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
    782					(afs[i] * 5000);
    783
    784		if (((band_low < x1) && (x1 < band_high)) ||
    785					((band_low < x2) && (x2 < band_high)))
    786					inband_interferer_div2[i] = true;
    787	}
    788
    789	inband_interferer_ind = true;
    790	for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
    791		if (inband_interferer_div2[i] || inband_interferer_div4[i]) {
    792			inband_interferer_ind = false;
    793			break;
    794		}
    795	}
    796
    797	if (inband_interferer_ind) {
    798		for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
    799			if (!inband_interferer_div2[i]) {
    800				sample_rate = (u8) afs[i];
    801				break;
    802			}
    803		}
    804	} else {
    805		for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
    806			if ((inband_interferer_div2[i] ||
    807			     !inband_interferer_div4[i])) {
    808				sample_rate = (u8) afs[i];
    809				break;
    810			}
    811		}
    812
    813	}
    814
    815	if (sample_rate > 207 || sample_rate < 192)
    816		sample_rate = 200;
    817
    818	fine_tune_freq = ((0x4000 * (ifine_tune_freq / 10)) /
    819					((sample_rate) * 1000));
    820
    821	coarse_tune_freq = (u8)(icoarse_tune_freq / 100000);
    822
    823	regs[0] = sample_rate;
    824	regs[1] = coarse_tune_freq;
    825	regs[2] = fine_tune_freq & 0xFF;
    826	regs[3] = fine_tune_freq >> 8 & 0xFF;
    827
    828	status |= si21_writeregs(state, PLL_DIVISOR_REG, &regs[0], 0x04);
    829
    830	state->fs = sample_rate;/*ADC MHz*/
    831	si21xx_setacquire(fe, c->symbol_rate, c->fec_inner);
    832
    833	if (status)
    834		return -EREMOTEIO;
    835
    836	return 0;
    837}
    838
    839static int si21xx_sleep(struct dvb_frontend *fe)
    840{
    841	struct si21xx_state *state = fe->demodulator_priv;
    842	u8 regdata;
    843
    844	dprintk("%s\n", __func__);
    845
    846	si21_readregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
    847	regdata |= 1 << 6;
    848	si21_writeregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
    849	state->initialised = 0;
    850
    851	return 0;
    852}
    853
    854static void si21xx_release(struct dvb_frontend *fe)
    855{
    856	struct si21xx_state *state = fe->demodulator_priv;
    857
    858	dprintk("%s\n", __func__);
    859
    860	kfree(state);
    861}
    862
    863static const struct dvb_frontend_ops si21xx_ops = {
    864	.delsys = { SYS_DVBS },
    865	.info = {
    866		.name			= "SL SI21XX DVB-S",
    867		.frequency_min_hz	=  950 * MHz,
    868		.frequency_max_hz	= 2150 * MHz,
    869		.frequency_stepsize_hz	=  125 * kHz,
    870		.symbol_rate_min	= 1000000,
    871		.symbol_rate_max	= 45000000,
    872		.symbol_rate_tolerance	= 500,	/* ppm */
    873		.caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
    874		FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
    875		FE_CAN_QPSK |
    876		FE_CAN_FEC_AUTO
    877	},
    878
    879	.release = si21xx_release,
    880	.init = si21xx_init,
    881	.sleep = si21xx_sleep,
    882	.write = si21_write,
    883	.read_status = si21_read_status,
    884	.read_ber = si21_read_ber,
    885	.read_signal_strength = si21_read_signal_strength,
    886	.read_snr = si21_read_snr,
    887	.read_ucblocks = si21_read_ucblocks,
    888	.diseqc_send_master_cmd = si21xx_send_diseqc_msg,
    889	.diseqc_send_burst = si21xx_send_diseqc_burst,
    890	.set_tone = si21xx_set_tone,
    891	.set_voltage = si21xx_set_voltage,
    892
    893	.set_frontend = si21xx_set_frontend,
    894};
    895
    896struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
    897						struct i2c_adapter *i2c)
    898{
    899	struct si21xx_state *state = NULL;
    900	int id;
    901
    902	dprintk("%s\n", __func__);
    903
    904	/* allocate memory for the internal state */
    905	state = kzalloc(sizeof(struct si21xx_state), GFP_KERNEL);
    906	if (state == NULL)
    907		goto error;
    908
    909	/* setup the state */
    910	state->config = config;
    911	state->i2c = i2c;
    912	state->initialised = 0;
    913	state->errmode = STATUS_BER;
    914
    915	/* check if the demod is there */
    916	id = si21_readreg(state, SYSTEM_MODE_REG);
    917	si21_writereg(state, SYSTEM_MODE_REG, id | 0x40); /* standby off */
    918	msleep(200);
    919	id = si21_readreg(state, 0x00);
    920
    921	/* register 0x00 contains:
    922		0x34 for SI2107
    923		0x24 for SI2108
    924		0x14 for SI2109
    925		0x04 for SI2110
    926	*/
    927	if (id != 0x04 && id != 0x14)
    928		goto error;
    929
    930	/* create dvb_frontend */
    931	memcpy(&state->frontend.ops, &si21xx_ops,
    932					sizeof(struct dvb_frontend_ops));
    933	state->frontend.demodulator_priv = state;
    934	return &state->frontend;
    935
    936error:
    937	kfree(state);
    938	return NULL;
    939}
    940EXPORT_SYMBOL(si21xx_attach);
    941
    942module_param(debug, int, 0644);
    943MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
    944
    945MODULE_DESCRIPTION("SL SI21XX DVB Demodulator driver");
    946MODULE_AUTHOR("Igor M. Liplianin");
    947MODULE_LICENSE("GPL");