Commit 5f36851c authored by Yunke Cao's avatar Yunke Cao Committed by Mauro Carvalho Chehab

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: 65900c58 ("media: uvcvideo: Allow entity-defined get_info and get_cur")
Signed-off-by: default avatarYunke Cao <yunkec@google.com>
Reviewed-by: default avatarRicardo Ribalda <ribalda@chromium.org>
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent 4c244254
...@@ -985,36 +985,56 @@ static s32 __uvc_ctrl_get_value(struct uvc_control_mapping *mapping, ...@@ -985,36 +985,56 @@ static s32 __uvc_ctrl_get_value(struct uvc_control_mapping *mapping,
return value; return value;
} }
static int __uvc_ctrl_get(struct uvc_video_chain *chain, static int __uvc_ctrl_load_cur(struct uvc_video_chain *chain,
struct uvc_control *ctrl, struct uvc_control_mapping *mapping, struct uvc_control *ctrl)
s32 *value)
{ {
u8 *data;
int ret; int ret;
if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) if (ctrl->loaded)
return -EACCES; return 0;
if (!ctrl->loaded) { data = uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT);
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;
if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) {
memset(data, 0, ctrl->info.size);
ctrl->loaded = 1; 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, *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, ...@@ -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. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment