Offload snd_usb_parse_audio_interface() function which
became quite long after adding UAC3 spec support.

Move class-specific parts to separate functions
which now produce audioformat structure that is
ready to be fed to snd_usb_add_audio_stream().

This also broke Blue Microphones workaround (which
relies on audioformat decoded from previous altsetting)
into two parts: prepare quirk flag analyzing previous
altsetting then use it with current altsetting.

Signed-off-by: Ruslan Bilovol <ruslan.bilo...@gmail.com>
---
 sound/usb/stream.c | 613 +++++++++++++++++++++++++++++------------------------
 1 file changed, 334 insertions(+), 279 deletions(-)

diff --git a/sound/usb/stream.c b/sound/usb/stream.c
index 6a8f584..586d664 100644
--- a/sound/usb/stream.c
+++ b/sound/usb/stream.c
@@ -626,6 +626,319 @@ static int parse_uac_endpoint_attributes(struct 
snd_usb_audio *chip,
        return NULL;
 }
 
+static struct audioformat *
+snd_usb_get_audioformat_uac12(struct snd_usb_audio *chip,
+                             struct usb_host_interface *alts,
+                             int protocol, int iface_no,
+                             int altno, int stream, int bm_quirk)
+{
+       struct usb_device *dev = chip->dev;
+       struct uac_format_type_i_continuous_descriptor *fmt;
+       unsigned int num_channels = 0, chconfig = 0;
+       struct audioformat *fp;
+       int clock = 0;
+       u64 format;
+
+       /* get audio formats */
+       if (protocol == UAC_VERSION_1) {
+               struct uac1_as_header_descriptor *as =
+                       snd_usb_find_csint_desc(alts->extra, alts->extralen,
+                                               NULL, UAC_AS_GENERAL);
+               struct uac_input_terminal_descriptor *iterm;
+
+               if (!as) {
+                       dev_err(&dev->dev,
+                               "%u:%d : UAC_AS_GENERAL descriptor not found\n",
+                               iface_no, altno);
+                       return NULL;
+               }
+
+               if (as->bLength < sizeof(*as)) {
+                       dev_err(&dev->dev,
+                               "%u:%d : invalid UAC_AS_GENERAL desc\n",
+                               iface_no, altno);
+                       return NULL;
+               }
+
+               format = le16_to_cpu(as->wFormatTag); /* remember the format 
value */
+
+               iterm = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf,
+                                                            as->bTerminalLink);
+               if (iterm) {
+                       num_channels = iterm->bNrChannels;
+                       chconfig = le16_to_cpu(iterm->wChannelConfig);
+               }
+       } else { /* UAC_VERSION_2 */
+               struct uac2_input_terminal_descriptor *input_term;
+               struct uac2_output_terminal_descriptor *output_term;
+               struct uac2_as_header_descriptor *as =
+                       snd_usb_find_csint_desc(alts->extra, alts->extralen,
+                                               NULL, UAC_AS_GENERAL);
+
+               if (!as) {
+                       dev_err(&dev->dev,
+                               "%u:%d : UAC_AS_GENERAL descriptor not found\n",
+                               iface_no, altno);
+                       return NULL;
+               }
+
+               if (as->bLength < sizeof(*as)) {
+                       dev_err(&dev->dev,
+                               "%u:%d : invalid UAC_AS_GENERAL desc\n",
+                               iface_no, altno);
+                       return NULL;
+               }
+
+               num_channels = as->bNrChannels;
+               format = le32_to_cpu(as->bmFormats);
+               chconfig = le32_to_cpu(as->bmChannelConfig);
+
+               /*
+                * lookup the terminal associated to this interface
+                * to extract the clock
+                */
+               input_term = 
snd_usb_find_input_terminal_descriptor(chip->ctrl_intf,
+                                                                   
as->bTerminalLink);
+               if (input_term) {
+                       clock = input_term->bCSourceID;
+                       if (!chconfig && (num_channels == 
input_term->bNrChannels))
+                               chconfig = 
le32_to_cpu(input_term->bmChannelConfig);
+                       goto found_clock;
+               }
+
+               output_term = 
snd_usb_find_output_terminal_descriptor(chip->ctrl_intf,
+                                                                     
as->bTerminalLink);
+               if (output_term) {
+                       clock = output_term->bCSourceID;
+                       goto found_clock;
+               }
+
+               dev_err(&dev->dev,
+                       "%u:%d : bogus bTerminalLink %d\n",
+                       iface_no, altno, as->bTerminalLink);
+               return NULL;
+       }
+
+found_clock:
+       /* get format type */
+       fmt = snd_usb_find_csint_desc(alts->extra, alts->extralen,
+                                     NULL, UAC_FORMAT_TYPE);
+       if (!fmt) {
+               dev_err(&dev->dev,
+                       "%u:%d : no UAC_FORMAT_TYPE desc\n",
+                       iface_no, altno);
+               return NULL;
+       }
+       if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8))
+                       || ((protocol == UAC_VERSION_2) &&
+                                       (fmt->bLength < 6))) {
+               dev_err(&dev->dev,
+                       "%u:%d : invalid UAC_FORMAT_TYPE desc\n",
+                       iface_no, altno);
+               return NULL;
+       }
+
+       /*
+        * Blue Microphones workaround: The last altsetting is
+        * identical with the previous one, except for a larger
+        * packet size, but is actually a mislabeled two-channel
+        * setting; ignore it.
+        *
+        * Part 2: analyze quirk flag and format
+        */
+       if (bm_quirk && fmt->bNrChannels == 1 && fmt->bSubframeSize == 2)
+               return NULL;
+
+       fp = kzalloc(sizeof(*fp), GFP_KERNEL);
+       if (!fp)
+               return ERR_PTR(-ENOMEM);
+
+       fp->iface = iface_no;
+       fp->altsetting = altno;
+       fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
+       fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
+       fp->datainterval = snd_usb_parse_datainterval(chip, alts);
+       fp->protocol = protocol;
+       fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
+       fp->channels = num_channels;
+       if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
+               fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
+                               * (fp->maxpacksize & 0x7ff);
+       fp->attributes = parse_uac_endpoint_attributes(chip, alts,
+                                                      protocol, iface_no);
+       fp->clock = clock;
+       INIT_LIST_HEAD(&fp->list);
+
+       /* some quirks for attributes here */
+       snd_usb_audioformat_attributes_quirk(chip, fp, stream);
+
+       /* ok, let's parse further... */
+       if (snd_usb_parse_audio_format(chip, fp, format,
+                                       fmt, stream) < 0) {
+               kfree(fp->rate_table);
+               kfree(fp);
+               return NULL;
+       }
+
+       /* Create chmap */
+       if (fp->channels != num_channels)
+               chconfig = 0;
+
+       fp->chmap = convert_chmap(fp->channels, chconfig, protocol);
+
+       return fp;
+}
+
+static struct audioformat *
+snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip,
+                            struct usb_host_interface *alts,
+                            int iface_no, int altno, int stream)
+{
+       struct usb_device *dev = chip->dev;
+       struct uac3_input_terminal_descriptor *input_term;
+       struct uac3_output_terminal_descriptor *output_term;
+       struct uac3_cluster_header_descriptor *cluster;
+       struct uac3_as_header_descriptor *as;
+       struct uac3_hc_descriptor_header hc_header;
+       struct snd_pcm_chmap_elem *chmap;
+       unsigned int num_channels;
+       struct audioformat *fp;
+       u16 cluster_id, wLength;
+       int clock = 0;
+       int err;
+
+       as = snd_usb_find_csint_desc(alts->extra, alts->extralen,
+                                    NULL, UAC_AS_GENERAL);
+       if (!as) {
+               dev_err(&dev->dev,
+                       "%u:%d : UAC_AS_GENERAL descriptor not found\n",
+                       iface_no, altno);
+               return NULL;
+       }
+
+       if (as->bLength < sizeof(*as)) {
+               dev_err(&dev->dev,
+                       "%u:%d : invalid UAC_AS_GENERAL desc\n",
+                       iface_no, altno);
+               return NULL;
+       }
+
+       cluster_id = le16_to_cpu(as->wClusterDescrID);
+       if (!cluster_id) {
+               dev_err(&dev->dev,
+                       "%u:%d : no cluster descriptor\n",
+                       iface_no, altno);
+               return NULL;
+       }
+
+       /*
+        * Get number of channels and channel map through
+        * High Capability Cluster Descriptor
+        *
+        * First step: get High Capability header and
+        * read size of Cluster Descriptor
+        */
+       err = snd_usb_ctl_msg(chip->dev,
+                       usb_rcvctrlpipe(chip->dev, 0),
+                       UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR,
+                       USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
+                       cluster_id,
+                       snd_usb_ctrl_intf(chip),
+                       &hc_header, sizeof(hc_header));
+       if (err < 0)
+               return ERR_PTR(err);
+       else if (err != sizeof(hc_header)) {
+               dev_err(&dev->dev,
+                       "%u:%d : can't get High Capability descriptor\n",
+                       iface_no, altno);
+               return ERR_PTR(-EIO);
+       }
+
+       /*
+        * Second step: allocate needed amount of memory
+        * and request Cluster Descriptor
+        */
+       wLength = le16_to_cpu(hc_header.wLength);
+       cluster = kzalloc(wLength, GFP_KERNEL);
+       if (!cluster)
+               return ERR_PTR(-ENOMEM);
+       err = snd_usb_ctl_msg(chip->dev,
+                       usb_rcvctrlpipe(chip->dev, 0),
+                       UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR,
+                       USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_IN,
+                       cluster_id,
+                       snd_usb_ctrl_intf(chip),
+                       cluster, wLength);
+       if (err < 0) {
+               kfree(cluster);
+               return ERR_PTR(err);
+       } else if (err != wLength) {
+               dev_err(&dev->dev,
+                       "%u:%d : can't get Cluster Descriptor\n",
+                       iface_no, altno);
+               kfree(cluster);
+               return ERR_PTR(-EIO);
+       }
+
+       num_channels = cluster->bNrChannels;
+       chmap = convert_chmap_v3(cluster);
+       kfree(cluster);
+
+       /*
+        * lookup the terminal associated to this interface
+        * to extract the clock
+        */
+       input_term = snd_usb_find_input_terminal_descriptor(chip->ctrl_intf,
+                                                           as->bTerminalLink);
+       if (input_term) {
+               clock = input_term->bCSourceID;
+               goto found_clock;
+       }
+
+       output_term = snd_usb_find_output_terminal_descriptor(chip->ctrl_intf,
+                                                            as->bTerminalLink);
+       if (output_term) {
+               clock = output_term->bCSourceID;
+               goto found_clock;
+       }
+
+       dev_err(&dev->dev, "%u:%d : bogus bTerminalLink %d\n",
+                       iface_no, altno, as->bTerminalLink);
+       return NULL;
+
+found_clock:
+       fp = kzalloc(sizeof(*fp), GFP_KERNEL);
+       if (!fp)
+               return ERR_PTR(-ENOMEM);
+
+       fp->iface = iface_no;
+       fp->altsetting = altno;
+       fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
+       fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
+       fp->datainterval = snd_usb_parse_datainterval(chip, alts);
+       fp->protocol = UAC_VERSION_3;
+       fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
+       fp->channels = num_channels;
+       if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
+               fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
+                               * (fp->maxpacksize & 0x7ff);
+       fp->attributes = parse_uac_endpoint_attributes(chip, alts,
+                                                      UAC_VERSION_3,
+                                                      iface_no);
+       fp->clock = clock;
+       fp->chmap = chmap;
+       INIT_LIST_HEAD(&fp->list);
+
+       /* ok, let's parse further... */
+       if (snd_usb_parse_audio_format_v3(chip, fp, as, stream) < 0) {
+               kfree(fp->rate_table);
+               kfree(fp);
+               return NULL;
+       }
+
+       return fp;
+}
+
 int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
 {
        struct usb_device *dev;
@@ -633,13 +946,8 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio 
*chip, int iface_no)
        struct usb_host_interface *alts;
        struct usb_interface_descriptor *altsd;
        int i, altno, err, stream;
-       u64 format = 0;
-       unsigned int num_channels = 0;
        struct audioformat *fp = NULL;
-       int num, protocol, clock = 0;
-       struct uac_format_type_i_continuous_descriptor *fmt = NULL;
-       struct snd_pcm_chmap_elem *chmap_v3 = NULL;
-       unsigned int chconfig;
+       int num, protocol;
 
        dev = chip->dev;
 
@@ -688,303 +996,50 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio 
*chip, int iface_no)
                    protocol <= 2)
                        protocol = UAC_VERSION_1;
 
-               chconfig = 0;
-               /* get audio formats */
                switch (protocol) {
                default:
                        dev_dbg(&dev->dev, "%u:%d: unknown interface protocol 
%#02x, assuming v1\n",
                                iface_no, altno, protocol);
                        protocol = UAC_VERSION_1;
                        /* fall through */
-
-               case UAC_VERSION_1: {
-                       struct uac1_as_header_descriptor *as =
-                               snd_usb_find_csint_desc(alts->extra, 
alts->extralen, NULL, UAC_AS_GENERAL);
-                       struct uac_input_terminal_descriptor *iterm;
-
-                       if (!as) {
-                               dev_err(&dev->dev,
-                                       "%u:%d : UAC_AS_GENERAL descriptor not 
found\n",
-                                       iface_no, altno);
-                               continue;
-                       }
-
-                       if (as->bLength < sizeof(*as)) {
-                               dev_err(&dev->dev,
-                                       "%u:%d : invalid UAC_AS_GENERAL desc\n",
-                                       iface_no, altno);
-                               continue;
-                       }
-
-                       format = le16_to_cpu(as->wFormatTag); /* remember the 
format value */
-
-                       iterm = 
snd_usb_find_input_terminal_descriptor(chip->ctrl_intf,
-                                                                      
as->bTerminalLink);
-                       if (iterm) {
-                               num_channels = iterm->bNrChannels;
-                               chconfig = le16_to_cpu(iterm->wChannelConfig);
-                       }
-
-                       break;
-               }
-
+               case UAC_VERSION_1:
+                       /* fall through */
                case UAC_VERSION_2: {
-                       struct uac2_input_terminal_descriptor *input_term;
-                       struct uac2_output_terminal_descriptor *output_term;
-                       struct uac2_as_header_descriptor *as =
-                               snd_usb_find_csint_desc(alts->extra, 
alts->extralen, NULL, UAC_AS_GENERAL);
-
-                       if (!as) {
-                               dev_err(&dev->dev,
-                                       "%u:%d : UAC_AS_GENERAL descriptor not 
found\n",
-                                       iface_no, altno);
-                               continue;
-                       }
-
-                       if (as->bLength < sizeof(*as)) {
-                               dev_err(&dev->dev,
-                                       "%u:%d : invalid UAC_AS_GENERAL desc\n",
-                                       iface_no, altno);
-                               continue;
-                       }
-
-                       num_channels = as->bNrChannels;
-                       format = le32_to_cpu(as->bmFormats);
-                       chconfig = le32_to_cpu(as->bmChannelConfig);
-
-                       /* lookup the terminal associated to this interface
-                        * to extract the clock */
-                       input_term = 
snd_usb_find_input_terminal_descriptor(chip->ctrl_intf,
-                                                                           
as->bTerminalLink);
-                       if (input_term) {
-                               clock = input_term->bCSourceID;
-                               if (!chconfig && (num_channels == 
input_term->bNrChannels))
-                                       chconfig = 
le32_to_cpu(input_term->bmChannelConfig);
-                               break;
-                       }
-
-                       output_term = 
snd_usb_find_output_terminal_descriptor(chip->ctrl_intf,
-                                                                             
as->bTerminalLink);
-                       if (output_term) {
-                               clock = output_term->bCSourceID;
-                               break;
-                       }
-
-                       dev_err(&dev->dev,
-                               "%u:%d : bogus bTerminalLink %d\n",
-                               iface_no, altno, as->bTerminalLink);
-                       continue;
-               }
-
-               case UAC_VERSION_3: {
-                       struct uac3_input_terminal_descriptor *input_term;
-                       struct uac3_output_terminal_descriptor *output_term;
-                       struct uac3_as_header_descriptor *as;
-                       struct uac3_cluster_header_descriptor *cluster;
-                       struct uac3_hc_descriptor_header hc_header;
-                       u16 cluster_id, wLength;
-
-                       as = snd_usb_find_csint_desc(alts->extra,
-                                                       alts->extralen,
-                                                       NULL, UAC_AS_GENERAL);
-
-                       if (!as) {
-                               dev_err(&dev->dev,
-                                       "%u:%d : UAC_AS_GENERAL descriptor not 
found\n",
-                                       iface_no, altno);
-                               continue;
-                       }
-
-                       if (as->bLength < sizeof(*as)) {
-                               dev_err(&dev->dev,
-                                       "%u:%d : invalid UAC_AS_GENERAL desc\n",
-                                       iface_no, altno);
-                               continue;
-                       }
-
-                       cluster_id = le16_to_cpu(as->wClusterDescrID);
-                       if (!cluster_id) {
-                               dev_err(&dev->dev,
-                                       "%u:%d : no cluster descriptor\n",
-                                       iface_no, altno);
-                               continue;
-                       }
-
-                       /*
-                        * Get number of channels and channel map through
-                        * High Capability Cluster Descriptor
-                        *
-                        * First step: get High Capability header and
-                        * read size of Cluster Descriptor
-                        */
-                       err = snd_usb_ctl_msg(chip->dev,
-                                       usb_rcvctrlpipe(chip->dev, 0),
-                                       UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR,
-                                       USB_RECIP_INTERFACE | USB_TYPE_CLASS | 
USB_DIR_IN,
-                                       cluster_id,
-                                       snd_usb_ctrl_intf(chip),
-                                       &hc_header, sizeof(hc_header));
-                       if (err < 0)
-                               return err;
-                       else if (err != sizeof(hc_header)) {
-                               dev_err(&dev->dev,
-                                       "%u:%d : can't get High Capability 
descriptor\n",
-                                       iface_no, altno);
-                               return -EIO;
-                       }
-
-                       /*
-                        * Second step: allocate needed amount of memory
-                        * and request Cluster Descriptor
-                        */
-                       wLength = le16_to_cpu(hc_header.wLength);
-                       cluster = kzalloc(wLength, GFP_KERNEL);
-                       if (!cluster)
-                               return -ENOMEM;
-                       err = snd_usb_ctl_msg(chip->dev,
-                                       usb_rcvctrlpipe(chip->dev, 0),
-                                       UAC3_CS_REQ_HIGH_CAPABILITY_DESCRIPTOR,
-                                       USB_RECIP_INTERFACE | USB_TYPE_CLASS | 
USB_DIR_IN,
-                                       cluster_id,
-                                       snd_usb_ctrl_intf(chip),
-                                       cluster, wLength);
-                       if (err < 0) {
-                               kfree(cluster);
-                               return err;
-                       } else if (err != wLength) {
-                               dev_err(&dev->dev,
-                                       "%u:%d : can't get Cluster 
Descriptor\n",
-                                       iface_no, altno);
-                               kfree(cluster);
-                               return -EIO;
-                       }
-
-                       num_channels = cluster->bNrChannels;
-                       chmap_v3 = convert_chmap_v3(cluster);
-
-                       kfree(cluster);
-
-                       format = le64_to_cpu(as->bmFormats);
-
-                       /* lookup the terminal associated to this interface
-                        * to extract the clock */
-                       input_term = snd_usb_find_input_terminal_descriptor(
-                                                       chip->ctrl_intf,
-                                                       as->bTerminalLink);
-
-                       if (input_term) {
-                               clock = input_term->bCSourceID;
-                               break;
-                       }
-
-                       output_term = 
snd_usb_find_output_terminal_descriptor(chip->ctrl_intf,
-                                                                             
as->bTerminalLink);
-                       if (output_term) {
-                               clock = output_term->bCSourceID;
-                               break;
-                       }
-
-                       dev_err(&dev->dev,
-                               "%u:%d : bogus bTerminalLink %d\n",
-                               iface_no, altno, as->bTerminalLink);
-                       continue;
-               }
-               }
-
-               if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) {
-                       /* get format type */
-                       fmt = snd_usb_find_csint_desc(alts->extra,
-                                                     alts->extralen,
-                                                     NULL, UAC_FORMAT_TYPE);
-                       if (!fmt) {
-                               dev_err(&dev->dev,
-                                       "%u:%d : no UAC_FORMAT_TYPE desc\n",
-                                       iface_no, altno);
-                               continue;
-                       }
-                       if (((protocol == UAC_VERSION_1) && (fmt->bLength < 8))
-                                       || ((protocol == UAC_VERSION_2) &&
-                                                       (fmt->bLength < 6))) {
-                               dev_err(&dev->dev,
-                                       "%u:%d : invalid UAC_FORMAT_TYPE 
desc\n",
-                                       iface_no, altno);
-                               continue;
-                       }
+                       int bm_quirk = 0;
 
                        /*
                         * Blue Microphones workaround: The last altsetting is
                         * identical with the previous one, except for a larger
                         * packet size, but is actually a mislabeled two-channel
                         * setting; ignore it.
+                        *
+                        * Part 1: prepare quirk flag
                         */
-                       if (fmt->bNrChannels == 1 &&
-                           fmt->bSubframeSize == 2 &&
-                           altno == 2 && num == 3 &&
+                       if (altno == 2 && num == 3 &&
                            fp && fp->altsetting == 1 && fp->channels == 1 &&
                            fp->formats == SNDRV_PCM_FMTBIT_S16_LE &&
                            protocol == UAC_VERSION_1 &&
                            le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize) 
==
                                                        fp->maxpacksize * 2)
-                               continue;
+                               bm_quirk = 1;
+
+                       fp = snd_usb_get_audioformat_uac12(chip, alts, protocol,
+                                                          iface_no, altno,
+                                                          stream, bm_quirk);
+                       break;
+               }
+               case UAC_VERSION_3:
+                       fp = snd_usb_get_audioformat_uac3(chip, alts,
+                                               iface_no, altno, stream);
+                       break;
                }
 
