[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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]

Add to Google Powered by Linux