aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYunke Cao <yunkec@google.com>2022-07-07 10:53:31 +0200
committerMauro Carvalho Chehab <mchehab@kernel.org>2022-08-30 16:09:41 +0200
commit5f36851c36b30f713f588ed2b60aa7b4512e2c76 (patch)
tree75a5107cc5d61afecd1d6c63de224a74a9f0ded7
parentmedia: uvcvideo: Fix typo 'the the' in comment (diff)
downloadlinux-dev-5f36851c36b30f713f588ed2b60aa7b4512e2c76.tar.xz
linux-dev-5f36851c36b30f713f588ed2b60aa7b4512e2c76.zip
media: uvcvideo: Use entity get_cur in uvc_ctrl_set
Entity controls should get_cur using an entity-defined function instead of via a query. Fix this in uvc_ctrl_set. Fixes: 65900c581d01 ("media: uvcvideo: Allow entity-defined get_info and get_cur") Signed-off-by: Yunke Cao <yunkec@google.com> Reviewed-by: Ricardo Ribalda <ribalda@chromium.org> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
-rw-r--r--drivers/media/usb/uvc/uvc_ctrl.c83
1 files changed, 46 insertions, 37 deletions
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c
index 5c33b0b7ef9a..97f312020516 100644
--- a/drivers/media/usb/uvc/uvc_ctrl.c
+++ b/drivers/media/usb/uvc/uvc_ctrl.c
@@ -985,36 +985,56 @@ static s32 __uvc_ctrl_get_value(struct uvc_control_mapping *mapping,
return value;
}
-static int __uvc_ctrl_get(struct uvc_video_chain *chain,
- struct uvc_control *ctrl, struct uvc_control_mapping *mapping,
- s32 *value)
+static int __uvc_ctrl_load_cur(struct uvc_video_chain *chain,
+ struct uvc_control *ctrl)
{
+ u8 *data;
int ret;
- if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0)
- return -EACCES;
+ if (ctrl->loaded)
+ return 0;
- if (!ctrl->loaded) {
- if (ctrl->entity->get_cur) {
- ret = ctrl->entity->get_cur(chain->dev,
- ctrl->entity,
- ctrl->info.selector,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
- ctrl->info.size);
- } else {
- ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
- ctrl->entity->id,
- chain->dev->intfnum,
- ctrl->info.selector,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
- ctrl->info.size);
- }
- if (ret < 0)
- return ret;
+ data = uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT);
+ if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) {
+ memset(data, 0, ctrl->info.size);
ctrl->loaded = 1;
+
+ return 0;
}
+ if (ctrl->entity->get_cur)
+ ret = ctrl->entity->get_cur(chain->dev, ctrl->entity,
+ ctrl->info.selector, data,
+ ctrl->info.size);
+ else
+ ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
+ ctrl->entity->id, chain->dev->intfnum,
+ ctrl->info.selector, data,
+ ctrl->info.size);
+
+ if (ret < 0)
+ return ret;
+
+ ctrl->loaded = 1;
+
+ return ret;
+}
+
+static int __uvc_ctrl_get(struct uvc_video_chain *chain,
+ struct uvc_control *ctrl,
+ struct uvc_control_mapping *mapping,
+ s32 *value)
+{
+ int ret;
+
+ if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0)
+ return -EACCES;
+
+ ret = __uvc_ctrl_load_cur(chain, ctrl);
+ if (ret < 0)
+ return ret;
+
*value = __uvc_ctrl_get_value(mapping,
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
@@ -1810,21 +1830,10 @@ int uvc_ctrl_set(struct uvc_fh *handle,
* needs to be loaded from the device to perform the read-modify-write
* operation.
*/
- if (!ctrl->loaded && (ctrl->info.size * 8) != mapping->size) {
- if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) {
- memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
- 0, ctrl->info.size);
- } else {
- ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
- ctrl->entity->id, chain->dev->intfnum,
- ctrl->info.selector,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
- ctrl->info.size);
- if (ret < 0)
- return ret;
- }
-
- ctrl->loaded = 1;
+ if ((ctrl->info.size * 8) != mapping->size) {
+ ret = __uvc_ctrl_load_cur(chain, ctrl);
+ if (ret < 0)
+ return ret;
}
/* Backup the current value in case we need to rollback later. */