ALSA: snd-usb: add quirks handler for DSD streams
authorDaniel Mack <zonque@gmail.com>
Tue, 16 Apr 2013 16:01:40 +0000 (00:01 +0800)
committerTakashi Iwai <tiwai@suse.de>
Thu, 18 Apr 2013 08:03:53 +0000 (10:03 +0200)
Unfortunately, none of the UAC standards provides a way to identify DSD
(Direct Stream Digital) formats. Hence, this patch adds a quirks
handler to identify USB interfaces that are capable of handling DSD.

That quirks handler can augment the already parsed formats bit-field,
by any of the new SNDRV_PCM_FMTBIT_DSD_{U8_U16} and setting the dsd_dop
flag in the audio format, if the driver should take care for the DOP
byte stuffing.

The only devices that are known to work with this are the ones with
a 'Playback Designs' vendor id.

Signed-off-by: Daniel Mack <zonque@gmail.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/usb/format.c
sound/usb/quirks.c
sound/usb/quirks.h

index 20c775170959815effee98518a0ef03d451826d8..020ede0259eb2b43a95a096b6d63335af735611e 100644 (file)
@@ -136,6 +136,9 @@ static u64 parse_audio_format_i_type(struct snd_usb_audio *chip,
                snd_printk(KERN_INFO "%d:%u:%d : unsupported format bits %#x\n",
                           chip->dev->devnum, fp->iface, fp->altsetting, format);
        }
+
+       pcm_formats |= snd_usb_interface_dsd_format_quirks(chip, fp, sample_bytes);
+
        return pcm_formats;
 }
 
index 175fbb7d334a5306e449e2ec68233aea02f11d72..e564adb74852c9c25e66063fa49268c459b3ae05 100644 (file)
@@ -916,3 +916,31 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe,
                mdelay(20);
 }
 
+/*
+ * snd_usb_interface_dsd_format_quirks() is called from format.c to
+ * augment the PCM format bit-field for DSD types. The UAC standards
+ * don't have a designated bit field to denote DSD-capable interfaces,
+ * hence all hardware that is known to support this format has to be
+ * listed here.
+ */
+u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
+                                       struct audioformat *fp,
+                                       unsigned int sample_bytes)
+{
+       /* Playback Designs */
+       if (le16_to_cpu(chip->dev->descriptor.idVendor) == 0x23ba) {
+               switch (fp->altsetting) {
+               case 1:
+                       fp->dsd_dop = true;
+                       return SNDRV_PCM_FMTBIT_DSD_U16_LE;
+               case 2:
+                       fp->dsd_bitrev = true;
+                       return SNDRV_PCM_FMTBIT_DSD_U8;
+               case 3:
+                       fp->dsd_bitrev = true;
+                       return SNDRV_PCM_FMTBIT_DSD_U16_LE;
+               }
+       }
+
+       return 0;
+}
index 7c3681fd1c3cdce22acb9190b310803a28f72cb3..665e972a1b40988d7602e5d888f78b8ba81311e4 100644 (file)
@@ -31,4 +31,8 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe,
                           __u8 request, __u8 requesttype, __u16 value,
                           __u16 index, void *data, __u16 size);
 
+u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
+                                       struct audioformat *fp,
+                                       unsigned int sample_bytes);
+
 #endif /* __USBAUDIO_QUIRKS_H */