ALSA: snd-usb: handle raw data format of UAC2 devices
authorDaniel Mack <zonque@gmail.com>
Sun, 17 Mar 2013 12:07:25 +0000 (20:07 +0800)
committerTakashi Iwai <tiwai@suse.de>
Mon, 18 Mar 2013 07:47:13 +0000 (08:47 +0100)
UAC2 compliant audio devices may announce the capability to transport
raw audio data on their endpoints. Catch this and handle it as
'special' stream on the ALSA side.

Signed-off-by: Daniel Mack <zonque@gmail.com>
Reported-by: Andreas Koch <andreas@akdesigninc.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
include/linux/usb/audio-v2.h
sound/usb/format.c

index ed13053..c5f2158 100644 (file)
@@ -170,6 +170,8 @@ struct uac2_as_header_descriptor {
        __u8 iChannelNames;
 } __attribute__((packed));
 
+#define UAC2_FORMAT_TYPE_I_RAW_DATA    (1 << 31)
+
 /* 4.10.1.2 Class-Specific AS Isochronous Audio Data Endpoint Descriptor */
 
 struct uac2_iso_endpoint_descriptor {
index b30d6fb..a695caf 100644 (file)
@@ -47,7 +47,7 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
                                     int protocol)
 {
        int sample_width, sample_bytes;
-       u64 pcm_formats;
+       u64 pcm_formats = 0;
 
        switch (protocol) {
        case UAC_VERSION_1:
@@ -63,14 +63,17 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
                struct uac_format_type_i_ext_descriptor *fmt = _fmt;
                sample_width = fmt->bBitResolution;
                sample_bytes = fmt->bSubslotSize;
+
+               if (format & UAC2_FORMAT_TYPE_I_RAW_DATA)
+                       pcm_formats |= SNDRV_PCM_FMTBIT_SPECIAL;
+
                format <<= 1;
                break;
        }
        }
 
-       pcm_formats = 0;
-
-       if (format == 0 || format == (1 << UAC_FORMAT_TYPE_I_UNDEFINED)) {
+       if ((pcm_formats == 0) &&
+           (format == 0 || format == (1 << UAC_FORMAT_TYPE_I_UNDEFINED))) {
                /* some devices don't define this correctly... */
                snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n",
                            chip->dev->devnum, fp->iface, fp->altsetting);