aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorJurgen Kramer <gtmkramer@xs4all.nl>2014-11-28 11:32:54 -0500
committerTakashi Iwai <tiwai@suse.de>2014-11-28 12:02:35 -0500
commit6874daad4b0fbed5b2f9bef7f4d3f2b895463a95 (patch)
tree2e1306a87375fdd6cb877e5b77b2ff5d44e4813c /sound
parent7a2e9ddc903225d8fb3a510a842144a239017ee4 (diff)
ALSA: usb-audio: Add mode select quirk for Denon/Marantz DACs
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>
Diffstat (limited to 'sound')
-rw-r--r--sound/usb/pcm.c5
-rw-r--r--sound/usb/quirks.c38
-rw-r--r--sound/usb/quirks.h3
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)
482 /* set interface */ 482 /* set interface */
483 if (subs->interface != fmt->iface || 483 if (subs->interface != fmt->iface ||
484 subs->altset_idx != fmt->altset_idx) { 484 subs->altset_idx != fmt->altset_idx) {
485
486 err = snd_usb_select_mode_quirk(subs, fmt);
487 if (err < 0)
488 return -EIO;
489
485 err = usb_set_interface(dev, fmt->iface, fmt->altsetting); 490 err = usb_set_interface(dev, fmt->iface, fmt->altsetting);
486 if (err < 0) { 491 if (err < 0) {
487 dev_err(&dev->dev, 492 dev_err(&dev->dev,
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index a9d4add89bbe..e0cde741e41d 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -1111,6 +1111,44 @@ void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
1111 } 1111 }
1112} 1112}
1113 1113
1114
1115/* Marantz/Denon USB DACs need a vendor cmd to switch
1116 * between PCM and native DSD mode
1117 */
1118int snd_usb_select_mode_quirk(struct snd_usb_substream *subs,
1119 struct audioformat *fmt)
1120{
1121 struct usb_device *dev = subs->dev;
1122 int err;
1123
1124 switch (subs->stream->chip->usb_id) {
1125 case USB_ID(0x154e, 0x3005): /* Marantz HD-DAC1 */
1126 case USB_ID(0x154e, 0x3006): /* Marantz SA-14S1 */
1127
1128 /* First switch to alt set 0, otherwise the mode switch cmd
1129 * will not be accepted by the DAC
1130 */
1131 err = usb_set_interface(dev, fmt->iface, 0);
1132 if (err < 0)
1133 return err;
1134
1135 mdelay(20); /* Delay needed after setting the interface */
1136
1137 switch (fmt->altsetting) {
1138 case 2: /* DSD mode requested */
1139 case 1: /* PCM mode requested */
1140 err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0,
1141 USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
1142 fmt->altsetting - 1, 1, NULL, 0);
1143 if (err < 0)
1144 return err;
1145 break;
1146 }
1147 mdelay(20);
1148 }
1149 return 0;
1150}
1151
1114void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep) 1152void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep)
1115{ 1153{
1116 /* 1154 /*
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,
31 __u8 request, __u8 requesttype, __u16 value, 31 __u8 request, __u8 requesttype, __u16 value,
32 __u16 index, void *data, __u16 size); 32 __u16 index, void *data, __u16 size);
33 33
34int snd_usb_select_mode_quirk(struct snd_usb_substream *subs,
35 struct audioformat *fmt);
36
34u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, 37u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
35 struct audioformat *fp, 38 struct audioformat *fp,
36 unsigned int sample_bytes); 39 unsigned int sample_bytes);