@@ -1322,9 +1322,25 @@ static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
break;
}
- if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN)
- v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN,
- uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
+ if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MIN) {
+ switch (v4l2_ctrl->id) {
+ case V4L2_CID_ZOOM_CONTINUOUS:
+ case V4L2_CID_PAN_SPEED:
+ case V4L2_CID_TILT_SPEED:
+ /*
+ * For the relative speed implementation the minimum
+ * value cannot be probed so it becomes the additive
+ * inverse of maximum.
+ */
+ v4l2_ctrl->minimum = -1 * mapping->get(mapping, UVC_GET_MAX,
+ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
+ break;
+ default:
+ v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN,
+ uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
+ break;
+ }
+ }
if (ctrl->info.flags & UVC_CTRL_FLAG_GET_MAX)
v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX,
@@ -1914,6 +1930,21 @@ int uvc_ctrl_set(struct uvc_fh *handle,
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
max = mapping->get(mapping, UVC_GET_MAX,
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
+
+ /*
+ * For the relative speed implementation the minimum
+ * value cannot be probed so it becomes the additive
+ * inverse of maximum.
+ */
+ switch (xctrl->id) {
+ case V4L2_CID_ZOOM_CONTINUOUS:
+ case V4L2_CID_PAN_SPEED:
+ case V4L2_CID_TILT_SPEED:
+ min = max * -1;
+ default:
+ break;
+ }
+
step = mapping->get(mapping, UVC_GET_RES,
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
if (step == 0)