From ceb18f511beeb8b750f027f170eb6d901a082e9a Mon Sep 17 00:00:00 2001 From: Ruslan Bilovol Date: Mon, 19 Mar 2018 03:46:02 +0200 Subject: ALSA: usb-audio: move audioformat quirks to quirks.c Offload USB audio interface parsing function by moving quirks to a specially designed location (quirks.c) Signed-off-by: Ruslan Bilovol Signed-off-by: Takashi Iwai --- sound/usb/quirks.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'sound/usb/quirks.c') diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index ea8f3de92fa4..eeea8e18aea3 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1403,3 +1403,37 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, return 0; } + +void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip, + struct audioformat *fp, + int stream) +{ + switch (chip->usb_id) { + case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */ + /* Optoplay sets the sample rate attribute although + * it seems not supporting it in fact. + */ + fp->attributes &= ~UAC_EP_CS_ATTR_SAMPLE_RATE; + break; + case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */ + case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */ + /* doesn't set the sample rate attribute, but supports it */ + fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE; + break; + case USB_ID(0x0763, 0x2001): /* M-Audio Quattro USB */ + case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */ + case USB_ID(0x047f, 0x0ca1): /* plantronics headset */ + case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is + an older model 77d:223) */ + /* + * plantronics headset and Griffin iMic have set adaptive-in + * although it's really not... + */ + fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE; + if (stream == SNDRV_PCM_STREAM_PLAYBACK) + fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE; + else + fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC; + break; + } +} -- cgit v1.2.3 From 71426535f49fe6034d0e0db77608b91a0c1a022d Mon Sep 17 00:00:00 2001 From: Nobutaka Okabe Date: Fri, 23 Mar 2018 19:18:22 +0900 Subject: ALSA: usb-audio: Add native DSD support for Luxman DA-06 Add native DSD support quirk for Luxman DA-06 DAC, by adding the PID/VID 1852:5065. Rename "is_marantz_denon_dac()" function to "is_itf_usb_dsd_2alts_dac()" to cover broader device family sharing the same USB audio implementation(*). For the same reason, rename "is_teac_dsd_dac()" function to "is_itf_usb_dsd_3alts_dac()". (*) These devices have the same USB controller "ITF-USB DSD", supplied by INTERFACE Co., Ltd. "ITF-USB DSD" USB controller has two patterns, Pattern 1. (2 altsets version) - Altset 0: for control - Altset 1: for stream (S32) - Altset 2: for stream (S32, DSD_U32) Pattern 2. (3 altsets version) - Altset 0: for control - Altset 1: for stream (S16) - Altset 2: for stream (S32) - Altset 3: for stream (S32, DSD_U32) "is_itf_usb_dsd_2alts_dac()" returns true, if the DAC has "Pattern 1" USB controller, and "is_itf_usb_dsd_3alts_dac()" returns true, if "Pattern2". Signed-off-by: Nobutaka Okabe Signed-off-by: Takashi Iwai --- sound/usb/quirks.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'sound/usb/quirks.c') diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 6aa0ebd4a5a2..dec86df3f47a 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1149,24 +1149,27 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip) return false; } -/* Marantz/Denon USB DACs need a vendor cmd to switch +/* ITF-USB DSD based DACs need a vendor cmd to switch * between PCM and native DSD mode + * (2 altsets version) */ -static bool is_marantz_denon_dac(unsigned int id) +static bool is_itf_usb_dsd_2alts_dac(unsigned int id) { switch (id) { case USB_ID(0x154e, 0x1003): /* Denon DA-300USB */ case USB_ID(0x154e, 0x3005): /* Marantz HD-DAC1 */ case USB_ID(0x154e, 0x3006): /* Marantz SA-14S1 */ + case USB_ID(0x1852, 0x5065): /* Luxman DA-06 */ return true; } return false; } -/* TEAC UD-501/UD-503/NT-503 USB DACs need a vendor cmd to switch - * between PCM/DOP and native DSD mode +/* ITF-USB DSD based DACs need a vendor cmd to switch + * between PCM and native DSD mode + * (3 altsets version) */ -static bool is_teac_dsd_dac(unsigned int id) +static bool is_itf_usb_dsd_3alts_dac(unsigned int id) { switch (id) { case USB_ID(0x0644, 0x8043): /* TEAC UD-501/UD-503/NT-503 */ @@ -1183,7 +1186,7 @@ int snd_usb_select_mode_quirk(struct snd_usb_substream *subs, struct usb_device *dev = subs->dev; int err; - if (is_marantz_denon_dac(subs->stream->chip->usb_id)) { + if (is_itf_usb_dsd_2alts_dac(subs->stream->chip->usb_id)) { /* First switch to alt set 0, otherwise the mode switch cmd * will not be accepted by the DAC */ @@ -1204,7 +1207,7 @@ int snd_usb_select_mode_quirk(struct snd_usb_substream *subs, break; } mdelay(20); - } else if (is_teac_dsd_dac(subs->stream->chip->usb_id)) { + } else if (is_itf_usb_dsd_3alts_dac(subs->stream->chip->usb_id)) { /* Vendor mode switch cmd is required. */ switch (fmt->altsetting) { case 3: /* DSD mode (DSD_U32) requested */ @@ -1300,10 +1303,10 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) mdelay(20); - /* Marantz/Denon devices with USB DAC functionality need a delay + /* ITF-USB DSD based DACs functionality need a delay * after each class compliant request */ - if (is_marantz_denon_dac(chip->usb_id) + if (is_itf_usb_dsd_2alts_dac(chip->usb_id) && (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) mdelay(20); @@ -1390,14 +1393,14 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, break; } - /* Denon/Marantz devices with USB DAC functionality */ - if (is_marantz_denon_dac(chip->usb_id)) { + /* ITF-USB DSD based DACs (2 altsets version) */ + if (is_itf_usb_dsd_2alts_dac(chip->usb_id)) { if (fp->altsetting == 2) return SNDRV_PCM_FMTBIT_DSD_U32_BE; } - /* TEAC devices with USB DAC functionality */ - if (is_teac_dsd_dac(chip->usb_id)) { + /* ITF-USB DSD based DACs (3 altsets version) */ + if (is_itf_usb_dsd_3alts_dac(chip->usb_id)) { if (fp->altsetting == 3) return SNDRV_PCM_FMTBIT_DSD_U32_BE; } -- cgit v1.2.3 From 74dc71f83e500b2c6bb0d01a947e1b7231456dd8 Mon Sep 17 00:00:00 2001 From: Nobutaka Okabe Date: Fri, 23 Mar 2018 19:20:00 +0900 Subject: ALSA: usb-audio: FIX native DSD support for TEAC UD-501 DAC There are two versions of TEAC UD-501, the normal version and the vendor updated version(UD-501V2). They have the same VID/PID, but the num of the altsetting is different, UD-501 has 2 altsets for stream, and UD-501V2 has 3. So, add the logic to distinguish them by the Product Name, not by the PID. Signed-off-by: Nobutaka Okabe Signed-off-by: Takashi Iwai --- sound/usb/quirks.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) (limited to 'sound/usb/quirks.c') diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index dec86df3f47a..da73405c3115 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1153,14 +1153,23 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip) * between PCM and native DSD mode * (2 altsets version) */ -static bool is_itf_usb_dsd_2alts_dac(unsigned int id) +static bool is_itf_usb_dsd_2alts_dac(struct snd_usb_audio *chip) { - switch (id) { + char *product = chip->dev->product; /* DAC product name */ + + switch (chip->usb_id) { case USB_ID(0x154e, 0x1003): /* Denon DA-300USB */ case USB_ID(0x154e, 0x3005): /* Marantz HD-DAC1 */ case USB_ID(0x154e, 0x3006): /* Marantz SA-14S1 */ case USB_ID(0x1852, 0x5065): /* Luxman DA-06 */ return true; + case USB_ID(0x0644, 0x8043): + /* TEAC UD-501 */ + if (product && strcmp("UD-501", product)) { + return true; + } else { + return false; + } } return false; } @@ -1169,13 +1178,21 @@ static bool is_itf_usb_dsd_2alts_dac(unsigned int id) * between PCM and native DSD mode * (3 altsets version) */ -static bool is_itf_usb_dsd_3alts_dac(unsigned int id) +static bool is_itf_usb_dsd_3alts_dac(struct snd_usb_audio *chip) { - switch (id) { - case USB_ID(0x0644, 0x8043): /* TEAC UD-501/UD-503/NT-503 */ + char *product = chip->dev->product; /* DAC product name */ + + switch (chip->usb_id) { case USB_ID(0x0644, 0x8044): /* Esoteric D-05X */ case USB_ID(0x0644, 0x804a): /* TEAC UD-301 */ return true; + case USB_ID(0x0644, 0x8043): + /* TEAC UD-501V2/UD-503/NT-503 */ + if (product && !strcmp("UD-501", product)) { + return true; + } else { + return false; + } } return false; } @@ -1186,7 +1203,7 @@ int snd_usb_select_mode_quirk(struct snd_usb_substream *subs, struct usb_device *dev = subs->dev; int err; - if (is_itf_usb_dsd_2alts_dac(subs->stream->chip->usb_id)) { + if (is_itf_usb_dsd_2alts_dac(subs->stream->chip)) { /* First switch to alt set 0, otherwise the mode switch cmd * will not be accepted by the DAC */ @@ -1207,7 +1224,7 @@ int snd_usb_select_mode_quirk(struct snd_usb_substream *subs, break; } mdelay(20); - } else if (is_itf_usb_dsd_3alts_dac(subs->stream->chip->usb_id)) { + } else if (is_itf_usb_dsd_3alts_dac(subs->stream->chip)) { /* Vendor mode switch cmd is required. */ switch (fmt->altsetting) { case 3: /* DSD mode (DSD_U32) requested */ @@ -1306,7 +1323,7 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, /* ITF-USB DSD based DACs functionality need a delay * after each class compliant request */ - if (is_itf_usb_dsd_2alts_dac(chip->usb_id) + if (is_itf_usb_dsd_2alts_dac(chip) && (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) mdelay(20); @@ -1394,13 +1411,13 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, } /* ITF-USB DSD based DACs (2 altsets version) */ - if (is_itf_usb_dsd_2alts_dac(chip->usb_id)) { + if (is_itf_usb_dsd_2alts_dac(chip)) { if (fp->altsetting == 2) return SNDRV_PCM_FMTBIT_DSD_U32_BE; } /* ITF-USB DSD based DACs (3 altsets version) */ - if (is_itf_usb_dsd_3alts_dac(chip->usb_id)) { + if (is_itf_usb_dsd_3alts_dac(chip)) { if (fp->altsetting == 3) return SNDRV_PCM_FMTBIT_DSD_U32_BE; } -- cgit v1.2.3 From f3b906d720e429a3acd95f8cbd4fda366fb1659d Mon Sep 17 00:00:00 2001 From: Nobutaka Okabe Date: Fri, 23 Mar 2018 19:21:13 +0900 Subject: ALSA: usb-audio: Integrate native DSD support for ITF-USB based DACs. Integrate the native DSD support quirk codes of "ITF-USB DSD" based DACs. Now, "is_itf_usb_dsd_2alts_dac()" and "is_itf_usb_dsd_3alts_dac()" is integrated into one function "is_itf_usb_dsd_dac()". So, remove the logic to distinguish UD-501 and UD-501V2 by the "Product Name". The integration is possible by changing the following two functions. - snd_usb_select_mode_quirk(): Change the determination condition of the DSD mode switch command, from the altset number being used, to the audio format being played. Actually, this operation is same as playback using ASIO driver in Windows environment. - snd_usb_interface_dsd_format_quirk(): To which altset supports native DSD is determined by the number of altsets. Previously, it's a constant "2" or "3". Signed-off-by: Nobutaka Okabe Signed-off-by: Takashi Iwai --- sound/usb/quirks.c | 84 +++++++++++++++--------------------------------------- 1 file changed, 23 insertions(+), 61 deletions(-) (limited to 'sound/usb/quirks.c') diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index da73405c3115..acbeb52f6fd6 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -1151,48 +1151,18 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip) /* ITF-USB DSD based DACs need a vendor cmd to switch * between PCM and native DSD mode - * (2 altsets version) */ -static bool is_itf_usb_dsd_2alts_dac(struct snd_usb_audio *chip) +static bool is_itf_usb_dsd_dac(unsigned int id) { - char *product = chip->dev->product; /* DAC product name */ - - switch (chip->usb_id) { + switch (id) { case USB_ID(0x154e, 0x1003): /* Denon DA-300USB */ case USB_ID(0x154e, 0x3005): /* Marantz HD-DAC1 */ case USB_ID(0x154e, 0x3006): /* Marantz SA-14S1 */ case USB_ID(0x1852, 0x5065): /* Luxman DA-06 */ - return true; - case USB_ID(0x0644, 0x8043): - /* TEAC UD-501 */ - if (product && strcmp("UD-501", product)) { - return true; - } else { - return false; - } - } - return false; -} - -/* ITF-USB DSD based DACs need a vendor cmd to switch - * between PCM and native DSD mode - * (3 altsets version) - */ -static bool is_itf_usb_dsd_3alts_dac(struct snd_usb_audio *chip) -{ - char *product = chip->dev->product; /* DAC product name */ - - switch (chip->usb_id) { + case USB_ID(0x0644, 0x8043): /* TEAC UD-501/UD-501V2/UD-503/NT-503 */ case USB_ID(0x0644, 0x8044): /* Esoteric D-05X */ case USB_ID(0x0644, 0x804a): /* TEAC UD-301 */ return true; - case USB_ID(0x0644, 0x8043): - /* TEAC UD-501V2/UD-503/NT-503 */ - if (product && !strcmp("UD-501", product)) { - return true; - } else { - return false; - } } return false; } @@ -1203,7 +1173,7 @@ int snd_usb_select_mode_quirk(struct snd_usb_substream *subs, struct usb_device *dev = subs->dev; int err; - if (is_itf_usb_dsd_2alts_dac(subs->stream->chip)) { + if (is_itf_usb_dsd_dac(subs->stream->chip->usb_id)) { /* First switch to alt set 0, otherwise the mode switch cmd * will not be accepted by the DAC */ @@ -1213,37 +1183,26 @@ int snd_usb_select_mode_quirk(struct snd_usb_substream *subs, 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); - } else if (is_itf_usb_dsd_3alts_dac(subs->stream->chip)) { /* Vendor mode switch cmd is required. */ - switch (fmt->altsetting) { - case 3: /* DSD mode (DSD_U32) requested */ + if (fmt->formats & SNDRV_PCM_FMTBIT_DSD_U32_BE) { + /* DSD mode (DSD_U32) requested */ err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0, USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, 1, 1, NULL, 0); if (err < 0) return err; - break; - case 2: /* PCM or DOP mode (S32) requested */ - case 1: /* PCM mode (S16) requested */ + } else { + /* PCM or DOP mode (S32) requested */ + /* PCM mode (S16) requested */ err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0, USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, 0, 1, NULL, 0); if (err < 0) return err; - break; + } + mdelay(20); } return 0; } @@ -1323,7 +1282,7 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe, /* ITF-USB DSD based DACs functionality need a delay * after each class compliant request */ - if (is_itf_usb_dsd_2alts_dac(chip) + if (is_itf_usb_dsd_dac(chip->usb_id) && (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS) mdelay(20); @@ -1349,6 +1308,8 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, struct audioformat *fp, unsigned int sample_bytes) { + struct usb_interface *iface; + /* Playback Designs */ if (USB_ID_VENDOR(chip->usb_id) == 0x23ba) { switch (fp->altsetting) { @@ -1410,15 +1371,16 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip, break; } - /* ITF-USB DSD based DACs (2 altsets version) */ - if (is_itf_usb_dsd_2alts_dac(chip)) { - if (fp->altsetting == 2) - return SNDRV_PCM_FMTBIT_DSD_U32_BE; - } + /* ITF-USB DSD based DACs */ + if (is_itf_usb_dsd_dac(chip->usb_id)) { + iface = usb_ifnum_to_if(chip->dev, fp->iface); - /* ITF-USB DSD based DACs (3 altsets version) */ - if (is_itf_usb_dsd_3alts_dac(chip)) { - if (fp->altsetting == 3) + /* Altsetting 2 support native DSD if the num of altsets is + * three (0-2), + * Altsetting 3 support native DSD if the num of altsets is + * four (0-3). + */ + if (fp->altsetting == iface->num_altsetting - 1) return SNDRV_PCM_FMTBIT_DSD_U32_BE; } -- cgit v1.2.3