diff options
author | Jurgen Kramer <gtmkramer@xs4all.nl> | 2014-11-28 11:32:54 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2014-11-28 12:02:35 -0500 |
commit | 6874daad4b0fbed5b2f9bef7f4d3f2b895463a95 (patch) | |
tree | 2e1306a87375fdd6cb877e5b77b2ff5d44e4813c /sound | |
parent | 7a2e9ddc903225d8fb3a510a842144a239017ee4 (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.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) | |||
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 | */ | ||
1118 | int 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 | |||
1114 | void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep) | 1152 | void 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 | ||
34 | int snd_usb_select_mode_quirk(struct snd_usb_substream *subs, | ||
35 | struct audioformat *fmt); | ||
36 | |||
34 | u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, | 37 | u64 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); |