diff options
author | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-06-08 12:54:57 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-06-19 12:32:03 -0400 |
commit | 64ea37bbd8a5815522706f0099ad3f11c7537e15 (patch) | |
tree | ea6ce352af1e6828b9ab27326fbd8170fc9e8a51 | |
parent | f2fd7ce6f2dbf286fd07fb82109599df741b57d3 (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.c | 34 |
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 | */ |
792 | static int au0828_analog_stream_enable(struct au0828_dev *d) | 791 | static 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; |