* [PATCH v2] [media] af9035: fix for MXL5007T devices with I2C read issues
@ 2016-05-12 10:47 Alessandro Radicati
2016-06-01 7:03 ` Antti Palosaari
0 siblings, 1 reply; 2+ messages in thread
From: Alessandro Radicati @ 2016-05-12 10:47 UTC (permalink / raw)
To: crope, areguero; +Cc: linux-media
The MXL5007T tuner will lock-up on some devices after an I2C
read transaction. This patch works around this issue by inhibiting such
operations and emulating a 0x00 response. The workaround is only applied to
USB devices known to exhibit this flaw.
Signed-off-by: Alessandro Radicati <alessandro@radicati.net>
---
drivers/media/usb/dvb-usb-v2/af9035.c | 21 +++++++++++++++++++++
drivers/media/usb/dvb-usb-v2/af9035.h | 1 +
2 files changed, 22 insertions(+)
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
index 2638e32..06e300e 100644
--- a/drivers/media/usb/dvb-usb-v2/af9035.c
+++ b/drivers/media/usb/dvb-usb-v2/af9035.c
@@ -348,6 +348,9 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
ret = af9035_rd_regs(d, reg, &msg[1].buf[0],
msg[1].len);
+ } else if (state->no_read) {
+ memset(msg[1].buf, 0, msg[1].len);
+ ret = 0;
} else {
/* I2C write + read */
u8 buf[MAX_XFER_SIZE];
@@ -421,6 +424,9 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
if (msg[0].len > 40) {
/* TODO: correct limits > 40 */
ret = -EOPNOTSUPP;
+ } else if (state->no_read) {
+ memset(msg[0].buf, 0, msg[0].len);
+ ret = 0;
} else {
/* I2C read */
u8 buf[5];
@@ -962,6 +968,21 @@ skip_eeprom:
state->af9033_config[i].clock = clock_lut_af9035[tmp];
}
+ state->no_read = false;
+ /* Some MXL5007T devices cannot properly handle tuner I2C read ops. */
+ if (state->af9033_config[0].tuner == AF9033_TUNER_MXL5007T &&
+ le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_AVERMEDIA)
+
+ switch (le16_to_cpu(d->udev->descriptor.idProduct)) {
+ case USB_PID_AVERMEDIA_A867:
+ case USB_PID_AVERMEDIA_TWINSTAR:
+ dev_info(&d->udev->dev,
+ "%s: Device may have issues with I2C read operations. Enabling fix.\n",
+ KBUILD_MODNAME);
+ state->no_read = true;
+ break;
+ }
+
return 0;
err:
diff --git a/drivers/media/usb/dvb-usb-v2/af9035.h b/drivers/media/usb/dvb-usb-v2/af9035.h
index 89e629a..c91d1a3 100644
--- a/drivers/media/usb/dvb-usb-v2/af9035.h
+++ b/drivers/media/usb/dvb-usb-v2/af9035.h
@@ -62,6 +62,7 @@ struct state {
u8 chip_version;
u16 chip_type;
u8 dual_mode:1;
+ u8 no_read:1;
u16 eeprom_addr;
u8 af9033_i2c_addr[2];
struct af9033_config af9033_config[2];
--
2.7.4
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH v2] [media] af9035: fix for MXL5007T devices with I2C read issues
2016-05-12 10:47 [PATCH v2] [media] af9035: fix for MXL5007T devices with I2C read issues Alessandro Radicati
@ 2016-06-01 7:03 ` Antti Palosaari
0 siblings, 0 replies; 2+ messages in thread
From: Antti Palosaari @ 2016-06-01 7:03 UTC (permalink / raw)
To: Alessandro Radicati, areguero; +Cc: linux-media
Applied for 4.8, thanks!
Antti
On 05/12/2016 01:47 PM, Alessandro Radicati wrote:
> The MXL5007T tuner will lock-up on some devices after an I2C
> read transaction. This patch works around this issue by inhibiting such
> operations and emulating a 0x00 response. The workaround is only applied to
> USB devices known to exhibit this flaw.
>
> Signed-off-by: Alessandro Radicati <alessandro@radicati.net>
> ---
> drivers/media/usb/dvb-usb-v2/af9035.c | 21 +++++++++++++++++++++
> drivers/media/usb/dvb-usb-v2/af9035.h | 1 +
> 2 files changed, 22 insertions(+)
>
> diff --git a/drivers/media/usb/dvb-usb-v2/af9035.c b/drivers/media/usb/dvb-usb-v2/af9035.c
> index 2638e32..06e300e 100644
> --- a/drivers/media/usb/dvb-usb-v2/af9035.c
> +++ b/drivers/media/usb/dvb-usb-v2/af9035.c
> @@ -348,6 +348,9 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
>
> ret = af9035_rd_regs(d, reg, &msg[1].buf[0],
> msg[1].len);
> + } else if (state->no_read) {
> + memset(msg[1].buf, 0, msg[1].len);
> + ret = 0;
> } else {
> /* I2C write + read */
> u8 buf[MAX_XFER_SIZE];
> @@ -421,6 +424,9 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
> if (msg[0].len > 40) {
> /* TODO: correct limits > 40 */
> ret = -EOPNOTSUPP;
> + } else if (state->no_read) {
> + memset(msg[0].buf, 0, msg[0].len);
> + ret = 0;
> } else {
> /* I2C read */
> u8 buf[5];
> @@ -962,6 +968,21 @@ skip_eeprom:
> state->af9033_config[i].clock = clock_lut_af9035[tmp];
> }
>
> + state->no_read = false;
> + /* Some MXL5007T devices cannot properly handle tuner I2C read ops. */
> + if (state->af9033_config[0].tuner == AF9033_TUNER_MXL5007T &&
> + le16_to_cpu(d->udev->descriptor.idVendor) == USB_VID_AVERMEDIA)
> +
> + switch (le16_to_cpu(d->udev->descriptor.idProduct)) {
> + case USB_PID_AVERMEDIA_A867:
> + case USB_PID_AVERMEDIA_TWINSTAR:
> + dev_info(&d->udev->dev,
> + "%s: Device may have issues with I2C read operations. Enabling fix.\n",
> + KBUILD_MODNAME);
> + state->no_read = true;
> + break;
> + }
> +
> return 0;
>
> err:
> diff --git a/drivers/media/usb/dvb-usb-v2/af9035.h b/drivers/media/usb/dvb-usb-v2/af9035.h
> index 89e629a..c91d1a3 100644
> --- a/drivers/media/usb/dvb-usb-v2/af9035.h
> +++ b/drivers/media/usb/dvb-usb-v2/af9035.h
> @@ -62,6 +62,7 @@ struct state {
> u8 chip_version;
> u16 chip_type;
> u8 dual_mode:1;
> + u8 no_read:1;
> u16 eeprom_addr;
> u8 af9033_i2c_addr[2];
> struct af9033_config af9033_config[2];
>
--
http://palosaari.fi/
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2016-06-01 7:03 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-12 10:47 [PATCH v2] [media] af9035: fix for MXL5007T devices with I2C read issues Alessandro Radicati
2016-06-01 7:03 ` Antti Palosaari
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).