Skip to content

Commit 5f36851

Browse files
Yunke Caomchehab
authored andcommitted
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: 65900c5 ("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>
1 parent 4c24425 commit 5f36851

File tree

1 file changed

+46
-37
lines changed

1 file changed

+46
-37
lines changed

drivers/media/usb/uvc/uvc_ctrl.c

Lines changed: 46 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -985,36 +985,56 @@ static s32 __uvc_ctrl_get_value(struct uvc_control_mapping *mapping,
985985
return value;
986986
}
987987

988-
static int __uvc_ctrl_get(struct uvc_video_chain *chain,
989-
struct uvc_control *ctrl, struct uvc_control_mapping *mapping,
990-
s32 *value)
988+
static int __uvc_ctrl_load_cur(struct uvc_video_chain *chain,
989+
struct uvc_control *ctrl)
991990
{
991+
u8 *data;
992992
int ret;
993993

994-
if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0)
995-
return -EACCES;
994+
if (ctrl->loaded)
995+
return 0;
996996

997-
if (!ctrl->loaded) {
998-
if (ctrl->entity->get_cur) {
999-
ret = ctrl->entity->get_cur(chain->dev,
1000-
ctrl->entity,
1001-
ctrl->info.selector,
1002-
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1003-
ctrl->info.size);
1004-
} else {
1005-
ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
1006-
ctrl->entity->id,
1007-
chain->dev->intfnum,
1008-
ctrl->info.selector,
1009-
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1010-
ctrl->info.size);
1011-
}
1012-
if (ret < 0)
1013-
return ret;
997+
data = uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT);
1014998

999+
if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) {
1000+
memset(data, 0, ctrl->info.size);
10151001
ctrl->loaded = 1;
1002+
1003+
return 0;
10161004
}
10171005

1006+
if (ctrl->entity->get_cur)
1007+
ret = ctrl->entity->get_cur(chain->dev, ctrl->entity,
1008+
ctrl->info.selector, data,
1009+
ctrl->info.size);
1010+
else
1011+
ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
1012+
ctrl->entity->id, chain->dev->intfnum,
1013+
ctrl->info.selector, data,
1014+
ctrl->info.size);
1015+
1016+
if (ret < 0)
1017+
return ret;
1018+
1019+
ctrl->loaded = 1;
1020+
1021+
return ret;
1022+
}
1023+
1024+
static int __uvc_ctrl_get(struct uvc_video_chain *chain,
1025+
struct uvc_control *ctrl,
1026+
struct uvc_control_mapping *mapping,
1027+
s32 *value)
1028+
{
1029+
int ret;
1030+
1031+
if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0)
1032+
return -EACCES;
1033+
1034+
ret = __uvc_ctrl_load_cur(chain, ctrl);
1035+
if (ret < 0)
1036+
return ret;
1037+
10181038
*value = __uvc_ctrl_get_value(mapping,
10191039
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
10201040

@@ -1810,21 +1830,10 @@ int uvc_ctrl_set(struct uvc_fh *handle,
18101830
* needs to be loaded from the device to perform the read-modify-write
18111831
* operation.
18121832
*/
1813-
if (!ctrl->loaded && (ctrl->info.size * 8) != mapping->size) {
1814-
if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) {
1815-
memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1816-
0, ctrl->info.size);
1817-
} else {
1818-
ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
1819-
ctrl->entity->id, chain->dev->intfnum,
1820-
ctrl->info.selector,
1821-
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1822-
ctrl->info.size);
1823-
if (ret < 0)
1824-
return ret;
1825-
}
1826-
1827-
ctrl->loaded = 1;
1833+
if ((ctrl->info.size * 8) != mapping->size) {
1834+
ret = __uvc_ctrl_load_cur(chain, ctrl);
1835+
if (ret < 0)
1836+
return ret;
18281837
}
18291838

18301839
/* Backup the current value in case we need to rollback later. */

0 commit comments

Comments
 (0)