1 From 64ea37bbd8a5815522706f0099ad3f11c7537e15 Mon Sep 17 00:00:00 2001
2 From: Mauro Carvalho Chehab <m.chehab@samsung.com>
3 Date: Sun, 8 Jun 2014 13:54:57 -0300
4 Subject: media: au0828: Only alt setting logic when needed
6 From: Mauro Carvalho Chehab <m.chehab@samsung.com>
8 commit 64ea37bbd8a5815522706f0099ad3f11c7537e15 upstream.
10 It seems that there's a bug at au0828 hardware/firmware
11 related to alternate setting: when the device is already at
12 alt 5, a further call causes the URBs to receive -ESHUTDOWN.
14 I found two different encarnations of this issue:
16 1) at qv4l2, it fails the second time we try to open the
18 2) at xawtv, when audio underrun occurs, with is very
19 frequent, at least on my test machine.
21 The fix is simple: just check if alt=5 before calling
24 Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
25 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
28 drivers/media/usb/au0828/au0828-video.c | 34 ++++++++++++++++----------------
29 1 file changed, 17 insertions(+), 17 deletions(-)
31 --- a/drivers/media/usb/au0828/au0828-video.c
32 +++ b/drivers/media/usb/au0828/au0828-video.c
33 @@ -787,11 +787,27 @@ static int au0828_i2s_init(struct au0828
36 * Auvitek au0828 analog stream enable
37 - * Please set interface0 to AS5 before enable the stream
39 static int au0828_analog_stream_enable(struct au0828_dev *d)
41 + struct usb_interface *iface;
44 dprintk(1, "au0828_analog_stream_enable called\n");
46 + iface = usb_ifnum_to_if(d->usbdev, 0);
47 + if (iface && iface->cur_altsetting->desc.bAlternateSetting != 5) {
48 + dprintk(1, "Changing intf#0 to alt 5\n");
49 + /* set au0828 interface0 to AS5 here again */
50 + ret = usb_set_interface(d->usbdev, 0, 5);
52 + printk(KERN_INFO "Au0828 can't set alt setting to 5!\n");
57 + /* FIXME: size should be calculated using d->width, d->height */
59 au0828_writereg(d, AU0828_SENSORCTRL_VBI_103, 0x00);
60 au0828_writereg(d, 0x106, 0x00);
62 @@ -1002,15 +1018,6 @@ static int au0828_v4l2_open(struct file
65 if (dev->users == 0) {
66 - /* set au0828 interface0 to AS5 here again */
67 - ret = usb_set_interface(dev->usbdev, 0, 5);
69 - mutex_unlock(&dev->lock);
70 - printk(KERN_INFO "Au0828 can't set alternate to 5!\n");
75 au0828_analog_stream_enable(dev);
76 au0828_analog_stream_reset(dev);
78 @@ -1252,13 +1259,6 @@ static int au0828_set_format(struct au08
82 - /* set au0828 interface0 to AS5 here again */
83 - ret = usb_set_interface(dev->usbdev, 0, 5);
85 - printk(KERN_INFO "Au0828 can't set alt setting to 5!\n");
89 au0828_analog_stream_enable(dev);