From fc4ce6cd9855dcd1151a9afc067ea354179089f9 Mon Sep 17 00:00:00 2001 From: Devin Heitmueller Date: Wed, 11 Mar 2009 03:01:00 -0300 Subject: V4L/DVB (11077): au0828: properly handle missing analog USB endpoint Move the setup of the analog isoc handler into au0828-video.c, so it does not occur if there is not an .input section defined for the board. Also fixes a case where if there is an input section but the board does not actually have analog support, the digital support will continue to work as expected. Thanks to Michael Krufky for providing sample hardware of various configurations to test with. Signed-off-by: Devin Heitmueller Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/au0828/au0828-video.c | 33 ++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'drivers/media/video/au0828/au0828-video.c') diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c index ce80882d45e2..4c77aebfe6ee 100644 --- a/drivers/media/video/au0828/au0828-video.c +++ b/drivers/media/video/au0828/au0828-video.c @@ -1618,12 +1618,43 @@ static const struct video_device au0828_video_template = { /**************************************************************************/ -int au0828_analog_register(struct au0828_dev *dev) +int au0828_analog_register(struct au0828_dev *dev, + struct usb_interface *interface) { int retval = -ENOMEM; + struct usb_host_interface *iface_desc; + struct usb_endpoint_descriptor *endpoint; + int i; dprintk(1, "au0828_analog_register called!\n"); + /* set au0828 usb interface0 to as5 */ + retval = usb_set_interface(dev->usbdev, + interface->cur_altsetting->desc.bInterfaceNumber, 5); + if (retval != 0) { + printk("Failure setting usb interface0 to as5\n"); + return retval; + } + + /* Figure out which endpoint has the isoc interface */ + iface_desc = interface->cur_altsetting; + for(i = 0; i < iface_desc->desc.bNumEndpoints; i++){ + endpoint = &iface_desc->endpoint[i].desc; + if(((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) && + ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC)){ + + /* we find our isoc in endpoint */ + u16 tmp = le16_to_cpu(endpoint->wMaxPacketSize); + dev->max_pkt_size = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); + dev->isoc_in_endpointaddr = endpoint->bEndpointAddress; + } + } + if(!(dev->isoc_in_endpointaddr)) { + printk("Could not locate isoc endpoint\n"); + kfree(dev); + return -ENODEV; + } + init_waitqueue_head(&dev->open); spin_lock_init(&dev->slock); mutex_init(&dev->lock); -- cgit v1.2.3