aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/uvc
diff options
context:
space:
mode:
authorMing Lei <tom.leiming@gmail.com>2011-07-15 23:51:00 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-09-21 21:17:14 -0400
commitdd182e5416e872e30d90cf071758eec1cf6340d5 (patch)
tree3b98ba603165b3cfcbde70ee30a94a31e927c06f /drivers/media/video/uvc
parent5ebbf72dc51bd3b481aa91fea37a7157da5fc548 (diff)
[media] uvcvideo: Set alternate setting 0 on resume if the bus has been reset
If the bus has been reset on resume, set the alternate setting to 0. This should be the default value, but some devices crash or otherwise misbehave if they don't receive a SET_INTERFACE request before any other video control request. Microdia's 0c45:6437 camera has been found to require this change or it will stop sending video data after resume. uvc_video.c] Signed-off-by: Ming Lei <ming.lei@canonical.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/uvc')
-rw-r--r--drivers/media/video/uvc/uvc_driver.c2
-rw-r--r--drivers/media/video/uvc/uvc_video.c10
-rw-r--r--drivers/media/video/uvc/uvcvideo.h2
3 files changed, 11 insertions, 3 deletions
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index d29f9c2d0854..e4100b1f68df 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1961,7 +1961,7 @@ static int __uvc_resume(struct usb_interface *intf, int reset)
1961 1961
1962 list_for_each_entry(stream, &dev->streams, list) { 1962 list_for_each_entry(stream, &dev->streams, list) {
1963 if (stream->intf == intf) 1963 if (stream->intf == intf)
1964 return uvc_video_resume(stream); 1964 return uvc_video_resume(stream, reset);
1965 } 1965 }
1966 1966
1967 uvc_trace(UVC_TRACE_SUSPEND, "Resume: video streaming USB interface " 1967 uvc_trace(UVC_TRACE_SUSPEND, "Resume: video streaming USB interface "
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index 8244167c8915..ffd1158628b6 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -1104,10 +1104,18 @@ int uvc_video_suspend(struct uvc_streaming *stream)
1104 * buffers, making sure userspace applications are notified of the problem 1104 * buffers, making sure userspace applications are notified of the problem
1105 * instead of waiting forever. 1105 * instead of waiting forever.
1106 */ 1106 */
1107int uvc_video_resume(struct uvc_streaming *stream) 1107int uvc_video_resume(struct uvc_streaming *stream, int reset)
1108{ 1108{
1109 int ret; 1109 int ret;
1110 1110
1111 /* If the bus has been reset on resume, set the alternate setting to 0.
1112 * This should be the default value, but some devices crash or otherwise
1113 * misbehave if they don't receive a SET_INTERFACE request before any
1114 * other video control request.
1115 */
1116 if (reset)
1117 usb_set_interface(stream->dev->udev, stream->intfnum, 0);
1118
1111 stream->frozen = 0; 1119 stream->frozen = 0;
1112 1120
1113 ret = uvc_commit_video(stream, &stream->ctrl); 1121 ret = uvc_commit_video(stream, &stream->ctrl);
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index df32a43ca86a..cbdd49bf8b67 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -638,7 +638,7 @@ extern void uvc_mc_cleanup_entity(struct uvc_entity *entity);
638/* Video */ 638/* Video */
639extern int uvc_video_init(struct uvc_streaming *stream); 639extern int uvc_video_init(struct uvc_streaming *stream);
640extern int uvc_video_suspend(struct uvc_streaming *stream); 640extern int uvc_video_suspend(struct uvc_streaming *stream);
641extern int uvc_video_resume(struct uvc_streaming *stream); 641extern int uvc_video_resume(struct uvc_streaming *stream, int reset);
642extern int uvc_video_enable(struct uvc_streaming *stream, int enable); 642extern int uvc_video_enable(struct uvc_streaming *stream, int enable);
643extern int uvc_probe_video(struct uvc_streaming *stream, 643extern int uvc_probe_video(struct uvc_streaming *stream,
644 struct uvc_streaming_control *probe); 644 struct uvc_streaming_control *probe);