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>
This commit is contained in:
Yunke Cao 2022-07-07 10:53:31 +02:00 committed by Mauro Carvalho Chehab
parent 4c24425488
commit 5f36851c36

View File

@ -985,35 +985,55 @@ static s32 __uvc_ctrl_get_value(struct uvc_control_mapping *mapping,
return value; return value;
} }
static int __uvc_ctrl_load_cur(struct uvc_video_chain *chain,
struct uvc_control *ctrl)
{
u8 *data;
int ret;
if (ctrl->loaded)
return 0;
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, static int __uvc_ctrl_get(struct uvc_video_chain *chain,
struct uvc_control *ctrl, struct uvc_control_mapping *mapping, struct uvc_control *ctrl,
s32 *value) struct uvc_control_mapping *mapping,
s32 *value)
{ {
int ret; int ret;
if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0)
return -EACCES; return -EACCES;
if (!ctrl->loaded) { ret = __uvc_ctrl_load_cur(chain, ctrl);
if (ctrl->entity->get_cur) { if (ret < 0)
ret = ctrl->entity->get_cur(chain->dev, return ret;
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;
ctrl->loaded = 1;
}
*value = __uvc_ctrl_get_value(mapping, *value = __uvc_ctrl_get_value(mapping,
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT)); 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 * needs to be loaded from the device to perform the read-modify-write
* operation. * operation.
*/ */
if (!ctrl->loaded && (ctrl->info.size * 8) != mapping->size) { if ((ctrl->info.size * 8) != mapping->size) {
if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) { ret = __uvc_ctrl_load_cur(chain, ctrl);
memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), if (ret < 0)
0, ctrl->info.size); return ret;
} 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;
} }
/* Backup the current value in case we need to rollback later. */ /* Backup the current value in case we need to rollback later. */