ALSA: usb-audio: store protocol version in struct audioformat
authorClemens Ladisch <clemens@ladisch.de>
Thu, 31 Jan 2013 20:39:17 +0000 (21:39 +0100)
committerClemens Ladisch <clemens@ladisch.de>
Thu, 27 Jun 2013 19:59:47 +0000 (21:59 +0200)
Instead of reading bInterfaceProtocol from the descriptor whenever it's
needed, store this value in the audioformat structure.  Besides
simplifying some code, this will allow us to correctly handle vendor-
specific devices where the descriptors are marked with other values.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
sound/usb/card.h
sound/usb/clock.c
sound/usb/format.c
sound/usb/format.h
sound/usb/pcm.c
sound/usb/stream.c

index bf2889a2cae548a1da3022c0c926d0a907b3aa41..5ecacaa90b53fc163c9383b18100bb1ce97f1dfe 100644 (file)
@@ -21,6 +21,7 @@ struct audioformat {
        unsigned char endpoint;         /* endpoint */
        unsigned char ep_attr;          /* endpoint attributes */
        unsigned char datainterval;     /* log_2 of data packet interval */
+       unsigned char protocol;         /* UAC_VERSION_1/2 */
        unsigned int maxpacksize;       /* max. packet size */
        unsigned int rates;             /* rate bitmasks */
        unsigned int rate_min, rate_max;        /* min/max rates */
index 3a2ce390e278afed2e9793d7d7b981965e604462..86f80c60b21f91202c8c17c40d7981c3d7f873f8 100644 (file)
@@ -407,9 +407,7 @@ int snd_usb_init_sample_rate(struct snd_usb_audio *chip, int iface,
                             struct usb_host_interface *alts,
                             struct audioformat *fmt, int rate)
 {
-       struct usb_interface_descriptor *altsd = get_iface_desc(alts);
-
-       switch (altsd->bInterfaceProtocol) {
+       switch (fmt->protocol) {
        case UAC_VERSION_1:
        default:
                return set_sample_rate_v1(chip, iface, alts, fmt, rate);
index 99299ffb33ac22597d57b1a11fd2b1e856f154bd..3525231c6b97325dcbb400ae0c7f9e021555ad8b 100644 (file)
  */
 static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
                                     struct audioformat *fp,
-                                    unsigned int format, void *_fmt,
-                                    int protocol)
+                                    unsigned int format, void *_fmt)
 {
        int sample_width, sample_bytes;
        u64 pcm_formats = 0;
 
-       switch (protocol) {
+       switch (fp->protocol) {
        case UAC_VERSION_1:
        default: {
                struct uac_format_type_i_discrete_descriptor *fmt = _fmt;
@@ -360,11 +359,8 @@ err:
  */
 static int parse_audio_format_i(struct snd_usb_audio *chip,
                                struct audioformat *fp, unsigned int format,
-                               struct uac_format_type_i_continuous_descriptor *fmt,
-                               struct usb_host_interface *iface)
+                               struct uac_format_type_i_continuous_descriptor *fmt)
 {
-       struct usb_interface_descriptor *altsd = get_iface_desc(iface);
-       int protocol = altsd->bInterfaceProtocol;
        snd_pcm_format_t pcm_format;
        int ret;
 
@@ -387,8 +383,7 @@ static int parse_audio_format_i(struct snd_usb_audio *chip,
                }
                fp->formats = pcm_format_to_bits(pcm_format);
        } else {
-               fp->formats = parse_audio_format_i_type(chip, fp, format,
-                                                       fmt, protocol);
+               fp->formats = parse_audio_format_i_type(chip, fp, format, fmt);
                if (!fp->formats)
                        return -EINVAL;
        }
@@ -398,11 +393,8 @@ static int parse_audio_format_i(struct snd_usb_audio *chip,
         * proprietary class specific descriptor.
         * audio class v2 uses class specific EP0 range requests for that.
         */
-       switch (protocol) {
+       switch (fp->protocol) {
        default:
-               snd_printdd(KERN_WARNING "%d:%u:%d : invalid protocol version %d, assuming v1\n",
-                          chip->dev->devnum, fp->iface, fp->altsetting, protocol);
-               /* fall through */
        case UAC_VERSION_1:
                fp->channels = fmt->bNrChannels;
                ret = parse_audio_format_rates_v1(chip, fp, (unsigned char *) fmt, 7);
@@ -427,12 +419,9 @@ static int parse_audio_format_i(struct snd_usb_audio *chip,
  */
 static int parse_audio_format_ii(struct snd_usb_audio *chip,
                                 struct audioformat *fp,
-                                int format, void *_fmt,
-                                struct usb_host_interface *iface)
+                                int format, void *_fmt)
 {
        int brate, framesize, ret;
-       struct usb_interface_descriptor *altsd = get_iface_desc(iface);
-       int protocol = altsd->bInterfaceProtocol;
 
        switch (format) {
        case UAC_FORMAT_TYPE_II_AC3:
@@ -452,11 +441,8 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip,
 
        fp->channels = 1;
 
-       switch (protocol) {
+       switch (fp->protocol) {
        default:
-               snd_printdd(KERN_WARNING "%d:%u:%d : invalid protocol version %d, assuming v1\n",
-                          chip->dev->devnum, fp->iface, fp->altsetting, protocol);
-               /* fall through */
        case UAC_VERSION_1: {
                struct uac_format_type_ii_discrete_descriptor *fmt = _fmt;
                brate = le16_to_cpu(fmt->wMaxBitRate);
@@ -483,17 +469,17 @@ static int parse_audio_format_ii(struct snd_usb_audio *chip,
 int snd_usb_parse_audio_format(struct snd_usb_audio *chip,
                               struct audioformat *fp, unsigned int format,
                               struct uac_format_type_i_continuous_descriptor *fmt,
-                              int stream, struct usb_host_interface *iface)
+                              int stream)
 {
        int err;
 
        switch (fmt->bFormatType) {
        case UAC_FORMAT_TYPE_I:
        case UAC_FORMAT_TYPE_III:
-               err = parse_audio_format_i(chip, fp, format, fmt, iface);
+               err = parse_audio_format_i(chip, fp, format, fmt);
                break;
        case UAC_FORMAT_TYPE_II:
-               err = parse_audio_format_ii(chip, fp, format, fmt, iface);
+               err = parse_audio_format_ii(chip, fp, format, fmt);
                break;
        default:
                snd_printd(KERN_INFO "%d:%u:%d : format type %d is not supported yet\n",
index 6f315226f32042ea95881766d42aedfc26cf9f66..4b8a01129f240361a946f3993be4184077d120e9 100644 (file)
@@ -4,6 +4,6 @@
 int snd_usb_parse_audio_format(struct snd_usb_audio *chip,
                               struct audioformat *fp, unsigned int format,
                               struct uac_format_type_i_continuous_descriptor *fmt,
-                              int stream, struct usb_host_interface *iface);
+                              int stream);
 
 #endif /*  __USBAUDIO_FORMAT_H */
index 93b6e32cfeadbdec4e55aff381b8dc60738fca4a..776c58c7cba0d4cbe289e5d002d4626619b32307 100644 (file)
@@ -202,13 +202,11 @@ int snd_usb_init_pitch(struct snd_usb_audio *chip, int iface,
                       struct usb_host_interface *alts,
                       struct audioformat *fmt)
 {
-       struct usb_interface_descriptor *altsd = get_iface_desc(alts);
-
        /* if endpoint doesn't have pitch control, bail out */
        if (!(fmt->attributes & UAC_EP_CS_ATTR_PITCH_CONTROL))
                return 0;
 
-       switch (altsd->bInterfaceProtocol) {
+       switch (fmt->protocol) {
        case UAC_VERSION_1:
        default:
                return init_pitch_v1(chip, iface, alts, fmt);
index 7db2f8958e7942e223f3b48f8df2a922cfde1258..1ea5871cb980ea9f9f81aea0414e694b91ef0932 100644 (file)
@@ -635,6 +635,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
                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)
@@ -676,7 +677,7 @@ int snd_usb_parse_audio_interface(struct snd_usb_audio *chip, int iface_no)
                }
 
                /* ok, let's parse further... */
-               if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream, alts) < 0) {
+               if (snd_usb_parse_audio_format(chip, fp, format, fmt, stream) < 0) {
                        kfree(fp->rate_table);
                        kfree(fp->chmap);
                        kfree(fp);