diff options
author | Michael Krufky <mkrufky@kernellabs.com> | 2009-09-15 11:14:17 -0400 |
---|---|---|
committer | Michael Krufky <mkrufky@kernellabs.com> | 2009-09-15 11:14:17 -0400 |
commit | b0d1e983e98ec9b72146c16d08b3409a418c62df (patch) | |
tree | b61e50f54f11599f31b476c477a69883597f5fad /linux/drivers/media/video/uvc | |
parent | 2c16279409d239adbbc884a308e71264ea02ef46 (diff) | |
parent | 219fe38bd79dab42db83cacc1f5444d0e27fa8ea (diff) | |
download | mediapointer-dvb-s2-b0d1e983e98ec9b72146c16d08b3409a418c62df.tar.gz mediapointer-dvb-s2-b0d1e983e98ec9b72146c16d08b3409a418c62df.tar.bz2 |
merge: ~mkrufky/tda18271
From: Michael Krufky <mkrufky@kernellabs.com>
Priority: normal
Signed-off-by: Michael Krufky <mkrufky@kernellabs.com>
Diffstat (limited to 'linux/drivers/media/video/uvc')
-rw-r--r-- | linux/drivers/media/video/uvc/Kconfig | 2 | ||||
-rw-r--r-- | linux/drivers/media/video/uvc/uvc_ctrl.c | 240 | ||||
-rw-r--r-- | linux/drivers/media/video/uvc/uvc_driver.c | 244 | ||||
-rw-r--r-- | linux/drivers/media/video/uvc/uvc_queue.c | 14 | ||||
-rw-r--r-- | linux/drivers/media/video/uvc/uvc_status.c | 31 | ||||
-rw-r--r-- | linux/drivers/media/video/uvc/uvc_v4l2.c | 61 | ||||
-rw-r--r-- | linux/drivers/media/video/uvc/uvc_video.c | 52 | ||||
-rw-r--r-- | linux/drivers/media/video/uvc/uvcvideo.h | 166 |
8 files changed, 385 insertions, 425 deletions
diff --git a/linux/drivers/media/video/uvc/Kconfig b/linux/drivers/media/video/uvc/Kconfig index c2d9760de..2956a7637 100644 --- a/linux/drivers/media/video/uvc/Kconfig +++ b/linux/drivers/media/video/uvc/Kconfig @@ -9,7 +9,7 @@ config USB_VIDEO_CLASS config USB_VIDEO_CLASS_INPUT_EVDEV bool "UVC input events device support" default y - depends on USB_VIDEO_CLASS && INPUT + depends on USB_VIDEO_CLASS=INPUT || INPUT=y ---help--- This option makes USB Video Class devices register an input device to report button events. diff --git a/linux/drivers/media/video/uvc/uvc_ctrl.c b/linux/drivers/media/video/uvc/uvc_ctrl.c index 7774ce6b5..81928f838 100644 --- a/linux/drivers/media/video/uvc/uvc_ctrl.c +++ b/linux/drivers/media/video/uvc/uvc_ctrl.c @@ -36,7 +36,7 @@ static struct uvc_control_info uvc_ctrls[] = { { .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_BRIGHTNESS_CONTROL, + .selector = UVC_PU_BRIGHTNESS_CONTROL, .index = 0, .size = 2, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE @@ -44,7 +44,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_CONTRAST_CONTROL, + .selector = UVC_PU_CONTRAST_CONTROL, .index = 1, .size = 2, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE @@ -52,7 +52,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_HUE_CONTROL, + .selector = UVC_PU_HUE_CONTROL, .index = 2, .size = 2, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE @@ -60,7 +60,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_SATURATION_CONTROL, + .selector = UVC_PU_SATURATION_CONTROL, .index = 3, .size = 2, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE @@ -68,7 +68,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_SHARPNESS_CONTROL, + .selector = UVC_PU_SHARPNESS_CONTROL, .index = 4, .size = 2, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE @@ -76,7 +76,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_GAMMA_CONTROL, + .selector = UVC_PU_GAMMA_CONTROL, .index = 5, .size = 2, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE @@ -84,7 +84,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_WHITE_BALANCE_TEMPERATURE_CONTROL, + .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL, .index = 6, .size = 2, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE @@ -92,7 +92,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_WHITE_BALANCE_COMPONENT_CONTROL, + .selector = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL, .index = 7, .size = 4, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE @@ -100,7 +100,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_BACKLIGHT_COMPENSATION_CONTROL, + .selector = UVC_PU_BACKLIGHT_COMPENSATION_CONTROL, .index = 8, .size = 2, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE @@ -108,7 +108,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_GAIN_CONTROL, + .selector = UVC_PU_GAIN_CONTROL, .index = 9, .size = 2, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE @@ -116,7 +116,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_POWER_LINE_FREQUENCY_CONTROL, + .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL, .index = 10, .size = 1, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE @@ -124,7 +124,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_HUE_AUTO_CONTROL, + .selector = UVC_PU_HUE_AUTO_CONTROL, .index = 11, .size = 1, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR @@ -132,7 +132,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL, + .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL, .index = 12, .size = 1, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR @@ -140,7 +140,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL, + .selector = UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL, .index = 13, .size = 1, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR @@ -148,7 +148,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_DIGITAL_MULTIPLIER_CONTROL, + .selector = UVC_PU_DIGITAL_MULTIPLIER_CONTROL, .index = 14, .size = 2, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE @@ -156,7 +156,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL, + .selector = UVC_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL, .index = 15, .size = 2, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE @@ -164,21 +164,21 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_ANALOG_VIDEO_STANDARD_CONTROL, + .selector = UVC_PU_ANALOG_VIDEO_STANDARD_CONTROL, .index = 16, .size = 1, .flags = UVC_CONTROL_GET_CUR, }, { .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_ANALOG_LOCK_STATUS_CONTROL, + .selector = UVC_PU_ANALOG_LOCK_STATUS_CONTROL, .index = 17, .size = 1, .flags = UVC_CONTROL_GET_CUR, }, { .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_SCANNING_MODE_CONTROL, + .selector = UVC_CT_SCANNING_MODE_CONTROL, .index = 0, .size = 1, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR @@ -186,7 +186,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_AE_MODE_CONTROL, + .selector = UVC_CT_AE_MODE_CONTROL, .index = 1, .size = 1, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR @@ -195,7 +195,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_AE_PRIORITY_CONTROL, + .selector = UVC_CT_AE_PRIORITY_CONTROL, .index = 2, .size = 1, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR @@ -203,7 +203,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_EXPOSURE_TIME_ABSOLUTE_CONTROL, + .selector = UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL, .index = 3, .size = 4, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE @@ -211,7 +211,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_EXPOSURE_TIME_RELATIVE_CONTROL, + .selector = UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL, .index = 4, .size = 1, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR @@ -219,7 +219,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_FOCUS_ABSOLUTE_CONTROL, + .selector = UVC_CT_FOCUS_ABSOLUTE_CONTROL, .index = 5, .size = 2, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE @@ -227,7 +227,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_FOCUS_RELATIVE_CONTROL, + .selector = UVC_CT_FOCUS_RELATIVE_CONTROL, .index = 6, .size = 2, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE @@ -235,7 +235,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_IRIS_ABSOLUTE_CONTROL, + .selector = UVC_CT_IRIS_ABSOLUTE_CONTROL, .index = 7, .size = 2, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE @@ -243,7 +243,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_IRIS_RELATIVE_CONTROL, + .selector = UVC_CT_IRIS_RELATIVE_CONTROL, .index = 8, .size = 1, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR @@ -251,7 +251,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_ZOOM_ABSOLUTE_CONTROL, + .selector = UVC_CT_ZOOM_ABSOLUTE_CONTROL, .index = 9, .size = 2, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE @@ -259,7 +259,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_ZOOM_RELATIVE_CONTROL, + .selector = UVC_CT_ZOOM_RELATIVE_CONTROL, .index = 10, .size = 3, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE @@ -267,7 +267,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_PANTILT_ABSOLUTE_CONTROL, + .selector = UVC_CT_PANTILT_ABSOLUTE_CONTROL, .index = 11, .size = 8, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE @@ -275,7 +275,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_PANTILT_RELATIVE_CONTROL, + .selector = UVC_CT_PANTILT_RELATIVE_CONTROL, .index = 12, .size = 4, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE @@ -283,7 +283,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_ROLL_ABSOLUTE_CONTROL, + .selector = UVC_CT_ROLL_ABSOLUTE_CONTROL, .index = 13, .size = 2, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE @@ -291,7 +291,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_ROLL_RELATIVE_CONTROL, + .selector = UVC_CT_ROLL_RELATIVE_CONTROL, .index = 14, .size = 2, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_RANGE @@ -299,7 +299,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_FOCUS_AUTO_CONTROL, + .selector = UVC_CT_FOCUS_AUTO_CONTROL, .index = 17, .size = 1, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR @@ -307,7 +307,7 @@ static struct uvc_control_info uvc_ctrls[] = { }, { .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_PRIVACY_CONTROL, + .selector = UVC_CT_PRIVACY_CONTROL, .index = 18, .size = 1, .flags = UVC_CONTROL_SET_CUR | UVC_CONTROL_GET_CUR @@ -334,13 +334,13 @@ static __s32 uvc_ctrl_get_zoom(struct uvc_control_mapping *mapping, __s8 zoom = (__s8)data[0]; switch (query) { - case GET_CUR: + case UVC_GET_CUR: return (zoom == 0) ? 0 : (zoom > 0 ? data[2] : -data[2]); - case GET_MIN: - case GET_MAX: - case GET_RES: - case GET_DEF: + case UVC_GET_MIN: + case UVC_GET_MAX: + case UVC_GET_RES: + case UVC_GET_DEF: default: return data[2]; } @@ -358,7 +358,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .id = V4L2_CID_BRIGHTNESS, .name = "Brightness", .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_BRIGHTNESS_CONTROL, + .selector = UVC_PU_BRIGHTNESS_CONTROL, .size = 16, .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_INTEGER, @@ -368,7 +368,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .id = V4L2_CID_CONTRAST, .name = "Contrast", .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_CONTRAST_CONTROL, + .selector = UVC_PU_CONTRAST_CONTROL, .size = 16, .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_INTEGER, @@ -378,7 +378,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .id = V4L2_CID_HUE, .name = "Hue", .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_HUE_CONTROL, + .selector = UVC_PU_HUE_CONTROL, .size = 16, .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_INTEGER, @@ -388,7 +388,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .id = V4L2_CID_SATURATION, .name = "Saturation", .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_SATURATION_CONTROL, + .selector = UVC_PU_SATURATION_CONTROL, .size = 16, .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_INTEGER, @@ -398,7 +398,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .id = V4L2_CID_SHARPNESS, .name = "Sharpness", .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_SHARPNESS_CONTROL, + .selector = UVC_PU_SHARPNESS_CONTROL, .size = 16, .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_INTEGER, @@ -408,7 +408,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .id = V4L2_CID_GAMMA, .name = "Gamma", .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_GAMMA_CONTROL, + .selector = UVC_PU_GAMMA_CONTROL, .size = 16, .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_INTEGER, @@ -418,7 +418,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .id = V4L2_CID_BACKLIGHT_COMPENSATION, .name = "Backlight Compensation", .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_BACKLIGHT_COMPENSATION_CONTROL, + .selector = UVC_PU_BACKLIGHT_COMPENSATION_CONTROL, .size = 16, .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_INTEGER, @@ -428,7 +428,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .id = V4L2_CID_GAIN, .name = "Gain", .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_GAIN_CONTROL, + .selector = UVC_PU_GAIN_CONTROL, .size = 16, .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_INTEGER, @@ -438,7 +438,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .id = V4L2_CID_POWER_LINE_FREQUENCY, .name = "Power Line Frequency", .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_POWER_LINE_FREQUENCY_CONTROL, + .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL, .size = 2, .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_MENU, @@ -450,7 +450,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .id = V4L2_CID_HUE_AUTO, .name = "Hue, Auto", .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_HUE_AUTO_CONTROL, + .selector = UVC_PU_HUE_AUTO_CONTROL, .size = 1, .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, @@ -460,7 +460,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .id = V4L2_CID_EXPOSURE_AUTO, .name = "Exposure, Auto", .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_AE_MODE_CONTROL, + .selector = UVC_CT_AE_MODE_CONTROL, .size = 4, .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_MENU, @@ -472,7 +472,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .id = V4L2_CID_EXPOSURE_AUTO_PRIORITY, .name = "Exposure, Auto Priority", .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_AE_PRIORITY_CONTROL, + .selector = UVC_CT_AE_PRIORITY_CONTROL, .size = 1, .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, @@ -482,7 +482,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .id = V4L2_CID_EXPOSURE_ABSOLUTE, .name = "Exposure (Absolute)", .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_EXPOSURE_TIME_ABSOLUTE_CONTROL, + .selector = UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL, .size = 32, .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_INTEGER, @@ -492,7 +492,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .id = V4L2_CID_AUTO_WHITE_BALANCE, .name = "White Balance Temperature, Auto", .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL, + .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL, .size = 1, .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, @@ -502,7 +502,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .id = V4L2_CID_WHITE_BALANCE_TEMPERATURE, .name = "White Balance Temperature", .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_WHITE_BALANCE_TEMPERATURE_CONTROL, + .selector = UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL, .size = 16, .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_INTEGER, @@ -512,7 +512,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .id = V4L2_CID_AUTO_WHITE_BALANCE, .name = "White Balance Component, Auto", .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL, + .selector = UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL, .size = 1, .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, @@ -522,7 +522,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .id = V4L2_CID_BLUE_BALANCE, .name = "White Balance Blue Component", .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_WHITE_BALANCE_COMPONENT_CONTROL, + .selector = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL, .size = 16, .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_INTEGER, @@ -532,7 +532,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .id = V4L2_CID_RED_BALANCE, .name = "White Balance Red Component", .entity = UVC_GUID_UVC_PROCESSING, - .selector = PU_WHITE_BALANCE_COMPONENT_CONTROL, + .selector = UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL, .size = 16, .offset = 16, .v4l2_type = V4L2_CTRL_TYPE_INTEGER, @@ -542,7 +542,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .id = V4L2_CID_FOCUS_ABSOLUTE, .name = "Focus (absolute)", .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_FOCUS_ABSOLUTE_CONTROL, + .selector = UVC_CT_FOCUS_ABSOLUTE_CONTROL, .size = 16, .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_INTEGER, @@ -552,7 +552,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .id = V4L2_CID_FOCUS_AUTO, .name = "Focus, Auto", .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_FOCUS_AUTO_CONTROL, + .selector = UVC_CT_FOCUS_AUTO_CONTROL, .size = 1, .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, @@ -562,7 +562,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .id = V4L2_CID_ZOOM_ABSOLUTE, .name = "Zoom, Absolute", .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_ZOOM_ABSOLUTE_CONTROL, + .selector = UVC_CT_ZOOM_ABSOLUTE_CONTROL, .size = 16, .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_INTEGER, @@ -572,7 +572,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .id = V4L2_CID_ZOOM_CONTINUOUS, .name = "Zoom, Continuous", .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_ZOOM_RELATIVE_CONTROL, + .selector = UVC_CT_ZOOM_RELATIVE_CONTROL, .size = 0, .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_INTEGER, @@ -584,7 +584,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { .id = V4L2_CID_PRIVACY, .name = "Privacy", .entity = UVC_GUID_UVC_CAMERA, - .selector = CT_PRIVACY_CONTROL, + .selector = UVC_CT_PRIVACY_CONTROL, .size = 1, .offset = 0, .v4l2_type = V4L2_CTRL_TYPE_BOOLEAN, @@ -677,16 +677,16 @@ static const __u8 uvc_media_transport_input_guid[16] = static int uvc_entity_match_guid(struct uvc_entity *entity, __u8 guid[16]) { switch (UVC_ENTITY_TYPE(entity)) { - case ITT_CAMERA: + case UVC_ITT_CAMERA: return memcmp(uvc_camera_guid, guid, 16) == 0; - case ITT_MEDIA_TRANSPORT_INPUT: + case UVC_ITT_MEDIA_TRANSPORT_INPUT: return memcmp(uvc_media_transport_input_guid, guid, 16) == 0; - case VC_PROCESSING_UNIT: + case UVC_VC_PROCESSING_UNIT: return memcmp(uvc_processing_guid, guid, 16) == 0; - case VC_EXTENSION_UNIT: + case UVC_VC_EXTENSION_UNIT: return memcmp(entity->extension.guidExtensionCode, guid, 16) == 0; @@ -795,11 +795,13 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video, v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { - if ((ret = uvc_query_ctrl(video->dev, GET_DEF, ctrl->entity->id, - video->dev->intfnum, ctrl->info->selector, - data, ctrl->info->size)) < 0) + ret = uvc_query_ctrl(video->dev, UVC_GET_DEF, ctrl->entity->id, + video->dev->intfnum, ctrl->info->selector, data, + ctrl->info->size); + if (ret < 0) goto out; - v4l2_ctrl->default_value = mapping->get(mapping, GET_DEF, data); + v4l2_ctrl->default_value = + mapping->get(mapping, UVC_GET_DEF, data); } switch (mapping->v4l2_type) { @@ -831,25 +833,28 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video, } if (ctrl->info->flags & UVC_CONTROL_GET_MIN) { - if ((ret = uvc_query_ctrl(video->dev, GET_MIN, ctrl->entity->id, - video->dev->intfnum, ctrl->info->selector, - data, ctrl->info->size)) < 0) + ret = uvc_query_ctrl(video->dev, UVC_GET_MIN, ctrl->entity->id, + video->dev->intfnum, ctrl->info->selector, data, + ctrl->info->size); + if (ret < 0) goto out; - v4l2_ctrl->minimum = mapping->get(mapping, GET_MIN, data); + v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN, data); } if (ctrl->info->flags & UVC_CONTROL_GET_MAX) { - if ((ret = uvc_query_ctrl(video->dev, GET_MAX, ctrl->entity->id, - video->dev->intfnum, ctrl->info->selector, - data, ctrl->info->size)) < 0) + ret = uvc_query_ctrl(video->dev, UVC_GET_MAX, ctrl->entity->id, + video->dev->intfnum, ctrl->info->selector, data, + ctrl->info->size); + if (ret < 0) goto out; - v4l2_ctrl->maximum = mapping->get(mapping, GET_MAX, data); + v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX, data); } if (ctrl->info->flags & UVC_CONTROL_GET_RES) { - if ((ret = uvc_query_ctrl(video->dev, GET_RES, ctrl->entity->id, - video->dev->intfnum, ctrl->info->selector, - data, ctrl->info->size)) < 0) + ret = uvc_query_ctrl(video->dev, UVC_GET_RES, ctrl->entity->id, + video->dev->intfnum, ctrl->info->selector, data, + ctrl->info->size); + if (ret < 0) goto out; - v4l2_ctrl->step = mapping->get(mapping, GET_RES, data); + v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES, data); } ret = 0; @@ -914,7 +919,7 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, continue; if (!rollback) - ret = uvc_query_ctrl(dev, SET_CUR, ctrl->entity->id, + ret = uvc_query_ctrl(dev, UVC_SET_CUR, ctrl->entity->id, dev->intfnum, ctrl->info->selector, uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), ctrl->info->size); @@ -976,7 +981,7 @@ int uvc_ctrl_get(struct uvc_video_device *video, return -EINVAL; if (!ctrl->loaded) { - ret = uvc_query_ctrl(video->dev, GET_CUR, ctrl->entity->id, + ret = uvc_query_ctrl(video->dev, UVC_GET_CUR, ctrl->entity->id, video->dev->intfnum, ctrl->info->selector, uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), ctrl->info->size); @@ -986,7 +991,7 @@ int uvc_ctrl_get(struct uvc_video_device *video, ctrl->loaded = 1; } - xctrl->value = mapping->get(mapping, GET_CUR, + xctrl->value = mapping->get(mapping, UVC_GET_CUR, uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT)); if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) { @@ -1025,7 +1030,7 @@ int uvc_ctrl_set(struct uvc_video_device *video, memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), 0, ctrl->info->size); } else { - ret = uvc_query_ctrl(video->dev, GET_CUR, + ret = uvc_query_ctrl(video->dev, UVC_GET_CUR, ctrl->entity->id, video->dev->intfnum, ctrl->info->selector, uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), @@ -1117,9 +1122,9 @@ int uvc_xu_ctrl_query(struct uvc_video_device *video, goto out; } - ret = uvc_query_ctrl(video->dev, set ? SET_CUR : GET_CUR, xctrl->unit, - video->dev->intfnum, xctrl->selector, data, - xctrl->size); + ret = uvc_query_ctrl(video->dev, set ? UVC_SET_CUR : UVC_GET_CUR, + xctrl->unit, video->dev->intfnum, xctrl->selector, + data, xctrl->size); if (ret < 0) goto out; @@ -1213,7 +1218,7 @@ static void uvc_ctrl_add_ctrl(struct uvc_device *dev, if (!found) return; - if (UVC_ENTITY_TYPE(entity) == VC_EXTENSION_UNIT) { + if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT) { /* Check if the device control information and length match * the user supplied information. */ @@ -1221,8 +1226,9 @@ static void uvc_ctrl_add_ctrl(struct uvc_device *dev, __le16 size; __u8 inf; - if ((ret = uvc_query_ctrl(dev, GET_LEN, ctrl->entity->id, - dev->intfnum, info->selector, (__u8 *)&size, 2)) < 0) { + ret = uvc_query_ctrl(dev, UVC_GET_LEN, ctrl->entity->id, + dev->intfnum, info->selector, (__u8 *)&size, 2); + if (ret < 0) { uvc_trace(UVC_TRACE_CONTROL, "GET_LEN failed on " "control " UVC_GUID_FORMAT "/%u (%d).\n", UVC_GUID_ARGS(info->entity), info->selector, @@ -1238,8 +1244,9 @@ static void uvc_ctrl_add_ctrl(struct uvc_device *dev, return; } - if ((ret = uvc_query_ctrl(dev, GET_INFO, ctrl->entity->id, - dev->intfnum, info->selector, &inf, 1)) < 0) { + ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id, + dev->intfnum, info->selector, &inf, 1); + if (ret < 0) { uvc_trace(UVC_TRACE_CONTROL, "GET_INFO failed on " "control " UVC_GUID_FORMAT "/%u (%d).\n", UVC_GUID_ARGS(info->entity), info->selector, @@ -1374,47 +1381,43 @@ end: } /* - * Prune an entity of its bogus controls. This currently includes processing - * unit auto controls for which no corresponding manual control is available. - * Such auto controls make little sense if any, and are known to crash at - * least the SiGma Micro webcam. + * Prune an entity of its bogus controls using a blacklist. Bogus controls + * are currently the ones that crash the camera or unconditionally return an + * error when queried. */ static void -uvc_ctrl_prune_entity(struct uvc_entity *entity) +uvc_ctrl_prune_entity(struct uvc_device *dev, struct uvc_entity *entity) { static const struct { - u8 idx_manual; - u8 idx_auto; + struct usb_device_id id; + u8 index; } blacklist[] = { - { 2, 11 }, /* Hue */ - { 6, 12 }, /* White Balance Temperature */ - { 7, 13 }, /* White Balance Component */ + { { USB_DEVICE(0x1c4f, 0x3000) }, 6 }, /* WB Temperature */ + { { USB_DEVICE(0x5986, 0x0241) }, 2 }, /* Hue */ }; u8 *controls; unsigned int size; unsigned int i; - if (UVC_ENTITY_TYPE(entity) != VC_PROCESSING_UNIT) + if (UVC_ENTITY_TYPE(entity) != UVC_VC_PROCESSING_UNIT) return; controls = entity->processing.bmControls; size = entity->processing.bControlSize; for (i = 0; i < ARRAY_SIZE(blacklist); ++i) { - if (blacklist[i].idx_auto >= 8 * size || - blacklist[i].idx_manual >= 8 * size) + if (!usb_match_id(dev->intf, &blacklist[i].id)) continue; - if (!uvc_test_bit(controls, blacklist[i].idx_auto) || - uvc_test_bit(controls, blacklist[i].idx_manual)) + if (blacklist[i].index >= 8 * size || + !uvc_test_bit(controls, blacklist[i].index)) continue; - uvc_trace(UVC_TRACE_CONTROL, "Auto control %u/%u has no " - "matching manual control, removing it.\n", entity->id, - blacklist[i].idx_auto); + uvc_trace(UVC_TRACE_CONTROL, "%u/%u control is black listed, " + "removing it.\n", entity->id, blacklist[i].index); - uvc_clear_bit(controls, blacklist[i].idx_auto); + uvc_clear_bit(controls, blacklist[i].index); } } @@ -1433,19 +1436,18 @@ int uvc_ctrl_init_device(struct uvc_device *dev) unsigned int bControlSize = 0, ncontrols = 0; __u8 *bmControls = NULL; - if (UVC_ENTITY_TYPE(entity) == VC_EXTENSION_UNIT) { + if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT) { bmControls = entity->extension.bmControls; bControlSize = entity->extension.bControlSize; - } else if (UVC_ENTITY_TYPE(entity) == VC_PROCESSING_UNIT) { + } else if (UVC_ENTITY_TYPE(entity) == UVC_VC_PROCESSING_UNIT) { bmControls = entity->processing.bmControls; bControlSize = entity->processing.bControlSize; - } else if (UVC_ENTITY_TYPE(entity) == ITT_CAMERA) { + } else if (UVC_ENTITY_TYPE(entity) == UVC_ITT_CAMERA) { bmControls = entity->camera.bmControls; bControlSize = entity->camera.bControlSize; } - if (dev->quirks & UVC_QUIRK_PRUNE_CONTROLS) - uvc_ctrl_prune_entity(entity); + uvc_ctrl_prune_entity(dev, entity); for (i = 0; i < bControlSize; ++i) ncontrols += hweight8(bmControls[i]); diff --git a/linux/drivers/media/video/uvc/uvc_driver.c b/linux/drivers/media/video/uvc/uvc_driver.c index 0d2d87198..1d09751a3 100644 --- a/linux/drivers/media/video/uvc/uvc_driver.c +++ b/linux/drivers/media/video/uvc/uvc_driver.c @@ -249,23 +249,23 @@ static struct uvc_entity *uvc_entity_by_reference(struct uvc_device *dev, list_for_each_entry_continue(entity, &dev->entities, list) { switch (UVC_ENTITY_TYPE(entity)) { - case TT_STREAMING: + case UVC_TT_STREAMING: if (entity->output.bSourceID == id) return entity; break; - case VC_PROCESSING_UNIT: + case UVC_VC_PROCESSING_UNIT: if (entity->processing.bSourceID == id) return entity; break; - case VC_SELECTOR_UNIT: + case UVC_VC_SELECTOR_UNIT: for (i = 0; i < entity->selector.bNrInPins; ++i) if (entity->selector.baSourceID[i] == id) return entity; break; - case VC_EXTENSION_UNIT: + case UVC_VC_EXTENSION_UNIT: for (i = 0; i < entity->extension.bNrInPins; ++i) if (entity->extension.baSourceID[i] == id) return entity; @@ -289,21 +289,19 @@ static int uvc_parse_format(struct uvc_device *dev, struct uvc_format_desc *fmtdesc; struct uvc_frame *frame; const unsigned char *start = buffer; - unsigned char *_buffer; unsigned int interval; unsigned int i, n; - int _buflen; __u8 ftype; format->type = buffer[2]; format->index = buffer[3]; switch (buffer[2]) { - case VS_FORMAT_UNCOMPRESSED: - case VS_FORMAT_FRAME_BASED: - n = buffer[2] == VS_FORMAT_UNCOMPRESSED ? 27 : 28; + case UVC_VS_FORMAT_UNCOMPRESSED: + case UVC_VS_FORMAT_FRAME_BASED: + n = buffer[2] == UVC_VS_FORMAT_UNCOMPRESSED ? 27 : 28; if (buflen < n) { - uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" + uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " "interface %d FORMAT error\n", dev->udev->devnum, alts->desc.bInterfaceNumber); @@ -327,18 +325,18 @@ static int uvc_parse_format(struct uvc_device *dev, } format->bpp = buffer[21]; - if (buffer[2] == VS_FORMAT_UNCOMPRESSED) { - ftype = VS_FRAME_UNCOMPRESSED; + if (buffer[2] == UVC_VS_FORMAT_UNCOMPRESSED) { + ftype = UVC_VS_FRAME_UNCOMPRESSED; } else { - ftype = VS_FRAME_FRAME_BASED; + ftype = UVC_VS_FRAME_FRAME_BASED; if (buffer[27]) format->flags = UVC_FMT_FLAG_COMPRESSED; } break; - case VS_FORMAT_MJPEG: + case UVC_VS_FORMAT_MJPEG: if (buflen < 11) { - uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" + uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " "interface %d FORMAT error\n", dev->udev->devnum, alts->desc.bInterfaceNumber); @@ -349,12 +347,12 @@ static int uvc_parse_format(struct uvc_device *dev, format->fcc = V4L2_PIX_FMT_MJPEG; format->flags = UVC_FMT_FLAG_COMPRESSED; format->bpp = 0; - ftype = VS_FRAME_MJPEG; + ftype = UVC_VS_FRAME_MJPEG; break; - case VS_FORMAT_DV: + case UVC_VS_FORMAT_DV: if (buflen < 9) { - uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" + uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " "interface %d FORMAT error\n", dev->udev->devnum, alts->desc.bInterfaceNumber); @@ -372,7 +370,7 @@ static int uvc_parse_format(struct uvc_device *dev, strlcpy(format->name, "HD-DV", sizeof format->name); break; default: - uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" + uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " "interface %d: unknown DV format %u\n", dev->udev->devnum, alts->desc.bInterfaceNumber, buffer[8]); @@ -397,11 +395,11 @@ static int uvc_parse_format(struct uvc_device *dev, format->nframes = 1; break; - case VS_FORMAT_MPEG2TS: - case VS_FORMAT_STREAM_BASED: + case UVC_VS_FORMAT_MPEG2TS: + case UVC_VS_FORMAT_STREAM_BASED: /* Not supported yet. */ default: - uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" + uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " "interface %d unsupported format %u\n", dev->udev->devnum, alts->desc.bInterfaceNumber, buffer[2]); @@ -413,21 +411,12 @@ static int uvc_parse_format(struct uvc_device *dev, buflen -= buffer[0]; buffer += buffer[0]; - /* Count the number of frame descriptors to test the bFrameIndex - * field when parsing the descriptors. We can't rely on the - * bNumFrameDescriptors field as some cameras don't initialize it - * properly. - */ - for (_buflen = buflen, _buffer = buffer; - _buflen > 2 && _buffer[2] == ftype; - _buflen -= _buffer[0], _buffer += _buffer[0]) - format->nframes++; - /* Parse the frame descriptors. Only uncompressed, MJPEG and frame * based formats have frame descriptors. */ while (buflen > 2 && buffer[2] == ftype) { - if (ftype != VS_FRAME_FRAME_BASED) + frame = &format->frame[format->nframes]; + if (ftype != UVC_VS_FRAME_FRAME_BASED) n = buflen > 25 ? buffer[25] : 0; else n = buflen > 21 ? buffer[21] : 0; @@ -435,29 +424,19 @@ static int uvc_parse_format(struct uvc_device *dev, n = n ? n : 3; if (buflen < 26 + 4*n) { - uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" + uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " "interface %d FRAME error\n", dev->udev->devnum, alts->desc.bInterfaceNumber); return -EINVAL; } - if (buffer[3] - 1 >= format->nframes) { - uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" - "interface %d frame index %u out of range\n", - dev->udev->devnum, alts->desc.bInterfaceNumber, - buffer[3]); - return -EINVAL; - } - - frame = &format->frame[buffer[3] - 1]; - frame->bFrameIndex = buffer[3]; frame->bmCapabilities = buffer[4]; frame->wWidth = get_unaligned_le16(&buffer[5]); frame->wHeight = get_unaligned_le16(&buffer[7]); frame->dwMinBitRate = get_unaligned_le32(&buffer[9]); frame->dwMaxBitRate = get_unaligned_le32(&buffer[13]); - if (ftype != VS_FRAME_FRAME_BASED) { + if (ftype != UVC_VS_FRAME_FRAME_BASED) { frame->dwMaxVideoFrameBufferSize = get_unaligned_le32(&buffer[17]); frame->dwDefaultFrameInterval = @@ -507,18 +486,19 @@ static int uvc_parse_format(struct uvc_device *dev, 10000000/frame->dwDefaultFrameInterval, (100000000/frame->dwDefaultFrameInterval)%10); + format->nframes++; buflen -= buffer[0]; buffer += buffer[0]; } - if (buflen > 2 && buffer[2] == VS_STILL_IMAGE_FRAME) { + if (buflen > 2 && buffer[2] == UVC_VS_STILL_IMAGE_FRAME) { buflen -= buffer[0]; buffer += buffer[0]; } - if (buflen > 2 && buffer[2] == VS_COLORFORMAT) { + if (buflen > 2 && buffer[2] == UVC_VS_COLORFORMAT) { if (buflen < 6) { - uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming" + uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " "interface %d COLORFORMAT error\n", dev->udev->devnum, alts->desc.bInterfaceNumber); @@ -550,7 +530,7 @@ static int uvc_parse_streaming(struct uvc_device *dev, int ret = -EINVAL; if (intf->cur_altsetting->desc.bInterfaceSubClass - != SC_VIDEOSTREAMING) { + != UVC_SC_VIDEOSTREAMING) { uvc_trace(UVC_TRACE_DESCR, "device %d interface %d isn't a " "video streaming interface\n", dev->udev->devnum, intf->altsetting[0].desc.bInterfaceNumber); @@ -609,12 +589,12 @@ static int uvc_parse_streaming(struct uvc_device *dev, /* Parse the header descriptor. */ switch (buffer[2]) { - case VS_OUTPUT_HEADER: + case UVC_VS_OUTPUT_HEADER: streaming->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; size = 9; break; - case VS_INPUT_HEADER: + case UVC_VS_INPUT_HEADER: streaming->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; size = 13; break; @@ -638,7 +618,7 @@ static int uvc_parse_streaming(struct uvc_device *dev, streaming->header.bNumFormats = p; streaming->header.bEndpointAddress = buffer[6]; - if (buffer[2] == VS_INPUT_HEADER) { + if (buffer[2] == UVC_VS_INPUT_HEADER) { streaming->header.bmInfo = buffer[7]; streaming->header.bTerminalLink = buffer[8]; streaming->header.bStillCaptureMethod = buffer[9]; @@ -664,15 +644,15 @@ static int uvc_parse_streaming(struct uvc_device *dev, _buflen = buflen; /* Count the format and frame descriptors. */ - while (_buflen > 2) { + while (_buflen > 2 && _buffer[1] == USB_DT_CS_INTERFACE) { switch (_buffer[2]) { - case VS_FORMAT_UNCOMPRESSED: - case VS_FORMAT_MJPEG: - case VS_FORMAT_FRAME_BASED: + case UVC_VS_FORMAT_UNCOMPRESSED: + case UVC_VS_FORMAT_MJPEG: + case UVC_VS_FORMAT_FRAME_BASED: nformats++; break; - case VS_FORMAT_DV: + case UVC_VS_FORMAT_DV: /* DV format has no frame descriptor. We will create a * dummy frame descriptor with a dummy frame interval. */ @@ -681,22 +661,22 @@ static int uvc_parse_streaming(struct uvc_device *dev, nintervals++; break; - case VS_FORMAT_MPEG2TS: - case VS_FORMAT_STREAM_BASED: + case UVC_VS_FORMAT_MPEG2TS: + case UVC_VS_FORMAT_STREAM_BASED: uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming " "interface %d FORMAT %u is not supported.\n", dev->udev->devnum, alts->desc.bInterfaceNumber, _buffer[2]); break; - case VS_FRAME_UNCOMPRESSED: - case VS_FRAME_MJPEG: + case UVC_VS_FRAME_UNCOMPRESSED: + case UVC_VS_FRAME_MJPEG: nframes++; if (_buflen > 25) nintervals += _buffer[25] ? _buffer[25] : 3; break; - case VS_FRAME_FRAME_BASED: + case UVC_VS_FRAME_FRAME_BASED: nframes++; if (_buflen > 21) nintervals += _buffer[21] ? _buffer[21] : 3; @@ -729,12 +709,12 @@ static int uvc_parse_streaming(struct uvc_device *dev, streaming->nformats = nformats; /* Parse the format descriptors. */ - while (buflen > 2) { + while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE) { switch (buffer[2]) { - case VS_FORMAT_UNCOMPRESSED: - case VS_FORMAT_MJPEG: - case VS_FORMAT_DV: - case VS_FORMAT_FRAME_BASED: + case UVC_VS_FORMAT_UNCOMPRESSED: + case UVC_VS_FORMAT_MJPEG: + case UVC_VS_FORMAT_DV: + case UVC_VS_FORMAT_FRAME_BASED: format->frame = frame; ret = uvc_parse_format(dev, streaming, format, &interval, buffer, buflen); @@ -839,7 +819,7 @@ static int uvc_parse_vendor_control(struct uvc_device *dev, return -ENOMEM; unit->id = buffer[3]; - unit->type = VC_EXTENSION_UNIT; + unit->type = UVC_VC_EXTENSION_UNIT; memcpy(unit->extension.guidExtensionCode, &buffer[4], 16); unit->extension.bNumControls = buffer[20]; unit->extension.bNrInPins = get_unaligned_le16(&buffer[21]); @@ -876,7 +856,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev, __u16 type; switch (buffer[2]) { - case VC_HEADER: + case UVC_VC_HEADER: n = buflen >= 12 ? buffer[11] : 0; if (buflen < 12 || buflen < 12 + n) { @@ -903,7 +883,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev, } break; - case VC_INPUT_TERMINAL: + case UVC_VC_INPUT_TERMINAL: if (buflen < 8) { uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol " "interface %d INPUT_TERMINAL error\n", @@ -928,11 +908,11 @@ static int uvc_parse_standard_control(struct uvc_device *dev, p = 0; len = 8; - if (type == ITT_CAMERA) { + if (type == UVC_ITT_CAMERA) { n = buflen >= 15 ? buffer[14] : 0; len = 15; - } else if (type == ITT_MEDIA_TRANSPORT_INPUT) { + } else if (type == UVC_ITT_MEDIA_TRANSPORT_INPUT) { n = buflen >= 9 ? buffer[8] : 0; p = buflen >= 10 + n ? buffer[9+n] : 0; len = 10; @@ -952,7 +932,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev, term->id = buffer[3]; term->type = type | UVC_TERM_INPUT; - if (UVC_ENTITY_TYPE(term) == ITT_CAMERA) { + if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) { term->camera.bControlSize = n; term->camera.bmControls = (__u8 *)term + sizeof *term; term->camera.wObjectiveFocalLengthMin = @@ -962,7 +942,8 @@ static int uvc_parse_standard_control(struct uvc_device *dev, term->camera.wOcularFocalLength = get_unaligned_le16(&buffer[12]); memcpy(term->camera.bmControls, &buffer[15], n); - } else if (UVC_ENTITY_TYPE(term) == ITT_MEDIA_TRANSPORT_INPUT) { + } else if (UVC_ENTITY_TYPE(term) == + UVC_ITT_MEDIA_TRANSPORT_INPUT) { term->media.bControlSize = n; term->media.bmControls = (__u8 *)term + sizeof *term; term->media.bTransportModeSize = p; @@ -975,9 +956,9 @@ static int uvc_parse_standard_control(struct uvc_device *dev, if (buffer[7] != 0) usb_string(udev, buffer[7], term->name, sizeof term->name); - else if (UVC_ENTITY_TYPE(term) == ITT_CAMERA) + else if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) sprintf(term->name, "Camera %u", buffer[3]); - else if (UVC_ENTITY_TYPE(term) == ITT_MEDIA_TRANSPORT_INPUT) + else if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT) sprintf(term->name, "Media %u", buffer[3]); else sprintf(term->name, "Input %u", buffer[3]); @@ -985,7 +966,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev, list_add_tail(&term->list, &dev->entities); break; - case VC_OUTPUT_TERMINAL: + case UVC_VC_OUTPUT_TERMINAL: if (buflen < 9) { uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol " "interface %d OUTPUT_TERMINAL error\n", @@ -1022,7 +1003,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev, list_add_tail(&term->list, &dev->entities); break; - case VC_SELECTOR_UNIT: + case UVC_VC_SELECTOR_UNIT: p = buflen >= 5 ? buffer[4] : 0; if (buflen < 5 || buflen < 6 + p) { @@ -1051,7 +1032,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev, list_add_tail(&unit->list, &dev->entities); break; - case VC_PROCESSING_UNIT: + case UVC_VC_PROCESSING_UNIT: n = buflen >= 8 ? buffer[7] : 0; p = dev->uvc_version >= 0x0110 ? 10 : 9; @@ -1086,7 +1067,7 @@ static int uvc_parse_standard_control(struct uvc_device *dev, list_add_tail(&unit->list, &dev->entities); break; - case VC_EXTENSION_UNIT: + case UVC_VC_EXTENSION_UNIT: p = buflen >= 22 ? buffer[21] : 0; n = buflen >= 24 + p ? buffer[22+p] : 0; @@ -1214,7 +1195,7 @@ static int uvc_scan_chain_entity(struct uvc_video_device *video, struct uvc_entity *entity) { switch (UVC_ENTITY_TYPE(entity)) { - case VC_EXTENSION_UNIT: + case UVC_VC_EXTENSION_UNIT: if (uvc_trace_param & UVC_TRACE_PROBE) printk(" <- XU %d", entity->id); @@ -1227,7 +1208,7 @@ static int uvc_scan_chain_entity(struct uvc_video_device *video, list_add_tail(&entity->chain, &video->extensions); break; - case VC_PROCESSING_UNIT: + case UVC_VC_PROCESSING_UNIT: if (uvc_trace_param & UVC_TRACE_PROBE) printk(" <- PU %d", entity->id); @@ -1240,7 +1221,7 @@ static int uvc_scan_chain_entity(struct uvc_video_device *video, video->processing = entity; break; - case VC_SELECTOR_UNIT: + case UVC_VC_SELECTOR_UNIT: if (uvc_trace_param & UVC_TRACE_PROBE) printk(" <- SU %d", entity->id); @@ -1257,16 +1238,16 @@ static int uvc_scan_chain_entity(struct uvc_video_device *video, video->selector = entity; break; - case ITT_VENDOR_SPECIFIC: - case ITT_CAMERA: - case ITT_MEDIA_TRANSPORT_INPUT: + case UVC_ITT_VENDOR_SPECIFIC: + case UVC_ITT_CAMERA: + case UVC_ITT_MEDIA_TRANSPORT_INPUT: if (uvc_trace_param & UVC_TRACE_PROBE) printk(" <- IT %d\n", entity->id); list_add_tail(&entity->chain, &video->iterms); break; - case TT_STREAMING: + case UVC_TT_STREAMING: if (uvc_trace_param & UVC_TRACE_PROBE) printk(" <- IT %d\n", entity->id); @@ -1311,12 +1292,12 @@ static int uvc_scan_chain_forward(struct uvc_video_device *video, if (forward == NULL) break; - if (UVC_ENTITY_TYPE(forward) != VC_EXTENSION_UNIT || + if (UVC_ENTITY_TYPE(forward) != UVC_VC_EXTENSION_UNIT || forward == prev) continue; if (forward->extension.bNrInPins != 1) { - uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has" + uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has " "more than 1 input pin.\n", entity->id); return -1; } @@ -1343,15 +1324,15 @@ static int uvc_scan_chain_backward(struct uvc_video_device *video, int id = -1, i; switch (UVC_ENTITY_TYPE(entity)) { - case VC_EXTENSION_UNIT: + case UVC_VC_EXTENSION_UNIT: id = entity->extension.baSourceID[0]; break; - case VC_PROCESSING_UNIT: + case UVC_VC_PROCESSING_UNIT: id = entity->processing.bSourceID; break; - case VC_SELECTOR_UNIT: + case UVC_VC_SELECTOR_UNIT: /* Single-input selector units are ignored. */ if (entity->selector.bNrInPins == 1) { id = entity->selector.baSourceID[0]; @@ -1397,7 +1378,7 @@ static int uvc_scan_chain(struct uvc_video_device *video) entity = video->oterm; uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain: OT %d", entity->id); - if (UVC_ENTITY_TYPE(entity) == TT_STREAMING) + if (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING) video->sterm = entity; id = entity->output.bSourceID; @@ -1614,6 +1595,7 @@ static int uvc_probe(struct usb_interface *intf, INIT_LIST_HEAD(&dev->entities); INIT_LIST_HEAD(&dev->streaming); kref_init(&dev->kref); + atomic_set(&dev->users, 0); dev->udev = usb_get_dev(udev); dev->intf = usb_get_intf(intf); @@ -1683,7 +1665,8 @@ static void uvc_disconnect(struct usb_interface *intf) */ usb_set_intfdata(intf, NULL); - if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOSTREAMING) + if (intf->cur_altsetting->desc.bInterfaceSubClass == + UVC_SC_VIDEOSTREAMING) return; /* uvc_v4l2_open() might race uvc_disconnect(). A static driver-wide @@ -1711,7 +1694,8 @@ static int uvc_suspend(struct usb_interface *intf, pm_message_t message) intf->cur_altsetting->desc.bInterfaceNumber); /* Controls are cached on the fly so they don't need to be saved. */ - if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOCONTROL) + if (intf->cur_altsetting->desc.bInterfaceSubClass == + UVC_SC_VIDEOCONTROL) return uvc_status_suspend(dev); if (dev->video.streaming->intf != intf) { @@ -1726,14 +1710,18 @@ static int uvc_suspend(struct usb_interface *intf, pm_message_t message) static int __uvc_resume(struct usb_interface *intf, int reset) { struct uvc_device *dev = usb_get_intfdata(intf); - int ret; uvc_trace(UVC_TRACE_SUSPEND, "Resuming interface %u\n", intf->cur_altsetting->desc.bInterfaceNumber); - if (intf->cur_altsetting->desc.bInterfaceSubClass == SC_VIDEOCONTROL) { - if (reset && (ret = uvc_ctrl_resume_device(dev)) < 0) - return ret; + if (intf->cur_altsetting->desc.bInterfaceSubClass == + UVC_SC_VIDEOCONTROL) { + if (reset) { + int ret = uvc_ctrl_resume_device(dev); + + if (ret < 0) + return ret; + } return uvc_status_resume(dev); } @@ -1863,11 +1851,29 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_STREAM_NO_FID }, - /* ViMicro */ + /* ViMicro Vega */ + { .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x0ac8, + .idProduct = 0x332d, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_FIX_BANDWIDTH }, + /* ViMicro - Minoru3D */ { .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, .idVendor = 0x0ac8, - .idProduct = 0x0000, + .idProduct = 0x3410, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_FIX_BANDWIDTH }, + /* ViMicro Venus - Minoru3D */ + { .match_flags = USB_DEVICE_ID_MATCH_VENDOR + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x0ac8, + .idProduct = 0x3420, .bInterfaceClass = USB_CLASS_VIDEO, .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, @@ -1880,7 +1886,8 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceClass = USB_CLASS_VIDEO, .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, - .driver_info = UVC_QUIRK_PROBE_MINMAX }, + .driver_info = UVC_QUIRK_PROBE_MINMAX + | UVC_QUIRK_PROBE_DEF }, /* Syntek (HP Spartan) */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -1917,7 +1924,16 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_STREAM_NO_FID }, - /* Lenovo Thinkpad SL500 */ + /* Syntek (JAOtech Smart Terminal) */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x174f, + .idProduct = 0x8a34, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_STREAM_NO_FID }, + /* Lenovo Thinkpad SL400/SL500 */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, .idVendor = 0x17ef, @@ -1926,6 +1942,16 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_STREAM_NO_FID }, + /* Aveo Technology USB 2.0 Camera */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x1871, + .idProduct = 0x0306, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_PROBE_MINMAX + | UVC_QUIRK_PROBE_EXTRAFIELDS }, /* Ecamm Pico iMage */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, @@ -1935,6 +1961,15 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_PROBE_EXTRAFIELDS }, + /* FSC WebCam V30S */ + { .match_flags = USB_DEVICE_ID_MATCH_DEVICE + | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x18ec, + .idProduct = 0x3288, + .bInterfaceClass = USB_CLASS_VIDEO, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 0, + .driver_info = UVC_QUIRK_PROBE_MINMAX }, /* Bodelin ProScopeHR */ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_HI @@ -1955,8 +1990,7 @@ static struct usb_device_id uvc_ids[] = { .bInterfaceSubClass = 1, .bInterfaceProtocol = 0, .driver_info = UVC_QUIRK_PROBE_MINMAX - | UVC_QUIRK_IGNORE_SELECTOR_UNIT - | UVC_QUIRK_PRUNE_CONTROLS }, + | UVC_QUIRK_IGNORE_SELECTOR_UNIT }, /* Generic USB Video Class */ { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) }, {} diff --git a/linux/drivers/media/video/uvc/uvc_queue.c b/linux/drivers/media/video/uvc/uvc_queue.c index 0155752e4..f854698c4 100644 --- a/linux/drivers/media/video/uvc/uvc_queue.c +++ b/linux/drivers/media/video/uvc/uvc_queue.c @@ -172,6 +172,20 @@ int uvc_free_buffers(struct uvc_video_queue *queue) return 0; } +/* + * Check if buffers have been allocated. + */ +int uvc_queue_allocated(struct uvc_video_queue *queue) +{ + int allocated; + + mutex_lock(&queue->mutex); + allocated = queue->count != 0; + mutex_unlock(&queue->mutex); + + return allocated; +} + static void __uvc_query_buffer(struct uvc_buffer *buf, struct v4l2_buffer *v4l2_buf) { diff --git a/linux/drivers/media/video/uvc/uvc_status.c b/linux/drivers/media/video/uvc/uvc_status.c index 4f4171fa8..b05df63b4 100644 --- a/linux/drivers/media/video/uvc/uvc_status.c +++ b/linux/drivers/media/video/uvc/uvc_status.c @@ -47,8 +47,8 @@ static int uvc_input_init(struct uvc_device *dev) input->cdev.dev = &dev->intf->dev; #endif - set_bit(EV_KEY, input->evbit); - set_bit(BTN_0, input->keybit); + __set_bit(EV_KEY, input->evbit); + __set_bit(KEY_CAMERA, input->keybit); if ((ret = input_register_device(input)) < 0) goto error; @@ -70,8 +70,10 @@ static void uvc_input_cleanup(struct uvc_device *dev) static void uvc_input_report_key(struct uvc_device *dev, unsigned int code, int value) { - if (dev->input) + if (dev->input) { input_report_key(dev->input, code, value); + input_sync(dev->input); + } } #else @@ -96,7 +98,7 @@ static void uvc_event_streaming(struct uvc_device *dev, __u8 *data, int len) return; uvc_trace(UVC_TRACE_STATUS, "Button (intf %u) %s len %d\n", data[1], data[3] ? "pressed" : "released", len); - uvc_input_report_key(dev, BTN_0, data[3]); + uvc_input_report_key(dev, KEY_CAMERA, data[3]); } else { uvc_trace(UVC_TRACE_STATUS, "Stream %u error event %02x %02x " "len %d.\n", data[1], data[2], data[3], len); @@ -204,7 +206,7 @@ int uvc_status_init(struct uvc_device *dev) dev->status, UVC_MAX_STATUS_SIZE, uvc_status_complete, dev, interval); - return usb_submit_urb(dev->int_urb, GFP_KERNEL); + return 0; } void uvc_status_cleanup(struct uvc_device *dev) @@ -215,15 +217,30 @@ void uvc_status_cleanup(struct uvc_device *dev) uvc_input_cleanup(dev); } -int uvc_status_suspend(struct uvc_device *dev) +int uvc_status_start(struct uvc_device *dev) +{ + if (dev->int_urb == NULL) + return 0; + + return usb_submit_urb(dev->int_urb, GFP_KERNEL); +} + +void uvc_status_stop(struct uvc_device *dev) { usb_kill_urb(dev->int_urb); +} + +int uvc_status_suspend(struct uvc_device *dev) +{ + if (atomic_read(&dev->users)) + usb_kill_urb(dev->int_urb); + return 0; } int uvc_status_resume(struct uvc_device *dev) { - if (dev->int_urb == NULL) + if (dev->int_urb == NULL || atomic_read(&dev->users) == 0) return 0; return usb_submit_urb(dev->int_urb, GFP_NOIO); diff --git a/linux/drivers/media/video/uvc/uvc_v4l2.c b/linux/drivers/media/video/uvc/uvc_v4l2.c index 0baa59f61..31a9ed4ff 100644 --- a/linux/drivers/media/video/uvc/uvc_v4l2.c +++ b/linux/drivers/media/video/uvc/uvc_v4l2.c @@ -46,6 +46,8 @@ static int uvc_v4l2_query_menu(struct uvc_video_device *video, struct uvc_menu_info *menu_info; struct uvc_control_mapping *mapping; struct uvc_control *ctrl; + u32 index = query_menu->index; + u32 id = query_menu->id; ctrl = uvc_find_control(video, query_menu->id, &mapping); if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) @@ -54,6 +56,10 @@ static int uvc_v4l2_query_menu(struct uvc_video_device *video, if (query_menu->index >= mapping->menu_count) return -EINVAL; + memset(query_menu, 0, sizeof(*query_menu)); + query_menu->id = id; + query_menu->index = index; + menu_info = &mapping->menu_info[query_menu->index]; strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name); return 0; @@ -245,7 +251,7 @@ static int uvc_v4l2_set_format(struct uvc_video_device *video, if (fmt->type != video->streaming->type) return -EINVAL; - if (uvc_queue_streaming(&video->queue)) + if (uvc_queue_allocated(&video->queue)) return -EBUSY; ret = uvc_v4l2_try_format(video, fmt, &probe, &format, &frame); @@ -437,6 +443,17 @@ static int uvc_v4l2_open(struct file *file) goto done; } + if (atomic_inc_return(&video->dev->users) == 1) { + if ((ret = uvc_status_start(video->dev)) < 0) { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) + usb_autopm_put_interface(video->dev->intf); +#endif + atomic_dec(&video->dev->users); + kfree(handle); + goto done; + } + } + handle->device = video; handle->state = UVC_HANDLE_PASSIVE; file->private_data = handle; @@ -471,6 +488,9 @@ static int uvc_v4l2_release(struct file *file) kfree(handle); file->private_data = NULL; + if (atomic_dec_return(&video->dev->users) == 0) + uvc_status_stop(video->dev); + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19) usb_autopm_put_interface(video->dev->intf); #endif @@ -518,7 +538,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) memset(&xctrl, 0, sizeof xctrl); xctrl.id = ctrl->id; - uvc_ctrl_begin(video); + ret = uvc_ctrl_begin(video); + if (ret < 0) + return ret; + ret = uvc_ctrl_get(video, &xctrl); uvc_ctrl_rollback(video); if (ret >= 0) @@ -535,7 +558,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) xctrl.id = ctrl->id; xctrl.value = ctrl->value; - uvc_ctrl_begin(video); + ret = uvc_ctrl_begin(video); + if (ret < 0) + return ret; + ret = uvc_ctrl_set(video, &xctrl); if (ret < 0) { uvc_ctrl_rollback(video); @@ -554,7 +580,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) struct v4l2_ext_control *ctrl = ctrls->controls; unsigned int i; - uvc_ctrl_begin(video); + ret = uvc_ctrl_begin(video); + if (ret < 0) + return ret; + for (i = 0; i < ctrls->count; ++ctrl, ++i) { ret = uvc_ctrl_get(video, ctrl); if (ret < 0) { @@ -627,7 +656,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) memset(input, 0, sizeof *input); input->index = index; strlcpy(input->name, iterm->name, sizeof input->name); - if (UVC_ENTITY_TYPE(iterm) == ITT_CAMERA) + if (UVC_ENTITY_TYPE(iterm) == UVC_ITT_CAMERA) input->type = V4L2_INPUT_TYPE_CAMERA; break; } @@ -642,9 +671,9 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) break; } - ret = uvc_query_ctrl(video->dev, GET_CUR, video->selector->id, - video->dev->intfnum, SU_INPUT_SELECT_CONTROL, - &input, 1); + ret = uvc_query_ctrl(video->dev, UVC_GET_CUR, + video->selector->id, video->dev->intfnum, + UVC_SU_INPUT_SELECT_CONTROL, &input, 1); if (ret < 0) return ret; @@ -654,7 +683,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) case VIDIOC_S_INPUT: { - u8 input = *(u32 *)arg + 1; + u32 input = *(u32 *)arg + 1; if ((ret = uvc_acquire_privileges(handle)) < 0) return ret; @@ -666,12 +695,12 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) break; } - if (input > video->selector->selector.bNrInPins) + if (input == 0 || input > video->selector->selector.bNrInPins) return -EINVAL; - return uvc_query_ctrl(video->dev, SET_CUR, video->selector->id, - video->dev->intfnum, SU_INPUT_SELECT_CONTROL, - &input, 1); + return uvc_query_ctrl(video->dev, UVC_SET_CUR, + video->selector->id, video->dev->intfnum, + UVC_SU_INPUT_SELECT_CONTROL, &input, 1); } /* Try, Get, Set & Enum format */ @@ -679,11 +708,17 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) { struct v4l2_fmtdesc *fmt = arg; struct uvc_format *format; + enum v4l2_buf_type type = fmt->type; + __u32 index = fmt->index; if (fmt->type != video->streaming->type || fmt->index >= video->streaming->nformats) return -EINVAL; + memset(fmt, 0, sizeof(*fmt)); + fmt->index = index; + fmt->type = type; + format = &video->streaming->format[fmt->index]; fmt->flags = 0; if (format->flags & UVC_FMT_FLAG_COMPRESSED) diff --git a/linux/drivers/media/video/uvc/uvc_video.c b/linux/drivers/media/video/uvc/uvc_video.c index 82a9999b6..f4f4e1bb3 100644 --- a/linux/drivers/media/video/uvc/uvc_video.c +++ b/linux/drivers/media/video/uvc/uvc_video.c @@ -65,7 +65,8 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video, struct uvc_streaming_control *ctrl) { struct uvc_format *format; - struct uvc_frame *frame; + struct uvc_frame *frame = NULL; + unsigned int i; if (ctrl->bFormatIndex <= 0 || ctrl->bFormatIndex > video->streaming->nformats) @@ -73,11 +74,15 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video, format = &video->streaming->format[ctrl->bFormatIndex - 1]; - if (ctrl->bFrameIndex <= 0 || - ctrl->bFrameIndex > format->nframes) - return; + for (i = 0; i < format->nframes; ++i) { + if (format->frame[i].bFrameIndex == ctrl->bFrameIndex) { + frame = &format->frame[i]; + break; + } + } - frame = &format->frame[ctrl->bFrameIndex - 1]; + if (frame == NULL) + return; if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) || (ctrl->dwMaxVideoFrameSize == 0 && @@ -123,11 +128,14 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video, if (data == NULL) return -ENOMEM; + if ((video->dev->quirks & UVC_QUIRK_PROBE_DEF) && query == UVC_GET_DEF) + return -EIO; + ret = __uvc_query_ctrl(video->dev, query, 0, video->streaming->intfnum, - probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size, - UVC_CTRL_STREAMING_TIMEOUT); + probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data, + size, UVC_CTRL_STREAMING_TIMEOUT); - if ((query == GET_MIN || query == GET_MAX) && ret == 2) { + if ((query == UVC_GET_MIN || query == UVC_GET_MAX) && ret == 2) { /* Some cameras, mostly based on Bison Electronics chipsets, * answer a GET_MIN or GET_MAX request with the wCompQuality * field only. @@ -139,7 +147,7 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video, ctrl->wCompQuality = le16_to_cpup((__le16 *)data); ret = 0; goto out; - } else if (query == GET_DEF && probe == 1 && ret != size) { + } else if (query == UVC_GET_DEF && probe == 1 && ret != size) { /* Many cameras don't support the GET_DEF request on their * video probe control. Warn once and return, the caller will * fall back to GET_CUR. @@ -227,10 +235,10 @@ static int uvc_set_video_ctrl(struct uvc_video_device *video, data[33] = ctrl->bMaxVersion; } - ret = __uvc_query_ctrl(video->dev, SET_CUR, 0, + ret = __uvc_query_ctrl(video->dev, UVC_SET_CUR, 0, video->streaming->intfnum, - probe ? VS_PROBE_CONTROL : VS_COMMIT_CONTROL, data, size, - UVC_CTRL_STREAMING_TIMEOUT); + probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data, + size, UVC_CTRL_STREAMING_TIMEOUT); if (ret != size) { uvc_printk(KERN_ERR, "Failed to set UVC %s control : " "%d (exp. %u).\n", probe ? "probe" : "commit", @@ -264,10 +272,10 @@ int uvc_probe_video(struct uvc_video_device *video, /* Get the minimum and maximum values for compression settings. */ if (!(video->dev->quirks & UVC_QUIRK_PROBE_MINMAX)) { - ret = uvc_get_video_ctrl(video, &probe_min, 1, GET_MIN); + ret = uvc_get_video_ctrl(video, &probe_min, 1, UVC_GET_MIN); if (ret < 0) goto done; - ret = uvc_get_video_ctrl(video, &probe_max, 1, GET_MAX); + ret = uvc_get_video_ctrl(video, &probe_max, 1, UVC_GET_MAX); if (ret < 0) goto done; @@ -275,8 +283,11 @@ int uvc_probe_video(struct uvc_video_device *video, } for (i = 0; i < 2; ++i) { - if ((ret = uvc_set_video_ctrl(video, probe, 1)) < 0 || - (ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0) + ret = uvc_set_video_ctrl(video, probe, 1); + if (ret < 0) + goto done; + ret = uvc_get_video_ctrl(video, probe, 1, UVC_GET_CUR); + if (ret < 0) goto done; if (video->streaming->intf->num_altsetting == 1) @@ -746,7 +757,7 @@ static int uvc_alloc_urb_buffers(struct uvc_video_device *video, /* Buffers are already allocated, bail out. */ if (video->urb_size) - return 0; + return video->urb_size / psize; /* Compute the number of packets. Bulk endpoints might transfer UVC * payloads accross multiple URBs. @@ -1064,7 +1075,7 @@ int uvc_video_init(struct uvc_video_device *video) * requests on the probe control will just keep their current streaming * parameters. */ - if (uvc_get_video_ctrl(video, probe, 1, GET_DEF) == 0) + if (uvc_get_video_ctrl(video, probe, 1, UVC_GET_DEF) == 0) uvc_set_video_ctrl(video, probe, 1); /* Initialize the streaming parameters with the probe control current @@ -1072,7 +1083,8 @@ int uvc_video_init(struct uvc_video_device *video) * control will always use values retrieved from a successful GET_CUR * request on the probe control, as required by the UVC specification. */ - if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0) + ret = uvc_get_video_ctrl(video, probe, 1, UVC_GET_CUR); + if (ret < 0) return ret; /* Check if the default format descriptor exists. Use the first @@ -1093,7 +1105,7 @@ int uvc_video_init(struct uvc_video_device *video) /* Zero bFrameIndex might be correct. Stream-based formats (including * MPEG-2 TS and DV) do not support frames but have a dummy frame * descriptor with bFrameIndex set to zero. If the default frame - * descriptor is not found, use the first avalable frame. + * descriptor is not found, use the first available frame. */ for (i = format->nframes; i > 0; --i) { frame = &format->frame[i-1]; diff --git a/linux/drivers/media/video/uvc/uvcvideo.h b/linux/drivers/media/video/uvc/uvcvideo.h index 53d5c9e0c..e700bdc20 100644 --- a/linux/drivers/media/video/uvc/uvcvideo.h +++ b/linux/drivers/media/video/uvc/uvcvideo.h @@ -67,156 +67,13 @@ struct uvc_xu_control { #ifdef __KERNEL__ #include <linux/poll.h> +#include <linux/usb/video.h> #include "compat.h" /* -------------------------------------------------------------------------- * UVC constants */ -#define SC_UNDEFINED 0x00 -#define SC_VIDEOCONTROL 0x01 -#define SC_VIDEOSTREAMING 0x02 -#define SC_VIDEO_INTERFACE_COLLECTION 0x03 - -#define PC_PROTOCOL_UNDEFINED 0x00 - -#define CS_UNDEFINED 0x20 -#define CS_DEVICE 0x21 -#define CS_CONFIGURATION 0x22 -#define CS_STRING 0x23 -#define CS_INTERFACE 0x24 -#define CS_ENDPOINT 0x25 - -/* VideoControl class specific interface descriptor */ -#define VC_DESCRIPTOR_UNDEFINED 0x00 -#define VC_HEADER 0x01 -#define VC_INPUT_TERMINAL 0x02 -#define VC_OUTPUT_TERMINAL 0x03 -#define VC_SELECTOR_UNIT 0x04 -#define VC_PROCESSING_UNIT 0x05 -#define VC_EXTENSION_UNIT 0x06 - -/* VideoStreaming class specific interface descriptor */ -#define VS_UNDEFINED 0x00 -#define VS_INPUT_HEADER 0x01 -#define VS_OUTPUT_HEADER 0x02 -#define VS_STILL_IMAGE_FRAME 0x03 -#define VS_FORMAT_UNCOMPRESSED 0x04 -#define VS_FRAME_UNCOMPRESSED 0x05 -#define VS_FORMAT_MJPEG 0x06 -#define VS_FRAME_MJPEG 0x07 -#define VS_FORMAT_MPEG2TS 0x0a -#define VS_FORMAT_DV 0x0c -#define VS_COLORFORMAT 0x0d -#define VS_FORMAT_FRAME_BASED 0x10 -#define VS_FRAME_FRAME_BASED 0x11 -#define VS_FORMAT_STREAM_BASED 0x12 - -/* Endpoint type */ -#define EP_UNDEFINED 0x00 -#define EP_GENERAL 0x01 -#define EP_ENDPOINT 0x02 -#define EP_INTERRUPT 0x03 - -/* Request codes */ -#define RC_UNDEFINED 0x00 -#define SET_CUR 0x01 -#define GET_CUR 0x81 -#define GET_MIN 0x82 -#define GET_MAX 0x83 -#define GET_RES 0x84 -#define GET_LEN 0x85 -#define GET_INFO 0x86 -#define GET_DEF 0x87 - -/* VideoControl interface controls */ -#define VC_CONTROL_UNDEFINED 0x00 -#define VC_VIDEO_POWER_MODE_CONTROL 0x01 -#define VC_REQUEST_ERROR_CODE_CONTROL 0x02 - -/* Terminal controls */ -#define TE_CONTROL_UNDEFINED 0x00 - -/* Selector Unit controls */ -#define SU_CONTROL_UNDEFINED 0x00 -#define SU_INPUT_SELECT_CONTROL 0x01 - -/* Camera Terminal controls */ -#define CT_CONTROL_UNDEFINED 0x00 -#define CT_SCANNING_MODE_CONTROL 0x01 -#define CT_AE_MODE_CONTROL 0x02 -#define CT_AE_PRIORITY_CONTROL 0x03 -#define CT_EXPOSURE_TIME_ABSOLUTE_CONTROL 0x04 -#define CT_EXPOSURE_TIME_RELATIVE_CONTROL 0x05 -#define CT_FOCUS_ABSOLUTE_CONTROL 0x06 -#define CT_FOCUS_RELATIVE_CONTROL 0x07 -#define CT_FOCUS_AUTO_CONTROL 0x08 -#define CT_IRIS_ABSOLUTE_CONTROL 0x09 -#define CT_IRIS_RELATIVE_CONTROL 0x0a -#define CT_ZOOM_ABSOLUTE_CONTROL 0x0b -#define CT_ZOOM_RELATIVE_CONTROL 0x0c -#define CT_PANTILT_ABSOLUTE_CONTROL 0x0d -#define CT_PANTILT_RELATIVE_CONTROL 0x0e -#define CT_ROLL_ABSOLUTE_CONTROL 0x0f -#define CT_ROLL_RELATIVE_CONTROL 0x10 -#define CT_PRIVACY_CONTROL 0x11 - -/* Processing Unit controls */ -#define PU_CONTROL_UNDEFINED 0x00 -#define PU_BACKLIGHT_COMPENSATION_CONTROL 0x01 -#define PU_BRIGHTNESS_CONTROL 0x02 -#define PU_CONTRAST_CONTROL 0x03 -#define PU_GAIN_CONTROL 0x04 -#define PU_POWER_LINE_FREQUENCY_CONTROL 0x05 -#define PU_HUE_CONTROL 0x06 -#define PU_SATURATION_CONTROL 0x07 -#define PU_SHARPNESS_CONTROL 0x08 -#define PU_GAMMA_CONTROL 0x09 -#define PU_WHITE_BALANCE_TEMPERATURE_CONTROL 0x0a -#define PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTROL 0x0b -#define PU_WHITE_BALANCE_COMPONENT_CONTROL 0x0c -#define PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL 0x0d -#define PU_DIGITAL_MULTIPLIER_CONTROL 0x0e -#define PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL 0x0f -#define PU_HUE_AUTO_CONTROL 0x10 -#define PU_ANALOG_VIDEO_STANDARD_CONTROL 0x11 -#define PU_ANALOG_LOCK_STATUS_CONTROL 0x12 - -#define LXU_MOTOR_PANTILT_RELATIVE_CONTROL 0x01 -#define LXU_MOTOR_PANTILT_RESET_CONTROL 0x02 -#define LXU_MOTOR_FOCUS_MOTOR_CONTROL 0x03 - -/* VideoStreaming interface controls */ -#define VS_CONTROL_UNDEFINED 0x00 -#define VS_PROBE_CONTROL 0x01 -#define VS_COMMIT_CONTROL 0x02 -#define VS_STILL_PROBE_CONTROL 0x03 -#define VS_STILL_COMMIT_CONTROL 0x04 -#define VS_STILL_IMAGE_TRIGGER_CONTROL 0x05 -#define VS_STREAM_ERROR_CODE_CONTROL 0x06 -#define VS_GENERATE_KEY_FRAME_CONTROL 0x07 -#define VS_UPDATE_FRAME_SEGMENT_CONTROL 0x08 -#define VS_SYNC_DELAY_CONTROL 0x09 - -#define TT_VENDOR_SPECIFIC 0x0100 -#define TT_STREAMING 0x0101 - -/* Input Terminal types */ -#define ITT_VENDOR_SPECIFIC 0x0200 -#define ITT_CAMERA 0x0201 -#define ITT_MEDIA_TRANSPORT_INPUT 0x0202 - -/* Output Terminal types */ -#define OTT_VENDOR_SPECIFIC 0x0300 -#define OTT_DISPLAY 0x0301 -#define OTT_MEDIA_TRANSPORT_OUTPUT 0x0302 - -/* External Terminal types */ -#define EXTERNAL_VENDOR_SPECIFIC 0x0400 -#define COMPOSITE_CONNECTOR 0x0401 -#define SVIDEO_CONNECTOR 0x0402 -#define COMPONENT_CONNECTOR 0x0403 - #define UVC_TERM_INPUT 0x0000 #define UVC_TERM_OUTPUT 0x8000 @@ -228,8 +85,6 @@ struct uvc_xu_control { #define UVC_ENTITY_IS_OTERM(entity) \ (((entity)->type & 0x8000) == UVC_TERM_OUTPUT) -#define UVC_STATUS_TYPE_CONTROL 1 -#define UVC_STATUS_TYPE_STREAMING 2 /* ------------------------------------------------------------------------ * GUIDs @@ -250,19 +105,6 @@ struct uvc_xu_control { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02} -#define UVC_GUID_LOGITECH_DEV_INFO \ - {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \ - 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x1e} -#define UVC_GUID_LOGITECH_USER_HW \ - {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \ - 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x1f} -#define UVC_GUID_LOGITECH_VIDEO \ - {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \ - 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x50} -#define UVC_GUID_LOGITECH_MOTOR \ - {0x82, 0x06, 0x61, 0x63, 0x70, 0x50, 0xab, 0x49, \ - 0xb8, 0xcc, 0xb3, 0x85, 0x5e, 0x8d, 0x22, 0x56} - #define UVC_GUID_FORMAT_MJPEG \ { 'M', 'J', 'P', 'G', 0x00, 0x00, 0x10, 0x00, \ 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71} @@ -314,8 +156,8 @@ struct uvc_xu_control { #define UVC_QUIRK_BUILTIN_ISIGHT 0x00000008 #define UVC_QUIRK_STREAM_NO_FID 0x00000010 #define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020 -#define UVC_QUIRK_PRUNE_CONTROLS 0x00000040 #define UVC_QUIRK_FIX_BANDWIDTH 0x00000080 +#define UVC_QUIRK_PROBE_DEF 0x00000100 /* Format flags */ #define UVC_FMT_FLAG_COMPRESSED 0x00000001 @@ -635,6 +477,7 @@ struct uvc_device { enum uvc_device_state state; struct kref kref; struct list_head list; + atomic_t users; /* Video control interface */ __u16 uvc_version; @@ -748,6 +591,7 @@ extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf); extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue, struct file *file, poll_table *wait); +extern int uvc_queue_allocated(struct uvc_video_queue *queue); static inline int uvc_queue_streaming(struct uvc_video_queue *queue) { return queue->flags & UVC_QUEUE_STREAMING; @@ -771,6 +615,8 @@ extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, /* Status */ extern int uvc_status_init(struct uvc_device *dev); extern void uvc_status_cleanup(struct uvc_device *dev); +extern int uvc_status_start(struct uvc_device *dev); +extern void uvc_status_stop(struct uvc_device *dev); extern int uvc_status_suspend(struct uvc_device *dev); extern int uvc_status_resume(struct uvc_device *dev); |