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

Commit 0db4bf42 authored by Steve Kerrison's avatar Steve Kerrison Committed by Mauro Carvalho Chehab
Browse files

[media] CXD2820R: Replace i2c message translation with repeater gate control



This patch implements an i2c_gate_ctrl op for the cxd2820r. Thanks to Robert
Schlabbach for identifying the register address and field to set.

The old i2c intercept code that prefixed messages with a passthrough byte has
been removed and the PCTV nanoStick T2 290e entry in em28xx-dvb has been
updated appropriately.

Tested for DVB-T2 use; I would appreciate it if somebody with DVB-C capabilities
could test it as well - from inspection I cannot see any problems.

This is patch v2. It fixes some schoolboy style errors and removes superfluous
i2c entries in cxd2820r.h.

Signed-off-by: default avatarSteve Kerrison <steve@stevekerrison.com>
Acked-by: default avatarAntti Palosaari <crope@iki.fi>
Tested-by: default avatarAntti Palosaari <crope@iki.fi>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 6fb2bdfa
Loading
Loading
Loading
Loading
+0 −9
Original line number Diff line number Diff line
@@ -93,9 +93,6 @@ extern struct dvb_frontend *cxd2820r_attach(
	struct i2c_adapter *i2c,
	struct dvb_frontend *fe
);
extern struct i2c_adapter *cxd2820r_get_tuner_i2c_adapter(
	struct dvb_frontend *fe
);
#else
static inline struct dvb_frontend *cxd2820r_attach(
	const struct cxd2820r_config *config,
@@ -106,12 +103,6 @@ static inline struct dvb_frontend *cxd2820r_attach(
	printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
	return NULL;
}
static inline struct i2c_adapter *cxd2820r_get_tuner_i2c_adapter(
	struct dvb_frontend *fe
)
{
	return NULL;
}

#endif

+0 −1
Original line number Diff line number Diff line
@@ -335,4 +335,3 @@ int cxd2820r_get_tune_settings_c(struct dvb_frontend *fe,

	return 0;
}
+8 −68
Original line number Diff line number Diff line
@@ -727,70 +727,20 @@ static void cxd2820r_release(struct dvb_frontend *fe)
	struct cxd2820r_priv *priv = fe->demodulator_priv;
	dbg("%s", __func__);

	if (fe->ops.info.type == FE_OFDM) {
		i2c_del_adapter(&priv->tuner_i2c_adapter);
	if (fe->ops.info.type == FE_OFDM)
		kfree(priv);
	}

	return;
}

static u32 cxd2820r_tuner_i2c_func(struct i2c_adapter *adapter)
{
	return I2C_FUNC_I2C;
}

static int cxd2820r_tuner_i2c_xfer(struct i2c_adapter *i2c_adap,
	struct i2c_msg msg[], int num)
{
	struct cxd2820r_priv *priv = i2c_get_adapdata(i2c_adap);
	int ret;
	u8 *obuf = kmalloc(msg[0].len + 2, GFP_KERNEL);
	struct i2c_msg msg2[2] = {
		{
			.addr = priv->cfg.i2c_address,
			.flags = 0,
			.len = msg[0].len + 2,
			.buf = obuf,
		}, {
			.addr = priv->cfg.i2c_address,
			.flags = I2C_M_RD,
			.len = msg[1].len,
			.buf = msg[1].buf,
		}
	};

	if (!obuf)
		return -ENOMEM;

	obuf[0] = 0x09;
	obuf[1] = (msg[0].addr << 1);
	if (num == 2) { /* I2C read */
		obuf[1] = (msg[0].addr << 1) | I2C_M_RD; /* I2C RD flag */
		msg2[0].len = msg[0].len + 2 - 1; /* '-1' maybe HW bug ? */
	}
	memcpy(&obuf[2], msg[0].buf, msg[0].len);

	ret = i2c_transfer(priv->i2c, msg2, num);
	if (ret < 0)
		warn("tuner i2c failed ret:%d", ret);

	kfree(obuf);

	return ret;
}

static struct i2c_algorithm cxd2820r_tuner_i2c_algo = {
	.master_xfer   = cxd2820r_tuner_i2c_xfer,
	.functionality = cxd2820r_tuner_i2c_func,
};

struct i2c_adapter *cxd2820r_get_tuner_i2c_adapter(struct dvb_frontend *fe)
static int cxd2820r_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
{
	struct cxd2820r_priv *priv = fe->demodulator_priv;
	return &priv->tuner_i2c_adapter;
	dbg("%s: %d", __func__, enable);

	/* Bit 0 of reg 0xdb in bank 0x00 controls I2C repeater */
	return cxd2820r_wr_reg_mask(priv, 0xdb, enable ? 1 : 0, 0x1);
}
EXPORT_SYMBOL(cxd2820r_get_tuner_i2c_adapter);

static struct dvb_frontend_ops cxd2820r_ops[2];

@@ -831,18 +781,6 @@ struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg,
		priv->fe[0].demodulator_priv = priv;
		priv->fe[1].demodulator_priv = priv;

		/* create tuner i2c adapter */
		strlcpy(priv->tuner_i2c_adapter.name,
			"CXD2820R tuner I2C adapter",
			sizeof(priv->tuner_i2c_adapter.name));
		priv->tuner_i2c_adapter.algo = &cxd2820r_tuner_i2c_algo;
		priv->tuner_i2c_adapter.algo_data = NULL;
		i2c_set_adapdata(&priv->tuner_i2c_adapter, priv);
		if (i2c_add_adapter(&priv->tuner_i2c_adapter) < 0) {
			err("tuner I2C bus could not be initialized");
			goto error;
		}

		return &priv->fe[0];

	} else {
@@ -883,6 +821,7 @@ static struct dvb_frontend_ops cxd2820r_ops[2] = {
		.sleep = cxd2820r_sleep,

		.get_tune_settings = cxd2820r_get_tune_settings,
		.i2c_gate_ctrl = cxd2820r_i2c_gate_ctrl,

		.get_frontend = cxd2820r_get_frontend,

@@ -911,6 +850,7 @@ static struct dvb_frontend_ops cxd2820r_ops[2] = {
		.sleep = cxd2820r_sleep,

		.get_tune_settings = cxd2820r_get_tune_settings,
		.i2c_gate_ctrl = cxd2820r_i2c_gate_ctrl,

		.set_frontend = cxd2820r_set_frontend,
		.get_frontend = cxd2820r_get_frontend,
+0 −1
Original line number Diff line number Diff line
@@ -50,7 +50,6 @@ struct cxd2820r_priv {
	struct i2c_adapter *i2c;
	struct dvb_frontend fe[2];
	struct cxd2820r_config cfg;
	struct i2c_adapter tuner_i2c_adapter;

	struct mutex fe_lock; /* FE lock */
	int active_fe:2; /* FE lock, -1=NONE, 0=DVB-T/T2, 1=DVB-C */
+0 −1
Original line number Diff line number Diff line
@@ -446,4 +446,3 @@ int cxd2820r_get_tune_settings_t(struct dvb_frontend *fe,

	return 0;
}
Loading