forked from luck/tmp_suning_uos_patched
[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: Steve Kerrison <steve@stevekerrison.com> Acked-by: Antti Palosaari <crope@iki.fi> Tested-by: Antti Palosaari <crope@iki.fi> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
6fb2bdfa06
commit
0db4bf42ba
|
@ -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
|
||||
|
||||
|
|
|
@ -335,4 +335,3 @@ int cxd2820r_get_tune_settings_c(struct dvb_frontend *fe,
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -446,4 +446,3 @@ int cxd2820r_get_tune_settings_t(struct dvb_frontend *fe,
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -420,4 +420,3 @@ int cxd2820r_get_tune_settings_t2(struct dvb_frontend *fe,
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -438,6 +438,7 @@ static struct cxd2820r_config em28xx_cxd2820r_config = {
|
|||
|
||||
static struct tda18271_config em28xx_cxd2820r_tda18271_config = {
|
||||
.output_opt = TDA18271_OUTPUT_LT_OFF,
|
||||
.gate = TDA18271_GATE_DIGITAL,
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
@ -751,11 +752,9 @@ static int em28xx_dvb_init(struct em28xx *dev)
|
|||
dvb->fe[0] = dvb_attach(cxd2820r_attach,
|
||||
&em28xx_cxd2820r_config, &dev->i2c_adap, NULL);
|
||||
if (dvb->fe[0]) {
|
||||
struct i2c_adapter *i2c_tuner;
|
||||
i2c_tuner = cxd2820r_get_tuner_i2c_adapter(dvb->fe[0]);
|
||||
/* FE 0 attach tuner */
|
||||
if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60,
|
||||
i2c_tuner, &em28xx_cxd2820r_tda18271_config)) {
|
||||
&dev->i2c_adap, &em28xx_cxd2820r_tda18271_config)) {
|
||||
dvb_frontend_detach(dvb->fe[0]);
|
||||
result = -EINVAL;
|
||||
goto out_free;
|
||||
|
@ -766,7 +765,7 @@ static int em28xx_dvb_init(struct em28xx *dev)
|
|||
dvb->fe[1]->id = 1;
|
||||
/* FE 1 attach tuner */
|
||||
if (!dvb_attach(tda18271_attach, dvb->fe[1], 0x60,
|
||||
i2c_tuner, &em28xx_cxd2820r_tda18271_config)) {
|
||||
&dev->i2c_adap, &em28xx_cxd2820r_tda18271_config)) {
|
||||
dvb_frontend_detach(dvb->fe[1]);
|
||||
/* leave FE 0 still active */
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user