diff options
Diffstat (limited to 'drivers/media/usb/uvc/uvc_ctrl.c')
| -rw-r--r-- | drivers/media/usb/uvc/uvc_ctrl.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index f7061a5ef1d..0eb82106d2f 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -664,7 +664,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .size = 32, .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_INTEGER, - .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED, + .data_type = UVC_CTRL_DATA_TYPE_SIGNED, }, { .id = V4L2_CID_TILT_ABSOLUTE, @@ -674,7 +674,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .size = 32, .offset = 32, .v4l2_type = V4L2_CTRL_TYPE_INTEGER, - .data_type = UVC_CTRL_DATA_TYPE_UNSIGNED, + .data_type = UVC_CTRL_DATA_TYPE_SIGNED, }, { .id = V4L2_CID_PRIVACY, @@ -927,7 +927,7 @@ static int __uvc_ctrl_get(struct uvc_video_chain *chain, int ret; if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0) - return -EINVAL; + return -EACCES; if (!ctrl->loaded) { ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, ctrl->entity->id, @@ -1431,8 +1431,10 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, int ret; ctrl = uvc_find_control(chain, xctrl->id, &mapping); - if (ctrl == NULL || (ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR) == 0) + if (ctrl == NULL) return -EINVAL; + if (!(ctrl->info.flags & UVC_CTRL_FLAG_SET_CUR)) + return -EACCES; /* Clamp out of range values. */ switch (mapping->v4l2_type) { @@ -1452,8 +1454,12 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, if (step == 0) step = 1; - xctrl->value = min + (xctrl->value - min + step/2) / step * step; - xctrl->value = clamp(xctrl->value, min, max); + xctrl->value = min + ((u32)(xctrl->value - min) + step / 2) + / step * step; + if (mapping->data_type == UVC_CTRL_DATA_TYPE_SIGNED) + xctrl->value = clamp(xctrl->value, min, max); + else + xctrl->value = clamp_t(u32, xctrl->value, min, max); value = xctrl->value; break; @@ -1481,7 +1487,7 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, step = mapping->get(mapping, UVC_GET_RES, uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES)); if (!(step & value)) - return -ERANGE; + return -EINVAL; } break; @@ -1832,7 +1838,7 @@ static int uvc_ctrl_add_info(struct uvc_device *dev, struct uvc_control *ctrl, { int ret = 0; - memcpy(&ctrl->info, info, sizeof(*info)); + ctrl->info = *info; INIT_LIST_HEAD(&ctrl->info.mappings); /* Allocate an array to save control values (cur, def, max, etc.) */ |
