Commit f7c7ac48 authored by Wesley Post's avatar Wesley Post Committed by Mauro Carvalho Chehab

[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: default avatarWesley Post <pa4wdh@xs4all.nl>
[hdegoede@redhat.com: Also add delays to w996Xcf.c, as that needs them too]
Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 5c915c68
...@@ -2042,6 +2042,9 @@ static void reg_w(struct sd *sd, u16 index, u16 value) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment