summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/tda9887.c
diff options
context:
space:
mode:
authorMichael Krufky <mkrufky@linuxtv.org>2008-01-28 00:24:57 -0500
committerMichael Krufky <mkrufky@linuxtv.org>2008-01-28 00:24:57 -0500
commitfafbcd8e6db5d009c92e1ae5b117301ab2c1f03c (patch)
treefaf675bf1e48642116c131fb237ee5589e70edd3 /linux/drivers/media/video/tda9887.c
parent4177905e93cd9f2d1de81831d10fd9137cac3ad6 (diff)
downloadmediapointer-dvb-s2-fafbcd8e6db5d009c92e1ae5b117301ab2c1f03c.tar.gz
mediapointer-dvb-s2-fafbcd8e6db5d009c92e1ae5b117301ab2c1f03c.tar.bz2
tda9887: allow multiple driver instances for the same hardware to share state
From: Michael Krufky <mkrufky@linuxtv.org> Convert tda9887 to use the new hybrid_tuner_request_state and hybrid_tuner_release_state macros to manage state sharing between hybrid tuner instances. Some ATSC/DVB cards need to put the analog demodulator into standby before tuning digital. This patch allows us to attach the tda9887 driver to the digital side of the bridge driver and be able to put it into standby without jeopardizing the analog demod driver's state. Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
Diffstat (limited to 'linux/drivers/media/video/tda9887.c')
-rw-r--r--linux/drivers/media/video/tda9887.c43
1 files changed, 33 insertions, 10 deletions
diff --git a/linux/drivers/media/video/tda9887.c b/linux/drivers/media/video/tda9887.c
index aa640c470..e98de7d40 100644
--- a/linux/drivers/media/video/tda9887.c
+++ b/linux/drivers/media/video/tda9887.c
@@ -29,8 +29,12 @@ static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "enable verbose debug messages");
+static DEFINE_MUTEX(tda9887_list_mutex);
+static LIST_HEAD(hybrid_tuner_instance_list);
+
struct tda9887_priv {
struct tuner_i2c_props i2c_props;
+ struct list_head hybrid_tuner_instance_list;
unsigned char data[4];
unsigned int config;
@@ -653,7 +657,15 @@ static int tda9887_set_config(struct dvb_frontend *fe, void *priv_cfg)
static void tda9887_release(struct dvb_frontend *fe)
{
- kfree(fe->analog_demod_priv);
+ struct tda9887_priv *priv = fe->analog_demod_priv;
+
+ mutex_lock(&tda9887_list_mutex);
+
+ if (priv)
+ hybrid_tuner_release_state(priv);
+
+ mutex_unlock(&tda9887_list_mutex);
+
fe->analog_demod_priv = NULL;
}
@@ -674,18 +686,29 @@ struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe,
u8 i2c_addr)
{
struct tda9887_priv *priv = NULL;
+ int instance;
- priv = kzalloc(sizeof(struct tda9887_priv), GFP_KERNEL);
- if (priv == NULL)
- return NULL;
- fe->analog_demod_priv = priv;
+ mutex_lock(&tda9887_list_mutex);
- priv->i2c_props.addr = i2c_addr;
- priv->i2c_props.adap = i2c_adap;
- priv->i2c_props.name = "tda9887";
- priv->mode = T_STANDBY;
+ instance = hybrid_tuner_request_state(struct tda9887_priv, priv,
+ hybrid_tuner_instance_list,
+ i2c_adap, i2c_addr, "tda9887");
+ switch (instance) {
+ case 0:
+ mutex_unlock(&tda9887_list_mutex);
+ return NULL;
+ break;
+ case 1:
+ fe->analog_demod_priv = priv;
+ priv->mode = T_STANDBY;
+ tuner_info("tda988[5/6/7] found\n");
+ break;
+ default:
+ fe->analog_demod_priv = priv;
+ break;
+ }
- tuner_info("tda988[5/6/7] found\n");
+ mutex_unlock(&tda9887_list_mutex);
memcpy(&fe->ops.analog_ops, &tda9887_ops,
sizeof(struct analog_demod_ops));