Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 64ea37bb authored by Mauro Carvalho Chehab's avatar Mauro Carvalho Chehab
Browse files

[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: default avatarMauro Carvalho Chehab <m.chehab@samsung.com>
parent f2fd7ce6
Loading
Loading
Loading
Loading
+17 −17
Original line number Original line Diff line number Diff line
@@ -787,11 +787,27 @@ static int au0828_i2s_init(struct au0828_dev *dev)


/*
/*
 * Auvitek au0828 analog stream enable
 * Auvitek au0828 analog stream enable
 * Please set interface0 to AS5 before enable the stream
 */
 */
static int au0828_analog_stream_enable(struct au0828_dev *d)
static int au0828_analog_stream_enable(struct au0828_dev *d)
{
{
	struct usb_interface *iface;
	int ret;

	dprintk(1, "au0828_analog_stream_enable called\n");
	dprintk(1, "au0828_analog_stream_enable called\n");

	iface = usb_ifnum_to_if(d->usbdev, 0);
	if (iface && iface->cur_altsetting->desc.bAlternateSetting != 5) {
		dprintk(1, "Changing intf#0 to alt 5\n");
		/* set au0828 interface0 to AS5 here again */
		ret = usb_set_interface(d->usbdev, 0, 5);
		if (ret < 0) {
			printk(KERN_INFO "Au0828 can't set alt setting to 5!\n");
			return -EBUSY;
		}
	}

	/* FIXME: size should be calculated using d->width, d->height */

	au0828_writereg(d, AU0828_SENSORCTRL_VBI_103, 0x00);
	au0828_writereg(d, AU0828_SENSORCTRL_VBI_103, 0x00);
	au0828_writereg(d, 0x106, 0x00);
	au0828_writereg(d, 0x106, 0x00);
	/* set x position */
	/* set x position */
@@ -1002,15 +1018,6 @@ static int au0828_v4l2_open(struct file *filp)
		return -ERESTARTSYS;
		return -ERESTARTSYS;
	}
	}
	if (dev->users == 0) {
	if (dev->users == 0) {
		/* set au0828 interface0 to AS5 here again */
		ret = usb_set_interface(dev->usbdev, 0, 5);
		if (ret < 0) {
			mutex_unlock(&dev->lock);
			printk(KERN_INFO "Au0828 can't set alternate to 5!\n");
			kfree(fh);
			return -EBUSY;
		}

		au0828_analog_stream_enable(dev);
		au0828_analog_stream_enable(dev);
		au0828_analog_stream_reset(dev);
		au0828_analog_stream_reset(dev);


@@ -1252,13 +1259,6 @@ static int au0828_set_format(struct au0828_dev *dev, unsigned int cmd,
		}
		}
	}
	}


	/* set au0828 interface0 to AS5 here again */
	ret = usb_set_interface(dev->usbdev, 0, 5);
	if (ret < 0) {
		printk(KERN_INFO "Au0828 can't set alt setting to 5!\n");
		return -EBUSY;
	}

	au0828_analog_stream_enable(dev);
	au0828_analog_stream_enable(dev);


	return 0;
	return 0;