[PATCH v2 3/3] media: uvcvideo: fix up missing AUTO_UPDATE on the OBSBOT Tiny 2
From: Michael Jordan
Date: Tue Sep 01 2026 - 20:26:15 EST
The OBSBOT Tiny 2 (3564:fef8) computes its GET_INFO capability byte per
control, but gets it wrong for the controls that matter most on a
motorised PTZ camera: CT_PANTILT_ABSOLUTE, CT_PANTILT_RELATIVE and
CT_ZOOM_ABSOLUTE all answer 0x03 -- GET and SET capable, with the
AUTOUPDATE bit clear. (The byte is not a constant stub: CT_ZOOM_RELATIVE
correctly reports 0x0f, CT_ROLL_ABSOLUTE reports 0x01.)
uvc_ctrl_get_flags() takes the flags from that byte, so it clears the
UVC_CTRL_FLAG_AUTO_UPDATE that the static uvc_ctrls[] entries set for
all three controls. Without AUTO_UPDATE nothing clears ctrl->loaded
after the first read, so uvcvideo serves them from its cache
indefinitely: VIDIOC_G_CTRL returns the last value the host commanded,
never the live one.
All three controls were verified on the hardware to change autonomously
and to report the live value on GET_CUR:
- pan/tilt position keeps changing for the seconds a commanded gimbal
move takes, and changes on its own under the camera's autonomous
subject tracking;
- zoom follows the subject under the camera's AI framing (observed
0-71% with the host issuing no zoom request, matching the vendor
status protocol's zoom report);
- the pan/tilt speed control reports the actual current speed during a
relative move (a commanded 80 reads back as 78, then the deceleration
ramp, then 0 once the gimbal reaches the end stop). Without
AUTO_UPDATE the cache would report the written speed forever.
Add fixup entries restoring AUTO_UPDATE, alongside the flags each
control already has in uvc_ctrls[], for these three controls. The fixup
replaces info->flags wholesale rather than OR-ing, so each entry spells
out the full flag set.
The camera's other AUTO_UPDATE-flagged controls were checked and
deliberately left alone: exposure, white balance and focus have working
autos, but their GET_CUR just echoes the last SET_CUR (the firmware
never reports the auto-chosen value), so AUTO_UPDATE would add USB
traffic for no benefit; there is no auto-hue; CT_ZOOM_RELATIVE already
reports AUTOUPDATE; CT_ROLL_ABSOLUTE is read-only and unmapped.
The vendor has been asked to fix the firmware (support ticket #8220,
2026-08-04); no fix is available at the time of writing.
lsusb -v (device descriptor and the Camera Terminal):
Bus 003 Device 006: ID 3564:fef8 Remo Tech Co., Ltd. OBSBOT Tiny 2
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.10
bDeviceClass 239 Miscellaneous Device
bDeviceSubClass 2 [unknown]
bDeviceProtocol 1 Interface Association
bMaxPacketSize0 64
idVendor 0x3564 Remo Tech Co., Ltd.
idProduct 0xfef8 OBSBOT Tiny 2
bcdDevice 4.09
iManufacturer 1 Remo Tech Co., Ltd.
iProduct 2 OBSBOT Tiny 2
iSerial 0
bNumConfigurations 1
[...]
VideoControl Interface Descriptor:
bLength 18
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 1
wTerminalType 0x0201 Camera Sensor
bAssocTerminal 0
iTerminal 0
wObjectiveFocalLengthMin 0
wObjectiveFocalLengthMax 0
wOcularFocalLength 0
bControlSize 3
bmControls 0x00023e3e
Auto-Exposure Mode
Auto-Exposure Priority
Exposure Time (Absolute)
Exposure Time (Relative)
Focus (Absolute)
Zoom (Absolute)
Zoom (Relative)
PanTilt (Absolute)
PanTilt (Relative)
Roll (Absolute)
Focus, Auto
Suggested-by: Ricardo Ribalda <ribalda@xxxxxxxxxxxx>
Signed-off-by: Michael Jordan <jordan.mymail@xxxxxxxxx>
---
drivers/media/usb/uvc/uvc_ctrl.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
index 64c90c380..74f6e8039 100644
--- a/drivers/media/usb/uvc/uvc_ctrl.c
+++ b/drivers/media/usb/uvc/uvc_ctrl.c
@@ -2876,6 +2876,26 @@ static bool uvc_ctrl_fixup_flags(struct uvc_device *dev,
UVC_CTRL_FLAG_GET_MIN | UVC_CTRL_FLAG_GET_MAX |
UVC_CTRL_FLAG_GET_DEF | UVC_CTRL_FLAG_SET_CUR |
UVC_CTRL_FLAG_AUTO_UPDATE },
+ /*
+ * OBSBOT Tiny 2: GET_INFO reports GET|SET without AUTOUPDATE
+ * for the pan/tilt and zoom controls, clearing the AUTO_UPDATE
+ * the driver's own control table sets for them. The device
+ * moves all three on its own (gimbal moves take seconds, and
+ * its autonomous subject tracking pans, tilts and zooms with
+ * no host involvement) and reports the live values on GET_CUR.
+ */
+ { { USB_DEVICE(0x3564, 0xfef8) }, 1,
+ UVC_CT_PANTILT_ABSOLUTE_CONTROL,
+ UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_RANGE |
+ UVC_CTRL_FLAG_RESTORE | UVC_CTRL_FLAG_AUTO_UPDATE },
+ { { USB_DEVICE(0x3564, 0xfef8) }, 1,
+ UVC_CT_PANTILT_RELATIVE_CONTROL,
+ UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_RANGE |
+ UVC_CTRL_FLAG_AUTO_UPDATE },
+ { { USB_DEVICE(0x3564, 0xfef8) }, 1,
+ UVC_CT_ZOOM_ABSOLUTE_CONTROL,
+ UVC_CTRL_FLAG_SET_CUR | UVC_CTRL_FLAG_GET_RANGE |
+ UVC_CTRL_FLAG_RESTORE | UVC_CTRL_FLAG_AUTO_UPDATE },
};
unsigned int i;
--
2.43.0