Re: [PATCH] media: uvcvideo: add capture quirks for 1e4e:7102

From: Ricardo Ribalda

Date: Fri Sep 18 2026 - 05:25:33 EST


Hi Henry

On Fri, 18 Sept 2026 at 02:35, Henry Paradiz <henry.paradiz@xxxxxxxxx> wrote:
>
> The eEver Live Streaming USB Device HDMI capture card (1e4e:7102,
> bcdDevice 1.00) exposes two problems when HDMI is connected but the
> input signal does not lock.


Could you please share the output of lsusb -v -d 1e4e:7102

>
> While idle, the device disconnects shortly after entering USB runtime
> suspend and repeatedly re-enumerates. Keeping it runtime-active stops
> this loop. Enable the existing UVC_QUIRK_DISABLE_AUTOSUSPEND for this
> USB ID to avoid the repeated USB, UVC and USB-audio discovery messages.
> Normal USB disconnect handling is preserved.
>
> On each enumeration, VIDIOC_TRY_FMT takes about 920 ms per call because
> uvcvideo negotiates with the device through UVC probe control transfers.
> PipeWire queries nine MJPEG frame sizes for colorimetry on its main loop,
> blocking unrelated audio mute and volume requests for roughly eight
> seconds while audio playback continues on a separate thread.

Isn't this a userspace or device issue?
If VIDIOC_TRY_FMT stalls the device, shouldn't you simply not call
VIDIOC_TRY_FMT?

This looks more like a hack than a quirk.

>
> Add UVC_QUIRK_SKIP_TRY_FMT_PROBE to answer this device's TRY_FMT calls
> using the parsed format and frame descriptors. The advertised frame
> buffer sizes match the observed probe results for all nine resolutions.
> S_FMT continues to negotiate with the hardware, and other devices retain
> their existing TRY_FMT behavior.
>
> Both quirks are enabled by one device-specific entry. The card can still
> provide diagnostic frames without an HDMI signal; HDMI signal recovery
> and capture configuration continue through the normal driver paths.
>
> Signed-off-by: Henry Paradiz <henry.paradiz@xxxxxxxxx>
> ---
> drivers/media/usb/uvc/uvc_driver.c | 4 ++++
> drivers/media/usb/uvc/uvc_v4l2.c | 19 ++++++++++++-------
> drivers/media/usb/uvc/uvcvideo.h | 1 +
> 3 files changed, 17 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
> --- a/drivers/media/usb/uvc/uvc_driver.c
> +++ b/drivers/media/usb/uvc/uvc_driver.c
> @@ -3055,6 +3055,10 @@
> .bInterfaceSubClass = 1,
> .bInterfaceProtocol = 0,
> .driver_info = (kernel_ulong_t)&uvc_quirk_probe_def },
> + /* eEver Live Streaming USB Device HDMI capture */
> + { USB_DEVICE_AND_INTERFACE_INFO(0x1e4e, 0x7102, USB_CLASS_VIDEO, 1, 0),

Please keep the list sorted by vid:pid

> + .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_SKIP_TRY_FMT_PROBE
> + | UVC_QUIRK_DISABLE_AUTOSUSPEND) },
> /* The Imaging Source USB CCD cameras */
> { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
> | USB_DEVICE_ID_MATCH_INT_INFO,
> diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
> --- a/drivers/media/usb/uvc/uvc_v4l2.c
> +++ b/drivers/media/usb/uvc/uvc_v4l2.c
> @@ -241,7 +241,7 @@
> static int uvc_v4l2_try_format(struct uvc_streaming *stream,
> struct v4l2_format *fmt, struct uvc_streaming_control *probe,
> const struct uvc_format **uvc_format,
> - const struct uvc_frame **uvc_frame)
> + const struct uvc_frame **uvc_frame, bool probe_device)
> {
> const struct uvc_format *format = NULL;
> const struct uvc_frame *frame = NULL;
> @@ -336,10 +336,14 @@
> probe->dwMaxVideoFrameSize =
> stream->ctrl.dwMaxVideoFrameSize;
>
> - /* Probe the device. */
> - ret = uvc_probe_video(stream, probe);
> - if (ret < 0)
> - return ret;
> + /* Some devices stall on probes during idle format enumeration. */
> + if (probe_device) {
> + ret = uvc_probe_video(stream, probe);
> + if (ret < 0)
> + return ret;
> + } else {
> + probe->dwMaxVideoFrameSize = frame->dwMaxVideoFrameBufferSize;
> + }
>
> /*
> * After the probe, update fmt with the values returned from
> @@ -432,7 +436,7 @@
> if (fmt->type != stream->type)
> return -EINVAL;
>
> - ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame);
> + ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame, true);
> if (ret < 0)
> return ret;
>
> @@ -649,7 +653,8 @@
> struct uvc_streaming *stream = handle->stream;
> struct uvc_streaming_control probe;
>
> - return uvc_v4l2_try_format(stream, fmt, &probe, NULL, NULL);
> + return uvc_v4l2_try_format(stream, fmt, &probe, NULL, NULL,
> + !(stream->dev->quirks & UVC_QUIRK_SKIP_TRY_FMT_PROBE));
> }
>
> static int uvc_ioctl_enum_input(struct file *file, void *priv,
> diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
> --- 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_SKIP_TRY_FMT_PROBE 0x00080000
>
> /* Format flags */
> #define UVC_FMT_FLAG_COMPRESSED 0x00000001
>


--
Ricardo Ribalda