mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 0/3] media: uvcvideo: live pan/tilt/zoom readback on the OBSBOT Tiny 2
@ 2026-09-02  0:25 Michael Jordan
  2026-09-02  0:25 ` [PATCH v2 1/3] media: uvcvideo: report AUTO_UPDATE controls as volatile Michael Jordan
                   ` (3 more replies)
  0 siblings, 4 replies; 20+ messages in thread
From: Michael Jordan @ 2026-09-02  0:25 UTC (permalink / raw)
  To: Laurent Pinchart, Hans de Goede, Ricardo Ribalda
  Cc: Mauro Carvalho Chehab, Hans Verkuil, linux-media, linux-kernel,
	Michael Jordan

The OBSBOT Tiny 2's GET_INFO strips the AUTOUPDATE bit from its pan,
tilt and zoom controls, so uvcvideo caches them and userspace can never
observe the actuator's live state. This series reports AUTO_UPDATE
controls as volatile to userspace, generalises the existing XU flags
fixup table to all controls, and adds entries for the three affected
controls on this camera.

Changes in v2 (following Ricardo's review of v1 [1]):

- Patch 1: unchanged; picked up Ricardo's Reviewed-by.
- Patch 2: uvc_ctrl_fixup_flags() now returns bool and runs at the
  start of uvc_ctrl_get_flags(), before the allocation, skipping the
  GET_INFO query entirely for controls the table covers (Ricardo).
- Patch 3: as asked, I checked whether the camera's other
  AUTO_UPDATE-flagged controls suffer the same bug. Two more do:
  CT_PANTILT_RELATIVE and CT_ZOOM_ABSOLUTE, both verified on hardware
  to change autonomously and report live values on GET_CUR; entries
  added for both. Exposure, white balance and focus turned out to be
  write-only on this firmware (their autos work, but GET_CUR echoes the
  last SET_CUR), so they gain nothing from AUTO_UPDATE and were left
  alone; details in the commit message. The commit message also no
  longer claims the capability byte is the same for every control --
  probing every control showed it is computed per control, just wrong
  for the PTZ ones. Dropped Ricardo's Reviewed-by since the patch
  changed materially.

The full lsusb -v output was posted in reply to v1's patch 3, in the
thread at [1].

[1] https://lore.kernel.org/linux-media/20260828152557.653475-1-jordan.mymail@gmail.com/

Michael Jordan (3):
  media: uvcvideo: report AUTO_UPDATE controls as volatile
  media: uvcvideo: generalise the XU flags fixup to all controls
  media: uvcvideo: fix up missing AUTO_UPDATE on the OBSBOT Tiny 2

 drivers/media/usb/uvc/uvc_ctrl.c | 122 ++++++++++++++++++++-----------
 1 file changed, 81 insertions(+), 41 deletions(-)

-- 
2.43.0


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v2 1/3] media: uvcvideo: report AUTO_UPDATE controls as volatile
  2026-09-02  0:25 [PATCH v2 0/3] media: uvcvideo: live pan/tilt/zoom readback on the OBSBOT Tiny 2 Michael Jordan
@ 2026-09-02  0:25 ` Michael Jordan
  2026-09-02  0:25 ` [PATCH v2 2/3] media: uvcvideo: generalise the XU flags fixup to all controls Michael Jordan
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 20+ messages in thread
From: Michael Jordan @ 2026-09-02  0:25 UTC (permalink / raw)
  To: Laurent Pinchart, Hans de Goede, Ricardo Ribalda
  Cc: Mauro Carvalho Chehab, Hans Verkuil, linux-media, linux-kernel,
	Michael Jordan

A control with UVC_CTRL_FLAG_AUTO_UPDATE is one whose value the device
changes on its own: the driver never trusts its cached value for it,
re-reading the device on every VIDIOC_G_EXT_CTRLS (the rollback at the
end of the ioctl runs uvc_ctrl_commit_entity(), which clears ctrl->loaded
for these controls) and re-reading it after each write. That is exactly
what V4L2_CTRL_FLAG_VOLATILE describes to userspace, but the driver never
reported it, so applications had no way to know that the value they read
can change under them and that a fresh read is worth issuing.

Report V4L2_CTRL_FLAG_VOLATILE for AUTO_UPDATE controls. The uAPI
documents writes to a volatile control as ignored unless
V4L2_CTRL_FLAG_EXECUTE_ON_WRITE is also set, and this driver sends every
write of a writable control to the device, so report EXECUTE_ON_WRITE
alongside it whenever the control is settable.

Suggested-by: Ricardo Ribalda <ribalda@chromium.org>
Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
Signed-off-by: Michael Jordan <jordan.mymail@gmail.com>
---
 drivers/media/usb/uvc/uvc_ctrl.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
index 3ca108b83..aceb26310 100644
--- a/drivers/media/usb/uvc/uvc_ctrl.c
+++ b/drivers/media/usb/uvc/uvc_ctrl.c
@@ -1840,6 +1840,17 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
 	if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX) &&
 	    (ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN))
 		v4l2_ctrl->flags |= V4L2_CTRL_FLAG_HAS_WHICH_MIN_MAX;
+	if (ctrl->info.flags & UVC_CTRL_FLAG_AUTO_UPDATE) {
+		v4l2_ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE;
+		/*
+		 * Writes to a volatile control are documented to be ignored
+		 * unless EXECUTE_ON_WRITE is also reported. The driver sends
+		 * every write of a writable control to the device, so report
+		 * the flag accordingly.
+		 */
+		if (ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR)
+			v4l2_ctrl->flags |= V4L2_CTRL_FLAG_EXECUTE_ON_WRITE;
+	}
 
 	if (mapping->master_id)
 		__uvc_find_control(ctrl->entity, mapping->master_id,
-- 
2.43.0


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v2 2/3] media: uvcvideo: generalise the XU flags fixup to all controls
  2026-09-02  0:25 [PATCH v2 0/3] media: uvcvideo: live pan/tilt/zoom readback on the OBSBOT Tiny 2 Michael Jordan
  2026-09-02  0:25 ` [PATCH v2 1/3] media: uvcvideo: report AUTO_UPDATE controls as volatile Michael Jordan
@ 2026-09-02  0:25 ` Michael Jordan
  2026-09-02  6:38   ` Ricardo Ribalda
  2026-09-28 11:44   ` Laurent Pinchart
  2026-09-02  0:25 ` [PATCH v2 3/3] media: uvcvideo: fix up missing AUTO_UPDATE on the OBSBOT Tiny 2 Michael Jordan
  2026-09-28 11:01 ` [PATCH v2 0/3] media: uvcvideo: live pan/tilt/zoom readback " Hans de Goede
  3 siblings, 2 replies; 20+ messages in thread
From: Michael Jordan @ 2026-09-02  0:25 UTC (permalink / raw)
  To: Laurent Pinchart, Hans de Goede, Ricardo Ribalda
  Cc: Mauro Carvalho Chehab, Hans Verkuil, linux-media, linux-kernel,
	Michael Jordan

uvc_ctrl_fixup_xu_info() holds a per-device table of controls whose
GET_INFO reply is wrong, and overrides the flags for them. It only runs
from uvc_ctrl_fill_xu_info(), so it can only correct extension unit
controls, but standard controls suffer from the same class of firmware
bug: a device can report a wrong capability byte for a Camera Terminal
or Processing Unit control just as easily.

Rename it to uvc_ctrl_fixup_flags() and call it at the start of
uvc_ctrl_get_flags(), where the flags are derived from GET_INFO for
every control, standard and XU alike. The fixup replaces the flags
wholesale, so when the table covers a control there is no point in
querying a device we already know gives a wrong answer: return early
and skip the GET_INFO request altogether. The call in
uvc_ctrl_fill_xu_info() is dropped, as uvc_ctrl_get_flags() now handles
the fixup for XU controls too.

No functional change for the devices already in the table: their
entries are XU controls, matched by entity and selector before as they
are now, and their flags come from the table either way. The only
difference is one GET_INFO request no longer issued per fixed-up
control.

Suggested-by: Ricardo Ribalda <ribalda@chromium.org>
Signed-off-by: Michael Jordan <jordan.mymail@gmail.com>
---
 drivers/media/usb/uvc/uvc_ctrl.c | 91 ++++++++++++++++++--------------
 1 file changed, 50 insertions(+), 41 deletions(-)

diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
index aceb26310..64c90c380 100644
--- a/drivers/media/usb/uvc/uvc_ctrl.c
+++ b/drivers/media/usb/uvc/uvc_ctrl.c
@@ -2852,6 +2852,48 @@ int uvc_ctrl_set(struct uvc_fh *handle, struct v4l2_ext_control *xctrl)
  * Dynamic controls
  */
 
+static bool uvc_ctrl_fixup_flags(struct uvc_device *dev,
+				 const struct uvc_control *ctrl,
+				 struct uvc_control_info *info)
+{
+	struct uvc_ctrl_fixup {
+		struct usb_device_id id;
+		u8 entity;
+		u8 selector;
+		u8 flags;
+	};
+
+	static const struct uvc_ctrl_fixup fixups[] = {
+		{ { USB_DEVICE(0x046d, 0x08c2) }, 9, 1,
+			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 },
+		{ { USB_DEVICE(0x046d, 0x08cc) }, 9, 1,
+			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 },
+		{ { USB_DEVICE(0x046d, 0x0994) }, 9, 1,
+			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 },
+	};
+
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(fixups); ++i) {
+		if (!usb_match_one_id(dev->intf, &fixups[i].id))
+			continue;
+
+		if (fixups[i].entity == ctrl->entity->id &&
+		    fixups[i].selector == info->selector) {
+			info->flags = fixups[i].flags;
+			return true;
+		}
+	}
+
+	return false;
+}
+
 /*
  * Retrieve flags for a given control
  */
@@ -2862,6 +2904,14 @@ static int uvc_ctrl_get_flags(struct uvc_device *dev,
 	u8 *data;
 	int ret;
 
+	/*
+	 * Some devices report bogus capabilities through GET_INFO. If the
+	 * fixup table covers this control, take the flags from the table and
+	 * skip the query altogether.
+	 */
+	if (uvc_ctrl_fixup_flags(dev, ctrl, info))
+		return 0;
+
 	data = kmalloc(1, GFP_KERNEL);
 	if (data == NULL)
 		return -ENOMEM;
@@ -2893,45 +2943,6 @@ static int uvc_ctrl_get_flags(struct uvc_device *dev,
 	return ret;
 }
 
-static void uvc_ctrl_fixup_xu_info(struct uvc_device *dev,
-	const struct uvc_control *ctrl, struct uvc_control_info *info)
-{
-	struct uvc_ctrl_fixup {
-		struct usb_device_id id;
-		u8 entity;
-		u8 selector;
-		u8 flags;
-	};
-
-	static const struct uvc_ctrl_fixup fixups[] = {
-		{ { USB_DEVICE(0x046d, 0x08c2) }, 9, 1,
-			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 },
-		{ { USB_DEVICE(0x046d, 0x08cc) }, 9, 1,
-			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 },
-		{ { USB_DEVICE(0x046d, 0x0994) }, 9, 1,
-			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 },
-	};
-
-	unsigned int i;
-
-	for (i = 0; i < ARRAY_SIZE(fixups); ++i) {
-		if (!usb_match_one_id(dev->intf, &fixups[i].id))
-			continue;
-
-		if (fixups[i].entity == ctrl->entity->id &&
-		    fixups[i].selector == info->selector) {
-			info->flags = fixups[i].flags;
-			return;
-		}
-	}
-}
-
 /*
  * Query control information (size and flags) for XU controls.
  */
@@ -2972,8 +2983,6 @@ static int uvc_ctrl_fill_xu_info(struct uvc_device *dev,
 		goto done;
 	}
 
-	uvc_ctrl_fixup_xu_info(dev, ctrl, info);
-
 	uvc_dbg(dev, CONTROL,
 		"XU control %pUl/%u queried: len %u, flags { get %u set %u auto %u }\n",
 		info->entity, info->selector, info->size,
-- 
2.43.0


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v2 3/3] media: uvcvideo: fix up missing AUTO_UPDATE on the OBSBOT Tiny 2
  2026-09-02  0:25 [PATCH v2 0/3] media: uvcvideo: live pan/tilt/zoom readback on the OBSBOT Tiny 2 Michael Jordan
  2026-09-02  0:25 ` [PATCH v2 1/3] media: uvcvideo: report AUTO_UPDATE controls as volatile Michael Jordan
  2026-09-02  0:25 ` [PATCH v2 2/3] media: uvcvideo: generalise the XU flags fixup to all controls Michael Jordan
@ 2026-09-02  0:25 ` Michael Jordan
  2026-09-02  6:34   ` Ricardo Ribalda
  2026-09-28 11:57   ` Laurent Pinchart
  2026-09-28 11:01 ` [PATCH v2 0/3] media: uvcvideo: live pan/tilt/zoom readback " Hans de Goede
  3 siblings, 2 replies; 20+ messages in thread
From: Michael Jordan @ 2026-09-02  0:25 UTC (permalink / raw)
  To: Laurent Pinchart, Hans de Goede, Ricardo Ribalda
  Cc: Mauro Carvalho Chehab, Hans Verkuil, linux-media, linux-kernel,
	Michael Jordan

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@chromium.org>
Signed-off-by: Michael Jordan <jordan.mymail@gmail.com>
---
 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


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 3/3] media: uvcvideo: fix up missing AUTO_UPDATE on the OBSBOT Tiny 2
  2026-09-02  0:25 ` [PATCH v2 3/3] media: uvcvideo: fix up missing AUTO_UPDATE on the OBSBOT Tiny 2 Michael Jordan
@ 2026-09-02  6:34   ` Ricardo Ribalda
  2026-09-27 22:06     ` Michael Jordan
  2026-09-28 11:57   ` Laurent Pinchart
  1 sibling, 1 reply; 20+ messages in thread
From: Ricardo Ribalda @ 2026-09-02  6:34 UTC (permalink / raw)
  To: Michael Jordan
  Cc: Laurent Pinchart, Hans de Goede, Mauro Carvalho Chehab,
	Hans Verkuil, linux-media, linux-kernel

Hi Michael

Thanks for your patch:

On Wed, 2 Sept 2026 at 02:26, Michael Jordan <jordan.mymail@gmail.com> wrote:
>
> 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
>
Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
Link: https://lore.kernel.org/linux-media/20260902002544.34798-1-jordan.mymail@gmail.com/T/#mf4b518b5bfa604a5c925d23d1653b927b811488e
> Suggested-by: Ricardo Ribalda <ribalda@chromium.org>
> Signed-off-by: Michael Jordan <jordan.mymail@gmail.com>
> ---
>  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
>


