[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)
|
if (sd->gspca_dev.usb_err < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* Avoid things going to fast for the bridge with a xhci host */
|
||||||
|
udelay(150);
|
||||||
|
|
||||||
switch (sd->bridge) {
|
switch (sd->bridge) {
|
||||||
case BRIDGE_OV511:
|
case BRIDGE_OV511:
|
||||||
case BRIDGE_OV511PLUS:
|
case BRIDGE_OV511PLUS:
|
||||||
@ -2103,6 +2106,8 @@ static int reg_r(struct sd *sd, u16 index)
|
|||||||
req = 1;
|
req = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Avoid things going to fast for the bridge with a xhci host */
|
||||||
|
udelay(150);
|
||||||
ret = usb_control_msg(sd->gspca_dev.dev,
|
ret = usb_control_msg(sd->gspca_dev.dev,
|
||||||
usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
|
usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
|
||||||
req,
|
req,
|
||||||
@ -2131,6 +2136,8 @@ static int reg_r8(struct sd *sd,
|
|||||||
if (sd->gspca_dev.usb_err < 0)
|
if (sd->gspca_dev.usb_err < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
/* Avoid things going to fast for the bridge with a xhci host */
|
||||||
|
udelay(150);
|
||||||
ret = usb_control_msg(sd->gspca_dev.dev,
|
ret = usb_control_msg(sd->gspca_dev.dev,
|
||||||
usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
|
usb_rcvctrlpipe(sd->gspca_dev.dev, 0),
|
||||||
1, /* REQ_IO */
|
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);
|
*((__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,
|
ret = usb_control_msg(sd->gspca_dev.dev,
|
||||||
usb_sndctrlpipe(sd->gspca_dev.dev, 0),
|
usb_sndctrlpipe(sd->gspca_dev.dev, 0),
|
||||||
1 /* REG_IO */,
|
1 /* REG_IO */,
|
||||||
|
@ -79,6 +79,8 @@ static void w9968cf_write_fsb(struct sd *sd, u16* data)
|
|||||||
value = *data++;
|
value = *data++;
|
||||||
memcpy(sd->gspca_dev.usb_buf, data, 6);
|
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,
|
ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0,
|
||||||
USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
|
USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
|
||||||
value, 0x06, sd->gspca_dev.usb_buf, 6, 500);
|
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)
|
if (sd->gspca_dev.usb_err < 0)
|
||||||
return;
|
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
|
/* 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 */
|
bitbanging i2c to be logged, making the logs impossible to read */
|
||||||
ret = usb_control_msg(sd->gspca_dev.dev,
|
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)
|
if (sd->gspca_dev.usb_err < 0)
|
||||||
return -1;
|
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
|
/* We don't use reg_r here, as the w9968cf is special and has 16
|
||||||
bit registers instead of 8 bit */
|
bit registers instead of 8 bit */
|
||||||
ret = usb_control_msg(sd->gspca_dev.dev,
|
ret = usb_control_msg(sd->gspca_dev.dev,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user