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: 65900c581d
("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:
parent
4c24425488
commit
5f36851c36
@ -985,35 +985,55 @@ static s32 __uvc_ctrl_get_value(struct uvc_control_mapping *mapping,
|
||||
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,
|
||||
struct uvc_control *ctrl, struct uvc_control_mapping *mapping,
|
||||
s32 *value)
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
ctrl->loaded = 1;
|
||||
}
|
||||
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. */
|
||||
|
Loading…
Reference in New Issue
Block a user