mirror of
https://github.com/adulau/aha.git
synced 2025-01-04 23:23:18 +00:00
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>
This commit is contained in:
parent
d9109bef4b
commit
fc4ce6cd98
3 changed files with 36 additions and 30 deletions
|
@ -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,
|
||||||
|
|
||||||
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,
|
||||||
|
|
||||||
/* 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 = {
|
||||||
|
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
||||||
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,
|
||||||
|
|
||||||
/* ----------------------------------------------------------- */
|
/* ----------------------------------------------------------- */
|
||||||
/* 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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue