Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: snd-usb: handle raw data format of UAC2 devices

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>

authored by

Daniel Mack and committed by
Takashi Iwai
717bfb5f 2fcdb06d

+9 -4
+2
include/linux/usb/audio-v2.h
··· 170 170 __u8 iChannelNames; 171 171 } __attribute__((packed)); 172 172 173 + #define UAC2_FORMAT_TYPE_I_RAW_DATA (1 << 31) 174 + 173 175 /* 4.10.1.2 Class-Specific AS Isochronous Audio Data Endpoint Descriptor */ 174 176 175 177 struct uac2_iso_endpoint_descriptor {
+7 -4
sound/usb/format.c
··· 47 47 int protocol) 48 48 { 49 49 int sample_width, sample_bytes; 50 - u64 pcm_formats; 50 + u64 pcm_formats = 0; 51 51 52 52 switch (protocol) { 53 53 case UAC_VERSION_1: ··· 63 63 struct uac_format_type_i_ext_descriptor *fmt = _fmt; 64 64 sample_width = fmt->bBitResolution; 65 65 sample_bytes = fmt->bSubslotSize; 66 + 67 + if (format & UAC2_FORMAT_TYPE_I_RAW_DATA) 68 + pcm_formats |= SNDRV_PCM_FMTBIT_SPECIAL; 69 + 66 70 format <<= 1; 67 71 break; 68 72 } 69 73 } 70 74 71 - pcm_formats = 0; 72 - 73 - if (format == 0 || format == (1 << UAC_FORMAT_TYPE_I_UNDEFINED)) { 75 + if ((pcm_formats == 0) && 76 + (format == 0 || format == (1 << UAC_FORMAT_TYPE_I_UNDEFINED))) { 74 77 /* some devices don't define this correctly... */ 75 78 snd_printdd(KERN_INFO "%d:%u:%d : format type 0 is detected, processed as PCM\n", 76 79 chip->dev->devnum, fp->iface, fp->altsetting);