[media] CXD2820R: Replace i2c message translation with repeater gate control
authorSteve Kerrison <steve@stevekerrison.com>
Tue, 9 Aug 2011 10:16:21 +0000 (07:16 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Sat, 3 Sep 2011 21:13:41 +0000 (18:13 -0300)
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>
drivers/media/dvb/frontends/cxd2820r.h
drivers/media/dvb/frontends/cxd2820r_c.c
drivers/media/dvb/frontends/cxd2820r_core.c
drivers/media/dvb/frontends/cxd2820r_priv.h
drivers/media/dvb/frontends/cxd2820r_t.c
drivers/media/dvb/frontends/cxd2820r_t2.c
drivers/media/video/em28xx/em28xx-dvb.c

index 2906582dc94c20a5ed58460b4d4b3a59e0332e84..03cab7b547fbac253331206de193848acc8b93a0 100644 (file)
@@ -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
 
index 3c07d400731d9f4337e06875d6d7136c43ab024d..b85f5011e344623fc3a03fbfb10d09d8df59a54f 100644 (file)
@@ -335,4 +335,3 @@ int cxd2820r_get_tune_settings_c(struct dvb_frontend *fe,
 
        return 0;
 }
-
index d416e85589e1150fe57c7b204a86b6c62ef8b6d2..01512670c6a698d291053ce277f8d8cb487ff5ce 100644 (file)
@@ -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,
index 0c0ebc9d5c4ac0ca7a051fa0c64b55dc23d6aa70..95539134efdb796c911543b908a37390e6eb2121 100644 (file)
@@ -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 */
index 6582564c930cb30fb37b28ebc8b9da79e3cc56af..a04f9c810101652138b2685973c1969d3cdf9c31 100644 (file)
@@ -446,4 +446,3 @@ int cxd2820r_get_tune_settings_t(struct dvb_frontend *fe,
 
        return 0;
 }
-
index c47b35c8acf13caf0dfdcd6d7b4c77c88f9ae5de..6548588309f7986ffc347e7c2915cc30fef0ec9c 100644 (file)
@@ -420,4 +420,3 @@ int cxd2820r_get_tune_settings_t2(struct dvb_frontend *fe,
 
        return 0;
 }
-
index b3406ebd57d7d35d7c647a3e963d599568bdbcd7..b606fc7f842dadc3653e61723b4450803ae45dfe 100644 (file)
@@ -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 */
                        }