Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 181722
b: refs/heads/master
c: e54532e
h: refs/heads/master
v: v3
  • Loading branch information
Laurent Pinchart authored and Mauro Carvalho Chehab committed Feb 26, 2010
1 parent 96e282f commit c610b11
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 59529081e092506edb81a42d914e2d0522f65ca7
refs/heads/master: e54532e591cd5b9ce77dbc8d9786ae9f600f101a
47 changes: 43 additions & 4 deletions trunk/drivers/media/video/uvc/uvc_ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1021,19 +1021,57 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
{
struct uvc_control *ctrl;
struct uvc_control_mapping *mapping;
s32 value = xctrl->value;
s32 value;
u32 step;
s32 min;
s32 max;
int ret;

ctrl = uvc_find_control(chain, xctrl->id, &mapping);
if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_SET_CUR) == 0)
return -EINVAL;

if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) {
if (value < 0 || value >= mapping->menu_count)
/* Clamp out of range values. */
switch (mapping->v4l2_type) {
case V4L2_CTRL_TYPE_INTEGER:
if (!ctrl->cached) {
ret = uvc_ctrl_populate_cache(chain, ctrl);
if (ret < 0)
return ret;
}

min = mapping->get(mapping, UVC_GET_MIN,
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
max = mapping->get(mapping, UVC_GET_MAX,
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
step = mapping->get(mapping, UVC_GET_RES,
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));

xctrl->value = min + (xctrl->value - min + step/2) / step * step;
xctrl->value = clamp(xctrl->value, min, max);
value = xctrl->value;
break;

case V4L2_CTRL_TYPE_BOOLEAN:
xctrl->value = clamp(xctrl->value, 0, 1);
value = xctrl->value;
break;

case V4L2_CTRL_TYPE_MENU:
if (xctrl->value < 0 || xctrl->value >= mapping->menu_count)
return -ERANGE;
value = mapping->menu_info[value].value;
value = mapping->menu_info[xctrl->value].value;
break;

default:
value = xctrl->value;
break;
}

/* If the mapping doesn't span the whole UVC control, the current value
* 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_CONTROL_GET_CUR) == 0) {
memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
Expand All @@ -1051,6 +1089,7 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
ctrl->loaded = 1;
}

/* Backup the current value in case we need to rollback later. */
if (!ctrl->dirty) {
memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/media/video/uvc/uvc_v4l2.c
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,8 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
return ret;
}
ret = uvc_ctrl_commit(chain);
if (ret == 0)
ctrl->value = xctrl.value;
break;
}

Expand Down

0 comments on commit c610b11

Please sign in to comment.