-- 
Ricardo Ribalda

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 2/3] media: uvcvideo: generalise the XU flags fixup to all controls
  2026-09-02  0:25 ` [PATCH v2 2/3] media: uvcvideo: generalise the XU flags fixup to all controls Michael Jordan
@ 2026-09-02  6:38   ` Ricardo Ribalda
  2026-09-28 11:44   ` Laurent Pinchart
  1 sibling, 0 replies; 20+ messages in thread
From: Ricardo Ribalda @ 2026-09-02  6:38 UTC (permalink / raw)
  To: Michael Jordan
  Cc: Laurent Pinchart, Hans de Goede, Mauro Carvalho Chehab,
	Hans Verkuil, linux-media, linux-kernel

Hi Michael

On Wed, 2 Sept 2026 at 02:25, Michael Jordan <jordan.mymail@gmail.com> wrote:
>
> uvc_ctrl_fixup_xu_info() holds a per-device table of controls whose
> GET_INFO reply is wrong, and overrides the flags for them. It only runs
> from uvc_ctrl_fill_xu_info(), so it can only correct extension unit
> controls, but standard controls suffer from the same class of firmware
> bug: a device can report a wrong capability byte for a Camera Terminal
> or Processing Unit control just as easily.
>
> Rename it to uvc_ctrl_fixup_flags() and call it at the start of
> uvc_ctrl_get_flags(), where the flags are derived from GET_INFO for
> every control, standard and XU alike. The fixup replaces the flags
> wholesale, so when the table covers a control there is no point in
> querying a device we already know gives a wrong answer: return early
> and skip the GET_INFO request altogether. The call in
> uvc_ctrl_fill_xu_info() is dropped, as uvc_ctrl_get_flags() now handles
> the fixup for XU controls too.
>
> No functional change for the devices already in the table: their
> entries are XU controls, matched by entity and selector before as they
> are now, and their flags come from the table either way. The only
> difference is one GET_INFO request no longer issued per fixed-up
> control.
>
> Suggested-by: Ricardo Ribalda <ribalda@chromium.org>
Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
> Signed-off-by: Michael Jordan <jordan.mymail@gmail.com>
> ---
>  drivers/media/usb/uvc/uvc_ctrl.c | 91 ++++++++++++++++++--------------
>  1 file changed, 50 insertions(+), 41 deletions(-)
>
> diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
> index aceb26310..64c90c380 100644
> --- a/drivers/media/usb/uvc/uvc_ctrl.c
> +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> @@ -2852,6 +2852,48 @@ int uvc_ctrl_set(struct uvc_fh *handle, struct v4l2_ext_control *xctrl)
>   * Dynamic controls
>   */
>
> +static bool uvc_ctrl_fixup_flags(struct uvc_device *dev,
> +                                const struct uvc_control *ctrl,
> +                                struct uvc_control_info *info)
> +{
> +       struct uvc_ctrl_fixup {
> +               struct usb_device_id id;
> +               u8 entity;
> +               u8 selector;
> +               u8 flags;
> +       };
> +
> +       static const struct uvc_ctrl_fixup fixups[] = {
> +               { { USB_DEVICE(0x046d, 0x08c2) }, 9, 1,
> +                       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 },
> +               { { USB_DEVICE(0x046d, 0x08cc) }, 9, 1,
> +                       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 },
> +               { { USB_DEVICE(0x046d, 0x0994) }, 9, 1,
> +                       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 },
> +       };
> +
> +       unsigned int i;
> +
> +       for (i = 0; i < ARRAY_SIZE(fixups); ++i) {
> +               if (!usb_match_one_id(dev->intf, &fixups[i].id))
> +                       continue;
> +
> +               if (fixups[i].entity == ctrl->entity->id &&
> +                   fixups[i].selector == info->selector) {
> +                       info->flags = fixups[i].flags;
> +                       return true;
> +               }
> +       }
> +
> +       return false;
> +}
> +
>  /*
>   * Retrieve flags for a given control
>   */
> @@ -2862,6 +2904,14 @@ static int uvc_ctrl_get_flags(struct uvc_device *dev,
>         u8 *data;
>         int ret;
>
> +       /*
> +        * Some devices report bogus capabilities through GET_INFO. If the
> +        * fixup table covers this control, take the flags from the table and
> +        * skip the query altogether.
> +        */
> +       if (uvc_ctrl_fixup_flags(dev, ctrl, info))
> +               return 0;
> +
>         data = kmalloc(1, GFP_KERNEL);
>         if (data == NULL)
>                 return -ENOMEM;
> @@ -2893,45 +2943,6 @@ static int uvc_ctrl_get_flags(struct uvc_device *dev,
>         return ret;
>  }
>
> -static void uvc_ctrl_fixup_xu_info(struct uvc_device *dev,
> -       const struct uvc_control *ctrl, struct uvc_control_info *info)
> -{
> -       struct uvc_ctrl_fixup {
> -               struct usb_device_id id;
> -               u8 entity;
> -               u8 selector;
> -               u8 flags;
> -       };
> -
> -       static const struct uvc_ctrl_fixup fixups[] = {
> -               { { USB_DEVICE(0x046d, 0x08c2) }, 9, 1,
> -                       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 },
> -               { { USB_DEVICE(0x046d, 0x08cc) }, 9, 1,
> -                       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 },
> -               { { USB_DEVICE(0x046d, 0x0994) }, 9, 1,
> -                       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 },
> -       };
> -
> -       unsigned int i;
> -
> -       for (i = 0; i < ARRAY_SIZE(fixups); ++i) {
> -               if (!usb_match_one_id(dev->intf, &fixups[i].id))
> -                       continue;
> -
> -               if (fixups[i].entity == ctrl->entity->id &&
> -                   fixups[i].selector == info->selector) {
> -                       info->flags = fixups[i].flags;
> -                       return;
> -               }
> -       }
> -}
> -
>  /*
>   * Query control information (size and flags) for XU controls.
>   */
> @@ -2972,8 +2983,6 @@ static int uvc_ctrl_fill_xu_info(struct uvc_device *dev,
>                 goto done;
>         }
>
> -       uvc_ctrl_fixup_xu_info(dev, ctrl, info);
> -
>         uvc_dbg(dev, CONTROL,
>                 "XU control %pUl/%u queried: len %u, flags { get %u set %u auto %u }\n",
>                 info->entity, info->selector, info->size,
> --
> 2.43.0
>


-- 
Ricardo Ribalda

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 3/3] media: uvcvideo: fix up missing AUTO_UPDATE on the OBSBOT Tiny 2
  2026-09-02  6:34   ` Ricardo Ribalda
@ 2026-09-27 22:06     ` Michael Jordan
  2026-09-28  6:57       ` Ricardo Ribalda
  0 siblings, 1 reply; 20+ messages in thread
From: Michael Jordan @ 2026-09-27 22:06 UTC (permalink / raw)
  To: Ricardo Ribalda
  Cc: Michael Jordan, Laurent Pinchart, Hans de Goede,
	Mauro Carvalho Chehab, Hans Verkuil, linux-media, linux-kernel

Hi Ricardo,

On Wed, 2 Sep 2026 08:34:34 +0200, Ricardo Ribalda <ribalda@chromium.org> wrote:
> Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>

Thanks for the reviews on v2.

I have a question about how to handle a second device. I now have an
OBSBOT Tail 2 (3564:fefc) and it has the same defect as the Tiny 2.

Its GET_INFO bytes match the Tiny 2 control for control:

  CT_PANTILT_ABSOLUTE   0x03
  CT_PANTILT_RELATIVE   0x03
  CT_ZOOM_ABSOLUTE      0x03
  CT_ZOOM_RELATIVE      0x0f
  CT_ROLL_ABSOLUTE      0x01

Without a fixup entry, pan_absolute reads back the commanded target the
moment it is written. With entries for 3564:fefc on top of v2, all three
controls report the live value on GET_CUR, both during a commanded move
and when the camera changes them on its own:

- pan/tilt position and pan/tilt speed follow the gimbal under the
  camera's subject tracking, with the host issuing no requests;
- zoom follows a zoom change made at the camera.

I checked the other AUTO_UPDATE controls the same way as for the Tiny 2.
White balance and focus only echo the last SET_CUR. Exposure time reports
live values until the host writes a manual exposure once, and from then
on echoes that value, across a power cycle. I would leave all of those
alone, as on the Tiny 2.

So the change is three more table entries, identical to the Tiny 2 ones
apart from the product ID. v2 still applies cleanly to media/next as of
2dcdfb625c3b, so nothing else forces a respin.

Which would you prefer?

 a) a v3 with the Tail 2 entries folded into 3/3;
 b) a v3 with the Tail 2 entries as a new 4/4, leaving 1-3 as reviewed;
 c) leave v2 as it is, and send the Tail 2 entries as a follow-up patch
    once v2 is applied.

I lean towards (c), so that a reviewed series is not disturbed, but I am
happy to do whichever is easiest for you and Laurent. In any of the three
I will include the Tail 2 lsusb -v output.

