diff options
author | Jurgen Kramer <gtmkramer@xs4all.nl> | 2014-11-28 17:32:54 +0100 |
---|---|---|
committer | Sasha Levin <sasha.levin@oracle.com> | 2015-06-09 14:31:45 -0400 |
commit | 5634e0f8d14084f47055b81350b5563d3f06fd4c (patch) | |
tree | ac165be4a30c0265a1fe3d31552742eeb6e053b2 /sound/usb | |
parent | 43772581af59b445d2350b2344b60b71972c1820 (diff) | |
download | linux-stable-5634e0f8d14084f47055b81350b5563d3f06fd4c.tar.gz linux-stable-5634e0f8d14084f47055b81350b5563d3f06fd4c.tar.bz2 linux-stable-5634e0f8d14084f47055b81350b5563d3f06fd4c.zip |
ALSA: usb-audio: Add mode select quirk for Denon/Marantz DACs
[ Upstream commit 6874daad4b0fbed5b2f9bef7f4d3f2b895463a95 ]
Denon/Marantz USB DACs need a specific vendor command to switch between PCM and
DSD mode. This patch adds a new quirk function to switch between the two modes
using the specific USB vendor command.
This patch applies to the following devices:
- Marantz SA-14S1
- Marantz HD-DAC1
Signed-off-by: Jurgen Kramer <gtmkramer@xs4all.nl>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
Diffstat (limited to 'sound/usb')
-rw-r--r-- | sound/usb/pcm.c | 5 | ||||
-rw-r--r-- | sound/usb/quirks.c | 38 | ||||
-rw-r--r-- | sound/usb/quirks.h | 3 |
3 files changed, 46 insertions, 0 deletions
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index c62a1659106d..0d8aba5fe1a8 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -482,6 +482,11 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) /* set interface */ if (subs->interface != fmt->iface || subs->altset_idx != fmt->altset_idx) { + + err = snd_usb_select_mode_quirk(subs, fmt); + if (err < 0) + return -EIO; + err = usb_set_interface(dev, fmt->iface, fmt->altsetting); if (err < 0) { dev_err(&dev->dev, diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index f59d98d38fa4..8039495ac85a 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1102,6 +1102,44 @@ void snd_usb_set_format_quirk(struct snd_usb_substream *subs, } } + +/* Marantz/Denon USB DACs need a vendor cmd to switch + * between PCM and native DSD mode + */ +int snd_usb_select_mode_quirk(struct snd_usb_substream *subs, + struct audioformat *fmt) +{ + struct usb_device *dev = subs->dev; + int err; + + switch (subs->stream->chip->usb_id) { + case USB_ID(0x154e, 0x3005): /* Marantz HD-DAC1 */ + case USB_ID(0x154e, 0x3006): /* Marantz SA-14S1 */ + + /* First switch to alt set 0, otherwise the mode switch cmd + * will not be accepted by the DAC + */ + err = usb_set_interface(dev, fmt->iface, 0); + if (err < 0) + return err; + + mdelay(20); /* Delay needed after setting the interface */ + + switch (fmt->altsetting) { + case 2: /* DSD mode requested */ + case 1: /* PCM mode requested */ + err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0, + USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, + fmt->altsetting - 1, 1, NULL, 0); + if (err < 0) + return err; + break; + } + mdelay(20); + } + return 0; +} + void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep) { /* diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h index 665e972a1b40..1b862386577d 100644 --- a/sound/usb/quirks.h +++ b/sound/usb/quirks.h @@ -31,6 +31,9 @@ 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); +int snd_usb_select_mode_quirk(struct snd_usb_substream *subs, + struct audioformat *fmt); + u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, struct audioformat *fp, unsigned int sample_bytes); |