Re: [linux-uvc-devel] [PATCH 1/1] media: uvcvideo: Add quirk for exponential exposure
Linux UVC driver and tools
Brought to you by:
pinchartl
|
From: Yuriy M. K. <yu...@gm...> - 2021-10-17 15:27:46
|
On 10/03/21 02:37 , Scott K Logan wrote:
> At least some of the Microsoft LifeCam series of webcams exhibit a
> behavior which requires a 'quirk' to be handled properly. When
> configuring the absolute exposure value of the image, there are only a
> handful of values which will result in a consistent change to the image
> exposure, while all other values appear to result in a maximum
> exposure.
> The valid values appear to follow an exponential pattern from the
> maximum value (10000) down to the minimum, yielding less than 15
> possible values depending on the device's reported minimum.
FTR, I have not tested patch (yet), but I checked
idVendor 0x045e Microsoft Corp.
idProduct 0x0810 LifeCam HD-3000
bcdDevice 1.08
iManufacturer 1
iProduct 2
iSerial 0
and it exhibit same behavior (only (1e4>>i) works, other values
interpreted as max), so you may want to add chunk below
> Signed-off-by: Scott K Logan <lo...@co...>
> ---
> drivers/media/usb/uvc/uvc_ctrl.c | 41 ++++++++++++++++++++++++++++++
> drivers/media/usb/uvc/uvc_driver.c | 18 +++++++++++++
> drivers/media/usb/uvc/uvcvideo.h | 1 +
> 3 files changed, 60 insertions(+)
>
> diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
> index 30bfe9069a1f..2dfc70597858 100644
> --- a/drivers/media/usb/uvc/uvc_ctrl.c
> +++ b/drivers/media/usb/uvc/uvc_ctrl.c
> @@ -2142,6 +2142,40 @@ int uvc_ctrl_restore_values(struct uvc_device *dev)
> return 0;
> }
>
> +/* --------------------------------------------------------------------------
> + * Quirks
> + */
> +
> +static s32 uvc_ctrl_get_abs_exposure_exponential(
> + struct uvc_control_mapping *mapping, u8 query, const u8 *data)
> +{
> + s32 i;
> + s32 value = uvc_get_le_value(mapping, query, data);
> +
> + switch (query) {
> + case UVC_GET_CUR:
> + case UVC_GET_MIN:
> + case UVC_GET_MAX:
> + case UVC_GET_DEF:
> + for (i = 0; i < 14; ++i) {
> + if (10000 >> i <= value)
> + break;
> + }
> + return 14 - i;
> + case UVC_GET_RES:
> + return 1;
> + default:
> + return value;
> + }
> +}
> +
> +static void uvc_ctrl_set_abs_exposure_exponential(
> + struct uvc_control_mapping *mapping, s32 value, u8 *data)
> +{
> + value = 10000 >> (14 - value);
> + uvc_set_le_value(mapping, value, data);
> +}
> +
> /* --------------------------------------------------------------------------
> * Control and mapping handling
> */
> @@ -2210,6 +2244,13 @@ static int __uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
> }
> }
>
> + if ((chain->dev->quirks & UVC_QUIRK_EXPONENTIAL_EXPOSURE) &&
> + ctrl->info.selector == UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL) {
> + uvc_dbg(chain->dev, CONTROL, "Applying exponential exposure quirk\n");
> + map->get = uvc_ctrl_get_abs_exposure_exponential;
> + map->set = uvc_ctrl_set_abs_exposure_exponential;
> + }
> +
> list_add_tail(&map->list, &ctrl->info.mappings);
> uvc_dbg(chain->dev, CONTROL, "Adding mapping '%s' to control %pUl/%u\n",
> uvc_map_get_name(map), ctrl->info.entity,
> diff --git a/drivers/media/usb/uvc/uvc_driver.c b/drivers/media/usb/uvc/uvc_driver.c
> index 7c007426e082..fa34802dfb33 100644
> --- a/drivers/media/usb/uvc/uvc_driver.c
> +++ b/drivers/media/usb/uvc/uvc_driver.c
> @@ -2718,6 +2718,24 @@ static const struct usb_device_id uvc_ids[] = {
> .bInterfaceSubClass = 1,
> .bInterfaceProtocol = 0,
> .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
> + /* Microsoft Lifecam HD-5000 */
> + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
> + | USB_DEVICE_ID_MATCH_INT_INFO,
> + .idVendor = 0x045e,
> + .idProduct = 0x076d,
> + .bInterfaceClass = USB_CLASS_VIDEO,
> + .bInterfaceSubClass = 1,
> + .bInterfaceProtocol = 0,
> + .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_EXPONENTIAL_EXPOSURE) },
+ /* Microsoft Lifecam HD-3000 */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x045e,
+ .idProduct = 0x0810,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_EXPONENTIAL_EXPOSURE) },
> + /* Microsoft Lifecam Studio */
> + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
> + | USB_DEVICE_ID_MATCH_INT_INFO,
> + .idVendor = 0x045e,
> + .idProduct = 0x0772,
> + .bInterfaceClass = USB_CLASS_VIDEO,
> + .bInterfaceSubClass = 1,
> + .bInterfaceProtocol = 0,
> + .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_EXPONENTIAL_EXPOSURE) },
> /* Logitech Quickcam Fusion */
> { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
> | USB_DEVICE_ID_MATCH_INT_INFO,
> diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
> index 2e5366143b81..b6d5ae0b1c90 100644
> --- a/drivers/media/usb/uvc/uvcvideo.h
> +++ b/drivers/media/usb/uvc/uvcvideo.h
> @@ -209,6 +209,7 @@
> #define UVC_QUIRK_RESTORE_CTRLS_ON_INIT 0x00000400
> #define UVC_QUIRK_FORCE_Y8 0x00000800
> #define UVC_QUIRK_FORCE_BPP 0x00001000
> +#define UVC_QUIRK_EXPONENTIAL_EXPOSURE 0x00002000
>
> /* Format flags */
> #define UVC_FMT_FLAG_COMPRESSED 0x00000001
> --
>
> 2.31.1
|