summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMing Lei <tom.leiming@gmail.com>2011-07-16 00:51:00 -0300
committerGreg Kroah-Hartman <gregkh@suse.de>2011-11-07 12:32:35 -0800
commitcd7d323474d891b72034f981c22d282805a63a3e (patch)
treeb779f82757d592ab0c8c9aecce4536e789898e6c
parent2955ef81efd268149787d93043c912f509150efa (diff)
uvcvideo: Set alternate setting 0 on resume if the bus has been reset
commit d59a7b1dbce8b972ec2dc9fcaaae0bfa23687423 upstream. 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> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-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 eb2ce2630a77..6689e8c2ae43 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1889,7 +1889,7 @@ static int __uvc_resume(struct usb_interface *intf, int reset)
list_for_each_entry(stream, &dev->streams, list) {
if (stream->intf == intf)
- return uvc_video_resume(stream);
+ return uvc_video_resume(stream, reset);
}
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 688598a6cf5c..2af5ee6552f5 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -1024,10 +1024,18 @@ int uvc_video_suspend(struct uvc_streaming *stream)
* buffers, making sure userspace applications are notified of the problem
* instead of waiting forever.
*/
-int uvc_video_resume(struct uvc_streaming *stream)
+int uvc_video_resume(struct uvc_streaming *stream, int reset)
{
int ret;
+ /* 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.
+ */
+ if (reset)
+ usb_set_interface(stream->dev->udev, stream->intfnum, 0);
+
stream->frozen = 0;
ret = uvc_commit_video(stream, &stream->ctrl);
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index 64007b90bd73..906a0165c36c 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -608,7 +608,7 @@ extern const struct v4l2_file_operations uvc_fops;
/* Video */
extern int uvc_video_init(struct uvc_streaming *stream);
extern int uvc_video_suspend(struct uvc_streaming *stream);
-extern int uvc_video_resume(struct uvc_streaming *stream);
+extern int uvc_video_resume(struct uvc_streaming *stream, int reset);
extern int uvc_video_enable(struct uvc_streaming *stream, int enable);
extern int uvc_probe_video(struct uvc_streaming *stream,
struct uvc_streaming_control *probe);