V4L/DVB: gspca - main: Handle the audio device
authorJean-François Moine <moinejf@free.fr>
Wed, 14 Jul 2010 09:30:18 +0000 (06:30 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Mon, 2 Aug 2010 19:43:06 +0000 (16:43 -0300)
When there is an audio device, use a lower alternate setting.
This patch does not fix correctly all audio and bandwidth problems.

Signed-off-by: Jean-François Moine <moinejf@free.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/gspca/gspca.c
drivers/media/video/gspca/gspca.h

index 29b047942826a7cc513bc89ae5b708e472e85426..d951b0f0e05319afa85daf80550a73cd348997a5 100644 (file)
@@ -640,12 +640,16 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
                                   : USB_ENDPOINT_XFER_ISOC;
        i = gspca_dev->alt;                     /* previous alt setting */
        if (gspca_dev->cam.reverse_alts) {
+               if (gspca_dev->audio)
+                       i++;
                while (++i < gspca_dev->nbalt) {
                        ep = alt_xfer(&intf->altsetting[i], xfer);
                        if (ep)
                                break;
                }
        } else {
+               if (gspca_dev->audio)
+                       i--;
                while (--i >= 0) {
                        ep = alt_xfer(&intf->altsetting[i], xfer);
                        if (ep)
@@ -2146,6 +2150,24 @@ int gspca_dev_probe2(struct usb_interface *intf,
        gspca_dev->dev = dev;
        gspca_dev->iface = intf->cur_altsetting->desc.bInterfaceNumber;
        gspca_dev->nbalt = intf->num_altsetting;
+
+       /* check if any audio device */
+       if (dev->config->desc.bNumInterfaces != 1) {
+               int i;
+               struct usb_interface *intf2;
+
+               for (i = 0; i < dev->config->desc.bNumInterfaces; i++) {
+                       intf2 = dev->config->interface[i];
+                       if (intf2 != NULL
+                        && intf2->altsetting != NULL
+                        && intf2->altsetting->desc.bInterfaceClass ==
+                                        USB_CLASS_AUDIO) {
+                               gspca_dev->audio = 1;
+                               break;
+                       }
+               }
+       }
+
        gspca_dev->sd_desc = sd_desc;
        gspca_dev->nbufread = 2;
        gspca_dev->empty_packet = -1;   /* don't check the empty packets */
index 17e55580631ed7634156db373287e9e4b49cadb0..b749c36d9f7eacf263efbdc222b8fed9603dc672 100644 (file)
@@ -198,6 +198,7 @@ struct gspca_dev {
        struct mutex read_lock;         /* read protection */
        struct mutex queue_lock;        /* ISOC queue protection */
        int usb_err;                    /* USB error - protected by usb_lock */
+       u16 pkt_size;                   /* ISOC packet size */
 #ifdef CONFIG_PM
        char frozen;                    /* suspend - resume */
 #endif
@@ -208,7 +209,7 @@ struct gspca_dev {
        __u8 iface;                     /* USB interface number */
        __u8 alt;                       /* USB alternate setting */
        __u8 nbalt;                     /* number of USB alternate settings */
-       u16 pkt_size;                   /* ISOC packet size */
+       u8 audio;                       /* presence of audio device */
 };
 
 int gspca_dev_probe(struct usb_interface *intf,