From 6d535bd8829b18c6b5276d65f8f25e57dd0bcbed Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Wed, 14 Mar 2012 10:27:31 -0300 Subject: [PATCH] [media] af9015: fix i2c failures for dual-tuner devices - part 2 Some changes for previous patch I liked to do. Just move tuner init and sleep to own functions from the demod init and sleep functions. Functionality remains still almost the same. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/af9015.c | 74 +++++++++++++++++++++++--------------- drivers/media/dvb/dvb-usb/af9015.h | 4 +-- 2 files changed, 48 insertions(+), 30 deletions(-) diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c index 9307b4ca..7e70ea5 100644 --- a/drivers/media/dvb/dvb-usb/af9015.c +++ b/drivers/media/dvb/dvb-usb/af9015.c @@ -1141,18 +1141,7 @@ static int af9015_af9013_init(struct dvb_frontend *fe) return -EAGAIN; ret = priv->init[adap->id](fe); - if (ret) - goto err_unlock; - - if (priv->tuner_ops_init[adap->id]) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - ret = priv->tuner_ops_init[adap->id](fe); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - } -err_unlock: mutex_unlock(&adap->dev->usb_mutex); return ret; @@ -1168,24 +1157,48 @@ static int af9015_af9013_sleep(struct dvb_frontend *fe) if (mutex_lock_interruptible(&adap->dev->usb_mutex)) return -EAGAIN; - if (priv->tuner_ops_sleep[adap->id]) { - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 1); - ret = priv->tuner_ops_sleep[adap->id](fe); - if (fe->ops.i2c_gate_ctrl) - fe->ops.i2c_gate_ctrl(fe, 0); - if (ret) - goto err_unlock; - } - ret = priv->sleep[adap->id](fe); -err_unlock: mutex_unlock(&adap->dev->usb_mutex); return ret; } +/* override tuner callbacks for resource locking */ +static int af9015_tuner_init(struct dvb_frontend *fe) +{ + int ret; + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct af9015_state *priv = adap->dev->priv; + + if (mutex_lock_interruptible(&adap->dev->usb_mutex)) + return -EAGAIN; + + ret = priv->tuner_init[adap->id](fe); + + mutex_unlock(&adap->dev->usb_mutex); + + return ret; +} + +/* override tuner callbacks for resource locking */ +static int af9015_tuner_sleep(struct dvb_frontend *fe) +{ + int ret; + struct dvb_usb_adapter *adap = fe->dvb->priv; + struct af9015_state *priv = adap->dev->priv; + + if (mutex_lock_interruptible(&adap->dev->usb_mutex)) + return -EAGAIN; + + ret = priv->tuner_sleep[adap->id](fe); + + mutex_unlock(&adap->dev->usb_mutex); + + return ret; +} + + static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap) { int ret; @@ -1364,13 +1377,18 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap) af9015_af9013_config[adap->id].tuner); } - state->tuner_ops_sleep[adap->id] = - adap->fe_adap[0].fe->ops.tuner_ops.sleep; - adap->fe_adap[0].fe->ops.tuner_ops.sleep = 0; + if (adap->fe_adap[0].fe->ops.tuner_ops.init) { + state->tuner_init[adap->id] = + adap->fe_adap[0].fe->ops.tuner_ops.init; + adap->fe_adap[0].fe->ops.tuner_ops.init = af9015_tuner_init; + } + + if (adap->fe_adap[0].fe->ops.tuner_ops.sleep) { + state->tuner_sleep[adap->id] = + adap->fe_adap[0].fe->ops.tuner_ops.sleep; + adap->fe_adap[0].fe->ops.tuner_ops.sleep = af9015_tuner_sleep; + } - state->tuner_ops_init[adap->id] = - adap->fe_adap[0].fe->ops.tuner_ops.init; - adap->fe_adap[0].fe->ops.tuner_ops.init = 0; return ret; } diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h index ee2ec5b..2f68419 100644 --- a/drivers/media/dvb/dvb-usb/af9015.h +++ b/drivers/media/dvb/dvb-usb/af9015.h @@ -108,8 +108,8 @@ struct af9015_state { int (*read_status[2]) (struct dvb_frontend *fe, fe_status_t *status); int (*init[2]) (struct dvb_frontend *fe); int (*sleep[2]) (struct dvb_frontend *fe); - int (*tuner_ops_init[2]) (struct dvb_frontend *fe); - int (*tuner_ops_sleep[2]) (struct dvb_frontend *fe); + int (*tuner_init[2]) (struct dvb_frontend *fe); + int (*tuner_sleep[2]) (struct dvb_frontend *fe); }; struct af9015_config { -- 2.7.4