[PATCH] media: uvcvideo: Add UVC_QUIRK_CTL_MSG_DELAY_1M for HIK camera

From: Kuangyi Chiang

Date: Wed Oct 28 2026 - 23:31:31 EST


UVC control requests issued when preparing a video stream sometimes
time out on the HIK 1080P Camera (2bdf:0280):

[ 48.363671] uvcvideo: Found UVC 1.00 device HIK 1080P Camera (2bdf:0280)
[ 53.465662] uvcvideo: Failed to set UVC probe control : -110 (exp. 26).
[ 58.585653] uvcvideo: Failed to query (129) UVC probe control : -110 (exp. 26).
[ 58.592967] uvcvideo: Failed to initialize the device (-5).

Adding a 1ms delay after each control message avoids the issue.

Introduce UVC_QUIRK_CTL_MSG_DELAY_1M for this device.

Signed-off-by: Kuangyi Chiang <ki.chiang65@xxxxxxxxx>
---
drivers/media/usb/uvc/uvc_driver.c | 9 +++++++++
drivers/media/usb/uvc/uvc_video.c | 10 ++++++++--
drivers/media/usb/uvc/uvcvideo.h | 1 +
3 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
index e289cc7..c720d75 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -3162,6 +3162,15 @@ static const struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_INFO_QUIRK(UVC_QUIRK_FORCE_BPP) },
+ /* HIK 1080P Camera */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x2bdf,
+ .idProduct = 0x0280,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_CTL_MSG_DELAY_1M) },
/* Insta360 Link */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
diff --git a/drivers/media/usb/uvc/uvc_video.c b/drivers/media/usb/uvc/uvc_video.c
index fc3536a..4667f86 100644
--- a/drivers/media/usb/uvc/uvc_video.c
+++ b/drivers/media/usb/uvc/uvc_video.c
@@ -35,13 +35,19 @@ static int __uvc_query_ctrl(struct uvc_device *dev, u8 query, u8 unit,
{
u8 type = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
unsigned int pipe;
+ int ret;

pipe = (query & 0x80) ? usb_rcvctrlpipe(dev->udev, 0)
: usb_sndctrlpipe(dev->udev, 0);
type |= (query & 0x80) ? USB_DIR_IN : USB_DIR_OUT;

- return usb_control_msg(dev->udev, pipe, query, type, cs << 8,
- unit << 8 | intfnum, data, size, timeout);
+ ret = usb_control_msg(dev->udev, pipe, query, type, cs << 8,
+ unit << 8 | intfnum, data, size, timeout);
+
+ if (dev->quirks & UVC_QUIRK_CTL_MSG_DELAY_1M)
+ usleep_range(1000, 2000);
+
+ return ret;
}

static const char *uvc_query_name(u8 query)
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index b6bcee4..1426d14 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -81,6 +81,7 @@
#define UVC_QUIRK_INVALID_DEVICE_SOF 0x00010000
#define UVC_QUIRK_MJPEG_NO_EOF 0x00020000
#define UVC_QUIRK_MSXU_META 0x00040000
+#define UVC_QUIRK_CTL_MSG_DELAY_1M 0x00080000

/* Format flags */
#define UVC_FMT_FLAG_COMPRESSED 0x00000001
--
2.25.1