Commit fc4ce6cd authored by Devin Heitmueller's avatar Devin Heitmueller Committed by Mauro Carvalho Chehab

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: default avatarDevin Heitmueller <dheitmueller@linuxtv.org>
Signed-off-by: default avatarMichael Krufky <mkrufky@linuxtv.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent d9109bef
...@@ -165,11 +165,9 @@ static void au0828_usb_disconnect(struct usb_interface *interface) ...@@ -165,11 +165,9 @@ static void au0828_usb_disconnect(struct usb_interface *interface)
static int au0828_usb_probe(struct usb_interface *interface, static int au0828_usb_probe(struct usb_interface *interface,
const struct usb_device_id *id) const struct usb_device_id *id)
{ {
int ifnum, i; int ifnum;
struct au0828_dev *dev; struct au0828_dev *dev;
struct usb_device *usbdev = interface_to_usbdev(interface); struct usb_device *usbdev = interface_to_usbdev(interface);
struct usb_host_interface *iface_desc;
struct usb_endpoint_descriptor *endpoint;
ifnum = interface->altsetting->desc.bInterfaceNumber; ifnum = interface->altsetting->desc.bInterfaceNumber;
...@@ -194,30 +192,6 @@ static int au0828_usb_probe(struct usb_interface *interface, ...@@ -194,30 +192,6 @@ static int au0828_usb_probe(struct usb_interface *interface,
usb_set_intfdata(interface, dev); 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 */ /* Power Up the bridge */
au0828_write(dev, REG_600, 1 << 4); au0828_write(dev, REG_600, 1 << 4);
...@@ -232,7 +206,7 @@ static int au0828_usb_probe(struct usb_interface *interface, ...@@ -232,7 +206,7 @@ static int au0828_usb_probe(struct usb_interface *interface,
/* Analog TV */ /* Analog TV */
if (dev->board.input != NULL) if (dev->board.input != NULL)
au0828_analog_register(dev); au0828_analog_register(dev, interface);
/* Digital TV */ /* Digital TV */
au0828_dvb_register(dev); au0828_dvb_register(dev);
......
...@@ -1618,12 +1618,43 @@ static const struct video_device au0828_video_template = { ...@@ -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; int retval = -ENOMEM;
struct usb_host_interface *iface_desc;
struct usb_endpoint_descriptor *endpoint;
int i;
dprintk(1, "au0828_analog_register called!\n"); 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); init_waitqueue_head(&dev->open);
spin_lock_init(&dev->slock); spin_lock_init(&dev->slock);
mutex_init(&dev->lock); mutex_init(&dev->lock);
......
...@@ -273,7 +273,8 @@ extern void au0828_call_i2c_clients(struct au0828_dev *dev, ...@@ -273,7 +273,8 @@ extern void au0828_call_i2c_clients(struct au0828_dev *dev,
/* ----------------------------------------------------------- */ /* ----------------------------------------------------------- */
/* au0828-video.c */ /* 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); int au0828_analog_stream_disable(struct au0828_dev *d);
void au0828_analog_unregister(struct au0828_dev *dev); void au0828_analog_unregister(struct au0828_dev *dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment