diff options
author | Devin Heitmueller <dheitmueller@linuxtv.org> | 2009-03-11 02:01:00 -0400 |
---|---|---|
committer | Devin Heitmueller <dheitmueller@linuxtv.org> | 2009-03-11 02:01:00 -0400 |
commit | 954299a93e6d076c844770136c359f48049b3d88 (patch) | |
tree | 32083f36b2321805b491e09bf8573a3355119226 /linux/drivers/media/video/au0828 | |
parent | 66833094069d442ee8db6a6a95d59c6598335302 (diff) | |
download | mediapointer-dvb-s2-954299a93e6d076c844770136c359f48049b3d88.tar.gz mediapointer-dvb-s2-954299a93e6d076c844770136c359f48049b3d88.tar.bz2 |
au0828: properly handle missing analog USB endpoint
From: Devin Heitmueller <dheitmueller@linuxtv.org>
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.
Priority: normal
Signed-off-by: Devin Heitmueller <dheitmueller@linuxtv.org>
Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
Diffstat (limited to 'linux/drivers/media/video/au0828')
-rw-r--r-- | linux/drivers/media/video/au0828/au0828-core.c | 30 | ||||
-rw-r--r-- | linux/drivers/media/video/au0828/au0828-video.c | 33 | ||||
-rw-r--r-- | linux/drivers/media/video/au0828/au0828.h | 3 |
3 files changed, 36 insertions, 30 deletions
diff --git a/linux/drivers/media/video/au0828/au0828-core.c b/linux/drivers/media/video/au0828/au0828-core.c index e5c399902..3e1ce6080 100644 --- a/linux/drivers/media/video/au0828/au0828-core.c +++ b/linux/drivers/media/video/au0828/au0828-core.c @@ -166,11 +166,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; @@ -195,30 +193,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); @@ -233,7 +207,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/linux/drivers/media/video/au0828/au0828-video.c b/linux/drivers/media/video/au0828/au0828-video.c index ae6dac3f2..e75b8b530 100644 --- a/linux/drivers/media/video/au0828/au0828-video.c +++ b/linux/drivers/media/video/au0828/au0828-video.c @@ -1622,12 +1622,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/linux/drivers/media/video/au0828/au0828.h b/linux/drivers/media/video/au0828/au0828.h index 2f48ec213..d2e54c8e1 100644 --- a/linux/drivers/media/video/au0828/au0828.h +++ b/linux/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); |