-               fp = kzalloc(sizeof(*fp), GFP_KERNEL);
                if (!fp)
-                       return -ENOMEM;
+                       continue;
+               else if (IS_ERR(fp))
+                       return PTR_ERR(fp);
 
-               fp->iface = iface_no;
-               fp->altsetting = altno;
                fp->altset_idx = i;
-               fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
-               fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
-               fp->datainterval = snd_usb_parse_datainterval(chip, alts);
-               fp->protocol = protocol;
-               fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 
0)->wMaxPacketSize);
-               fp->channels = num_channels;
-               if (snd_usb_get_speed(dev) == USB_SPEED_HIGH)
-                       fp->maxpacksize = (((fp->maxpacksize >> 11) & 3) + 1)
-                                       * (fp->maxpacksize & 0x7ff);
-               fp->attributes = parse_uac_endpoint_attributes(chip, alts, 
protocol, iface_no);
-               fp->clock = clock;
-               INIT_LIST_HEAD(&fp->list);
-
-               /* some quirks for attributes here */
-               snd_usb_audioformat_attributes_quirk(chip, fp, stream);
-
-               /* ok, let's parse further... */
-               if (protocol == UAC_VERSION_1 || protocol == UAC_VERSION_2) {
-                       if (snd_usb_parse_audio_format(chip, fp, format,
-                                                       fmt, stream) < 0) {
-                               kfree(fp->rate_table);
-                               kfree(fp);
-                               fp = NULL;
-                               continue;
-                       }
-               } else {
-                       struct uac3_as_header_descriptor *as;
-
-                       as = snd_usb_find_csint_desc(alts->extra,
-                                                    alts->extralen,
-                                                    NULL, UAC_AS_GENERAL);
-
-                       if (snd_usb_parse_audio_format_v3(chip, fp, as,
-                                                               stream) < 0) {
-                               kfree(fp->rate_table);
-                               kfree(fp);
-                               fp = NULL;
-                               continue;
-                       }
-               }
-
-               /* Create chmap */
-               if (fp->channels != num_channels)
-                       chconfig = 0;
-
-               if (protocol == UAC_VERSION_3)
-                       fp->chmap = chmap_v3;
-               else
-                       fp->chmap = convert_chmap(fp->channels, chconfig,
-                                                 protocol);
 
                dev_dbg(&dev->dev, "%u:%d: add audio endpoint %#x\n", iface_no, 
altno, fp->endpoint);
                err = snd_usb_add_audio_stream(chip, stream, fp);
-- 
1.9.1

Reply via email to