From: Devin Heitmueller Date: Wed, 11 Mar 2009 06:01:00 +0000 (-0300) Subject: V4L/DVB (11077): au0828: properly handle missing analog USB endpoint X-Git-Url: http://pilppa.com/gitweb/?a=commitdiff_plain;h=fc4ce6cd9855dcd1151a9afc067ea354179089f9;p=linux-2.6-omap-h63xx.git 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 --- diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/video/au0828/au0828-core.c index f47fd9d78fa..2b5ade626e5 100644 --- a/drivers/media/video/au0828/au0828-core.c +++ b/drivers/media/video/au0828/au0828-core.c @@ -165,11 +165,9 @@ static void au0828_usb_disconnect(struct usb_interface *interface) static int au0828_usb_probe(struct usb_interface *interface, const struct usb_device_id *id) { - int ifnum, i; + int ifnum; struct au0828_dev *dev; struct usb_device *usbdev = interface_to_usbdev(interface); - struct usb_host_interface *iface_desc; - struct usb_endpoint_descriptor *endpoint; ifnum = interface->altsetting->desc.bInterfaceNumber; @@ -194,30 +192,6 @@ static int au0828_usb_probe(struct usb_interface *interface, usb_set_intfdata(interface, dev); - /* set au0828 usb interface0 to as5 */ - usb_set_interface(usbdev, - interface->cur_altsetting->desc.bInterfaceNumber, 5); - - /* 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; - } - - /* Power Up the bridge */ au0828_write(dev, REG_600, 1 << 4); @@ -232,7 +206,7 @@ static int au0828_usb_probe(struct usb_interface *interface, /* Analog TV */ if (dev->board.input != NULL) - au0828_analog_register(dev); + au0828_analog_register(dev, interface); /* Digital TV */ au0828_dvb_register(dev); diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c index ce80882d45e..4c77aebfe6e 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); diff --git a/drivers/media/video/au0828/au0828.h b/drivers/media/video/au0828/au0828.h index 2f48ec2136b..d2e54c8e18c 100644 --- a/drivers/media/video/au0828/au0828.h +++ b/drivers/media/video/au0828/au0828.h @@ -273,7 +273,8 @@ extern void au0828_call_i2c_clients(struct au0828_dev *dev, /* ----------------------------------------------------------- */ /* au0828-video.c */ -int au0828_analog_register(struct au0828_dev *dev); +int au0828_analog_register(struct au0828_dev *dev, + struct usb_interface *interface); int au0828_analog_stream_disable(struct au0828_dev *d); void au0828_analog_unregister(struct au0828_dev *dev);