Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b858c331 authored by Igor M. Liplianin's avatar Igor M. Liplianin Committed by Mauro Carvalho Chehab
Browse files

[media] m88rs2000: make use ts2020



Tuner part of Montage rs2000 chip is similar to ts2020 tuner.
Patch to use ts2020 code.

[mchehab@redhat.com: a few CodingStyle fixes]
Signed-off-by: default avatarIgor M. Liplianin <liplianin@me.by>

Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 43385c8a
Loading
Loading
Loading
Loading
+100 −308
Original line number Diff line number Diff line
@@ -60,15 +60,13 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
#define info(format, arg...) \
	printk(KERN_INFO "m88rs2000-fe: " format "\n" , ## arg)

static int m88rs2000_writereg(struct m88rs2000_state *state, u8 tuner,
static int m88rs2000_writereg(struct m88rs2000_state *state,
	u8 reg, u8 data)
{
	int ret;
	u8 addr = (tuner == 0) ? state->config->tuner_addr :
		state->config->demod_addr;
	u8 buf[] = { reg, data };
	struct i2c_msg msg = {
		.addr = addr,
		.addr = state->config->demod_addr,
		.flags = 0,
		.buf = buf,
		.len = 2
@@ -83,44 +81,20 @@ static int m88rs2000_writereg(struct m88rs2000_state *state, u8 tuner,
	return (ret != 1) ? -EREMOTEIO : 0;
}

static int m88rs2000_demod_write(struct m88rs2000_state *state, u8 reg, u8 data)
{
	return m88rs2000_writereg(state, 1, reg, data);
}

static int m88rs2000_tuner_write(struct m88rs2000_state *state, u8 reg, u8 data)
{
	m88rs2000_demod_write(state, 0x81, 0x84);
	udelay(10);
	return m88rs2000_writereg(state, 0, reg, data);

}

static int m88rs2000_write(struct dvb_frontend *fe, const u8 buf[], int len)
{
	struct m88rs2000_state *state = fe->demodulator_priv;

	if (len != 2)
		return -EINVAL;

	return m88rs2000_writereg(state, 1, buf[0], buf[1]);
}

static u8 m88rs2000_readreg(struct m88rs2000_state *state, u8 tuner, u8 reg)
static u8 m88rs2000_readreg(struct m88rs2000_state *state, u8 reg)
{
	int ret;
	u8 b0[] = { reg };
	u8 b1[] = { 0 };
	u8 addr = (tuner == 0) ? state->config->tuner_addr :
		state->config->demod_addr;

	struct i2c_msg msg[] = {
		{
			.addr = addr,
			.addr = state->config->demod_addr,
			.flags = 0,
			.buf = b0,
			.len = 1
		}, {
			.addr = addr,
			.addr = state->config->demod_addr,
			.flags = I2C_M_RD,
			.buf = b1,
			.len = 1
@@ -136,18 +110,6 @@ static u8 m88rs2000_readreg(struct m88rs2000_state *state, u8 tuner, u8 reg)
	return b1[0];
}

static u8 m88rs2000_demod_read(struct m88rs2000_state *state, u8 reg)
{
	return m88rs2000_readreg(state, 1, reg);
}

static u8 m88rs2000_tuner_read(struct m88rs2000_state *state, u8 reg)
{
	m88rs2000_demod_write(state, 0x81, 0x85);
	udelay(10);
	return m88rs2000_readreg(state, 0, reg);
}

static int m88rs2000_set_symbolrate(struct dvb_frontend *fe, u32 srate)
{
	struct m88rs2000_state *state = fe->demodulator_priv;
@@ -166,9 +128,9 @@ static int m88rs2000_set_symbolrate(struct dvb_frontend *fe, u32 srate)
	b[0] = (u8) (temp >> 16) & 0xff;
	b[1] = (u8) (temp >> 8) & 0xff;
	b[2] = (u8) temp & 0xff;
	ret = m88rs2000_demod_write(state, 0x93, b[2]);
	ret |= m88rs2000_demod_write(state, 0x94, b[1]);
	ret |= m88rs2000_demod_write(state, 0x95, b[0]);
	ret = m88rs2000_writereg(state, 0x93, b[2]);
	ret |= m88rs2000_writereg(state, 0x94, b[1]);
	ret |= m88rs2000_writereg(state, 0x95, b[0]);

	deb_info("m88rs2000: m88rs2000_set_symbolrate\n");
	return ret;
@@ -182,37 +144,37 @@ static int m88rs2000_send_diseqc_msg(struct dvb_frontend *fe,
	int i;
	u8 reg;
	deb_info("%s\n", __func__);
	m88rs2000_demod_write(state, 0x9a, 0x30);
	reg = m88rs2000_demod_read(state, 0xb2);
	m88rs2000_writereg(state, 0x9a, 0x30);
	reg = m88rs2000_readreg(state, 0xb2);
	reg &= 0x3f;
	m88rs2000_demod_write(state, 0xb2, reg);
	m88rs2000_writereg(state, 0xb2, reg);
	for (i = 0; i <  m->msg_len; i++)
		m88rs2000_demod_write(state, 0xb3 + i, m->msg[i]);
		m88rs2000_writereg(state, 0xb3 + i, m->msg[i]);

	reg = m88rs2000_demod_read(state, 0xb1);
	reg = m88rs2000_readreg(state, 0xb1);
	reg &= 0x87;
	reg |= ((m->msg_len - 1) << 3) | 0x07;
	reg &= 0x7f;
	m88rs2000_demod_write(state, 0xb1, reg);
	m88rs2000_writereg(state, 0xb1, reg);

	for (i = 0; i < 15; i++) {
		if ((m88rs2000_demod_read(state, 0xb1) & 0x40) == 0x0)
		if ((m88rs2000_readreg(state, 0xb1) & 0x40) == 0x0)
			break;
		msleep(20);
	}

	reg = m88rs2000_demod_read(state, 0xb1);
	reg = m88rs2000_readreg(state, 0xb1);
	if ((reg & 0x40) > 0x0) {
		reg &= 0x7f;
		reg |= 0x40;
		m88rs2000_demod_write(state, 0xb1, reg);
		m88rs2000_writereg(state, 0xb1, reg);
	}

	reg = m88rs2000_demod_read(state, 0xb2);
	reg = m88rs2000_readreg(state, 0xb2);
	reg &= 0x3f;
	reg |= 0x80;
	m88rs2000_demod_write(state, 0xb2, reg);
	m88rs2000_demod_write(state, 0x9a, 0xb0);
	m88rs2000_writereg(state, 0xb2, reg);
	m88rs2000_writereg(state, 0x9a, 0xb0);


	return 0;
@@ -224,14 +186,14 @@ static int m88rs2000_send_diseqc_burst(struct dvb_frontend *fe,
	struct m88rs2000_state *state = fe->demodulator_priv;
	u8 reg0, reg1;
	deb_info("%s\n", __func__);
	m88rs2000_demod_write(state, 0x9a, 0x30);
	m88rs2000_writereg(state, 0x9a, 0x30);
	msleep(50);
	reg0 = m88rs2000_demod_read(state, 0xb1);
	reg1 = m88rs2000_demod_read(state, 0xb2);
	reg0 = m88rs2000_readreg(state, 0xb1);
	reg1 = m88rs2000_readreg(state, 0xb2);
	/* TODO complete this section */
	m88rs2000_demod_write(state, 0xb2, reg1);
	m88rs2000_demod_write(state, 0xb1, reg0);
	m88rs2000_demod_write(state, 0x9a, 0xb0);
	m88rs2000_writereg(state, 0xb2, reg1);
	m88rs2000_writereg(state, 0xb1, reg0);
	m88rs2000_writereg(state, 0x9a, 0xb0);

	return 0;
}
@@ -240,9 +202,9 @@ static int m88rs2000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
{
	struct m88rs2000_state *state = fe->demodulator_priv;
	u8 reg0, reg1;
	m88rs2000_demod_write(state, 0x9a, 0x30);
	reg0 = m88rs2000_demod_read(state, 0xb1);
	reg1 = m88rs2000_demod_read(state, 0xb2);
	m88rs2000_writereg(state, 0x9a, 0x30);
	reg0 = m88rs2000_readreg(state, 0xb1);
	reg1 = m88rs2000_readreg(state, 0xb2);

	reg1 &= 0x3f;

@@ -257,9 +219,9 @@ static int m88rs2000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
	default:
		break;
	}
	m88rs2000_demod_write(state, 0xb2, reg1);
	m88rs2000_demod_write(state, 0xb1, reg0);
	m88rs2000_demod_write(state, 0x9a, 0xb0);
	m88rs2000_writereg(state, 0xb2, reg1);
	m88rs2000_writereg(state, 0xb1, reg0);
	m88rs2000_writereg(state, 0x9a, 0xb0);
	return 0;
}

@@ -276,14 +238,6 @@ struct inittab m88rs2000_setup[] = {
	{DEMOD_WRITE, 0x00, 0x00},
	{DEMOD_WRITE, 0x9a, 0xb0},
	{DEMOD_WRITE, 0x81, 0xc1},
	{TUNER_WRITE, 0x42, 0x73},
	{TUNER_WRITE, 0x05, 0x07},
	{TUNER_WRITE, 0x20, 0x27},
	{TUNER_WRITE, 0x07, 0x02},
	{TUNER_WRITE, 0x11, 0xff},
	{TUNER_WRITE, 0x60, 0xf9},
	{TUNER_WRITE, 0x08, 0x01},
	{TUNER_WRITE, 0x00, 0x41},
	{DEMOD_WRITE, 0x81, 0x81},
	{DEMOD_WRITE, 0x86, 0xc6},
	{DEMOD_WRITE, 0x9a, 0x30},
@@ -301,23 +255,10 @@ struct inittab m88rs2000_shutdown[] = {
	{DEMOD_WRITE, 0xf1, 0x89},
	{DEMOD_WRITE, 0x00, 0x01},
	{DEMOD_WRITE, 0x9a, 0xb0},
	{TUNER_WRITE, 0x00, 0x40},
	{DEMOD_WRITE, 0x81, 0x81},
	{0xff, 0xaa, 0xff}
};

struct inittab tuner_reset[] = {
	{TUNER_WRITE, 0x42, 0x73},
	{TUNER_WRITE, 0x05, 0x07},
	{TUNER_WRITE, 0x20, 0x27},
	{TUNER_WRITE, 0x07, 0x02},
	{TUNER_WRITE, 0x11, 0xff},
	{TUNER_WRITE, 0x60, 0xf9},
	{TUNER_WRITE, 0x08, 0x01},
	{TUNER_WRITE, 0x00, 0x41},
	{0xff, 0xaa, 0xff}
};

struct inittab fe_reset[] = {
	{DEMOD_WRITE, 0x00, 0x01},
	{DEMOD_WRITE, 0xf1, 0xbf},
@@ -389,11 +330,7 @@ static int m88rs2000_tab_set(struct m88rs2000_state *state,
	for (i = 0; i < 255; i++) {
		switch (tab[i].cmd) {
		case 0x01:
			ret = m88rs2000_demod_write(state, tab[i].reg,
				tab[i].val);
			break;
		case 0x02:
			ret = m88rs2000_tuner_write(state, tab[i].reg,
			ret = m88rs2000_writereg(state, tab[i].reg,
				tab[i].val);
			break;
		case 0x10:
@@ -419,7 +356,7 @@ static int m88rs2000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
	struct m88rs2000_state *state = fe->demodulator_priv;
	u8 data;

	data = m88rs2000_demod_read(state, 0xb2);
	data = m88rs2000_readreg(state, 0xb2);
	data |= 0x03; /* bit0 V/H, bit1 off/on */

	switch (volt) {
@@ -434,23 +371,11 @@ static int m88rs2000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
		break;
	}

	m88rs2000_demod_write(state, 0xb2, data);
	m88rs2000_writereg(state, 0xb2, data);

	return 0;
}

static int m88rs2000_startup(struct m88rs2000_state *state)
{
	int ret = 0;
	u8 reg;

	reg = m88rs2000_tuner_read(state, 0x00);
	if ((reg & 0x40) == 0)
		ret = -ENODEV;

	return ret;
}

static int m88rs2000_init(struct dvb_frontend *fe)
{
	struct m88rs2000_state *state = fe->demodulator_priv;
@@ -479,7 +404,7 @@ static int m88rs2000_sleep(struct dvb_frontend *fe)
static int m88rs2000_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
	struct m88rs2000_state *state = fe->demodulator_priv;
	u8 reg = m88rs2000_demod_read(state, 0x8c);
	u8 reg = m88rs2000_readreg(state, 0x8c);

	*status = 0;

@@ -497,23 +422,23 @@ static int m88rs2000_read_ber(struct dvb_frontend *fe, u32 *ber)
	struct m88rs2000_state *state = fe->demodulator_priv;
	u8 tmp0, tmp1;

	m88rs2000_demod_write(state, 0x9a, 0x30);
	tmp0 = m88rs2000_demod_read(state, 0xd8);
	m88rs2000_writereg(state, 0x9a, 0x30);
	tmp0 = m88rs2000_readreg(state, 0xd8);
	if ((tmp0 & 0x10) != 0) {
		m88rs2000_demod_write(state, 0x9a, 0xb0);
		m88rs2000_writereg(state, 0x9a, 0xb0);
		*ber = 0xffffffff;
		return 0;
	}

	*ber = (m88rs2000_demod_read(state, 0xd7) << 8) |
		m88rs2000_demod_read(state, 0xd6);
	*ber = (m88rs2000_readreg(state, 0xd7) << 8) |
		m88rs2000_readreg(state, 0xd6);

	tmp1 = m88rs2000_demod_read(state, 0xd9);
	m88rs2000_demod_write(state, 0xd9, (tmp1 & ~7) | 4);
	tmp1 = m88rs2000_readreg(state, 0xd9);
	m88rs2000_writereg(state, 0xd9, (tmp1 & ~7) | 4);
	/* needs twice */
	m88rs2000_demod_write(state, 0xd8, (tmp0 & ~8) | 0x30);
	m88rs2000_demod_write(state, 0xd8, (tmp0 & ~8) | 0x30);
	m88rs2000_demod_write(state, 0x9a, 0xb0);
	m88rs2000_writereg(state, 0xd8, (tmp0 & ~8) | 0x30);
	m88rs2000_writereg(state, 0xd8, (tmp0 & ~8) | 0x30);
	m88rs2000_writereg(state, 0x9a, 0xb0);

	return 0;
}
@@ -529,7 +454,7 @@ static int m88rs2000_read_snr(struct dvb_frontend *fe, u16 *snr)
{
	struct m88rs2000_state *state = fe->demodulator_priv;

	*snr = 512 * m88rs2000_demod_read(state, 0x65);
	*snr = 512 * m88rs2000_readreg(state, 0x65);

	return 0;
}
@@ -539,166 +464,17 @@ static int m88rs2000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
	struct m88rs2000_state *state = fe->demodulator_priv;
	u8 tmp;

	*ucblocks = (m88rs2000_demod_read(state, 0xd5) << 8) |
			m88rs2000_demod_read(state, 0xd4);
	tmp = m88rs2000_demod_read(state, 0xd8);
	m88rs2000_demod_write(state, 0xd8, tmp & ~0x20);
	*ucblocks = (m88rs2000_readreg(state, 0xd5) << 8) |
			m88rs2000_readreg(state, 0xd4);
	tmp = m88rs2000_readreg(state, 0xd8);
	m88rs2000_writereg(state, 0xd8, tmp & ~0x20);
	/* needs two times */
	m88rs2000_demod_write(state, 0xd8, tmp | 0x20);
	m88rs2000_demod_write(state, 0xd8, tmp | 0x20);
	m88rs2000_writereg(state, 0xd8, tmp | 0x20);
	m88rs2000_writereg(state, 0xd8, tmp | 0x20);

	return 0;
}

static int m88rs2000_tuner_gate_ctrl(struct m88rs2000_state *state, u8 offset)
{
	int ret;
	ret = m88rs2000_tuner_write(state, 0x51, 0x1f - offset);
	ret |= m88rs2000_tuner_write(state, 0x51, 0x1f);
	ret |= m88rs2000_tuner_write(state, 0x50, offset);
	ret |= m88rs2000_tuner_write(state, 0x50, 0x00);
	msleep(20);
	return ret;
}

static int m88rs2000_set_tuner_rf(struct dvb_frontend *fe)
{
	struct m88rs2000_state *state = fe->demodulator_priv;
	int reg;
	reg = m88rs2000_tuner_read(state, 0x3d);
	reg &= 0x7f;
	if (reg < 0x16)
		reg = 0xa1;
	else if (reg == 0x16)
		reg = 0x99;
	else
		reg = 0xf9;

	m88rs2000_tuner_write(state, 0x60, reg);
	reg = m88rs2000_tuner_gate_ctrl(state, 0x08);

	if (fe->ops.i2c_gate_ctrl)
			fe->ops.i2c_gate_ctrl(fe, 0);
	return reg;
}

static int m88rs2000_set_tuner(struct dvb_frontend *fe, u16 *offset)
{
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
	struct m88rs2000_state *state = fe->demodulator_priv;
	int ret;
	u32 frequency = c->frequency;
	s32 offset_khz;
	s32 tmp;
	u32 symbol_rate = (c->symbol_rate / 1000);
	u32 f3db, gdiv28;
	u16 value, ndiv, lpf_coeff;
	u8 lpf_mxdiv, mlpf_max, mlpf_min, nlpf;
	u8 lo = 0x01, div4 = 0x0;

	/* Reset Tuner */
	ret = m88rs2000_tab_set(state, tuner_reset);

	/* Calculate frequency divider */
	if (frequency < 1060000) {
		lo |= 0x10;
		div4 = 0x1;
		ndiv = (frequency * 14 * 4) / FE_CRYSTAL_KHZ;
	} else
		ndiv = (frequency * 14 * 2) / FE_CRYSTAL_KHZ;
	ndiv = ndiv + ndiv % 2;
	ndiv = ndiv - 1024;

	ret = m88rs2000_tuner_write(state, 0x10, 0x80 | lo);

	/* Set frequency divider */
	ret |= m88rs2000_tuner_write(state, 0x01, (ndiv >> 8) & 0xf);
	ret |= m88rs2000_tuner_write(state, 0x02, ndiv & 0xff);

	ret |= m88rs2000_tuner_write(state, 0x03, 0x06);
	ret |= m88rs2000_tuner_gate_ctrl(state, 0x10);
	if (ret < 0)
		return -ENODEV;

	/* Tuner Frequency Range */
	ret = m88rs2000_tuner_write(state, 0x10, lo);

	ret |= m88rs2000_tuner_gate_ctrl(state, 0x08);

	/* Tuner RF */
	ret |= m88rs2000_set_tuner_rf(fe);

	gdiv28 = (FE_CRYSTAL_KHZ / 1000 * 1694 + 500) / 1000;
	ret |= m88rs2000_tuner_write(state, 0x04, gdiv28 & 0xff);
	ret |= m88rs2000_tuner_gate_ctrl(state, 0x04);
	if (ret < 0)
		return -ENODEV;

	value = m88rs2000_tuner_read(state, 0x26);

	f3db = (symbol_rate * 135) / 200 + 2000;
	f3db += FREQ_OFFSET_LOW_SYM_RATE;
	if (f3db < 7000)
		f3db = 7000;
	if (f3db > 40000)
		f3db = 40000;

	gdiv28 = gdiv28 * 207 / (value * 2 + 151);
	mlpf_max = gdiv28 * 135 / 100;
	mlpf_min = gdiv28 * 78 / 100;
	if (mlpf_max > 63)
		mlpf_max = 63;

	lpf_coeff = 2766;

	nlpf = (f3db * gdiv28 * 2 / lpf_coeff /
		(FE_CRYSTAL_KHZ / 1000)  + 1) / 2;
	if (nlpf > 23)
		nlpf = 23;
	if (nlpf < 1)
		nlpf = 1;

	lpf_mxdiv = (nlpf * (FE_CRYSTAL_KHZ / 1000)
		* lpf_coeff * 2  / f3db + 1) / 2;

	if (lpf_mxdiv < mlpf_min) {
		nlpf++;
		lpf_mxdiv = (nlpf * (FE_CRYSTAL_KHZ / 1000)
			* lpf_coeff * 2  / f3db + 1) / 2;
	}

	if (lpf_mxdiv > mlpf_max)
		lpf_mxdiv = mlpf_max;

	ret = m88rs2000_tuner_write(state, 0x04, lpf_mxdiv);
	ret |= m88rs2000_tuner_write(state, 0x06, nlpf);

	ret |= m88rs2000_tuner_gate_ctrl(state, 0x04);

	ret |= m88rs2000_tuner_gate_ctrl(state, 0x01);

	msleep(80);
	/* calculate offset assuming 96000kHz*/
	offset_khz = (ndiv - ndiv % 2 + 1024) * FE_CRYSTAL_KHZ
		/ 14 / (div4 + 1) / 2;

	offset_khz -= frequency;

	tmp = offset_khz;
	tmp *= 65536;

	tmp = (2 * tmp + 96000) / (2 * 96000);
	if (tmp < 0)
		tmp += 65536;

	*offset = tmp & 0xffff;

	if (fe->ops.i2c_gate_ctrl)
			fe->ops.i2c_gate_ctrl(fe, 0);

	return (ret < 0) ? -EINVAL : 0;
}

static int m88rs2000_set_fec(struct m88rs2000_state *state,
		fe_code_rate_t fec)
{
@@ -724,7 +500,7 @@ static int m88rs2000_set_fec(struct m88rs2000_state *state,
	default:
		fec_set = 0x08;
	}
	m88rs2000_demod_write(state, 0x76, fec_set);
	m88rs2000_writereg(state, 0x76, fec_set);

	return 0;
}
@@ -733,9 +509,9 @@ static int m88rs2000_set_fec(struct m88rs2000_state *state,
static fe_code_rate_t m88rs2000_get_fec(struct m88rs2000_state *state)
{
	u8 reg;
	m88rs2000_demod_write(state, 0x9a, 0x30);
	reg = m88rs2000_demod_read(state, 0x76);
	m88rs2000_demod_write(state, 0x9a, 0xb0);
	m88rs2000_writereg(state, 0x9a, 0x30);
	reg = m88rs2000_readreg(state, 0x76);
	m88rs2000_writereg(state, 0x9a, 0xb0);

	switch (reg) {
	case 0x88:
@@ -761,7 +537,9 @@ static int m88rs2000_set_frontend(struct dvb_frontend *fe)
	struct m88rs2000_state *state = fe->demodulator_priv;
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
	fe_status_t status;
	int i, ret;
	int i, ret = 0;
	s32 tmp;
	u32 tuner_freq;
	u16 offset = 0;
	u8 reg;

@@ -775,17 +553,37 @@ static int m88rs2000_set_frontend(struct dvb_frontend *fe)
	}

	/* Set Tuner */
	ret = m88rs2000_set_tuner(fe, &offset);
	if (fe->ops.tuner_ops.set_params)
		ret = fe->ops.tuner_ops.set_params(fe);

	if (ret < 0)
		return -ENODEV;

	if (fe->ops.tuner_ops.get_frequency)
		ret = fe->ops.tuner_ops.get_frequency(fe, &tuner_freq);

	if (ret < 0)
		return -ENODEV;

	ret = m88rs2000_demod_write(state, 0x9a, 0x30);
	offset = tuner_freq - c->frequency;

	/* calculate offset assuming 96000kHz*/
	tmp = offset;
	tmp *= 65536;

	tmp = (2 * tmp + 96000) / (2 * 96000);
	if (tmp < 0)
		tmp += 65536;

	offset = tmp & 0xffff;

	ret = m88rs2000_writereg(state, 0x9a, 0x30);
	/* Unknown usually 0xc6 sometimes 0xc1 */
	reg = m88rs2000_demod_read(state, 0x86);
	ret |= m88rs2000_demod_write(state, 0x86, reg);
	reg = m88rs2000_readreg(state, 0x86);
	ret |= m88rs2000_writereg(state, 0x86, reg);
	/* Offset lower nibble always 0 */
	ret |= m88rs2000_demod_write(state, 0x9c, (offset >> 8));
	ret |= m88rs2000_demod_write(state, 0x9d, offset & 0xf0);
	ret |= m88rs2000_writereg(state, 0x9c, (offset >> 8));
	ret |= m88rs2000_writereg(state, 0x9d, offset & 0xf0);


	/* Reset Demod */
@@ -794,16 +592,16 @@ static int m88rs2000_set_frontend(struct dvb_frontend *fe)
		return -ENODEV;

	/* Unknown */
	reg = m88rs2000_demod_read(state, 0x70);
	ret = m88rs2000_demod_write(state, 0x70, reg);
	reg = m88rs2000_readreg(state, 0x70);
	ret = m88rs2000_writereg(state, 0x70, reg);

	/* Set FEC */
	ret |= m88rs2000_set_fec(state, c->fec_inner);
	ret |= m88rs2000_demod_write(state, 0x85, 0x1);
	ret |= m88rs2000_demod_write(state, 0x8a, 0xbf);
	ret |= m88rs2000_demod_write(state, 0x8d, 0x1e);
	ret |= m88rs2000_demod_write(state, 0x90, 0xf1);
	ret |= m88rs2000_demod_write(state, 0x91, 0x08);
	ret |= m88rs2000_writereg(state, 0x85, 0x1);
	ret |= m88rs2000_writereg(state, 0x8a, 0xbf);
	ret |= m88rs2000_writereg(state, 0x8d, 0x1e);
	ret |= m88rs2000_writereg(state, 0x90, 0xf1);
	ret |= m88rs2000_writereg(state, 0x91, 0x08);

	if (ret < 0)
		return -ENODEV;
@@ -819,27 +617,25 @@ static int m88rs2000_set_frontend(struct dvb_frontend *fe)
		return -ENODEV;

	for (i = 0; i < 25; i++) {
		reg = m88rs2000_demod_read(state, 0x8c);
		reg = m88rs2000_readreg(state, 0x8c);
		if ((reg & 0x7) == 0x7) {
			status = FE_HAS_LOCK;
			break;
		}
		state->no_lock_count++;
		if (state->no_lock_count == 15) {
			reg = m88rs2000_demod_read(state, 0x70);
			reg = m88rs2000_readreg(state, 0x70);
			reg ^= 0x4;
			m88rs2000_demod_write(state, 0x70, reg);
			m88rs2000_writereg(state, 0x70, reg);
			state->no_lock_count = 0;
		}
		if (state->no_lock_count == 20)
			m88rs2000_set_tuner_rf(fe);
		msleep(20);
	}

	if (status & FE_HAS_LOCK) {
		state->fec_inner = m88rs2000_get_fec(state);
		/* Uknown suspect SNR level */
		reg = m88rs2000_demod_read(state, 0x65);
		reg = m88rs2000_readreg(state, 0x65);
	}

	state->tuner_frequency = c->frequency;
@@ -862,9 +658,9 @@ static int m88rs2000_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
	struct m88rs2000_state *state = fe->demodulator_priv;

	if (enable)
		m88rs2000_demod_write(state, 0x81, 0x84);
		m88rs2000_writereg(state, 0x81, 0x84);
	else
		m88rs2000_demod_write(state, 0x81, 0x81);
		m88rs2000_writereg(state, 0x81, 0x81);
	udelay(10);
	return 0;
}
@@ -895,7 +691,6 @@ static struct dvb_frontend_ops m88rs2000_ops = {
	.release = m88rs2000_release,
	.init = m88rs2000_init,
	.sleep = m88rs2000_sleep,
	.write = m88rs2000_write,
	.i2c_gate_ctrl = m88rs2000_i2c_gate_ctrl,
	.read_status = m88rs2000_read_status,
	.read_ber = m88rs2000_read_ber,
@@ -928,9 +723,6 @@ struct dvb_frontend *m88rs2000_attach(const struct m88rs2000_config *config,
	state->symbol_rate = 0;
	state->fec_inner = 0;

	if (m88rs2000_startup(state) < 0)
		goto error;

	/* create dvb_frontend */
	memcpy(&state->frontend.ops, &m88rs2000_ops,
			sizeof(struct dvb_frontend_ops));
+0 −6
Original line number Diff line number Diff line
@@ -26,8 +26,6 @@
struct m88rs2000_config {
	/* Demodulator i2c address */
	u8 demod_addr;
	/* Tuner address */
	u8 tuner_addr;

	u8 *inittab;

@@ -55,12 +53,8 @@ static inline struct dvb_frontend *m88rs2000_attach(
}
#endif /* CONFIG_DVB_M88RS2000 */

#define FE_CRYSTAL_KHZ 27000
#define FREQ_OFFSET_LOW_SYM_RATE 3000

enum {
	DEMOD_WRITE = 0x1,
	TUNER_WRITE,
	WRITE_DELAY = 0x10,
};
#endif /* M88RS2000_H */
+217 −164

File changed.

Preview size limit exceeded, changes collapsed.

+1 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@

struct ts2020_config {
	u8 tuner_address;
	u8 clk_out_div;
};

#if defined(CONFIG_DVB_TS2020) || \
+15 −14
Original line number Diff line number Diff line
@@ -474,6 +474,7 @@ static struct ds3000_config tevii_ds3000_config = {

static struct ts2020_config tevii_ts2020_config  = {
	.tuner_address = 0x60,
	.clk_out_div = 1,
};

static struct cx24116_config dvbworld_cx24116_config = {
Loading