From patchwork Fri Mar 4 21:37:53 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew de Quincey X-Patchwork-Id: 610271 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p24LbuXi008107 for ; Fri, 4 Mar 2011 21:37:56 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760215Ab1CDVhz (ORCPT ); Fri, 4 Mar 2011 16:37:55 -0500 Received: from mail-wy0-f174.google.com ([74.125.82.174]:62722 "EHLO mail-wy0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1760195Ab1CDVhy (ORCPT ); Fri, 4 Mar 2011 16:37:54 -0500 Received: by wyg36 with SMTP id 36so2529524wyg.19 for ; Fri, 04 Mar 2011 13:37:53 -0800 (PST) MIME-Version: 1.0 Received: by 10.216.16.100 with SMTP id g78mr981231weg.55.1299274673304; Fri, 04 Mar 2011 13:37:53 -0800 (PST) Received: by 10.216.3.13 with HTTP; Fri, 4 Mar 2011 13:37:53 -0800 (PST) X-Originating-IP: [82.71.49.12] Date: Fri, 4 Mar 2011 21:37:53 +0000 X-Google-Sender-Auth: ImpNz3Qu5oNdxpL_6sSB7fB_YLw Message-ID: Subject: [patch] Fix AF9015 Dual tuner i2c write failures From: Andrew de Quincey To: linux-media@vger.kernel.org Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Fri, 04 Mar 2011 21:37:56 +0000 (UTC) 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 {