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

m88rs2000.c (18421B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3	Driver for M88RS2000 demodulator and tuner
      4
      5	Copyright (C) 2012 Malcolm Priestley (tvboxspy@gmail.com)
      6	Beta Driver
      7
      8	Include various calculation code from DS3000 driver.
      9	Copyright (C) 2009 Konstantin Dimitrov.
     10
     11
     12*/
     13#include <linux/init.h>
     14#include <linux/module.h>
     15#include <linux/device.h>
     16#include <linux/jiffies.h>
     17#include <linux/string.h>
     18#include <linux/slab.h>
     19#include <linux/types.h>
     20
     21
     22#include <media/dvb_frontend.h>
     23#include "m88rs2000.h"
     24
     25struct m88rs2000_state {
     26	struct i2c_adapter *i2c;
     27	const struct m88rs2000_config *config;
     28	struct dvb_frontend frontend;
     29	u8 no_lock_count;
     30	u32 tuner_frequency;
     31	u32 symbol_rate;
     32	enum fe_code_rate fec_inner;
     33	u8 tuner_level;
     34	int errmode;
     35};
     36
     37static int m88rs2000_debug;
     38
     39module_param_named(debug, m88rs2000_debug, int, 0644);
     40MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
     41
     42#define dprintk(level, args...) do { \
     43	if (level & m88rs2000_debug) \
     44		printk(KERN_DEBUG "m88rs2000-fe: " args); \
     45} while (0)
     46
     47#define deb_info(args...)  dprintk(0x01, args)
     48#define info(format, arg...) \
     49	printk(KERN_INFO "m88rs2000-fe: " format "\n" , ## arg)
     50
     51static int m88rs2000_writereg(struct m88rs2000_state *state,
     52	u8 reg, u8 data)
     53{
     54	int ret;
     55	u8 buf[] = { reg, data };
     56	struct i2c_msg msg = {
     57		.addr = state->config->demod_addr,
     58		.flags = 0,
     59		.buf = buf,
     60		.len = 2
     61	};
     62
     63	ret = i2c_transfer(state->i2c, &msg, 1);
     64
     65	if (ret != 1)
     66		deb_info("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
     67			 __func__, reg, data, ret);
     68
     69	return (ret != 1) ? -EREMOTEIO : 0;
     70}
     71
     72static u8 m88rs2000_readreg(struct m88rs2000_state *state, u8 reg)
     73{
     74	int ret;
     75	u8 b0[] = { reg };
     76	u8 b1[] = { 0 };
     77
     78	struct i2c_msg msg[] = {
     79		{
     80			.addr = state->config->demod_addr,
     81			.flags = 0,
     82			.buf = b0,
     83			.len = 1
     84		}, {
     85			.addr = state->config->demod_addr,
     86			.flags = I2C_M_RD,
     87			.buf = b1,
     88			.len = 1
     89		}
     90	};
     91
     92	ret = i2c_transfer(state->i2c, msg, 2);
     93
     94	if (ret != 2)
     95		deb_info("%s: readreg error (reg == 0x%02x, ret == %i)\n",
     96				__func__, reg, ret);
     97
     98	return b1[0];
     99}
    100
    101static u32 m88rs2000_get_mclk(struct dvb_frontend *fe)
    102{
    103	struct m88rs2000_state *state = fe->demodulator_priv;
    104	u32 mclk;
    105	u8 reg;
    106	/* Must not be 0x00 or 0xff */
    107	reg = m88rs2000_readreg(state, 0x86);
    108	if (!reg || reg == 0xff)
    109		return 0;
    110
    111	reg /= 2;
    112	reg += 1;
    113
    114	mclk = (u32)(reg * RS2000_FE_CRYSTAL_KHZ + 28 / 2) / 28;
    115
    116	return mclk;
    117}
    118
    119static int m88rs2000_set_carrieroffset(struct dvb_frontend *fe, s16 offset)
    120{
    121	struct m88rs2000_state *state = fe->demodulator_priv;
    122	u32 mclk;
    123	s32 tmp;
    124	u8 reg;
    125	int ret;
    126
    127	mclk = m88rs2000_get_mclk(fe);
    128	if (!mclk)
    129		return -EINVAL;
    130
    131	tmp = (offset * 4096 + (s32)mclk / 2) / (s32)mclk;
    132	if (tmp < 0)
    133		tmp += 4096;
    134
    135	/* Carrier Offset */
    136	ret = m88rs2000_writereg(state, 0x9c, (u8)(tmp >> 4));
    137
    138	reg = m88rs2000_readreg(state, 0x9d);
    139	reg &= 0xf;
    140	reg |= (u8)(tmp & 0xf) << 4;
    141
    142	ret |= m88rs2000_writereg(state, 0x9d, reg);
    143
    144	return ret;
    145}
    146
    147static int m88rs2000_set_symbolrate(struct dvb_frontend *fe, u32 srate)
    148{
    149	struct m88rs2000_state *state = fe->demodulator_priv;
    150	int ret;
    151	u64 temp;
    152	u32 mclk;
    153	u8 b[3];
    154
    155	if ((srate < 1000000) || (srate > 45000000))
    156		return -EINVAL;
    157
    158	mclk = m88rs2000_get_mclk(fe);
    159	if (!mclk)
    160		return -EINVAL;
    161
    162	temp = srate / 1000;
    163	temp *= 1 << 24;
    164
    165	do_div(temp, mclk);
    166
    167	b[0] = (u8) (temp >> 16) & 0xff;
    168	b[1] = (u8) (temp >> 8) & 0xff;
    169	b[2] = (u8) temp & 0xff;
    170
    171	ret = m88rs2000_writereg(state, 0x93, b[2]);
    172	ret |= m88rs2000_writereg(state, 0x94, b[1]);
    173	ret |= m88rs2000_writereg(state, 0x95, b[0]);
    174
    175	if (srate > 10000000)
    176		ret |= m88rs2000_writereg(state, 0xa0, 0x20);
    177	else
    178		ret |= m88rs2000_writereg(state, 0xa0, 0x60);
    179
    180	ret |= m88rs2000_writereg(state, 0xa1, 0xe0);
    181
    182	if (srate > 12000000)
    183		ret |= m88rs2000_writereg(state, 0xa3, 0x20);
    184	else if (srate > 2800000)
    185		ret |= m88rs2000_writereg(state, 0xa3, 0x98);
    186	else
    187		ret |= m88rs2000_writereg(state, 0xa3, 0x90);
    188
    189	deb_info("m88rs2000: m88rs2000_set_symbolrate\n");
    190	return ret;
    191}
    192
    193static int m88rs2000_send_diseqc_msg(struct dvb_frontend *fe,
    194				    struct dvb_diseqc_master_cmd *m)
    195{
    196	struct m88rs2000_state *state = fe->demodulator_priv;
    197
    198	int i;
    199	u8 reg;
    200	deb_info("%s\n", __func__);
    201	m88rs2000_writereg(state, 0x9a, 0x30);
    202	reg = m88rs2000_readreg(state, 0xb2);
    203	reg &= 0x3f;
    204	m88rs2000_writereg(state, 0xb2, reg);
    205	for (i = 0; i <  m->msg_len; i++)
    206		m88rs2000_writereg(state, 0xb3 + i, m->msg[i]);
    207
    208	reg = m88rs2000_readreg(state, 0xb1);
    209	reg &= 0x87;
    210	reg |= ((m->msg_len - 1) << 3) | 0x07;
    211	reg &= 0x7f;
    212	m88rs2000_writereg(state, 0xb1, reg);
    213
    214	for (i = 0; i < 15; i++) {
    215		if ((m88rs2000_readreg(state, 0xb1) & 0x40) == 0x0)
    216			break;
    217		msleep(20);
    218	}
    219
    220	reg = m88rs2000_readreg(state, 0xb1);
    221	if ((reg & 0x40) > 0x0) {
    222		reg &= 0x7f;
    223		reg |= 0x40;
    224		m88rs2000_writereg(state, 0xb1, reg);
    225	}
    226
    227	reg = m88rs2000_readreg(state, 0xb2);
    228	reg &= 0x3f;
    229	reg |= 0x80;
    230	m88rs2000_writereg(state, 0xb2, reg);
    231	m88rs2000_writereg(state, 0x9a, 0xb0);
    232
    233
    234	return 0;
    235}
    236
    237static int m88rs2000_send_diseqc_burst(struct dvb_frontend *fe,
    238				       enum fe_sec_mini_cmd burst)
    239{
    240	struct m88rs2000_state *state = fe->demodulator_priv;
    241	u8 reg0, reg1;
    242	deb_info("%s\n", __func__);
    243	m88rs2000_writereg(state, 0x9a, 0x30);
    244	msleep(50);
    245	reg0 = m88rs2000_readreg(state, 0xb1);
    246	reg1 = m88rs2000_readreg(state, 0xb2);
    247	/* TODO complete this section */
    248	m88rs2000_writereg(state, 0xb2, reg1);
    249	m88rs2000_writereg(state, 0xb1, reg0);
    250	m88rs2000_writereg(state, 0x9a, 0xb0);
    251
    252	return 0;
    253}
    254
    255static int m88rs2000_set_tone(struct dvb_frontend *fe,
    256			      enum fe_sec_tone_mode tone)
    257{
    258	struct m88rs2000_state *state = fe->demodulator_priv;
    259	u8 reg0, reg1;
    260	m88rs2000_writereg(state, 0x9a, 0x30);
    261	reg0 = m88rs2000_readreg(state, 0xb1);
    262	reg1 = m88rs2000_readreg(state, 0xb2);
    263
    264	reg1 &= 0x3f;
    265
    266	switch (tone) {
    267	case SEC_TONE_ON:
    268		reg0 |= 0x4;
    269		reg0 &= 0xbc;
    270		break;
    271	case SEC_TONE_OFF:
    272		reg1 |= 0x80;
    273		break;
    274	default:
    275		break;
    276	}
    277	m88rs2000_writereg(state, 0xb2, reg1);
    278	m88rs2000_writereg(state, 0xb1, reg0);
    279	m88rs2000_writereg(state, 0x9a, 0xb0);
    280	return 0;
    281}
    282
    283struct inittab {
    284	u8 cmd;
    285	u8 reg;
    286	u8 val;
    287};
    288
    289static struct inittab m88rs2000_setup[] = {
    290	{DEMOD_WRITE, 0x9a, 0x30},
    291	{DEMOD_WRITE, 0x00, 0x01},
    292	{WRITE_DELAY, 0x19, 0x00},
    293	{DEMOD_WRITE, 0x00, 0x00},
    294	{DEMOD_WRITE, 0x9a, 0xb0},
    295	{DEMOD_WRITE, 0x81, 0xc1},
    296	{DEMOD_WRITE, 0x81, 0x81},
    297	{DEMOD_WRITE, 0x86, 0xc6},
    298	{DEMOD_WRITE, 0x9a, 0x30},
    299	{DEMOD_WRITE, 0xf0, 0x22},
    300	{DEMOD_WRITE, 0xf1, 0xbf},
    301	{DEMOD_WRITE, 0xb0, 0x45},
    302	{DEMOD_WRITE, 0xb2, 0x01}, /* set voltage pin always set 1*/
    303	{DEMOD_WRITE, 0x9a, 0xb0},
    304	{0xff, 0xaa, 0xff}
    305};
    306
    307static struct inittab m88rs2000_shutdown[] = {
    308	{DEMOD_WRITE, 0x9a, 0x30},
    309	{DEMOD_WRITE, 0xb0, 0x00},
    310	{DEMOD_WRITE, 0xf1, 0x89},
    311	{DEMOD_WRITE, 0x00, 0x01},
    312	{DEMOD_WRITE, 0x9a, 0xb0},
    313	{DEMOD_WRITE, 0x81, 0x81},
    314	{0xff, 0xaa, 0xff}
    315};
    316
    317static struct inittab fe_reset[] = {
    318	{DEMOD_WRITE, 0x00, 0x01},
    319	{DEMOD_WRITE, 0x20, 0x81},
    320	{DEMOD_WRITE, 0x21, 0x80},
    321	{DEMOD_WRITE, 0x10, 0x33},
    322	{DEMOD_WRITE, 0x11, 0x44},
    323	{DEMOD_WRITE, 0x12, 0x07},
    324	{DEMOD_WRITE, 0x18, 0x20},
    325	{DEMOD_WRITE, 0x28, 0x04},
    326	{DEMOD_WRITE, 0x29, 0x8e},
    327	{DEMOD_WRITE, 0x3b, 0xff},
    328	{DEMOD_WRITE, 0x32, 0x10},
    329	{DEMOD_WRITE, 0x33, 0x02},
    330	{DEMOD_WRITE, 0x34, 0x30},
    331	{DEMOD_WRITE, 0x35, 0xff},
    332	{DEMOD_WRITE, 0x38, 0x50},
    333	{DEMOD_WRITE, 0x39, 0x68},
    334	{DEMOD_WRITE, 0x3c, 0x7f},
    335	{DEMOD_WRITE, 0x3d, 0x0f},
    336	{DEMOD_WRITE, 0x45, 0x20},
    337	{DEMOD_WRITE, 0x46, 0x24},
    338	{DEMOD_WRITE, 0x47, 0x7c},
    339	{DEMOD_WRITE, 0x48, 0x16},
    340	{DEMOD_WRITE, 0x49, 0x04},
    341	{DEMOD_WRITE, 0x4a, 0x01},
    342	{DEMOD_WRITE, 0x4b, 0x78},
    343	{DEMOD_WRITE, 0X4d, 0xd2},
    344	{DEMOD_WRITE, 0x4e, 0x6d},
    345	{DEMOD_WRITE, 0x50, 0x30},
    346	{DEMOD_WRITE, 0x51, 0x30},
    347	{DEMOD_WRITE, 0x54, 0x7b},
    348	{DEMOD_WRITE, 0x56, 0x09},
    349	{DEMOD_WRITE, 0x58, 0x59},
    350	{DEMOD_WRITE, 0x59, 0x37},
    351	{DEMOD_WRITE, 0x63, 0xfa},
    352	{0xff, 0xaa, 0xff}
    353};
    354
    355static struct inittab fe_trigger[] = {
    356	{DEMOD_WRITE, 0x97, 0x04},
    357	{DEMOD_WRITE, 0x99, 0x77},
    358	{DEMOD_WRITE, 0x9b, 0x64},
    359	{DEMOD_WRITE, 0x9e, 0x00},
    360	{DEMOD_WRITE, 0x9f, 0xf8},
    361	{DEMOD_WRITE, 0x98, 0xff},
    362	{DEMOD_WRITE, 0xc0, 0x0f},
    363	{DEMOD_WRITE, 0x89, 0x01},
    364	{DEMOD_WRITE, 0x00, 0x00},
    365	{WRITE_DELAY, 0x0a, 0x00},
    366	{DEMOD_WRITE, 0x00, 0x01},
    367	{DEMOD_WRITE, 0x00, 0x00},
    368	{DEMOD_WRITE, 0x9a, 0xb0},
    369	{0xff, 0xaa, 0xff}
    370};
    371
    372static int m88rs2000_tab_set(struct m88rs2000_state *state,
    373		struct inittab *tab)
    374{
    375	int ret = 0;
    376	u8 i;
    377	if (tab == NULL)
    378		return -EINVAL;
    379
    380	for (i = 0; i < 255; i++) {
    381		switch (tab[i].cmd) {
    382		case 0x01:
    383			ret = m88rs2000_writereg(state, tab[i].reg,
    384				tab[i].val);
    385			break;
    386		case 0x10:
    387			if (tab[i].reg > 0)
    388				mdelay(tab[i].reg);
    389			break;
    390		case 0xff:
    391			if (tab[i].reg == 0xaa && tab[i].val == 0xff)
    392				return 0;
    393			break;
    394		case 0x00:
    395			break;
    396		default:
    397			return -EINVAL;
    398		}
    399		if (ret < 0)
    400			return -ENODEV;
    401	}
    402	return 0;
    403}
    404
    405static int m88rs2000_set_voltage(struct dvb_frontend *fe,
    406				 enum fe_sec_voltage volt)
    407{
    408	struct m88rs2000_state *state = fe->demodulator_priv;
    409	u8 data;
    410
    411	data = m88rs2000_readreg(state, 0xb2);
    412	data |= 0x03; /* bit0 V/H, bit1 off/on */
    413
    414	switch (volt) {
    415	case SEC_VOLTAGE_18:
    416		data &= ~0x03;
    417		break;
    418	case SEC_VOLTAGE_13:
    419		data &= ~0x03;
    420		data |= 0x01;
    421		break;
    422	case SEC_VOLTAGE_OFF:
    423		break;
    424	}
    425
    426	m88rs2000_writereg(state, 0xb2, data);
    427
    428	return 0;
    429}
    430
    431static int m88rs2000_init(struct dvb_frontend *fe)
    432{
    433	struct m88rs2000_state *state = fe->demodulator_priv;
    434	int ret;
    435
    436	deb_info("m88rs2000: init chip\n");
    437	/* Setup frontend from shutdown/cold */
    438	if (state->config->inittab)
    439		ret = m88rs2000_tab_set(state,
    440				(struct inittab *)state->config->inittab);
    441	else
    442		ret = m88rs2000_tab_set(state, m88rs2000_setup);
    443
    444	return ret;
    445}
    446
    447static int m88rs2000_sleep(struct dvb_frontend *fe)
    448{
    449	struct m88rs2000_state *state = fe->demodulator_priv;
    450	int ret;
    451	/* Shutdown the frondend */
    452	ret = m88rs2000_tab_set(state, m88rs2000_shutdown);
    453	return ret;
    454}
    455
    456static int m88rs2000_read_status(struct dvb_frontend *fe,
    457				 enum fe_status *status)
    458{
    459	struct m88rs2000_state *state = fe->demodulator_priv;
    460	u8 reg = m88rs2000_readreg(state, 0x8c);
    461
    462	*status = 0;
    463
    464	if ((reg & 0xee) == 0xee) {
    465		*status = FE_HAS_CARRIER | FE_HAS_SIGNAL | FE_HAS_VITERBI
    466			| FE_HAS_SYNC | FE_HAS_LOCK;
    467		if (state->config->set_ts_params)
    468			state->config->set_ts_params(fe, CALL_IS_READ);
    469	}
    470	return 0;
    471}
    472
    473static int m88rs2000_read_ber(struct dvb_frontend *fe, u32 *ber)
    474{
    475	struct m88rs2000_state *state = fe->demodulator_priv;
    476	u8 tmp0, tmp1;
    477
    478	m88rs2000_writereg(state, 0x9a, 0x30);
    479	tmp0 = m88rs2000_readreg(state, 0xd8);
    480	if ((tmp0 & 0x10) != 0) {
    481		m88rs2000_writereg(state, 0x9a, 0xb0);
    482		*ber = 0xffffffff;
    483		return 0;
    484	}
    485
    486	*ber = (m88rs2000_readreg(state, 0xd7) << 8) |
    487		m88rs2000_readreg(state, 0xd6);
    488
    489	tmp1 = m88rs2000_readreg(state, 0xd9);
    490	m88rs2000_writereg(state, 0xd9, (tmp1 & ~7) | 4);
    491	/* needs twice */
    492	m88rs2000_writereg(state, 0xd8, (tmp0 & ~8) | 0x30);
    493	m88rs2000_writereg(state, 0xd8, (tmp0 & ~8) | 0x30);
    494	m88rs2000_writereg(state, 0x9a, 0xb0);
    495
    496	return 0;
    497}
    498
    499static int m88rs2000_read_signal_strength(struct dvb_frontend *fe,
    500	u16 *strength)
    501{
    502	if (fe->ops.tuner_ops.get_rf_strength)
    503		fe->ops.tuner_ops.get_rf_strength(fe, strength);
    504
    505	return 0;
    506}
    507
    508static int m88rs2000_read_snr(struct dvb_frontend *fe, u16 *snr)
    509{
    510	struct m88rs2000_state *state = fe->demodulator_priv;
    511
    512	*snr = 512 * m88rs2000_readreg(state, 0x65);
    513
    514	return 0;
    515}
    516
    517static int m88rs2000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
    518{
    519	struct m88rs2000_state *state = fe->demodulator_priv;
    520	u8 tmp;
    521
    522	*ucblocks = (m88rs2000_readreg(state, 0xd5) << 8) |
    523			m88rs2000_readreg(state, 0xd4);
    524	tmp = m88rs2000_readreg(state, 0xd8);
    525	m88rs2000_writereg(state, 0xd8, tmp & ~0x20);
    526	/* needs two times */
    527	m88rs2000_writereg(state, 0xd8, tmp | 0x20);
    528	m88rs2000_writereg(state, 0xd8, tmp | 0x20);
    529
    530	return 0;
    531}
    532
    533static int m88rs2000_set_fec(struct m88rs2000_state *state,
    534			     enum fe_code_rate fec)
    535{
    536	u8 fec_set, reg;
    537	int ret;
    538
    539	switch (fec) {
    540	case FEC_1_2:
    541		fec_set = 0x8;
    542		break;
    543	case FEC_2_3:
    544		fec_set = 0x10;
    545		break;
    546	case FEC_3_4:
    547		fec_set = 0x20;
    548		break;
    549	case FEC_5_6:
    550		fec_set = 0x40;
    551		break;
    552	case FEC_7_8:
    553		fec_set = 0x80;
    554		break;
    555	case FEC_AUTO:
    556	default:
    557		fec_set = 0x0;
    558	}
    559
    560	reg = m88rs2000_readreg(state, 0x70);
    561	reg &= 0x7;
    562	ret = m88rs2000_writereg(state, 0x70, reg | fec_set);
    563
    564	ret |= m88rs2000_writereg(state, 0x76, 0x8);
    565
    566	return ret;
    567}
    568
    569static enum fe_code_rate m88rs2000_get_fec(struct m88rs2000_state *state)
    570{
    571	u8 reg;
    572	m88rs2000_writereg(state, 0x9a, 0x30);
    573	reg = m88rs2000_readreg(state, 0x76);
    574	m88rs2000_writereg(state, 0x9a, 0xb0);
    575
    576	reg &= 0xf0;
    577	reg >>= 5;
    578
    579	switch (reg) {
    580	case 0x4:
    581		return FEC_1_2;
    582	case 0x3:
    583		return FEC_2_3;
    584	case 0x2:
    585		return FEC_3_4;
    586	case 0x1:
    587		return FEC_5_6;
    588	case 0x0:
    589		return FEC_7_8;
    590	default:
    591		break;
    592	}
    593
    594	return FEC_AUTO;
    595}
    596
    597static int m88rs2000_set_frontend(struct dvb_frontend *fe)
    598{
    599	struct m88rs2000_state *state = fe->demodulator_priv;
    600	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
    601	enum fe_status status = 0;
    602	int i, ret = 0;
    603	u32 tuner_freq;
    604	s16 offset = 0;
    605	u8 reg;
    606
    607	state->no_lock_count = 0;
    608
    609	if (c->delivery_system != SYS_DVBS) {
    610		deb_info("%s: unsupported delivery system selected (%d)\n",
    611			 __func__, c->delivery_system);
    612		return -EOPNOTSUPP;
    613	}
    614
    615	/* Set Tuner */
    616	if (fe->ops.tuner_ops.set_params)
    617		ret = fe->ops.tuner_ops.set_params(fe);
    618
    619	if (ret < 0)
    620		return -ENODEV;
    621
    622	if (fe->ops.tuner_ops.get_frequency) {
    623		ret = fe->ops.tuner_ops.get_frequency(fe, &tuner_freq);
    624
    625		if (ret < 0)
    626			return -ENODEV;
    627
    628		offset = (s16)((s32)tuner_freq - c->frequency);
    629	} else {
    630		offset = 0;
    631	}
    632
    633	/* default mclk value 96.4285 * 2 * 1000 = 192857 */
    634	if (((c->frequency % 192857) >= (192857 - 3000)) ||
    635				(c->frequency % 192857) <= 3000)
    636		ret = m88rs2000_writereg(state, 0x86, 0xc2);
    637	else
    638		ret = m88rs2000_writereg(state, 0x86, 0xc6);
    639
    640	ret |= m88rs2000_set_carrieroffset(fe, offset);
    641	if (ret < 0)
    642		return -ENODEV;
    643
    644	/* Reset demod by symbol rate */
    645	if (c->symbol_rate > 27500000)
    646		ret = m88rs2000_writereg(state, 0xf1, 0xa4);
    647	else
    648		ret = m88rs2000_writereg(state, 0xf1, 0xbf);
    649
    650	ret |= m88rs2000_tab_set(state, fe_reset);
    651	if (ret < 0)
    652		return -ENODEV;
    653
    654	/* Set FEC */
    655	ret = m88rs2000_set_fec(state, c->fec_inner);
    656	ret |= m88rs2000_writereg(state, 0x85, 0x1);
    657	ret |= m88rs2000_writereg(state, 0x8a, 0xbf);
    658	ret |= m88rs2000_writereg(state, 0x8d, 0x1e);
    659	ret |= m88rs2000_writereg(state, 0x90, 0xf1);
    660	ret |= m88rs2000_writereg(state, 0x91, 0x08);
    661
    662	if (ret < 0)
    663		return -ENODEV;
    664
    665	/* Set Symbol Rate */
    666	ret = m88rs2000_set_symbolrate(fe, c->symbol_rate);
    667	if (ret < 0)
    668		return -ENODEV;
    669
    670	/* Set up Demod */
    671	ret = m88rs2000_tab_set(state, fe_trigger);
    672	if (ret < 0)
    673		return -ENODEV;
    674
    675	for (i = 0; i < 25; i++) {
    676		reg = m88rs2000_readreg(state, 0x8c);
    677		if ((reg & 0xee) == 0xee) {
    678			status = FE_HAS_LOCK;
    679			break;
    680		}
    681		state->no_lock_count++;
    682		if (state->no_lock_count == 15) {
    683			reg = m88rs2000_readreg(state, 0x70);
    684			reg ^= 0x4;
    685			m88rs2000_writereg(state, 0x70, reg);
    686			state->no_lock_count = 0;
    687		}
    688		msleep(20);
    689	}
    690
    691	if (status & FE_HAS_LOCK) {
    692		state->fec_inner = m88rs2000_get_fec(state);
    693		/* Unknown suspect SNR level */
    694		reg = m88rs2000_readreg(state, 0x65);
    695	}
    696
    697	state->tuner_frequency = c->frequency;
    698	state->symbol_rate = c->symbol_rate;
    699	return 0;
    700}
    701
    702static int m88rs2000_get_frontend(struct dvb_frontend *fe,
    703				  struct dtv_frontend_properties *c)
    704{
    705	struct m88rs2000_state *state = fe->demodulator_priv;
    706
    707	c->fec_inner = state->fec_inner;
    708	c->frequency = state->tuner_frequency;
    709	c->symbol_rate = state->symbol_rate;
    710	return 0;
    711}
    712
    713static int m88rs2000_get_tune_settings(struct dvb_frontend *fe,
    714	struct dvb_frontend_tune_settings *tune)
    715{
    716	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
    717
    718	if (c->symbol_rate > 3000000)
    719		tune->min_delay_ms = 2000;
    720	else
    721		tune->min_delay_ms = 3000;
    722
    723	tune->step_size = c->symbol_rate / 16000;
    724	tune->max_drift = c->symbol_rate / 2000;
    725
    726	return 0;
    727}
    728
    729static int m88rs2000_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
    730{
    731	struct m88rs2000_state *state = fe->demodulator_priv;
    732
    733	if (enable)
    734		m88rs2000_writereg(state, 0x81, 0x84);
    735	else
    736		m88rs2000_writereg(state, 0x81, 0x81);
    737	udelay(10);
    738	return 0;
    739}
    740
    741static void m88rs2000_release(struct dvb_frontend *fe)
    742{
    743	struct m88rs2000_state *state = fe->demodulator_priv;
    744	kfree(state);
    745}
    746
    747static const struct dvb_frontend_ops m88rs2000_ops = {
    748	.delsys = { SYS_DVBS },
    749	.info = {
    750		.name			= "M88RS2000 DVB-S",
    751		.frequency_min_hz	=  950 * MHz,
    752		.frequency_max_hz	= 2150 * MHz,
    753		.frequency_stepsize_hz	= 1 * MHz,
    754		.frequency_tolerance_hz	= 5 * MHz,
    755		.symbol_rate_min	= 1000000,
    756		.symbol_rate_max	= 45000000,
    757		.symbol_rate_tolerance	= 500,	/* ppm */
    758		.caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
    759		      FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
    760		      FE_CAN_QPSK | FE_CAN_INVERSION_AUTO |
    761		      FE_CAN_FEC_AUTO
    762	},
    763
    764	.release = m88rs2000_release,
    765	.init = m88rs2000_init,
    766	.sleep = m88rs2000_sleep,
    767	.i2c_gate_ctrl = m88rs2000_i2c_gate_ctrl,
    768	.read_status = m88rs2000_read_status,
    769	.read_ber = m88rs2000_read_ber,
    770	.read_signal_strength = m88rs2000_read_signal_strength,
    771	.read_snr = m88rs2000_read_snr,
    772	.read_ucblocks = m88rs2000_read_ucblocks,
    773	.diseqc_send_master_cmd = m88rs2000_send_diseqc_msg,
    774	.diseqc_send_burst = m88rs2000_send_diseqc_burst,
    775	.set_tone = m88rs2000_set_tone,
    776	.set_voltage = m88rs2000_set_voltage,
    777
    778	.set_frontend = m88rs2000_set_frontend,
    779	.get_frontend = m88rs2000_get_frontend,
    780	.get_tune_settings = m88rs2000_get_tune_settings,
    781};
    782
    783struct dvb_frontend *m88rs2000_attach(const struct m88rs2000_config *config,
    784				    struct i2c_adapter *i2c)
    785{
    786	struct m88rs2000_state *state = NULL;
    787
    788	/* allocate memory for the internal state */
    789	state = kzalloc(sizeof(struct m88rs2000_state), GFP_KERNEL);
    790	if (state == NULL)
    791		goto error;
    792
    793	/* setup the state */
    794	state->config = config;
    795	state->i2c = i2c;
    796	state->tuner_frequency = 0;
    797	state->symbol_rate = 0;
    798	state->fec_inner = 0;
    799
    800	/* create dvb_frontend */
    801	memcpy(&state->frontend.ops, &m88rs2000_ops,
    802			sizeof(struct dvb_frontend_ops));
    803	state->frontend.demodulator_priv = state;
    804	return &state->frontend;
    805
    806error:
    807	kfree(state);
    808
    809	return NULL;
    810}
    811EXPORT_SYMBOL(m88rs2000_attach);
    812
    813MODULE_DESCRIPTION("M88RS2000 DVB-S Demodulator driver");
    814MODULE_AUTHOR("Malcolm Priestley tvboxspy@gmail.com");
    815MODULE_LICENSE("GPL");
    816MODULE_VERSION("1.13");
    817