Thanks,
Michael

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 3/3] media: uvcvideo: fix up missing AUTO_UPDATE on the OBSBOT Tiny 2
  2026-09-27 22:06     ` Michael Jordan
@ 2026-09-28  6:57       ` Ricardo Ribalda
  2026-09-28 11:18         ` Ricardo Ribalda
  0 siblings, 1 reply; 20+ messages in thread
From: Ricardo Ribalda @ 2026-09-28  6:57 UTC (permalink / raw)
  To: Michael Jordan
  Cc: Laurent Pinchart, Hans de Goede, Mauro Carvalho Chehab,
	Hans Verkuil, linux-media, linux-kernel

Hi Michael

On Mon, 28 Sept 2026 at 00:06, Michael Jordan <jordan.mymail@gmail.com> wrote:
>
> Hi Ricardo,
>
> On Wed, 2 Sep 2026 08:34:34 +0200, Ricardo Ribalda <ribalda@chromium.org> wrote:
> > Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
>
> Thanks for the reviews on v2.
>
> I have a question about how to handle a second device. I now have an
> OBSBOT Tail 2 (3564:fefc) and it has the same defect as the Tiny 2.
>
> Its GET_INFO bytes match the Tiny 2 control for control:
>
>   CT_PANTILT_ABSOLUTE   0x03
>   CT_PANTILT_RELATIVE   0x03
>   CT_ZOOM_ABSOLUTE      0x03
>   CT_ZOOM_RELATIVE      0x0f
>   CT_ROLL_ABSOLUTE      0x01
>
> Without a fixup entry, pan_absolute reads back the commanded target the
> moment it is written. With entries for 3564:fefc on top of v2, all three
> controls report the live value on GET_CUR, both during a commanded move
> and when the camera changes them on its own:
>
> - pan/tilt position and pan/tilt speed follow the gimbal under the
>   camera's subject tracking, with the host issuing no requests;
> - zoom follows a zoom change made at the camera.
>
> I checked the other AUTO_UPDATE controls the same way as for the Tiny 2.
> White balance and focus only echo the last SET_CUR. Exposure time reports
> live values until the host writes a manual exposure once, and from then
> on echoes that value, across a power cycle. I would leave all of those
> alone, as on the Tiny 2.
>
> So the change is three more table entries, identical to the Tiny 2 ones
> apart from the product ID. v2 still applies cleanly to media/next as of
> 2dcdfb625c3b, so nothing else forces a respin.
>
> Which would you prefer?
>
>  a) a v3 with the Tail 2 entries folded into 3/3;
>  b) a v3 with the Tail 2 entries as a new 4/4, leaving 1-3 as reviewed;
>  c) leave v2 as it is, and send the Tail 2 entries as a follow-up patch
>     once v2 is applied.

I prefer b) because c) cannot be tested by media-ci.

>
> I lean towards (c), so that a reviewed series is not disturbed, but I am
> happy to do whichever is easiest for you and Laurent. In any of the three
> I will include the Tail 2 lsusb -v output.

BTW, I am curious, did you hear anything back from OBSBOT?
Could you also report this to them?

Thanks!

>
> Thanks,
> Michael



-- 
Ricardo Ribalda

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 0/3] media: uvcvideo: live pan/tilt/zoom readback on the OBSBOT Tiny 2
  2026-09-02  0:25 [PATCH v2 0/3] media: uvcvideo: live pan/tilt/zoom readback on the OBSBOT Tiny 2 Michael Jordan
                   ` (2 preceding siblings ...)
  2026-09-02  0:25 ` [PATCH v2 3/3] media: uvcvideo: fix up missing AUTO_UPDATE on the OBSBOT Tiny 2 Michael Jordan
@ 2026-09-28 11:01 ` Hans de Goede
  2026-09-28 11:12   ` Ricardo Ribalda
  2026-09-28 11:49   ` Laurent Pinchart
  3 siblings, 2 replies; 20+ messages in thread
From: Hans de Goede @ 2026-09-28 11:01 UTC (permalink / raw)
  To: Michael Jordan, Laurent Pinchart, Ricardo Ribalda
  Cc: Mauro Carvalho Chehab, Hans Verkuil, linux-media, linux-kernel

Hi All,

