diff options
author | Devin Heitmueller <dheitmueller@linuxtv.org> | 2009-03-11 02:01:00 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:43:26 -0400 |
commit | fc4ce6cd9855dcd1151a9afc067ea354179089f9 (patch) | |
tree | ab463988eb634e6bae258a57e55e9c72b22c7025 /drivers/media/video/au0828/au0828-video.c | |
parent | d9109bef4b4f501eee94ae68bf876f765d5c6941 (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.c | 33 |
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 = { | |||
1618 | 1618 | ||
1619 | /**************************************************************************/ | 1619 | /**************************************************************************/ |
1620 | 1620 | ||
1621 | int au0828_analog_register(struct au0828_dev *dev) | 1621 | int au0828_analog_register(struct au0828_dev *dev, |
1622 | struct usb_interface *interface) | ||
1622 | { | 1623 | { |
1623 | int retval = -ENOMEM; | 1624 | int retval = -ENOMEM; |
1625 | struct usb_host_interface *iface_desc; | ||
1626 | struct usb_endpoint_descriptor *endpoint; | ||
1627 | int i; | ||
1624 | 1628 | ||
1625 | dprintk(1, "au0828_analog_register called!\n"); | 1629 | dprintk(1, "au0828_analog_register called!\n"); |
1626 | 1630 | ||
1631 | /* set au0828 usb interface0 to as5 */ | ||
1632 | retval = usb_set_interface(dev->usbdev, | ||
1633 | interface->cur_altsetting->desc.bInterfaceNumber, 5); | ||
1634 | if (retval != 0) { | ||
1635 | printk("Failure setting usb interface0 to as5\n"); | ||
1636 | return retval; | ||
1637 | } | ||
1638 | |||
1639 | /* Figure out which endpoint has the isoc interface */ | ||
1640 | iface_desc = interface->cur_altsetting; | ||
1641 | for(i = 0; i < iface_desc->desc.bNumEndpoints; i++){ | ||
1642 | endpoint = &iface_desc->endpoint[i].desc; | ||
1643 | if(((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) && | ||
1644 | ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC)){ | ||
1645 | |||
1646 | /* we find our isoc in endpoint */ | ||
1647 | u16 tmp = le16_to_cpu(endpoint->wMaxPacketSize); | ||
1648 | dev->max_pkt_size = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); | ||
1649 | dev->isoc_in_endpointaddr = endpoint->bEndpointAddress; | ||
1650 | } | ||
1651 | } | ||
1652 | if(!(dev->isoc_in_endpointaddr)) { | ||
1653 | printk("Could not locate isoc endpoint\n"); | ||
1654 | kfree(dev); | ||
1655 | return -ENODEV; | ||
1656 | } | ||
1657 | |||
1627 | init_waitqueue_head(&dev->open); | 1658 | init_waitqueue_head(&dev->open); |
1628 | spin_lock_init(&dev->slock); | 1659 | spin_lock_init(&dev->slock); |
1629 | mutex_init(&dev->lock); | 1660 | mutex_init(&dev->lock); |