V4L/DVB (7136): tda18271: use hybrid_tuner_request_state to manage tuner instances
authorMichael Krufky <mkrufky@linuxtv.org>
Tue, 22 Apr 2008 17:41:54 +0000 (14:41 -0300)
committerMauro Carvalho Chehab <mchehab@infradead.org>
Thu, 24 Apr 2008 16:42:26 +0000 (13:42 -0300)
Convert tda18271 to use the new hybrid_tuner_request_state and
hybrid_tuner_release_state macros to manage state sharing between
hybrid tuner instances.

Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
drivers/media/dvb/frontends/tda18271-common.c
drivers/media/dvb/frontends/tda18271-fe.c
drivers/media/dvb/frontends/tda18271-priv.h

index bca57099061366badc9cc4fec3dc8dde982ca02f..39496463ccf3f39a54653e9e5b2bbe71724baedb 100644 (file)
@@ -125,16 +125,16 @@ int tda18271_read_regs(struct dvb_frontend *fe)
        unsigned char buf = 0x00;
        int ret;
        struct i2c_msg msg[] = {
-               { .addr = priv->i2c_addr, .flags = 0,
+               { .addr = priv->i2c_props.addr, .flags = 0,
                  .buf = &buf, .len = 1 },
-               { .addr = priv->i2c_addr, .flags = I2C_M_RD,
+               { .addr = priv->i2c_props.addr, .flags = I2C_M_RD,
                  .buf = regs, .len = 16 }
        };
 
        tda18271_i2c_gate_ctrl(fe, 1);
 
        /* read all registers */
-       ret = i2c_transfer(priv->i2c_adap, msg, 2);
+       ret = i2c_transfer(priv->i2c_props.adap, msg, 2);
 
        tda18271_i2c_gate_ctrl(fe, 0);
 
@@ -155,16 +155,16 @@ int tda18271_read_extended(struct dvb_frontend *fe)
        unsigned char buf = 0x00;
        int ret, i;
        struct i2c_msg msg[] = {
-               { .addr = priv->i2c_addr, .flags = 0,
+               { .addr = priv->i2c_props.addr, .flags = 0,
                  .buf = &buf, .len = 1 },
-               { .addr = priv->i2c_addr, .flags = I2C_M_RD,
+               { .addr = priv->i2c_props.addr, .flags = I2C_M_RD,
                  .buf = regdump, .len = TDA18271_NUM_REGS }
        };
 
        tda18271_i2c_gate_ctrl(fe, 1);
 
        /* read all registers */
-       ret = i2c_transfer(priv->i2c_adap, msg, 2);
+       ret = i2c_transfer(priv->i2c_props.adap, msg, 2);
 
        tda18271_i2c_gate_ctrl(fe, 0);
 
@@ -192,7 +192,7 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
        struct tda18271_priv *priv = fe->tuner_priv;
        unsigned char *regs = priv->tda18271_regs;
        unsigned char buf[TDA18271_NUM_REGS + 1];
-       struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
+       struct i2c_msg msg = { .addr = priv->i2c_props.addr, .flags = 0,
                               .buf = buf, .len = len + 1 };
        int i, ret;
 
@@ -205,7 +205,7 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
        tda18271_i2c_gate_ctrl(fe, 1);
 
        /* write registers */
-       ret = i2c_transfer(priv->i2c_adap, &msg, 1);
+       ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
 
        tda18271_i2c_gate_ctrl(fe, 0);
 
@@ -223,7 +223,8 @@ int tda18271_init_regs(struct dvb_frontend *fe)
        unsigned char *regs = priv->tda18271_regs;
 
        tda_dbg("initializing registers for device @ %d-%04x\n",
-               i2c_adapter_id(priv->i2c_adap), priv->i2c_addr);
+               i2c_adapter_id(priv->i2c_props.adap),
+               priv->i2c_props.addr);
 
        /* initialize registers */
        switch (priv->id) {
index dfe72aaec3802188f3f385d3171d80617c7d903e..7f7fab7cd5afda910413047caffe52842c723429 100644 (file)
@@ -31,8 +31,8 @@ static int tda18271_cal_on_startup;
 module_param_named(cal, tda18271_cal_on_startup, int, 0644);
 MODULE_PARM_DESC(cal, "perform RF tracking filter calibration on startup");
 
-static LIST_HEAD(tda18271_list);
 static DEFINE_MUTEX(tda18271_list_mutex);
+static LIST_HEAD(hybrid_tuner_instance_list);
 
 /*---------------------------------------------------------------------*/
 
@@ -986,16 +986,9 @@ static int tda18271_release(struct dvb_frontend *fe)
 
        mutex_lock(&tda18271_list_mutex);
 
-       priv->count--;
+       if (priv)
+               hybrid_tuner_release_state(priv);
 
-       if (!priv->count) {
-               tda_dbg("destroying instance @ %d-%04x\n",
-                       i2c_adapter_id(priv->i2c_adap),
-                       priv->i2c_addr);
-               list_del(&priv->tda18271_list);
-
-               kfree(priv);
-       }
        mutex_unlock(&tda18271_list_mutex);
 
        fe->tuner_priv = NULL;
@@ -1109,7 +1102,8 @@ static int tda18271_get_id(struct dvb_frontend *fe)
        }
 
        tda_info("%s detected @ %d-%04x%s\n", name,
-                i2c_adapter_id(priv->i2c_adap), priv->i2c_addr,
+                i2c_adapter_id(priv->i2c_props.adap),
+                priv->i2c_props.addr,
                 (0 == ret) ? "" : ", device not supported.");
 
        return ret;
@@ -1136,46 +1130,25 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
                                     struct tda18271_config *cfg)
 {
        struct tda18271_priv *priv = NULL;
-       int state_found = 0;
+       int instance;
 
        mutex_lock(&tda18271_list_mutex);
 
-       list_for_each_entry(priv, &tda18271_list, tda18271_list) {
-               if ((i2c_adapter_id(priv->i2c_adap) == i2c_adapter_id(i2c)) &&
-                   (priv->i2c_addr == addr)) {
-                       tda_dbg("attaching existing tuner @ %d-%04x\n",
-                               i2c_adapter_id(priv->i2c_adap),
-                               priv->i2c_addr);
-                       priv->count++;
-                       fe->tuner_priv = priv;
-                       state_found = 1;
-                       /* allow dvb driver to override i2c gate setting */
-                       if ((cfg) && (cfg->gate != TDA18271_GATE_ANALOG))
-                               priv->gate = cfg->gate;
-                       break;
-               }
-       }
-       if (state_found == 0) {
-               tda_dbg("creating new tuner instance @ %d-%04x\n",
-                       i2c_adapter_id(i2c), addr);
-
-               priv = kzalloc(sizeof(struct tda18271_priv), GFP_KERNEL);
-               if (priv == NULL) {
-                       mutex_unlock(&tda18271_list_mutex);
-                       return NULL;
-               }
-
-               priv->i2c_addr = addr;
-               priv->i2c_adap = i2c;
+       instance = hybrid_tuner_request_state(struct tda18271_priv, priv,
+                                             hybrid_tuner_instance_list,
+                                             i2c, addr, "tda18271");
+       switch (instance) {
+       case 0:
+               goto fail;
+               break;
+       case 1:
+               /* new tuner instance */
                priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
                priv->cal_initialized = false;
                mutex_init(&priv->lock);
-               priv->count++;
 
                fe->tuner_priv = priv;
 
-               list_add_tail(&priv->tda18271_list, &tda18271_list);
-
                if (tda18271_get_id(fe) < 0)
                        goto fail;
 
@@ -1189,6 +1162,15 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
                        tda18271_rf_cal_init(fe);
 
                mutex_unlock(&priv->lock);
+               break;
+       default:
+               /* existing tuner instance */
+               fe->tuner_priv = priv;
+
+               /* allow dvb driver to override i2c gate setting */
+               if ((cfg) && (cfg->gate != TDA18271_GATE_ANALOG))
+                       priv->gate = cfg->gate;
+               break;
        }
 
        /* override default std map with values in config struct */
index 7b939a5325fb970189feeb998913f37e49d11e19..840b1803d171e3e02ef7b6386b2a13ce9e6fc3cd 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/kernel.h>
 #include <linux/types.h>
 #include <linux/mutex.h>
+#include "tuner-i2c.h"
 #include "tda18271.h"
 
 #define R_ID     0x00  /* ID byte                */
@@ -98,17 +99,15 @@ enum tda18271_ver {
 };
 
 struct tda18271_priv {
-       u8 i2c_addr;
-       struct i2c_adapter *i2c_adap;
        unsigned char tda18271_regs[TDA18271_NUM_REGS];
 
-       struct list_head tda18271_list;
+       struct list_head        hybrid_tuner_instance_list;
+       struct tuner_i2c_props  i2c_props;
 
        enum tda18271_mode mode;
        enum tda18271_i2c_gate gate;
        enum tda18271_ver id;
 
-       unsigned int count;
        unsigned int tm_rfcal;
        unsigned int cal_initialized:1;