On Mon Feb 3 11:55:42 2025 +0000, Ricardo Ribalda wrote:
> We want to support fetching the min and max values with g_ext_ctrls,
> this patch is a preparation for that.
> 
> Instead of abusing uvc_query_v4l2_ctrl(), add an extra parameter to
> uvc_ctrl_get, so it can support fetching the default value.
> 
> Reviewed-by: Hans de Goede <hdego...@redhat.com>
> Tested-by: Yunke Cao <yun...@google.com>
> Signed-off-by: Ricardo Ribalda <riba...@chromium.org>
> Link: 
> https://lore.kernel.org/r/20250203-uvc-roi-v17-6-5900a9fed...@chromium.org
> Signed-off-by: Hans de Goede <hdego...@redhat.com>
> Signed-off-by: Hans Verkuil <hverk...@xs4all.nl>

Patch committed.

Thanks,
Hans Verkuil

 drivers/media/usb/uvc/uvc_ctrl.c | 21 ++++++++++++++++++---
 drivers/media/usb/uvc/uvc_v4l2.c | 28 +++++++++++-----------------
 drivers/media/usb/uvc/uvcvideo.h |  3 ++-
 3 files changed, 31 insertions(+), 21 deletions(-)

---

diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
index 3108d2fa1ff9..201af66a874d 100644
--- a/drivers/media/usb/uvc/uvc_ctrl.c
+++ b/drivers/media/usb/uvc/uvc_ctrl.c
@@ -1951,8 +1951,8 @@ done:
        return ret;
 }
 
-int uvc_ctrl_get(struct uvc_video_chain *chain,
-       struct v4l2_ext_control *xctrl)
+int uvc_ctrl_get(struct uvc_video_chain *chain, u32 which,
+                struct v4l2_ext_control *xctrl)
 {
        struct uvc_control *ctrl;
        struct uvc_control_mapping *mapping;
@@ -1964,7 +1964,22 @@ int uvc_ctrl_get(struct uvc_video_chain *chain,
        if (ctrl == NULL)
                return -EINVAL;
 
-       return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value);
+       switch (which) {
+       case V4L2_CTRL_WHICH_CUR_VAL:
+               return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value);
+       case V4L2_CTRL_WHICH_DEF_VAL:
+               if (!ctrl->cached) {
+                       int ret = uvc_ctrl_populate_cache(chain, ctrl);
+
+                       if (ret < 0)
+                               return ret;
+               }
+               xctrl->value = mapping->get(mapping, UVC_GET_DEF,
+                                           uvc_ctrl_data(ctrl, 
UVC_CTRL_DATA_DEF));
+               return 0;
+       }
+
+       return -EINVAL;
 }
 
 int uvc_ctrl_set(struct uvc_fh *handle,
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
index 93c6cdb23881..9493ab375f07 100644
--- a/drivers/media/usb/uvc/uvc_v4l2.c
+++ b/drivers/media/usb/uvc/uvc_v4l2.c
@@ -1027,34 +1027,28 @@ static int uvc_ioctl_g_ext_ctrls(struct file *file, 
void *fh,
        struct uvc_video_chain *chain = handle->chain;
        struct v4l2_ext_control *ctrl = ctrls->controls;
        unsigned int i;
+       u32 which;
        int ret;
 
+       switch (ctrls->which) {
+       case V4L2_CTRL_WHICH_DEF_VAL:
+       case V4L2_CTRL_WHICH_CUR_VAL:
+               which = ctrls->which;
+               break;
+       default:
+               which = V4L2_CTRL_WHICH_CUR_VAL;
+       }
+
        ret = uvc_ctrl_check_access(chain, ctrls, VIDIOC_G_EXT_CTRLS);
        if (ret < 0)
                return ret;
 
-       if (ctrls->which == V4L2_CTRL_WHICH_DEF_VAL) {
-               for (i = 0; i < ctrls->count; ++ctrl, ++i) {
-                       struct v4l2_queryctrl qc = { .id = ctrl->id };
-
-                       ret = uvc_query_v4l2_ctrl(chain, &qc);
-                       if (ret < 0) {
-                               ctrls->error_idx = i;
-                               return ret;
-                       }
-
-                       ctrl->value = qc.default_value;
-               }
-
-               return 0;
-       }
-
        ret = uvc_ctrl_begin(chain);
        if (ret < 0)
                return ret;
 
        for (i = 0; i < ctrls->count; ++ctrl, ++i) {
-               ret = uvc_ctrl_get(chain, ctrl);
+               ret = uvc_ctrl_get(chain, which, ctrl);
                if (ret < 0) {
                        uvc_ctrl_rollback(handle);
                        ctrls->error_idx = i;
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h
index 5e388f05f3fc..018613f98f48 100644
--- a/drivers/media/usb/uvc/uvcvideo.h
+++ b/drivers/media/usb/uvc/uvcvideo.h
@@ -793,7 +793,8 @@ static inline int uvc_ctrl_rollback(struct uvc_fh *handle)
        return __uvc_ctrl_commit(handle, 1, NULL);
 }
 
-int uvc_ctrl_get(struct uvc_video_chain *chain, struct v4l2_ext_control 
*xctrl);
+int uvc_ctrl_get(struct uvc_video_chain *chain, u32 which,
+                struct v4l2_ext_control *xctrl);
 int uvc_ctrl_set(struct uvc_fh *handle, struct v4l2_ext_control *xctrl);
 int uvc_ctrl_is_accessible(struct uvc_video_chain *chain, u32 v4l2_id,
                           const struct v4l2_ext_controls *ctrls,

Reply via email to