diff options
author | Antti Palosaari <crope@iki.fi> | 2012-03-14 10:27:31 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-03-19 19:41:07 -0300 |
commit | 6d535bd8829b18c6b5276d65f8f25e57dd0bcbed (patch) | |
tree | d363401deeebd2166463f01e48f1ffcb4c74ec00 /drivers/media | |
parent | be4a5e7f0e279b751a23570da583ec41ca32a34f (diff) | |
download | op-kernel-dev-6d535bd8829b18c6b5276d65f8f25e57dd0bcbed.zip op-kernel-dev-6d535bd8829b18c6b5276d65f8f25e57dd0bcbed.tar.gz |
[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 <crope@iki.fi>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/dvb/dvb-usb/af9015.c | 74 | ||||
-rw-r--r-- | 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 { |