[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:
Wesley Post 2016-02-29 15:39:10 -03:00 committed by Mauro Carvalho Chehab
parent 5c915c6876
commit f7c7ac480d
2 changed files with 17 additions and 0 deletions

View File

@ -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 */,

View File

@ -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,