aboutsummaryrefslogtreecommitdiff
path: root/sound/usb/quirks.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/usb/quirks.c')
-rw-r--r--sound/usb/quirks.c361
1 files changed, 196 insertions, 165 deletions
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index 326d1b0ea5e6..4479a590194f 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -75,19 +75,6 @@ static int ignore_interface_quirk(struct snd_usb_audio *chip,
}
-/*
- * Allow alignment on audio sub-slot (channel samples) rather than
- * on audio slots (audio frames)
- */
-static int create_align_transfer_quirk(struct snd_usb_audio *chip,
- struct usb_interface *iface,
- struct usb_driver *driver,
- const struct snd_usb_audio_quirk *quirk)
-{
- chip->txfr_quirk = 1;
- return 1; /* Continue with creating streams and mixer */
-}
-
static int create_any_midi_quirk(struct snd_usb_audio *chip,
struct usb_interface *intf,
struct usb_driver *driver,
@@ -108,9 +95,6 @@ static int create_standard_audio_quirk(struct snd_usb_audio *chip,
struct usb_interface_descriptor *altsd;
int err;
- if (chip->usb_id == USB_ID(0x1686, 0x00dd)) /* Zoom R16/24 */
- chip->tx_length_quirk = 1;
-
alts = &iface->altsetting[0];
altsd = get_iface_desc(alts);
err = snd_usb_parse_audio_interface(chip, altsd->bInterfaceNumber);
@@ -547,16 +531,7 @@ static int create_standard_mixer_quirk(struct snd_usb_audio *chip,
if (quirk->ifnum < 0)
return 0;
- return snd_usb_create_mixer(chip, quirk->ifnum, 0);
-}
-
-static int setup_disable_autosuspend(struct snd_usb_audio *chip,
- struct usb_interface *iface,
- struct usb_driver *driver,
- const struct snd_usb_audio_quirk *quirk)
-{
- usb_disable_autosuspend(interface_to_usbdev(iface));
- return 1; /* Continue with creating streams and mixer */
+ return snd_usb_create_mixer(chip, quirk->ifnum);
}
/*
@@ -595,9 +570,7 @@ int snd_usb_create_quirk(struct snd_usb_audio *chip,
[QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
[QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
[QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
- [QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk,
[QUIRK_AUDIO_STANDARD_MIXER] = create_standard_mixer_quirk,
- [QUIRK_SETUP_DISABLE_AUTOSUSPEND] = setup_disable_autosuspend,
};
if (quirk->type < QUIRK_TYPE_COUNT) {
@@ -1518,62 +1491,13 @@ void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
}
}
-bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip)
-{
- /* devices which do not support reading the sample rate. */
- switch (chip->usb_id) {
- case USB_ID(0x041e, 0x4080): /* Creative Live Cam VF0610 */
- case USB_ID(0x04d8, 0xfeea): /* Benchmark DAC1 Pre */
- case USB_ID(0x0556, 0x0014): /* Phoenix Audio TMX320VC */
- case USB_ID(0x05a3, 0x9420): /* ELP HD USB Camera */
- case USB_ID(0x05a7, 0x1020): /* Bose Companion 5 */
- case USB_ID(0x074d, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */
- case USB_ID(0x1395, 0x740a): /* Sennheiser DECT */
- case USB_ID(0x1901, 0x0191): /* GE B850V3 CP2114 audio interface */
- case USB_ID(0x21b4, 0x0081): /* AudioQuest DragonFly */
- case USB_ID(0x2912, 0x30c8): /* Audioengine D1 */
- case USB_ID(0x413c, 0xa506): /* Dell AE515 sound bar */
- case USB_ID(0x046d, 0x084c): /* Logitech ConferenceCam Connect */
- return true;
- }
-
- /* devices of these vendors don't support reading rate, either */
- switch (USB_ID_VENDOR(chip->usb_id)) {
- case 0x045e: /* MS Lifecam */
- case 0x047f: /* Plantronics */
- case 0x1de7: /* Phoenix Audio */
- return true;
- }
-
- return false;
-}
-
-/* ITF-USB DSD based DACs need a vendor cmd to switch
- * between PCM and native DSD mode
- */
-static bool is_itf_usb_dsd_dac(unsigned int id)
-{
- switch (id) {
- case USB_ID(0x154e, 0x1002): /* Denon DCD-1500RE */
- 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 */
- 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;
- }
- return false;
-}
-
int snd_usb_select_mode_quirk(struct snd_usb_audio *chip,
const struct audioformat *fmt)
{
struct usb_device *dev = chip->dev;
int err;
- if (is_itf_usb_dsd_dac(chip->usb_id)) {
+ if (chip->quirk_flags & QUIRK_FLAG_ITF_USB_DSD_DAC) {
/* First switch to alt set 0, otherwise the mode switch cmd
* will not be accepted by the DAC
*/
@@ -1636,22 +1560,6 @@ void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep)
ep->tenor_fb_quirk = 1;
}
-void snd_usb_set_interface_quirk(struct snd_usb_audio *chip)
-{
- if (!chip)
- return;
- /*
- * "Playback Design" products need a 50ms delay after setting the
- * USB interface.
- */
- switch (USB_ID_VENDOR(chip->usb_id)) {
- case 0x23ba: /* Playback Design */
- case 0x0644: /* TEAC Corp. */
- msleep(50);
- break;
- }
-}
-
/* quirk applied after snd_usb_ctl_msg(); not applied during boot quirks */
void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe,
__u8 request, __u8 requesttype, __u16 value,
@@ -1659,57 +1567,14 @@ void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe,
{
struct snd_usb_audio *chip = dev_get_drvdata(&dev->dev);
- if (!chip)
+ if (!chip || (requesttype & USB_TYPE_MASK) != USB_TYPE_CLASS)
return;
- /*
- * "Playback Design" products need a 20ms delay after each
- * class compliant request
- */
- if (USB_ID_VENDOR(chip->usb_id) == 0x23ba &&
- (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
- msleep(20);
-
- /*
- * "TEAC Corp." products need a 20ms delay after each
- * class compliant request
- */
- if (USB_ID_VENDOR(chip->usb_id) == 0x0644 &&
- (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
- msleep(20);
-
- /* ITF-USB DSD based DACs functionality need a delay
- * after each class compliant request
- */
- if (is_itf_usb_dsd_dac(chip->usb_id)
- && (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
- msleep(20);
- /*
- * Plantronics headsets (C320, C320-M, etc) need a delay to avoid
- * random microhpone failures.
- */
- if (USB_ID_VENDOR(chip->usb_id) == 0x047f &&
- (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
+ if (chip->quirk_flags & QUIRK_FLAG_CTL_MSG_DELAY)
msleep(20);
-
- /* Zoom R16/24, many Logitech(at least H650e/H570e/BCC950),
- * Jabra 550a, Kingston HyperX needs a tiny delay here,
- * otherwise requests like get/set frequency return
- * as failed despite actually succeeding.
- */
- if ((chip->usb_id == USB_ID(0x1686, 0x00dd) ||
- USB_ID_VENDOR(chip->usb_id) == 0x046d || /* Logitech */
- chip->usb_id == USB_ID(0x0b0e, 0x0349) ||
- chip->usb_id == USB_ID(0x0951, 0x16ad)) &&
- (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
+ else if (chip->quirk_flags & QUIRK_FLAG_CTL_MSG_DELAY_1M)
usleep_range(1000, 2000);
-
- /*
- * Samsung USBC Headset (AKG) need a tiny delay after each
- * class compliant request. (Model number: AAM625R or AAM627R)
- */
- if (chip->usb_id == USB_ID(0x04e8, 0xa051) &&
- (requesttype & USB_TYPE_MASK) == USB_TYPE_CLASS)
+ else if (chip->quirk_flags & QUIRK_FLAG_CTL_MSG_DELAY_5M)
usleep_range(5000, 6000);
}
@@ -1796,7 +1661,7 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
}
/* ITF-USB DSD based DACs */
- if (is_itf_usb_dsd_dac(chip->usb_id)) {
+ if (chip->quirk_flags & QUIRK_FLAG_ITF_USB_DSD_DAC) {
iface = usb_ifnum_to_if(chip->dev, fp->iface);
/* Altsetting 2 support native DSD if the num of altsets is
@@ -1808,29 +1673,9 @@ u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
return SNDRV_PCM_FMTBIT_DSD_U32_BE;
}
- /* Mostly generic method to detect many DSD-capable implementations -
- * from XMOS/Thesycon
- */
- switch (USB_ID_VENDOR(chip->usb_id)) {
- case 0x152a: /* Thesycon devices */
- case 0x20b1: /* XMOS based devices */
- case 0x22d9: /* Oppo */
- case 0x23ba: /* Playback Designs */
- case 0x25ce: /* Mytek devices */
- case 0x278b: /* Rotel? */
- case 0x292b: /* Gustard/Ess based devices */
- case 0x2972: /* FiiO devices */
- case 0x2ab6: /* T+A devices */
- case 0x3353: /* Khadas devices */
- case 0x3842: /* EVGA */
- case 0xc502: /* HiBy devices */
- if (fp->dsd_raw)
- return SNDRV_PCM_FMTBIT_DSD_U32_BE;
- break;
- default:
- break;
-
- }
+ /* Mostly generic method to detect many DSD-capable implementations */
+ if ((chip->quirk_flags & QUIRK_FLAG_DSD_RAW) && fp->dsd_raw)
+ return SNDRV_PCM_FMTBIT_DSD_U32_BE;
return 0;
}
@@ -1916,3 +1761,189 @@ bool snd_usb_registration_quirk(struct snd_usb_audio *chip, int iface)
/* Register as normal */
return false;
}
+
+/*
+ * driver behavior quirk flags
+ */
+struct usb_audio_quirk_flags_table {
+ u32 id;
+ u32 flags;
+};
+
+#define DEVICE_FLG(vid, pid, _flags) \
+ { .id = USB_ID(vid, pid), .flags = (_flags) }
+#define VENDOR_FLG(vid, _flags) DEVICE_FLG(vid, 0, _flags)
+
+static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
+ /* Device matches */
+ DEVICE_FLG(0x041e, 0x3000, /* Creative SB Extigy */
+ QUIRK_FLAG_IGNORE_CTL_ERROR),
+ DEVICE_FLG(0x041e, 0x4080, /* Creative Live Cam VF0610 */
+ QUIRK_FLAG_GET_SAMPLE_RATE),
+ DEVICE_FLG(0x046d, 0x084c, /* Logitech ConferenceCam Connect */
+ QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_CTL_MSG_DELAY_1M),
+ DEVICE_FLG(0x046d, 0x0991, /* Logitech QuickCam Pro */
+ QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_IGNORE_CTL_ERROR),
+ DEVICE_FLG(0x046d, 0x09a4, /* Logitech QuickCam E 3500 */
+ QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_IGNORE_CTL_ERROR),
+ DEVICE_FLG(0x04d8, 0xfeea, /* Benchmark DAC1 Pre */
+ QUIRK_FLAG_GET_SAMPLE_RATE),
+ DEVICE_FLG(0x04e8, 0xa051, /* Samsung USBC Headset (AKG) */
+ QUIRK_FLAG_SKIP_CLOCK_SELECTOR | QUIRK_FLAG_CTL_MSG_DELAY_5M),
+ DEVICE_FLG(0x054c, 0x0b8c, /* Sony WALKMAN NW-A45 DAC */
+ QUIRK_FLAG_SET_IFACE_FIRST),
+ DEVICE_FLG(0x0556, 0x0014, /* Phoenix Audio TMX320VC */
+ QUIRK_FLAG_GET_SAMPLE_RATE),
+ DEVICE_FLG(0x05a3, 0x9420, /* ELP HD USB Camera */
+ QUIRK_FLAG_GET_SAMPLE_RATE),
+ DEVICE_FLG(0x05a7, 0x1020, /* Bose Companion 5 */
+ QUIRK_FLAG_GET_SAMPLE_RATE),
+ DEVICE_FLG(0x05e1, 0x0408, /* Syntek STK1160 */
+ QUIRK_FLAG_ALIGN_TRANSFER),
+ DEVICE_FLG(0x05e1, 0x0480, /* Hauppauge Woodbury */
+ QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
+ DEVICE_FLG(0x0644, 0x8043, /* TEAC UD-501/UD-501V2/UD-503/NT-503 */
+ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY |
+ QUIRK_FLAG_IFACE_DELAY),
+ DEVICE_FLG(0x0644, 0x8044, /* Esoteric D-05X */
+ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY |
+ QUIRK_FLAG_IFACE_DELAY),
+ DEVICE_FLG(0x0644, 0x804a, /* TEAC UD-301 */
+ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY |
+ QUIRK_FLAG_IFACE_DELAY),
+ DEVICE_FLG(0x06f8, 0xb000, /* Hercules DJ Console (Windows Edition) */
+ QUIRK_FLAG_IGNORE_CTL_ERROR),
+ DEVICE_FLG(0x06f8, 0xd002, /* Hercules DJ Console (Macintosh Edition) */
+ QUIRK_FLAG_IGNORE_CTL_ERROR),
+ DEVICE_FLG(0x074d, 0x3553, /* Outlaw RR2150 (Micronas UAC3553B) */
+ QUIRK_FLAG_GET_SAMPLE_RATE),
+ DEVICE_FLG(0x08bb, 0x2702, /* LineX FM Transmitter */
+ QUIRK_FLAG_IGNORE_CTL_ERROR),
+ DEVICE_FLG(0x0951, 0x16ad, /* Kingston HyperX */
+ QUIRK_FLAG_CTL_MSG_DELAY_1M),
+ DEVICE_FLG(0x0b0e, 0x0349, /* Jabra 550a */
+ QUIRK_FLAG_CTL_MSG_DELAY_1M),
+ DEVICE_FLG(0x0fd9, 0x0008, /* Hauppauge HVR-950Q */
+ QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
+ DEVICE_FLG(0x1395, 0x740a, /* Sennheiser DECT */
+ QUIRK_FLAG_GET_SAMPLE_RATE),
+ DEVICE_FLG(0x13e5, 0x0001, /* Serato Phono */
+ QUIRK_FLAG_IGNORE_CTL_ERROR),
+ DEVICE_FLG(0x154e, 0x1002, /* Denon DCD-1500RE */
+ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY),
+ DEVICE_FLG(0x154e, 0x1003, /* Denon DA-300USB */
+ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY),
+ DEVICE_FLG(0x154e, 0x3005, /* Marantz HD-DAC1 */
+ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY),
+ DEVICE_FLG(0x154e, 0x3006, /* Marantz SA-14S1 */
+ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY),
+ DEVICE_FLG(0x154e, 0x500e, /* Denon DN-X1600 */
+ QUIRK_FLAG_IGNORE_CLOCK_SOURCE),
+ DEVICE_FLG(0x1686, 0x00dd, /* Zoom R16/24 */
+ QUIRK_FLAG_TX_LENGTH | QUIRK_FLAG_CTL_MSG_DELAY_1M),
+ DEVICE_FLG(0x17aa, 0x1046, /* Lenovo ThinkStation P620 Rear Line-in, Line-out and Microphone */
+ QUIRK_FLAG_DISABLE_AUTOSUSPEND),
+ DEVICE_FLG(0x17aa, 0x104d, /* Lenovo ThinkStation P620 Internal Speaker + Front Headset */
+ QUIRK_FLAG_DISABLE_AUTOSUSPEND),
+ DEVICE_FLG(0x1852, 0x5065, /* Luxman DA-06 */
+ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY),
+ DEVICE_FLG(0x1901, 0x0191, /* GE B850V3 CP2114 audio interface */
+ QUIRK_FLAG_GET_SAMPLE_RATE),
+ DEVICE_FLG(0x2040, 0x7200, /* Hauppauge HVR-950Q */
+ QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
+ DEVICE_FLG(0x2040, 0x7201, /* Hauppauge HVR-950Q-MXL */
+ QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
+ DEVICE_FLG(0x2040, 0x7210, /* Hauppauge HVR-950Q */
+ QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
+ DEVICE_FLG(0x2040, 0x7211, /* Hauppauge HVR-950Q-MXL */
+ QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
+ DEVICE_FLG(0x2040, 0x7213, /* Hauppauge HVR-950Q */
+ QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
+ DEVICE_FLG(0x2040, 0x7217, /* Hauppauge HVR-950Q */
+ QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
+ DEVICE_FLG(0x2040, 0x721b, /* Hauppauge HVR-950Q */
+ QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
+ DEVICE_FLG(0x2040, 0x721e, /* Hauppauge HVR-950Q */
+ QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
+ DEVICE_FLG(0x2040, 0x721f, /* Hauppauge HVR-950Q */
+ QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
+ DEVICE_FLG(0x2040, 0x7240, /* Hauppauge HVR-850 */
+ QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
+ DEVICE_FLG(0x2040, 0x7260, /* Hauppauge HVR-950Q */
+ QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
+ DEVICE_FLG(0x2040, 0x7270, /* Hauppauge HVR-950Q */
+ QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
+ DEVICE_FLG(0x2040, 0x7280, /* Hauppauge HVR-950Q */
+ QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
+ DEVICE_FLG(0x2040, 0x7281, /* Hauppauge HVR-950Q-MXL */
+ QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
+ DEVICE_FLG(0x2040, 0x8200, /* Hauppauge Woodbury */
+ QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
+ DEVICE_FLG(0x21b4, 0x0081, /* AudioQuest DragonFly */
+ QUIRK_FLAG_GET_SAMPLE_RATE),
+ DEVICE_FLG(0x2912, 0x30c8, /* Audioengine D1 */
+ QUIRK_FLAG_GET_SAMPLE_RATE),
+ DEVICE_FLG(0x413c, 0xa506, /* Dell AE515 sound bar */
+ QUIRK_FLAG_GET_SAMPLE_RATE),
+ DEVICE_FLG(0x534d, 0x2109, /* MacroSilicon MS2109 */
+ QUIRK_FLAG_ALIGN_TRANSFER),
+
+ /* Vendor matches */
+ VENDOR_FLG(0x045e, /* MS Lifecam */
+ QUIRK_FLAG_GET_SAMPLE_RATE),
+ VENDOR_FLG(0x046d, /* Logitech */
+ QUIRK_FLAG_CTL_MSG_DELAY_1M),
+ VENDOR_FLG(0x047f, /* Plantronics */
+ QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_CTL_MSG_DELAY),
+ VENDOR_FLG(0x0644, /* TEAC Corp. */
+ QUIRK_FLAG_CTL_MSG_DELAY | QUIRK_FLAG_IFACE_DELAY),
+ VENDOR_FLG(0x07fd, /* MOTU */
+ QUIRK_FLAG_VALIDATE_RATES),
+ VENDOR_FLG(0x152a, /* Thesycon devices */
+ QUIRK_FLAG_DSD_RAW),
+ VENDOR_FLG(0x1de7, /* Phoenix Audio */
+ QUIRK_FLAG_GET_SAMPLE_RATE),
+ VENDOR_FLG(0x20b1, /* XMOS based devices */
+ QUIRK_FLAG_DSD_RAW),
+ VENDOR_FLG(0x22d9, /* Oppo */
+ QUIRK_FLAG_DSD_RAW),
+ VENDOR_FLG(0x23ba, /* Playback Design */
+ QUIRK_FLAG_CTL_MSG_DELAY | QUIRK_FLAG_IFACE_DELAY |
+ QUIRK_FLAG_DSD_RAW),
+ VENDOR_FLG(0x25ce, /* Mytek devices */
+ QUIRK_FLAG_DSD_RAW),
+ VENDOR_FLG(0x278b, /* Rotel? */
+ QUIRK_FLAG_DSD_RAW),
+ VENDOR_FLG(0x292b, /* Gustard/Ess based devices */
+ QUIRK_FLAG_DSD_RAW),
+ VENDOR_FLG(0x2972, /* FiiO devices */
+ QUIRK_FLAG_DSD_RAW),
+ VENDOR_FLG(0x2ab6, /* T+A devices */
+ QUIRK_FLAG_DSD_RAW),
+ VENDOR_FLG(0x3353, /* Khadas devices */
+ QUIRK_FLAG_DSD_RAW),
+ VENDOR_FLG(0x3842, /* EVGA */
+ QUIRK_FLAG_DSD_RAW),
+ VENDOR_FLG(0xc502, /* HiBy devices */
+ QUIRK_FLAG_DSD_RAW),
+
+ {} /* terminator */
+};
+
+void snd_usb_init_quirk_flags(struct snd_usb_audio *chip)
+{
+ const struct usb_audio_quirk_flags_table *p;
+
+ for (p = quirk_flags_table; p->id; p++) {
+ if (chip->usb_id == p->id ||
+ (!USB_ID_PRODUCT(p->id) &&
+ USB_ID_VENDOR(chip->usb_id) == USB_ID_VENDOR(p->id))) {
+ usb_audio_dbg(chip,
+ "Set quirk_flags 0x%x for device %04x:%04x\n",
+ p->flags, USB_ID_VENDOR(chip->usb_id),
+ USB_ID_PRODUCT(chip->usb_id));
+ chip->quirk_flags |= p->flags;
+ return;
+ }
+ }
+}