mirror of
https://github.com/torvalds/linux.git
synced 2024-11-27 22:51:35 +00:00
[media] gspca: Fix ov519 i2c r/w not working when connected to a xhci host
Fix the ov519 driver not working (unable to talk to the sensor) when plugged into a xhci host. The root cause here is that uhci/ohci/ehci hosts typically will send any pending async requests every milli-second and then go to sleep for the rest if the milli-second, where as xhci hosts send them immediately, causing things to go too fast for the ov519 bridge. This commit adds a few delays fixing this. Signed-off-by: Wesley Post <pa4wdh@xs4all.nl> [hdegoede@redhat.com: Also add delays to w996Xcf.c, as that needs them too] Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
This commit is contained in:
parent
5c915c6876
commit
f7c7ac480d
@ -2042,6 +2042,9 @@ static void reg_w(struct sd *sd, u16 index, u16 value)
|
||||
if (sd->gspca_dev.usb_err < 0)
|
||||
return;
|
||||
|
||||
/* Avoid things going to fast for the bridge with a xhci host */
|
||||
udelay(150);
|
||||
|
||||
switch (sd->bridge) {
|
||||
case BRIDGE_OV511:
|
||||
case BRIDGE_OV511PLUS:
|
||||
@ -2103,6 +2106,8 @@ static int reg_r(struct sd *sd, u16 index)
|
||||
req = 1;
|
||||
}
|
||||
|
||||
/* Avoid things going to fast for the bridge with a xhci host */
|
||||
udelay(150);
|
||||
ret = usb_control_msg(sd->gspca_dev.dev,
|
||||
usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
|
||||
req,
|
||||
@ -2131,6 +2136,8 @@ static int reg_r8(struct sd *sd,
|
||||
if (sd->gspca_dev.usb_err < 0)
|
||||
return -1;
|
||||
|
||||
/* Avoid things going to fast for the bridge with a xhci host */
|
||||
udelay(150);
|
||||
ret = usb_control_msg(sd->gspca_dev.dev,
|
||||
usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
|
||||
1, /* REQ_IO */
|
||||
@ -2187,6 +2194,8 @@ static void ov518_reg_w32(struct sd *sd, u16 index, u32 value, int n)
|
||||
|
||||
*((__le32 *) sd->gspca_dev.usb_buf) = __cpu_to_le32(value);
|
||||
|
||||
/* Avoid things going to fast for the bridge with a xhci host */
|
||||
udelay(150);
|
||||
ret = usb_control_msg(sd->gspca_dev.dev,
|
||||
usb_sndctrlpipe(sd->gspca_dev.dev, 0),
|
||||
1 /* REG_IO */,
|
||||
|
@ -79,6 +79,8 @@ static void w9968cf_write_fsb(struct sd *sd, u16* data)
|
||||
value = *data++;
|
||||
memcpy(sd->gspca_dev.usb_buf, data, 6);
|
||||
|
||||
/* Avoid things going to fast for the bridge with a xhci host */
|
||||
udelay(150);
|
||||
ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
|
||||
USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
|
||||
value, 0x06, sd->gspca_dev.usb_buf, 6, 500);
|
||||
@ -99,6 +101,9 @@ static void w9968cf_write_sb(struct sd *sd, u16 value)
|
||||
if (sd->gspca_dev.usb_err < 0)
|
||||
return;
|
||||
|
||||
/* Avoid things going to fast for the bridge with a xhci host */
|
||||
udelay(150);
|
||||
|
||||
/* We don't use reg_w here, as that would cause all writes when
|
||||
bitbanging i2c to be logged, making the logs impossible to read */
|
||||
ret = usb_control_msg(sd->gspca_dev.dev,
|
||||
@ -126,6 +131,9 @@ static int w9968cf_read_sb(struct sd *sd)
|
||||
if (sd->gspca_dev.usb_err < 0)
|
||||
return -1;
|
||||
|
||||
/* Avoid things going to fast for the bridge with a xhci host */
|
||||
udelay(150);
|
||||
|
||||
/* We don't use reg_r here, as the w9968cf is special and has 16
|
||||
bit registers instead of 8 bit */
|
||||
ret = usb_control_msg(sd->gspca_dev.dev,
|
||||
|
Loading…
Reference in New Issue
Block a user