On 2-Sep-26 02:25, Michael Jordan wrote:
> The OBSBOT Tiny 2's GET_INFO strips the AUTOUPDATE bit from its pan,
> tilt and zoom controls, so uvcvideo caches them and userspace can never
> observe the actuator's live state. This series reports AUTO_UPDATE
> controls as volatile to userspace, generalises the existing XU flags
> fixup table to all controls, and adds entries for the three affected
> controls on this camera.
> 
> Changes in v2 (following Ricardo's review of v1 [1]):
> 
> - Patch 1: unchanged; picked up Ricardo's Reviewed-by.
> - Patch 2: uvc_ctrl_fixup_flags() now returns bool and runs at the
>   start of uvc_ctrl_get_flags(), before the allocation, skipping the
>   GET_INFO query entirely for controls the table covers (Ricardo).
> - Patch 3: as asked, I checked whether the camera's other
>   AUTO_UPDATE-flagged controls suffer the same bug. Two more do:
>   CT_PANTILT_RELATIVE and CT_ZOOM_ABSOLUTE, both verified on hardware
>   to change autonomously and report live values on GET_CUR; entries
>   added for both. Exposure, white balance and focus turned out to be
>   write-only on this firmware (their autos work, but GET_CUR echoes the
>   last SET_CUR), so they gain nothing from AUTO_UPDATE and were left
>   alone; details in the commit message. The commit message also no
>   longer claims the capability byte is the same for every control --
>   probing every control showed it is computed per control, just wrong
>   for the PTZ ones. Dropped Ricardo's Reviewed-by since the patch
>   changed materially.
> 
> The full lsusb -v output was posted in reply to v1's patch 3, in the
> thread at [1].
> 
> [1] https://lore.kernel.org/linux-media/20260828152557.653475-1-jordan.mymail@gmail.com/

Michael, thank you for the patch. Patches 1/2 look good to me:

Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>

Ricardo (and Michael, I wonder, in the light of Michael already having
found a second camera with the same issue and also in the light of your
"media: uvcvideo: Automatically handle invalid uvc_versions" series
if it would not be better to try to fix this up automatically instead
of relying on device quirks?

Specifically the UVC_CTRL_FLAG_AUTO_UPDATE flag is already there
in the default flags for these controls (and a bunch of others)
in uvc_ctrls[].

I wonder if we should simply always honor UVC_CTRL_FLAG_AUTO_UPDATE
from uvc_ctrls[] even when we do get a valid GET_INFO request and
simply or in the UVC_CTRL_FLAG_AUTO_UPDATE from uvc_ctrls[] if it
is there?

That avoids needing to adding more and more quirks for this.

Regards,

Hans




> Michael Jordan (3):
>   media: uvcvideo: report AUTO_UPDATE controls as volatile
>   media: uvcvideo: generalise the XU flags fixup to all controls
>   media: uvcvideo: fix up missing AUTO_UPDATE on the OBSBOT Tiny 2
> 
>  drivers/media/usb/uvc/uvc_ctrl.c | 122 ++++++++++++++++++++-----------
>  1 file changed, 81 insertions(+), 41 deletions(-)
> 


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 0/3] media: uvcvideo: live pan/tilt/zoom readback on the OBSBOT Tiny 2
  2026-09-28 11:01 ` [PATCH v2 0/3] media: uvcvideo: live pan/tilt/zoom readback " Hans de Goede
@ 2026-09-28 11:12   ` Ricardo Ribalda
  2026-09-28 11:14     ` Hans de Goede
  2026-09-28 11:49   ` Laurent Pinchart
  1 sibling, 1 reply; 20+ messages in thread
From: Ricardo Ribalda @ 2026-09-28 11:12 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Michael Jordan, Laurent Pinchart, Mauro Carvalho Chehab,
	Hans Verkuil, linux-media, linux-kernel

Hi Hans

On Mon, 28 Sept 2026 at 13:01, Hans de Goede <hansg@kernel.org> wrote:
>
> Hi All,
>
> On 2-Sep-26 02:25, Michael Jordan wrote:
> > The OBSBOT Tiny 2's GET_INFO strips the AUTOUPDATE bit from its pan,
> > tilt and zoom controls, so uvcvideo caches them and userspace can never
> > observe the actuator's live state. This series reports AUTO_UPDATE
> > controls as volatile to userspace, generalises the existing XU flags
> > fixup table to all controls, and adds entries for the three affected
> > controls on this camera.
> >
> > Changes in v2 (following Ricardo's review of v1 [1]):
> >
> > - Patch 1: unchanged; picked up Ricardo's Reviewed-by.
> > - Patch 2: uvc_ctrl_fixup_flags() now returns bool and runs at the
> >   start of uvc_ctrl_get_flags(), before the allocation, skipping the
> >   GET_INFO query entirely for controls the table covers (Ricardo).
> > - Patch 3: as asked, I checked whether the camera's other
> >   AUTO_UPDATE-flagged controls suffer the same bug. Two more do:
> >   CT_PANTILT_RELATIVE and CT_ZOOM_ABSOLUTE, both verified on hardware
> >   to change autonomously and report live values on GET_CUR; entries
> >   added for both. Exposure, white balance and focus turned out to be
> >   write-only on this firmware (their autos work, but GET_CUR echoes the
> >   last SET_CUR), so they gain nothing from AUTO_UPDATE and were left
> >   alone; details in the commit message. The commit message also no
> >   longer claims the capability byte is the same for every control --
> >   probing every control showed it is computed per control, just wrong
> >   for the PTZ ones. Dropped Ricardo's Reviewed-by since the patch
> >   changed materially.
> >
> > The full lsusb -v output was posted in reply to v1's patch 3, in the
> > thread at [1].
> >
> > [1] https://lore.kernel.org/linux-media/20260828152557.653475-1-jordan.mymail@gmail.com/
>
> Michael, thank you for the patch. Patches 1/2 look good to me:
>
> Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
>
> Ricardo (and Michael, I wonder, in the light of Michael already having
> found a second camera with the same issue and also in the light of your
> "media: uvcvideo: Automatically handle invalid uvc_versions" series
> if it would not be better to try to fix this up automatically instead
> of relying on device quirks?
>
> Specifically the UVC_CTRL_FLAG_AUTO_UPDATE flag is already there
> in the default flags for these controls (and a bunch of others)
> in uvc_ctrls[].
>
> I wonder if we should simply always honor UVC_CTRL_FLAG_AUTO_UPDATE
> from uvc_ctrls[] even when we do get a valid GET_INFO request and
> simply or in the UVC_CTRL_FLAG_AUTO_UPDATE from uvc_ctrls[] if it
> is there?

I would say that for now we can add quirks, and if we see a big
proliferation of them, we can implement something automatic.

My fear is that bypassing the device flags might trigger errors that
could disable the affected controls.

Since the two devices that Michael mentioned come from the same
manufacturer, I do not think they justify automatic handling just yet.
And who knows maybe OBSBOT will fix their firmware? (Yes I also
believe in Santa)


>
> That avoids needing to adding more and more quirks for this.
>
> Regards,
>
> Hans
>
>
>
>
> > Michael Jordan (3):
> >   media: uvcvideo: report AUTO_UPDATE controls as volatile
> >   media: uvcvideo: generalise the XU flags fixup to all controls
> >   media: uvcvideo: fix up missing AUTO_UPDATE on the OBSBOT Tiny 2
> >
> >  drivers/media/usb/uvc/uvc_ctrl.c | 122 ++++++++++++++++++++-----------
> >  1 file changed, 81 insertions(+), 41 deletions(-)
> >
>


-- 
Ricardo Ribalda

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 0/3] media: uvcvideo: live pan/tilt/zoom readback on the OBSBOT Tiny 2
  2026-09-28 11:12   ` Ricardo Ribalda
@ 2026-09-28 11:14     ` Hans de Goede
  0 siblings, 0 replies; 20+ messages in thread
From: Hans de Goede @ 2026-09-28 11:14 UTC (permalink / raw)
  To: Ricardo Ribalda
  Cc: Michael Jordan, Laurent Pinchart, Mauro Carvalho Chehab,
	Hans Verkuil, linux-media, linux-kernel

Hi,

On 28-Sep-26 13:12, Ricardo Ribalda wrote:
> Hi Hans
> 
> On Mon, 28 Sept 2026 at 13:01, Hans de Goede <hansg@kernel.org> wrote:
>>
>> Hi All,
>>
>> On 2-Sep-26 02:25, Michael Jordan wrote:
>>> The OBSBOT Tiny 2's GET_INFO strips the AUTOUPDATE bit from its pan,
>>> tilt and zoom controls, so uvcvideo caches them and userspace can never
>>> observe the actuator's live state. This series reports AUTO_UPDATE
>>> controls as volatile to userspace, generalises the existing XU flags
>>> fixup table to all controls, and adds entries for the three affected
>>> controls on this camera.
>>>
>>> Changes in v2 (following Ricardo's review of v1 [1]):
>>>
>>> - Patch 1: unchanged; picked up Ricardo's Reviewed-by.
>>> - Patch 2: uvc_ctrl_fixup_flags() now returns bool and runs at the
>>>   start of uvc_ctrl_get_flags(), before the allocation, skipping the
>>>   GET_INFO query entirely for controls the table covers (Ricardo).
>>> - Patch 3: as asked, I checked whether the camera's other
>>>   AUTO_UPDATE-flagged controls suffer the same bug. Two more do:
>>>   CT_PANTILT_RELATIVE and CT_ZOOM_ABSOLUTE, both verified on hardware
>>>   to change autonomously and report live values on GET_CUR; entries
>>>   added for both. Exposure, white balance and focus turned out to be
>>>   write-only on this firmware (their autos work, but GET_CUR echoes the
>>>   last SET_CUR), so they gain nothing from AUTO_UPDATE and were left
>>>   alone; details in the commit message. The commit message also no
>>>   longer claims the capability byte is the same for every control --
>>>   probing every control showed it is computed per control, just wrong
>>>   for the PTZ ones. Dropped Ricardo's Reviewed-by since the patch
>>>   changed materially.
>>>
>>> The full lsusb -v output was posted in reply to v1's patch 3, in the
>>> thread at [1].
>>>
>>> [1] https://lore.kernel.org/linux-media/20260828152557.653475-1-jordan.mymail@gmail.com/
>>
>> Michael, thank you for the patch. Patches 1/2 look good to me:
>>
>> Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
>>
>> Ricardo (and Michael, I wonder, in the light of Michael already having
>> found a second camera with the same issue and also in the light of your
>> "media: uvcvideo: Automatically handle invalid uvc_versions" series
>> if it would not be better to try to fix this up automatically instead
>> of relying on device quirks?
>>
>> Specifically the UVC_CTRL_FLAG_AUTO_UPDATE flag is already there
>> in the default flags for these controls (and a bunch of others)
>> in uvc_ctrls[].
>>
>> I wonder if we should simply always honor UVC_CTRL_FLAG_AUTO_UPDATE
>> from uvc_ctrls[] even when we do get a valid GET_INFO request and
>> simply or in the UVC_CTRL_FLAG_AUTO_UPDATE from uvc_ctrls[] if it
>> is there?
> 
> I would say that for now we can add quirks, and if we see a big
> proliferation of them, we can implement something automatic.
> 
> My fear is that bypassing the device flags might trigger errors that
> could disable the affected controls.
> 
> Since the two devices that Michael mentioned come from the same
> manufacturer, I do not think they justify automatic handling just yet.
> And who knows maybe OBSBOT will fix their firmware? (Yes I also
> believe in Santa)

Ok, fair enough lets go with this series as is then.

I'll go and merge these 3 patches into uvc/for-next sometime today.

Regards,

Hans



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 3/3] media: uvcvideo: fix up missing AUTO_UPDATE on the OBSBOT Tiny 2
  2026-09-28  6:57       ` Ricardo Ribalda
@ 2026-09-28 11:18         ` Ricardo Ribalda
  2026-09-28 14:34           ` Michael Jordan
  0 siblings, 1 reply; 20+ messages in thread
From: Ricardo Ribalda @ 2026-09-28 11:18 UTC (permalink / raw)
  To: Michael Jordan
  Cc: Laurent Pinchart, Hans de Goede, Mauro Carvalho Chehab,
	Hans Verkuil, linux-media, linux-kernel

Hi Michael

Since Hans is going to merge your series today into the uvc tree you
should do c) instead.

Sorry for the mixed messages :)

Regards!

On Mon, 28 Sept 2026 at 08:57, Ricardo Ribalda <ribalda@chromium.org> wrote:
>
> Hi Michael
>
> On Mon, 28 Sept 2026 at 00:06, Michael Jordan <jordan.mymail@gmail.com> wrote:
> >
> > Hi Ricardo,
> >
> > On Wed, 2 Sep 2026 08:34:34 +0200, Ricardo Ribalda <ribalda@chromium.org> wrote:
> > > Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
> >
> > Thanks for the reviews on v2.
> >
> > I have a question about how to handle a second device. I now have an
> > OBSBOT Tail 2 (3564:fefc) and it has the same defect as the Tiny 2.
> >
> > Its GET_INFO bytes match the Tiny 2 control for control:
> >
> >   CT_PANTILT_ABSOLUTE   0x03
> >   CT_PANTILT_RELATIVE   0x03
> >   CT_ZOOM_ABSOLUTE      0x03
> >   CT_ZOOM_RELATIVE      0x0f
> >   CT_ROLL_ABSOLUTE      0x01
> >
> > Without a fixup entry, pan_absolute reads back the commanded target the
> > moment it is written. With entries for 3564:fefc on top of v2, all three
> > controls report the live value on GET_CUR, both during a commanded move
> > and when the camera changes them on its own:
> >
> > - pan/tilt position and pan/tilt speed follow the gimbal under the
> >   camera's subject tracking, with the host issuing no requests;
> > - zoom follows a zoom change made at the camera.
> >
> > I checked the other AUTO_UPDATE controls the same way as for the Tiny 2.
> > White balance and focus only echo the last SET_CUR. Exposure time reports
> > live values until the host writes a manual exposure once, and from then
> > on echoes that value, across a power cycle. I would leave all of those
> > alone, as on the Tiny 2.
> >
> > So the change is three more table entries, identical to the Tiny 2 ones
> > apart from the product ID. v2 still applies cleanly to media/next as of
> > 2dcdfb625c3b, so nothing else forces a respin.
> >
> > Which would you prefer?
> >
> >  a) a v3 with the Tail 2 entries folded into 3/3;
> >  b) a v3 with the Tail 2 entries as a new 4/4, leaving 1-3 as reviewed;
> >  c) leave v2 as it is, and send the Tail 2 entries as a follow-up patch
> >     once v2 is applied.
>
> I prefer b) because c) cannot be tested by media-ci.
>
> >
> > I lean towards (c), so that a reviewed series is not disturbed, but I am
> > happy to do whichever is easiest for you and Laurent. In any of the three
> > I will include the Tail 2 lsusb -v output.
>
> BTW, I am curious, did you hear anything back from OBSBOT?
> Could you also report this to them?
>
> Thanks!
>
> >
> > Thanks,
> > Michael
>
>
>
> --
> Ricardo Ribalda



-- 
Ricardo Ribalda

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 2/3] media: uvcvideo: generalise the XU flags fixup to all controls
  2026-09-02  0:25 ` [PATCH v2 2/3] media: uvcvideo: generalise the XU flags fixup to all controls Michael Jordan
  2026-09-02  6:38   ` Ricardo Ribalda
@ 2026-09-28 11:44   ` Laurent Pinchart
  2026-09-28 14:34     ` Michael Jordan
  1 sibling, 1 reply; 20+ messages in thread
From: Laurent Pinchart @ 2026-09-28 11:44 UTC (permalink / raw)
  To: Michael Jordan
  Cc: Hans de Goede, Ricardo Ribalda, Mauro Carvalho Chehab,
	Hans Verkuil, linux-media, linux-kernel

On Tue, Sep 01, 2026 at 08:25:52PM -0400, Michael Jordan wrote:
> uvc_ctrl_fixup_xu_info() holds a per-device table of controls whose
> GET_INFO reply is wrong, and overrides the flags for them. It only runs
> from uvc_ctrl_fill_xu_info(), so it can only correct extension unit
> controls, but standard controls suffer from the same class of firmware
> bug: a device can report a wrong capability byte for a Camera Terminal
> or Processing Unit control just as easily.
> 
> Rename it to uvc_ctrl_fixup_flags() and call it at the start of
> uvc_ctrl_get_flags(), where the flags are derived from GET_INFO for
> every control, standard and XU alike. The fixup replaces the flags
> wholesale, so when the table covers a control there is no point in
> querying a device we already know gives a wrong answer: return early
> and skip the GET_INFO request altogether. The call in
> uvc_ctrl_fill_xu_info() is dropped, as uvc_ctrl_get_flags() now handles
> the fixup for XU controls too.
> 
> No functional change for the devices already in the table: their
> entries are XU controls, matched by entity and selector before as they
> are now, and their flags come from the table either way. The only
> difference is one GET_INFO request no longer issued per fixed-up
> control.

That's a long commit message for such a simple change. Is it
LLM-generated ? If so, you need an Assisted-by tag on this patch series.

> Suggested-by: Ricardo Ribalda <ribalda@chromium.org>
> Signed-off-by: Michael Jordan <jordan.mymail@gmail.com>
> ---
>  drivers/media/usb/uvc/uvc_ctrl.c | 91 ++++++++++++++++++--------------
>  1 file changed, 50 insertions(+), 41 deletions(-)
> 
> diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
> index aceb26310..64c90c380 100644
> --- a/drivers/media/usb/uvc/uvc_ctrl.c
> +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> @@ -2852,6 +2852,48 @@ int uvc_ctrl_set(struct uvc_fh *handle, struct v4l2_ext_control *xctrl)
>   * Dynamic controls
>   */
>  
> +static bool uvc_ctrl_fixup_flags(struct uvc_device *dev,
> +				 const struct uvc_control *ctrl,
> +				 struct uvc_control_info *info)
> +{
> +	struct uvc_ctrl_fixup {
> +		struct usb_device_id id;
> +		u8 entity;
> +		u8 selector;
> +		u8 flags;
> +	};
> +
> +	static const struct uvc_ctrl_fixup fixups[] = {
> +		{ { USB_DEVICE(0x046d, 0x08c2) }, 9, 1,
> +			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 },
> +		{ { USB_DEVICE(0x046d, 0x08cc) }, 9, 1,
> +			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 },
> +		{ { USB_DEVICE(0x046d, 0x0994) }, 9, 1,
> +			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 },
> +	};
> +
> +	unsigned int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(fixups); ++i) {
> +		if (!usb_match_one_id(dev->intf, &fixups[i].id))
> +			continue;
> +
> +		if (fixups[i].entity == ctrl->entity->id &&
> +		    fixups[i].selector == info->selector) {
> +			info->flags = fixups[i].flags;
> +			return true;
> +		}
> +	}

The O(n*m) complexity isn't nice, but it's not a new issue. It can be
addressed separately.

The code change looks fine.

> +
> +	return false;
> +}
> +
>  /*
>   * Retrieve flags for a given control
>   */
> @@ -2862,6 +2904,14 @@ static int uvc_ctrl_get_flags(struct uvc_device *dev,
>  	u8 *data;
>  	int ret;
>  
> +	/*
> +	 * Some devices report bogus capabilities through GET_INFO. If the
> +	 * fixup table covers this control, take the flags from the table and
> +	 * skip the query altogether.
> +	 */
> +	if (uvc_ctrl_fixup_flags(dev, ctrl, info))
> +		return 0;
> +
>  	data = kmalloc(1, GFP_KERNEL);
>  	if (data == NULL)
>  		return -ENOMEM;
> @@ -2893,45 +2943,6 @@ static int uvc_ctrl_get_flags(struct uvc_device *dev,
>  	return ret;
>  }
>  
> -static void uvc_ctrl_fixup_xu_info(struct uvc_device *dev,
> -	const struct uvc_control *ctrl, struct uvc_control_info *info)
> -{
> -	struct uvc_ctrl_fixup {
> -		struct usb_device_id id;
> -		u8 entity;
> -		u8 selector;
> -		u8 flags;
> -	};
> -
> -	static const struct uvc_ctrl_fixup fixups[] = {
> -		{ { USB_DEVICE(0x046d, 0x08c2) }, 9, 1,
> -			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 },
> -		{ { USB_DEVICE(0x046d, 0x08cc) }, 9, 1,
> -			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 },
> -		{ { USB_DEVICE(0x046d, 0x0994) }, 9, 1,
> -			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 },
> -	};
> -
> -	unsigned int i;
> -
> -	for (i = 0; i < ARRAY_SIZE(fixups); ++i) {
> -		if (!usb_match_one_id(dev->intf, &fixups[i].id))
> -			continue;
> -
> -		if (fixups[i].entity == ctrl->entity->id &&
> -		    fixups[i].selector == info->selector) {
> -			info->flags = fixups[i].flags;
> -			return;
> -		}
> -	}
> -}
> -
>  /*
>   * Query control information (size and flags) for XU controls.
>   */
> @@ -2972,8 +2983,6 @@ static int uvc_ctrl_fill_xu_info(struct uvc_device *dev,
>  		goto done;
>  	}
>  
> -	uvc_ctrl_fixup_xu_info(dev, ctrl, info);
> -
>  	uvc_dbg(dev, CONTROL,
>  		"XU control %pUl/%u queried: len %u, flags { get %u set %u auto %u }\n",
>  		info->entity, info->selector, info->size,

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 0/3] media: uvcvideo: live pan/tilt/zoom readback on the OBSBOT Tiny 2
  2026-09-28 11:01 ` [PATCH v2 0/3] media: uvcvideo: live pan/tilt/zoom readback " Hans de Goede
  2026-09-28 11:12   ` Ricardo Ribalda
@ 2026-09-28 11:49   ` Laurent Pinchart
  1 sibling, 0 replies; 20+ messages in thread
From: Laurent Pinchart @ 2026-09-28 11:49 UTC (permalink / raw)
  To: Hans de Goede
  Cc: Michael Jordan, Ricardo Ribalda, Mauro Carvalho Chehab,
	Hans Verkuil, linux-media, linux-kernel

On Mon, Sep 28, 2026 at 01:01:11PM +0200, Hans de Goede wrote:
> Hi All,
> 
> On 2-Sep-26 02:25, Michael Jordan wrote:
> > The OBSBOT Tiny 2's GET_INFO strips the AUTOUPDATE bit from its pan,
> > tilt and zoom controls, so uvcvideo caches them and userspace can never
> > observe the actuator's live state. This series reports AUTO_UPDATE
> > controls as volatile to userspace, generalises the existing XU flags
> > fixup table to all controls, and adds entries for the three affected
> > controls on this camera.
> > 
> > Changes in v2 (following Ricardo's review of v1 [1]):
> > 
> > - Patch 1: unchanged; picked up Ricardo's Reviewed-by.
> > - Patch 2: uvc_ctrl_fixup_flags() now returns bool and runs at the
> >   start of uvc_ctrl_get_flags(), before the allocation, skipping the
> >   GET_INFO query entirely for controls the table covers (Ricardo).
> > - Patch 3: as asked, I checked whether the camera's other
> >   AUTO_UPDATE-flagged controls suffer the same bug. Two more do:
> >   CT_PANTILT_RELATIVE and CT_ZOOM_ABSOLUTE, both verified on hardware
> >   to change autonomously and report live values on GET_CUR; entries
> >   added for both. Exposure, white balance and focus turned out to be
> >   write-only on this firmware (their autos work, but GET_CUR echoes the
> >   last SET_CUR), so they gain nothing from AUTO_UPDATE and were left
> >   alone; details in the commit message. The commit message also no
> >   longer claims the capability byte is the same for every control --
> >   probing every control showed it is computed per control, just wrong
> >   for the PTZ ones. Dropped Ricardo's Reviewed-by since the patch
> >   changed materially.
> > 
> > The full lsusb -v output was posted in reply to v1's patch 3, in the
> > thread at [1].
> > 
> > [1] https://lore.kernel.org/linux-media/20260828152557.653475-1-jordan.mymail@gmail.com/
> 
> Michael, thank you for the patch. Patches 1/2 look good to me:
> 
> Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
> 
> Ricardo (and Michael, I wonder, in the light of Michael already having
> found a second camera with the same issue and also in the light of your
> "media: uvcvideo: Automatically handle invalid uvc_versions" series
> if it would not be better to try to fix this up automatically instead
> of relying on device quirks?
> 
> Specifically the UVC_CTRL_FLAG_AUTO_UPDATE flag is already there
> in the default flags for these controls (and a bunch of others)
> in uvc_ctrls[].

The UVC_CTRL_FLAG_AUTO_UPDATE flag in uvc_ctrls indicates which control
*may* be auto-update controls. In many devices, lots of those will not
be auto-update controls. For instance, UVC_PU_HUE_CONTROL may only
auto-update when auto-hue is enabled. Devices that implement manual hue
only will not update this control.

We use the flags in uvc_ctrls as a fallback if getting control info from
the device fails (in uvc_ctrl_get_flags()). I think that's the right
thing to do.

> I wonder if we should simply always honor UVC_CTRL_FLAG_AUTO_UPDATE
> from uvc_ctrls[] even when we do get a valid GET_INFO request and
> simply or in the UVC_CTRL_FLAG_AUTO_UPDATE from uvc_ctrls[] if it
> is there?
> 
> That avoids needing to adding more and more quirks for this.
> 
> Regards,
> 
> Hans
> 
> > Michael Jordan (3):
> >   media: uvcvideo: report AUTO_UPDATE controls as volatile
> >   media: uvcvideo: generalise the XU flags fixup to all controls
> >   media: uvcvideo: fix up missing AUTO_UPDATE on the OBSBOT Tiny 2
> > 
> >  drivers/media/usb/uvc/uvc_ctrl.c | 122 ++++++++++++++++++++-----------
> >  1 file changed, 81 insertions(+), 41 deletions(-)

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 3/3] media: uvcvideo: fix up missing AUTO_UPDATE on the OBSBOT Tiny 2
  2026-09-02  0:25 ` [PATCH v2 3/3] media: uvcvideo: fix up missing AUTO_UPDATE on the OBSBOT Tiny 2 Michael Jordan
  2026-09-02  6:34   ` Ricardo Ribalda
@ 2026-09-28 11:57   ` Laurent Pinchart
  2026-09-28 14:34     ` Michael Jordan
  1 sibling, 1 reply; 20+ messages in thread
From: Laurent Pinchart @ 2026-09-28 11:57 UTC (permalink / raw)
  To: Michael Jordan
  Cc: Hans de Goede, Ricardo Ribalda, Mauro Carvalho Chehab,
	Hans Verkuil, linux-media, linux-kernel

On Tue, Sep 01, 2026 at 08:25:53PM -0400, Michael Jordan wrote:
> 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:

The device implements an interrupt endpoint. Does it report control
change events for those controls ?

> - 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,

Any public link ?

> 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@chromium.org>
> Signed-off-by: Michael Jordan <jordan.mymail@gmail.com>
> ---
>  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.
> +		 */

This belongs to the commit message.

> +		{ { 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;

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 2/3] media: uvcvideo: generalise the XU flags fixup to all controls
  2026-09-28 11:44   ` Laurent Pinchart
@ 2026-09-28 14:34     ` Michael Jordan
  0 siblings, 0 replies; 20+ messages in thread
From: Michael Jordan @ 2026-09-28 14:34 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Michael Jordan, Hans de Goede, Ricardo Ribalda,
	Mauro Carvalho Chehab, Hans Verkuil, linux-media, linux-kernel

Hi Laurent,

On Mon, 28 Sep 2026 14:44:23 +0300, Laurent Pinchart <laurent.pinchart@ideasonboard.com> wrote:
> That's a long commit message for such a simple change. Is it
> LLM-generated ? If so, you need an Assisted-by tag on this patch series.

Yes, the series was written with the help of an LLM (Claude Fable 5).
I will add

  Assisted-by: Claude:claude-fable-5

to all three patches and cut this commit message down to what the
change needs. Apologies for the verbosity.

> The code change looks fine.

Thanks.

Michael

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 3/3] media: uvcvideo: fix up missing AUTO_UPDATE on the OBSBOT Tiny 2
  2026-09-28 11:57   ` Laurent Pinchart
@ 2026-09-28 14:34     ` Michael Jordan
  2026-09-28 14:55       ` Hans de Goede
  2026-09-28 18:53       ` Laurent Pinchart
  0 siblings, 2 replies; 20+ messages in thread
From: Michael Jordan @ 2026-09-28 14:34 UTC (permalink / raw)
  To: Laurent Pinchart
  Cc: Michael Jordan, Hans de Goede, Ricardo Ribalda,
	Mauro Carvalho Chehab, Hans Verkuil, linux-media, linux-kernel

Hi Laurent,

On Mon, 28 Sep 2026 14:57:13 +0300, Laurent Pinchart <laurent.pinchart@ideasonboard.com> wrote:
> The device implements an interrupt endpoint. Does it report control
> change events for those controls ?

No. I checked today on both the Tiny 2 and the Tail 2, with the uvcvideo
status trace enabled (trace=0x200) and a stream running so the status
URB was submitted. Neither camera sent a single status packet during
commanded pan and zoom moves, or while its subject tracking changed
pan/tilt and zoom on its own. GET_CUR reported the live values
throughout.

> > The vendor has been asked to fix the firmware (support ticket #8220,
>
> Any public link ?

No, sorry. It is a private ticket filed through OBSBOT's support
channel, which is the only way I have found to contact them. I have the
confirmation email showing it was received and is awaiting a reply, and
can forward it if that is useful, but there has been no response since
2026-08-04.

> This belongs to the commit message.

Agreed, I will move it there.

With the Assisted-by tags and the shorter 2/3 message, that makes a v3.
Hans, let me know whether you would like me to send one, or would
rather fix these up when applying.

Michael

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 3/3] media: uvcvideo: fix up missing AUTO_UPDATE on the OBSBOT Tiny 2
  2026-09-28 11:18         ` Ricardo Ribalda
@ 2026-09-28 14:34           ` Michael Jordan
  0 siblings, 0 replies; 20+ messages in thread
From: Michael Jordan @ 2026-09-28 14:34 UTC (permalink / raw)
  To: Ricardo Ribalda
  Cc: Michael Jordan, Laurent Pinchart, Hans de Goede,
	Mauro Carvalho Chehab, Hans Verkuil, linux-media, linux-kernel

Hi Ricardo,

On Mon, 28 Sep 2026 13:18:18 +0200, Ricardo Ribalda <ribalda@chromium.org> wrote:
> Since Hans is going to merge your series today into the uvc tree you
> should do c) instead.

Will do: the Tail 2 entries will follow as a separate patch once the
series is applied.

> BTW, I am curious, did you hear anything back from OBSBOT?
> Could you also report this to them?

Nothing beyond the automatic confirmation; the ticket has been awaiting
a reply since 2026-08-04. Their support channel is the only way I have
found to reach them, so I will report the Tail 2 there as well. To be
honest my confidence that they will respond is low: both cameras work
fine on Windows and macOS, so I suspect this is not a priority for them.

Michael

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 3/3] media: uvcvideo: fix up missing AUTO_UPDATE on the OBSBOT Tiny 2
  2026-09-28 14:34     ` Michael Jordan
@ 2026-09-28 14:55       ` Hans de Goede
  2026-09-28 18:53       ` Laurent Pinchart
  1 sibling, 0 replies; 20+ messages in thread
From: Hans de Goede @ 2026-09-28 14:55 UTC (permalink / raw)
  To: Michael Jordan, Laurent Pinchart
  Cc: Ricardo Ribalda, Mauro Carvalho Chehab, Hans Verkuil,
	linux-media, linux-kernel

Hi,

On 28-Sep-26 16:34, Michael Jordan wrote:
> Hi Laurent,
> 
> On Mon, 28 Sep 2026 14:57:13 +0300, Laurent Pinchart <laurent.pinchart@ideasonboard.com> wrote:
>> The device implements an interrupt endpoint. Does it report control
>> change events for those controls ?
> 
> No. I checked today on both the Tiny 2 and the Tail 2, with the uvcvideo
> status trace enabled (trace=0x200) and a stream running so the status
> URB was submitted. Neither camera sent a single status packet during
> commanded pan and zoom moves, or while its subject tracking changed
> pan/tilt and zoom on its own. GET_CUR reported the live values
> throughout.
> 
>>> The vendor has been asked to fix the firmware (support ticket #8220,
>>
>> Any public link ?
> 
> No, sorry. It is a private ticket filed through OBSBOT's support
> channel, which is the only way I have found to contact them. I have the
> confirmation email showing it was received and is awaiting a reply, and
> can forward it if that is useful, but there has been no response since
> 2026-08-04.
> 
>> This belongs to the commit message.
> 
> Agreed, I will move it there.
> 
> With the Assisted-by tags and the shorter 2/3 message, that makes a v3.
> Hans, let me know whether you would like me to send one, or would
> rather fix these up when applying.

Laurent is also merging some patches atm, not sure what his plans
are for this series. With that said:

I plan to pick this up tomorrow morning, if you can send a full v3,
with the second cameras quirks also added as a patch 4/4 on top
of the updated original 3 patches that will make things easier for me
tomorrow morning.


Thanks & Regards,

Hans




^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v2 3/3] media: uvcvideo: fix up missing AUTO_UPDATE on the OBSBOT Tiny 2
  2026-09-28 14:34     ` Michael Jordan
  2026-09-28 14:55       ` Hans de Goede
@ 2026-09-28 18:53       ` Laurent Pinchart
  1 sibling, 0 replies; 20+ messages in thread
From: Laurent Pinchart @ 2026-09-28 18:53 UTC (permalink / raw)
  To: Michael Jordan
  Cc: Hans de Goede, Ricardo Ribalda, Mauro Carvalho Chehab,
	Hans Verkuil, linux-media, linux-kernel

On Mon, Sep 28, 2026 at 10:34:48AM -0400, Michael Jordan wrote:
> On Mon, 28 Sep 2026 14:57:13 +0300, Laurent Pinchart wrote:
> > The device implements an interrupt endpoint. Does it report control
> > change events for those controls ?
> 
> No. I checked today on both the Tiny 2 and the Tail 2, with the uvcvideo
> status trace enabled (trace=0x200) and a stream running so the status
> URB was submitted. Neither camera sent a single status packet during
> commanded pan and zoom moves, or while its subject tracking changed
> pan/tilt and zoom on its own. GET_CUR reported the live values
> throughout.
> 
> > > The vendor has been asked to fix the firmware (support ticket #8220,
> >
> > Any public link ?
> 
> No, sorry. It is a private ticket filed through OBSBOT's support
> channel, which is the only way I have found to contact them. I have the
> confirmation email showing it was received and is awaiting a reply, and
> can forward it if that is useful, but there has been no response since
> 2026-08-04.
> 
> > This belongs to the commit message.
> 
> Agreed, I will move it there.
> 
> With the Assisted-by tags and the shorter 2/3 message, that makes a v3.
> Hans, let me know whether you would like me to send one, or would
> rather fix these up when applying.

The long commit messages is a part that bothers me. Not only are they
long to read for the reviewers with a lot of unnecessary noise, they
convey a feeling that the LLM outputs are sent to the list without being
truly understood.

I'd be much happier if you shortened the commit messages to focus on the
useful information, conveying *your* understanding of the issue by
ditching the LLM text and writing the messages yourself.

-- 
Regards,

Laurent Pinchart

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2026-09-28 18:53 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-02  0:25 [PATCH v2 0/3] media: uvcvideo: live pan/tilt/zoom readback on the OBSBOT Tiny 2 Michael Jordan
2026-09-02  0:25 ` [PATCH v2 1/3] media: uvcvideo: report AUTO_UPDATE controls as volatile Michael Jordan
2026-09-02  0:25 ` [PATCH v2 2/3] media: uvcvideo: generalise the XU flags fixup to all controls Michael Jordan
2026-09-02  6:38   ` Ricardo Ribalda
2026-09-28 11:44   ` Laurent Pinchart
2026-09-28 14:34     ` Michael Jordan
2026-09-02  0:25 ` [PATCH v2 3/3] media: uvcvideo: fix up missing AUTO_UPDATE on the OBSBOT Tiny 2 Michael Jordan
2026-09-02  6:34   ` Ricardo Ribalda
2026-09-27 22:06     ` Michael Jordan
2026-09-28  6:57       ` Ricardo Ribalda
2026-09-28 11:18         ` Ricardo Ribalda
2026-09-28 14:34           ` Michael Jordan
2026-09-28 11:57   ` Laurent Pinchart
2026-09-28 14:34     ` Michael Jordan
2026-09-28 14:55       ` Hans de Goede
2026-09-28 18:53       ` Laurent Pinchart
2026-09-28 11:01 ` [PATCH v2 0/3] media: uvcvideo: live pan/tilt/zoom readback " Hans de Goede
2026-09-28 11:12   ` Ricardo Ribalda
2026-09-28 11:14     ` Hans de Goede
2026-09-28 11:49   ` Laurent Pinchart

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®