diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/uvc/uvc_driver.c | 9 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvc_video.c | 34 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvcvideo.h | 1 |
3 files changed, 40 insertions, 4 deletions
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c index ebcd5bf0edb7..22e2783ac555 100644 --- a/drivers/media/video/uvc/uvc_driver.c +++ b/drivers/media/video/uvc/uvc_driver.c | |||
@@ -1861,6 +1861,15 @@ static struct usb_device_id uvc_ids[] = { | |||
1861 | .bInterfaceSubClass = 1, | 1861 | .bInterfaceSubClass = 1, |
1862 | .bInterfaceProtocol = 0, | 1862 | .bInterfaceProtocol = 0, |
1863 | .driver_info = UVC_QUIRK_STREAM_NO_FID }, | 1863 | .driver_info = UVC_QUIRK_STREAM_NO_FID }, |
1864 | /* ViMicro */ | ||
1865 | { .match_flags = USB_DEVICE_ID_MATCH_VENDOR | ||
1866 | | USB_DEVICE_ID_MATCH_INT_INFO, | ||
1867 | .idVendor = 0x0ac8, | ||
1868 | .idProduct = 0x0000, | ||
1869 | .bInterfaceClass = USB_CLASS_VIDEO, | ||
1870 | .bInterfaceSubClass = 1, | ||
1871 | .bInterfaceProtocol = 0, | ||
1872 | .driver_info = UVC_QUIRK_FIX_BANDWIDTH }, | ||
1864 | /* MT6227 */ | 1873 | /* MT6227 */ |
1865 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE | 1874 | { .match_flags = USB_DEVICE_ID_MATCH_DEVICE |
1866 | | USB_DEVICE_ID_MATCH_INT_INFO, | 1875 | | USB_DEVICE_ID_MATCH_INT_INFO, |
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 0789ba381fc1..a95e17329c5b 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c | |||
@@ -61,7 +61,7 @@ int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit, | |||
61 | return 0; | 61 | return 0; |
62 | } | 62 | } |
63 | 63 | ||
64 | static void uvc_fixup_buffer_size(struct uvc_video_device *video, | 64 | static void uvc_fixup_video_ctrl(struct uvc_video_device *video, |
65 | struct uvc_streaming_control *ctrl) | 65 | struct uvc_streaming_control *ctrl) |
66 | { | 66 | { |
67 | struct uvc_format *format; | 67 | struct uvc_format *format; |
@@ -84,6 +84,31 @@ static void uvc_fixup_buffer_size(struct uvc_video_device *video, | |||
84 | video->dev->uvc_version < 0x0110)) | 84 | video->dev->uvc_version < 0x0110)) |
85 | ctrl->dwMaxVideoFrameSize = | 85 | ctrl->dwMaxVideoFrameSize = |
86 | frame->dwMaxVideoFrameBufferSize; | 86 | frame->dwMaxVideoFrameBufferSize; |
87 | |||
88 | if (video->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH && | ||
89 | video->streaming->intf->num_altsetting > 1) { | ||
90 | u32 interval; | ||
91 | u32 bandwidth; | ||
92 | |||
93 | interval = (ctrl->dwFrameInterval > 100000) | ||
94 | ? ctrl->dwFrameInterval | ||
95 | : frame->dwFrameInterval[0]; | ||
96 | |||
97 | /* Compute a bandwidth estimation by multiplying the frame | ||
98 | * size by the number of video frames per second, divide the | ||
99 | * result by the number of USB frames (or micro-frames for | ||
100 | * high-speed devices) per second and add the UVC header size | ||
101 | * (assumed to be 12 bytes long). | ||
102 | */ | ||
103 | bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp; | ||
104 | bandwidth *= 10000000 / interval + 1; | ||
105 | bandwidth /= 1000; | ||
106 | if (video->dev->udev->speed == USB_SPEED_HIGH) | ||
107 | bandwidth /= 8; | ||
108 | bandwidth += 12; | ||
109 | |||
110 | ctrl->dwMaxPayloadTransferSize = bandwidth; | ||
111 | } | ||
87 | } | 112 | } |
88 | 113 | ||
89 | static int uvc_get_video_ctrl(struct uvc_video_device *video, | 114 | static int uvc_get_video_ctrl(struct uvc_video_device *video, |
@@ -158,10 +183,11 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video, | |||
158 | ctrl->bMaxVersion = 0; | 183 | ctrl->bMaxVersion = 0; |
159 | } | 184 | } |
160 | 185 | ||
161 | /* Some broken devices return a null or wrong dwMaxVideoFrameSize. | 186 | /* Some broken devices return null or wrong dwMaxVideoFrameSize and |
162 | * Try to get the value from the format and frame descriptors. | 187 | * dwMaxPayloadTransferSize fields. Try to get the value from the |
188 | * format and frame descriptors. | ||
163 | */ | 189 | */ |
164 | uvc_fixup_buffer_size(video, ctrl); | 190 | uvc_fixup_video_ctrl(video, ctrl); |
165 | ret = 0; | 191 | ret = 0; |
166 | 192 | ||
167 | out: | 193 | out: |
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index 6f55c4d49cf4..e5014e668f99 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h | |||
@@ -314,6 +314,7 @@ struct uvc_xu_control { | |||
314 | #define UVC_QUIRK_STREAM_NO_FID 0x00000010 | 314 | #define UVC_QUIRK_STREAM_NO_FID 0x00000010 |
315 | #define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020 | 315 | #define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020 |
316 | #define UVC_QUIRK_PRUNE_CONTROLS 0x00000040 | 316 | #define UVC_QUIRK_PRUNE_CONTROLS 0x00000040 |
317 | #define UVC_QUIRK_FIX_BANDWIDTH 0x00000080 | ||
317 | 318 | ||
318 | /* Format flags */ | 319 | /* Format flags */ |
319 | #define UVC_FMT_FLAG_COMPRESSED 0x00000001 | 320 | #define UVC_FMT_FLAG_COMPRESSED 0x00000001 |