Re: [PATCH] af9013 frontend tuner bus lock
2011/9/28 tvboxspy <tvboxspy@xxxxxxxxx>:
> Frontend bus lock for af9015 devices.
>
> Last week, I aqcuired a dual KWorld PlusTV Dual DVB-T Stick (DVB-T 399U).
>
> The lock is intended for dual frontends that share the same tuner I2C address
> to stop either frontend sending data while any gate is open. The patch
> should have no effect on single devices or multiple single devices, well
> not on the ones I have!
>
> It also delays read_status call backs being sent while either gate is open, a
> mostly like cause of corruption.
>
> The lock also covers the attachment process of the tuner in case there is any
> race condition, although unlikely.
>
> Points about troubles with Myth TV;
> Streaming corruptions are more likely to appear from the I2C noise generated
> from setting either frontend. Afatech love their bits as bytes:-)
>
> Latest version of Myth TV appears to have a bug where you can't select the second
> frontend independently and when it does it tunes to the same frequency as
> the first frontend!
>
> Signed-off-by: Malcolm Priestley <tvboxspy@xxxxxxxxx>
> ---
> drivers/media/dvb/dvb-usb/af9015.c | 7 ++++++-
> drivers/media/dvb/frontends/af9013.c | 13 ++++++++++++-
> drivers/media/dvb/frontends/af9013.h | 5 +++--
> 3 files changed, 21 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
> index c6c275b..0089858 100644
> --- a/drivers/media/dvb/dvb-usb/af9015.c
> +++ b/drivers/media/dvb/dvb-usb/af9015.c
> @@ -43,6 +43,7 @@ MODULE_PARM_DESC(remote, "select remote");
> DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
>
> static DEFINE_MUTEX(af9015_usb_mutex);
> +static DEFINE_MUTEX(af9015_fe_mutex);
>
> static struct af9015_config af9015_config;
> static struct dvb_usb_device_properties af9015_properties[3];
> @@ -1114,7 +1115,7 @@ static int af9015_af9013_frontend_attach(struct dvb_usb_adapter *adap)
>
> /* attach demodulator */
> adap->fe_adap[0].fe = dvb_attach(af9013_attach, &af9015_af9013_config[adap->id],
> - &adap->dev->i2c_adap);
> + &adap->dev->i2c_adap, &af9015_fe_mutex);
>
> return adap->fe_adap[0].fe == NULL ? -ENODEV : 0;
> }
> @@ -1187,6 +1188,9 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
> int ret;
> deb_info("%s:\n", __func__);
>
> + if (mutex_lock_interruptible(&af9015_fe_mutex) < 0)
> + return -EAGAIN;
> +
> switch (af9015_af9013_config[adap->id].tuner) {
> case AF9013_TUNER_MT2060:
> case AF9013_TUNER_MT2060_2:
> @@ -1242,6 +1246,7 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
> err("Unknown tuner id:%d",
> af9015_af9013_config[adap->id].tuner);
> }
> + mutex_unlock(&af9015_fe_mutex);
> return ret;
> }
>
> diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c
> index 345311c..b220a87 100644
> --- a/drivers/media/dvb/frontends/af9013.c
> +++ b/drivers/media/dvb/frontends/af9013.c
> @@ -50,6 +50,7 @@ struct af9013_state {
> u16 snr;
> u32 frequency;
> unsigned long next_statistics_check;
> + struct mutex *fe_mutex;
> };
>
> static u8 regmask[8] = { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
> @@ -630,9 +631,14 @@ static int af9013_set_frontend(struct dvb_frontend *fe,
> state->frequency = params->frequency;
>
> /* program tuner */
> + if (mutex_lock_interruptible(state->fe_mutex) < 0)
> + return -EAGAIN;
> +
> if (fe->ops.tuner_ops.set_params)
> fe->ops.tuner_ops.set_params(fe, params);
>
> + mutex_unlock(state->fe_mutex);
> +
> /* program CFOE coefficients */
> ret = af9013_set_coeff(state, params->u.ofdm.bandwidth);
> if (ret)
> @@ -1038,6 +1044,9 @@ static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status)
> u8 tmp;
> *status = 0;
>
> + if (mutex_lock_interruptible(state->fe_mutex) < 0)
> + return -EAGAIN;
> +
> /* MPEG2 lock */
> ret = af9013_read_reg_bits(state, 0xd507, 6, 1, &tmp);
> if (ret)
> @@ -1086,6 +1095,7 @@ static int af9013_read_status(struct dvb_frontend *fe, fe_status_t *status)
> ret = af9013_update_statistics(fe);
>
> error:
> + mutex_unlock(state->fe_mutex);
> return ret;
> }
>
> @@ -1446,7 +1456,7 @@ static void af9013_release(struct dvb_frontend *fe)
> static struct dvb_frontend_ops af9013_ops;
>
> struct dvb_frontend *af9013_attach(const struct af9013_config *config,
> - struct i2c_adapter *i2c)
> + struct i2c_adapter *i2c, struct mutex *fe_mutex)
> {
> int ret;
> struct af9013_state *state = NULL;
> @@ -1459,6 +1469,7 @@ struct dvb_frontend *af9013_attach(const struct af9013_config *config,
>
> /* setup the state */
> state->i2c = i2c;
> + state->fe_mutex = fe_mutex;
> memcpy(&state->config, config, sizeof(struct af9013_config));
>
> /* download firmware */
> diff --git a/drivers/media/dvb/frontends/af9013.h b/drivers/media/dvb/frontends/af9013.h
> index e53d873..95c966a 100644
> --- a/drivers/media/dvb/frontends/af9013.h
> +++ b/drivers/media/dvb/frontends/af9013.h
> @@ -96,10 +96,11 @@ struct af9013_config {
> #if defined(CONFIG_DVB_AF9013) || \
> (defined(CONFIG_DVB_AF9013_MODULE) && defined(MODULE))
> extern struct dvb_frontend *af9013_attach(const struct af9013_config *config,
> - struct i2c_adapter *i2c);
> + struct i2c_adapter *i2c, struct mutex *fe_mutex);
> #else
> static inline struct dvb_frontend *af9013_attach(
> -const struct af9013_config *config, struct i2c_adapter *i2c)
> + const struct af9013_config *config, struct i2c_adapter *i2,
> + struct mutex *fe_mutex)
> {
> printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
> return NULL;
> --
> 1.7.5.4
>
>
Thanks!!! I have same device, I apply the patch to the s2-liplianin
branch and it works well.
Two days on MythTV and there is no pixeled playback and not I2C
messges on dmesg.
Thank you very much, I was waiting long for this fix.
Kind regards.
--
Josu Lazkano
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
[Linux Input]
[Video for Linux]
[Mplayer Users]
[Linux USB Devel]
[Linux Audio Users]
[Photos]
[Yosemite Photos]
[Linux Kernel]
[Linux SCSI]
[XFree86]
[Devices]
[Yosemite Backpacking]