summaryrefslogtreecommitdiff
path: root/drivers/media/video/au0828/au0828-video.c
diff options
context:
space:
mode:
authorDevin Heitmueller <dheitmueller@linuxtv.org>2009-03-11 03:01:00 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 12:43:26 -0300
commitfc4ce6cd9855dcd1151a9afc067ea354179089f9 (patch)
treeab463988eb634e6bae258a57e55e9c72b22c7025 /drivers/media/video/au0828/au0828-video.c
parentd9109bef4b4f501eee94ae68bf876f765d5c6941 (diff)
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 <mkrufky@linuxtv.org> for providing sample hardware of various configurations to test with. Signed-off-by: Devin Heitmueller <dheitmueller@linuxtv.org> Signed-off-by: Michael Krufky <mkrufky@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/au0828/au0828-video.c')
-rw-r--r--drivers/media/video/au0828/au0828-video.c33
1 files changed, 32 insertions, 1 deletions
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);