diff mbox

Fix AF9015 Dual tuner i2c write failures

Message ID AANLkTi=rcfL_pku9hhx68C_Fb_76KsW2Yy+Oys10a7+4@mail.gmail.com (mailing list archive)
State Superseded
Headers show

Commit Message

Andrew de Quincey March 4, 2011, 9:37 p.m. UTC
None
diff mbox

Patch

diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index 31c0a0e..740d969 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -1083,6 +1083,104 @@  static int af9015_i2c_init(struct dvb_usb_device *d)
 	return ret;
 }
 
+static int af9015_lock_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
+{
+	int result;
+	struct dvb_usb_adapter *adap = fe->dvb->priv;
+	struct af9015_state *state = adap->dev->priv;
+
+	if (mutex_lock_interruptible(&adap->dev->usb_mutex))
+		return -EAGAIN;
+
+	result = state->fe_ops[adap->id].set_frontend(fe, params);
+	mutex_unlock(&adap->dev->usb_mutex);
+	return result;
+}
+                
+static int af9015_lock_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* params)
+{
+	int result;
+	struct dvb_usb_adapter *adap = fe->dvb->priv;
+	struct af9015_state *state = adap->dev->priv;
+
+	if (mutex_lock_interruptible(&adap->dev->usb_mutex))
+		return -EAGAIN;
+
+	result = state->fe_ops[adap->id].get_frontend(fe, params);
+	mutex_unlock(&adap->dev->usb_mutex);
+	return result;
+}
+                        
+static int af9015_lock_read_status(struct dvb_frontend* fe, fe_status_t* status)
+{
+	int result;
+	struct dvb_usb_adapter *adap = fe->dvb->priv;
+	struct af9015_state *state = adap->dev->priv;
+
+	if (mutex_lock_interruptible(&adap->dev->usb_mutex))
+		return -EAGAIN;
+
+	result = state->fe_ops[adap->id].read_status(fe, status);
+	mutex_unlock(&adap->dev->usb_mutex);
+	return result;
+}
+
+static int af9015_lock_read_ber(struct dvb_frontend* fe, u32* ber)
+{
+	int result;
+	struct dvb_usb_adapter *adap = fe->dvb->priv;
+	struct af9015_state *state = adap->dev->priv;
+
+	if (mutex_lock_interruptible(&adap->dev->usb_mutex))
+		return -EAGAIN;
+
+	result = state->fe_ops[adap->id].read_ber(fe, ber);
+	mutex_unlock(&adap->dev->usb_mutex);
+	return result;
+}
+
+static int af9015_lock_read_signal_strength(struct dvb_frontend* fe, u16* strength)
+{
+	int result;
+	struct dvb_usb_adapter *adap = fe->dvb->priv;
+	struct af9015_state *state = adap->dev->priv;
+
+	if (mutex_lock_interruptible(&adap->dev->usb_mutex))
+		return -EAGAIN;
+
+	result = state->fe_ops[adap->id].read_signal_strength(fe, strength);
+	mutex_unlock(&adap->dev->usb_mutex);
+	return result;
+}
+
+static int af9015_lock_read_snr(struct dvb_frontend* fe, u16* snr)
+{
+	int result;
+	struct dvb_usb_adapter *adap = fe->dvb->priv;
+	struct af9015_state *state = adap->dev->priv;
+
+	if (mutex_lock_interruptible(&adap->dev->usb_mutex))
+		return -EAGAIN;
+
+	result = state->fe_ops[adap->id].read_snr(fe, snr);
+	mutex_unlock(&adap->dev->usb_mutex);
+	return result;
+}
+
+static int af9015_lock_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
+{
+	int result;
+	struct dvb_usb_adapter *adap = fe->dvb->priv;
+	struct af9015_state *state = adap->dev->priv;
+
+	if (mutex_lock_interruptible(&adap->dev->usb_mutex))
+		return -EAGAIN;
+
+	result = state->fe_ops[adap->id].read_ucblocks(fe, ucblocks);
+	mutex_unlock(&adap->dev->usb_mutex);
+	return result;
+}
+
 static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap)
 {
 	int ret;
@@ -1116,6 +1214,22 @@  static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap)
 	/* attach demodulator */
 	adap->fe = dvb_attach(af9013_attach, &af9015_af9013_config[adap->id],
 		i2c_adap);
+		
+	memcpy(&state->fe_ops[adap->id], &adap->fe->ops, sizeof(struct dvb_frontend_ops));
+	if (adap->fe->ops.set_frontend)
+		adap->fe->ops.set_frontend = af9015_lock_set_frontend;
+	if (adap->fe->ops.get_frontend)
+		adap->fe->ops.get_frontend = af9015_lock_get_frontend;
+	if (adap->fe->ops.read_status)
+		adap->fe->ops.read_status = af9015_lock_read_status;
+	if (adap->fe->ops.read_ber)
+		adap->fe->ops.read_ber = af9015_lock_read_ber;
+	if (adap->fe->ops.read_signal_strength)
+		adap->fe->ops.read_signal_strength = af9015_lock_read_signal_strength;
+	if (adap->fe->ops.read_snr)
+		adap->fe->ops.read_snr = af9015_lock_read_snr;
+	if (adap->fe->ops.read_ucblocks)
+		adap->fe->ops.read_ucblocks = af9015_lock_read_ucblocks;
 
 	return adap->fe == NULL ? -ENODEV : 0;
 }
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h
index f20cfa6..759bb3f 100644
--- a/drivers/media/dvb/dvb-usb/af9015.h
+++ b/drivers/media/dvb/dvb-usb/af9015.h
@@ -102,6 +102,7 @@  struct af9015_state {
 	struct i2c_adapter i2c_adap; /* I2C adapter for 2nd FE */
 	u8 rc_repeat;
 	u32 rc_keycode;
+	struct dvb_frontend_ops fe_ops[2];
 };
 
 struct af9015_config {