[media] gspca: Fix ov519 i2c r/w not working when connected to a xhci host
authorWesley Post <pa4wdh@xs4all.nl>
Mon, 29 Feb 2016 18:39:10 +0000 (15:39 -0300)
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>
Tue, 1 Mar 2016 13:40:14 +0000 (10:40 -0300)
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>
drivers/media/usb/gspca/ov519.c
drivers/media/usb/gspca/w996Xcf.c

index c95f32a0c02b4283d0f4c66b253e0a7e402f392d..eb668e71a5e8ed85ea427a7ce8d70404091902e2 100644 (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 */,
index fb9fe2ef3a6f60059b7f3fee4e89254b4869d52f..896f1b2b91793907a62d751f178c30001da683bc 100644 (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,