mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
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>
This commit is contained in:
parent
7a2e9ddc90
commit
6874daad4b
@ -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,
|
||||
|
@ -1111,6 +1111,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)
|
||||
{
|
||||
/*
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user