aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/au0828
diff options
context:
space:
mode:
authorDevin Heitmueller <dheitmueller@linuxtv.org>2009-03-11 02:01:00 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:43:26 -0400
commitfc4ce6cd9855dcd1151a9afc067ea354179089f9 (patch)
treeab463988eb634e6bae258a57e55e9c72b22c7025 /drivers/media/video/au0828
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')
-rw-r--r--drivers/media/video/au0828/au0828-core.c30
-rw-r--r--drivers/media/video/au0828/au0828-video.c33
-rw-r--r--drivers/media/video/au0828/au0828.h3
3 files changed, 36 insertions, 30 deletions
diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/video/au0828/au0828-core.c
index f47fd9d78fa0..2b5ade626e57 100644
--- a/drivers/media/video/au0828/au0828-core.c
+++ b/drivers/media/video/au0828/au0828-core.c
@@ -165,11 +165,9 @@ static void au0828_usb_disconnect(struct usb_interface *interface)
165static int au0828_usb_probe(struct usb_interface *interface, 165static int au0828_usb_probe(struct usb_interface *interface,
166 const struct usb_device_id *id) 166 const struct usb_device_id *id)
167{ 167{
168 int ifnum, i; 168 int ifnum;
169 struct au0828_dev *dev; 169 struct au0828_dev *dev;
170 struct usb_device *usbdev = interface_to_usbdev(interface); 170 struct usb_device *usbdev = interface_to_usbdev(interface);
171 struct usb_host_interface *iface_desc;
172 struct usb_endpoint_descriptor *endpoint;
173 171
174 ifnum = interface->altsetting->desc.bInterfaceNumber; 172 ifnum = interface->altsetting->desc.bInterfaceNumber;
175 173
@@ -194,30 +192,6 @@ static int au0828_usb_probe(struct usb_interface *interface,
194 192
195 usb_set_intfdata(interface, dev); 193 usb_set_intfdata(interface, dev);
196 194
197 /* set au0828 usb interface0 to as5 */
198 usb_set_interface(usbdev,
199 interface->cur_altsetting->desc.bInterfaceNumber, 5);
200
201 /* Figure out which endpoint has the isoc interface */
202 iface_desc = interface->cur_altsetting;
203 for(i = 0; i < iface_desc->desc.bNumEndpoints; i++){
204 endpoint = &iface_desc->endpoint[i].desc;
205 if(((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) &&
206 ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC)){
207
208 /* we find our isoc in endpoint */
209 u16 tmp = le16_to_cpu(endpoint->wMaxPacketSize);
210 dev->max_pkt_size = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
211 dev->isoc_in_endpointaddr = endpoint->bEndpointAddress;
212 }
213 }
214 if(!(dev->isoc_in_endpointaddr)) {
215 printk("Could not locate isoc endpoint\n");
216 kfree(dev);
217 return -ENODEV;
218 }
219
220
221 /* Power Up the bridge */ 195 /* Power Up the bridge */
222 au0828_write(dev, REG_600, 1 << 4); 196 au0828_write(dev, REG_600, 1 << 4);
223 197
@@ -232,7 +206,7 @@ static int au0828_usb_probe(struct usb_interface *interface,
232 206
233 /* Analog TV */ 207 /* Analog TV */
234 if (dev->board.input != NULL) 208 if (dev->board.input != NULL)
235 au0828_analog_register(dev); 209 au0828_analog_register(dev, interface);
236 210
237 /* Digital TV */ 211 /* Digital TV */
238 au0828_dvb_register(dev); 212 au0828_dvb_register(dev);
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
1621int au0828_analog_register(struct au0828_dev *dev) 1621int 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);
diff --git a/drivers/media/video/au0828/au0828.h b/drivers/media/video/au0828/au0828.h
index 2f48ec2136bf..d2e54c8e18c4 100644
--- a/drivers/media/video/au0828/au0828.h
+++ b/drivers/media/video/au0828/au0828.h
@@ -273,7 +273,8 @@ extern void au0828_call_i2c_clients(struct au0828_dev *dev,
273 273
274/* ----------------------------------------------------------- */ 274/* ----------------------------------------------------------- */
275/* au0828-video.c */ 275/* au0828-video.c */
276int au0828_analog_register(struct au0828_dev *dev); 276int au0828_analog_register(struct au0828_dev *dev,
277 struct usb_interface *interface);
277int au0828_analog_stream_disable(struct au0828_dev *d); 278int au0828_analog_stream_disable(struct au0828_dev *d);
278void au0828_analog_unregister(struct au0828_dev *dev); 279void au0828_analog_unregister(struct au0828_dev *dev);
279 280