Skip to content

Commit

Permalink
V4L/DVB (7346): tda9887: allow multiple driver instances for the same…
Browse files Browse the repository at this point in the history
… hardware to share state

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>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
  • Loading branch information
Michael Krufky authored and Mauro Carvalho Chehab committed Apr 24, 2008
1 parent 081b496 commit ac8b63b
Showing 1 changed file with 33 additions and 10 deletions.
43 changes: 33 additions & 10 deletions drivers/media/video/tda9887.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,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;
Expand Down Expand Up @@ -642,7 +646,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;
}

Expand All @@ -663,18 +675,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));
Expand Down

0 comments on commit ac8b63b

Please sign in to comment.