]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
media: uvcvideo: Allow custom control mapping
authorRicardo Ribalda <ribalda@chromium.org>
Mon, 10 Jun 2024 23:09:52 +0000 (23:09 +0000)
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Mon, 17 Jun 2024 20:21:10 +0000 (23:21 +0300)
Some advanced controls might not be completely implemented by vendors.

If the controls are a enumeration, UVC does not gives a way to probe
what is implemented and what is not.

Let's create a new callback function where heuristics can be implemented
to detect what is implemented and what not and update the control
mapping accordingly.

Reviewed-by: Sergey Senozhatsky <senozhatsky@chromium.org>
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Ricardo Ribalda <ribalda@chromium.org>
drivers/media/usb/uvc/uvc_ctrl.c
drivers/media/usb/uvc/uvcvideo.h

index a7d0ec22d95c05c166d38265a4f01ff8266db99f..c619370f9afdece3a7bcd5cd3a5f6202e64a6ac3 100644 (file)
@@ -2659,6 +2659,13 @@ static void uvc_ctrl_init_ctrl(struct uvc_video_chain *chain,
        for (i = 0; i < ARRAY_SIZE(uvc_ctrl_mappings); ++i) {
                const struct uvc_control_mapping *mapping = &uvc_ctrl_mappings[i];
 
+               /* Let the device provide a custom mapping. */
+               if (mapping->filter_mapping) {
+                       mapping = mapping->filter_mapping(chain, ctrl);
+                       if (!mapping)
+                               continue;
+               }
+
                if (uvc_entity_match_guid(ctrl->entity, mapping->entity) &&
                    ctrl->info.selector == mapping->selector)
                        __uvc_ctrl_add_mapping(chain, ctrl, mapping);
index f21207debd540d0b4c94ca4dcae50cea60d581d1..5cf5e194efd9fa1488757b36584c616fb3125b48 100644 (file)
@@ -87,7 +87,9 @@
 
 struct gpio_desc;
 struct sg_table;
+struct uvc_control;
 struct uvc_device;
+struct uvc_video_chain;
 
 /*
  * TODO: Put the most frequently accessed fields at the beginning of
@@ -126,6 +128,9 @@ struct uvc_control_mapping {
        s32 master_manual;
        u32 slave_ids[2];
 
+       const struct uvc_control_mapping *(*filter_mapping)
+                               (struct uvc_video_chain *chain,
+                               struct uvc_control *ctrl);
        s32 (*get)(struct uvc_control_mapping *mapping, u8 query,
                   const u8 *data);
        void (*set)(struct uvc_control_mapping *mapping, s32 value,