aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <m.chehab@samsung.com>2014-06-08 12:54:57 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-06-19 12:32:03 -0400
commit64ea37bbd8a5815522706f0099ad3f11c7537e15 (patch)
treeea6ce352af1e6828b9ab27326fbd8170fc9e8a51
parentf2fd7ce6f2dbf286fd07fb82109599df741b57d3 (diff)
[media] au0828: Only alt setting logic when needed
It seems that there's a bug at au0828 hardware/firmware related to alternate setting: when the device is already at alt 5, a further call causes the URBs to receive -ESHUTDOWN. I found two different encarnations of this issue: 1) at qv4l2, it fails the second time we try to open the video screen; 2) at xawtv, when audio underrun occurs, with is very frequent, at least on my test machine. The fix is simple: just check if alt=5 before calling set_usb_interface(). Cc: stable@vger.kernel.org Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r--drivers/media/usb/au0828/au0828-video.c34
1 files changed, 17 insertions, 17 deletions
diff --git a/drivers/media/usb/au0828/au0828-video.c b/drivers/media/usb/au0828/au0828-video.c
index 4aa1d7a1641b..85d83ca5a4cd 100644
--- a/drivers/media/usb/au0828/au0828-video.c
+++ b/drivers/media/usb/au0828/au0828-video.c
@@ -787,11 +787,27 @@ static int au0828_i2s_init(struct au0828_dev *dev)
787 787
788/* 788/*
789 * Auvitek au0828 analog stream enable 789 * Auvitek au0828 analog stream enable
790 * Please set interface0 to AS5 before enable the stream
791 */ 790 */
792static int au0828_analog_stream_enable(struct au0828_dev *d) 791static int au0828_analog_stream_enable(struct au0828_dev *d)
793{ 792{
793 struct usb_interface *iface;
794 int ret;
795
794 dprintk(1, "au0828_analog_stream_enable called\n"); 796 dprintk(1, "au0828_analog_stream_enable called\n");
797
798 iface = usb_ifnum_to_if(d->usbdev, 0);
799 if (iface && iface->cur_altsetting->desc.bAlternateSetting != 5) {
800 dprintk(1, "Changing intf#0 to alt 5\n");
801 /* set au0828 interface0 to AS5 here again */
802 ret = usb_set_interface(d->usbdev, 0, 5);
803 if (ret < 0) {
804 printk(KERN_INFO "Au0828 can't set alt setting to 5!\n");
805 return -EBUSY;
806 }
807 }
808
809 /* FIXME: size should be calculated using d->width, d->height */
810
795 au0828_writereg(d, AU0828_SENSORCTRL_VBI_103, 0x00); 811 au0828_writereg(d, AU0828_SENSORCTRL_VBI_103, 0x00);
796 au0828_writereg(d, 0x106, 0x00); 812 au0828_writereg(d, 0x106, 0x00);
797 /* set x position */ 813 /* set x position */
@@ -1002,15 +1018,6 @@ static int au0828_v4l2_open(struct file *filp)
1002 return -ERESTARTSYS; 1018 return -ERESTARTSYS;
1003 } 1019 }
1004 if (dev->users == 0) { 1020 if (dev->users == 0) {
1005 /* set au0828 interface0 to AS5 here again */
1006 ret = usb_set_interface(dev->usbdev, 0, 5);
1007 if (ret < 0) {
1008 mutex_unlock(&dev->lock);
1009 printk(KERN_INFO "Au0828 can't set alternate to 5!\n");
1010 kfree(fh);
1011 return -EBUSY;
1012 }
1013
1014 au0828_analog_stream_enable(dev); 1021 au0828_analog_stream_enable(dev);
1015 au0828_analog_stream_reset(dev); 1022 au0828_analog_stream_reset(dev);
1016 1023
@@ -1252,13 +1259,6 @@ static int au0828_set_format(struct au0828_dev *dev, unsigned int cmd,
1252 } 1259 }
1253 } 1260 }
1254 1261
1255 /* set au0828 interface0 to AS5 here again */
1256 ret = usb_set_interface(dev->usbdev, 0, 5);
1257 if (ret < 0) {
1258 printk(KERN_INFO "Au0828 can't set alt setting to 5!\n");
1259 return -EBUSY;
1260 }
1261
1262 au0828_analog_stream_enable(dev); 1262 au0828_analog_stream_enable(dev);
1263 1263
1264 return 0; 1264 return 0;