media: uvcvideo: Use entity get_cur in uvc_ctrl_set
[ Upstream commit5f36851c36
] 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> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
Родитель
6c5da92103
Коммит
23624abbc9
|
@ -988,35 +988,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));
|
||||
|
@ -1667,21 +1687,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. */
|
||||
|
|
Загрузка…
Ссылка в новой задаче