xref: /openbmc/linux/sound/usb/quirks.c (revision 0f9b4c3ca5fdf3e177266ef994071b1a03f07318)
11a59d1b8SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2e5779998SDaniel Mack /*
3e5779998SDaniel Mack  */
4e5779998SDaniel Mack 
5e5779998SDaniel Mack #include <linux/init.h>
636db0456SStephen Rothwell #include <linux/slab.h>
7e5779998SDaniel Mack #include <linux/usb.h>
8e5779998SDaniel Mack #include <linux/usb/audio.h>
9aafe77ccSClemens Ladisch #include <linux/usb/midi.h>
10ad43d528SLinus Walleij #include <linux/bits.h>
11e5779998SDaniel Mack 
129e38658fSDaniel Mack #include <sound/control.h>
13e5779998SDaniel Mack #include <sound/core.h>
14e5779998SDaniel Mack #include <sound/info.h>
15e5779998SDaniel Mack #include <sound/pcm.h>
16e5779998SDaniel Mack 
17e5779998SDaniel Mack #include "usbaudio.h"
18e5779998SDaniel Mack #include "card.h"
19f0b5e634SDaniel Mack #include "mixer.h"
207b1eda22SDaniel Mack #include "mixer_quirks.h"
21e5779998SDaniel Mack #include "midi.h"
22ff49d1dfSTakashi Iwai #include "midi2.h"
23e5779998SDaniel Mack #include "quirks.h"
24e5779998SDaniel Mack #include "helper.h"
25e5779998SDaniel Mack #include "endpoint.h"
26e5779998SDaniel Mack #include "pcm.h"
273d8d4dcfSDaniel Mack #include "clock.h"
28e8e8babfSDaniel Mack #include "stream.h"
29e5779998SDaniel Mack 
30e5779998SDaniel Mack /*
31e5779998SDaniel Mack  * handle the quirks for the contained interfaces
32e5779998SDaniel Mack  */
create_composite_quirk(struct snd_usb_audio * chip,struct usb_interface * iface,struct usb_driver * driver,const struct snd_usb_audio_quirk * quirk_comp)33e5779998SDaniel Mack static int create_composite_quirk(struct snd_usb_audio *chip,
34e5779998SDaniel Mack 				  struct usb_interface *iface,
35e5779998SDaniel Mack 				  struct usb_driver *driver,
3685a81813STakashi Iwai 				  const struct snd_usb_audio_quirk *quirk_comp)
37e5779998SDaniel Mack {
38e5779998SDaniel Mack 	int probed_ifnum = get_iface_desc(iface->altsetting)->bInterfaceNumber;
3985a81813STakashi Iwai 	const struct snd_usb_audio_quirk *quirk;
40e5779998SDaniel Mack 	int err;
41e5779998SDaniel Mack 
4285a81813STakashi Iwai 	for (quirk = quirk_comp->data; quirk->ifnum >= 0; ++quirk) {
43e5779998SDaniel Mack 		iface = usb_ifnum_to_if(chip->dev, quirk->ifnum);
44e5779998SDaniel Mack 		if (!iface)
45e5779998SDaniel Mack 			continue;
46e5779998SDaniel Mack 		if (quirk->ifnum != probed_ifnum &&
47e5779998SDaniel Mack 		    usb_interface_claimed(iface))
48e5779998SDaniel Mack 			continue;
49e5779998SDaniel Mack 		err = snd_usb_create_quirk(chip, iface, driver, quirk);
50e5779998SDaniel Mack 		if (err < 0)
51e5779998SDaniel Mack 			return err;
52d4b8fc66STakashi Iwai 	}
53d4b8fc66STakashi Iwai 
5485a81813STakashi Iwai 	for (quirk = quirk_comp->data; quirk->ifnum >= 0; ++quirk) {
55d4b8fc66STakashi Iwai 		iface = usb_ifnum_to_if(chip->dev, quirk->ifnum);
56d4b8fc66STakashi Iwai 		if (!iface)
57d4b8fc66STakashi Iwai 			continue;
58d4b8fc66STakashi Iwai 		if (quirk->ifnum != probed_ifnum &&
595fb45414STakashi Iwai 		    !usb_interface_claimed(iface)) {
605fb45414STakashi Iwai 			err = usb_driver_claim_interface(driver, iface,
615fb45414STakashi Iwai 							 USB_AUDIO_IFACE_UNUSED);
625fb45414STakashi Iwai 			if (err < 0)
635fb45414STakashi Iwai 				return err;
645fb45414STakashi Iwai 		}
65e5779998SDaniel Mack 	}
66d4b8fc66STakashi Iwai 
67e5779998SDaniel Mack 	return 0;
68e5779998SDaniel Mack }
69e5779998SDaniel Mack 
ignore_interface_quirk(struct snd_usb_audio * chip,struct usb_interface * iface,struct usb_driver * driver,const struct snd_usb_audio_quirk * quirk)70e5779998SDaniel Mack static int ignore_interface_quirk(struct snd_usb_audio *chip,
71e5779998SDaniel Mack 				  struct usb_interface *iface,
72e5779998SDaniel Mack 				  struct usb_driver *driver,
73e5779998SDaniel Mack 				  const struct snd_usb_audio_quirk *quirk)
74e5779998SDaniel Mack {
75e5779998SDaniel Mack 	return 0;
76e5779998SDaniel Mack }
77e5779998SDaniel Mack 
78e5779998SDaniel Mack 
create_any_midi_quirk(struct snd_usb_audio * chip,struct usb_interface * intf,struct usb_driver * driver,const struct snd_usb_audio_quirk * quirk)79e5779998SDaniel Mack static int create_any_midi_quirk(struct snd_usb_audio *chip,
80e5779998SDaniel Mack 				 struct usb_interface *intf,
81e5779998SDaniel Mack 				 struct usb_driver *driver,
82e5779998SDaniel Mack 				 const struct snd_usb_audio_quirk *quirk)
83e5779998SDaniel Mack {
84ff49d1dfSTakashi Iwai 	return snd_usb_midi_v2_create(chip, intf, quirk, 0);
85e5779998SDaniel Mack }
86e5779998SDaniel Mack 
87e5779998SDaniel Mack /*
88e5779998SDaniel Mack  * create a stream for an interface with proper descriptors
89e5779998SDaniel Mack  */
create_standard_audio_quirk(struct snd_usb_audio * chip,struct usb_interface * iface,struct usb_driver * driver,const struct snd_usb_audio_quirk * quirk)90e5779998SDaniel Mack static int create_standard_audio_quirk(struct snd_usb_audio *chip,
91e5779998SDaniel Mack 				       struct usb_interface *iface,
92e5779998SDaniel Mack 				       struct usb_driver *driver,
93e5779998SDaniel Mack 				       const struct snd_usb_audio_quirk *quirk)
94e5779998SDaniel Mack {
95e5779998SDaniel Mack 	struct usb_host_interface *alts;
96e5779998SDaniel Mack 	struct usb_interface_descriptor *altsd;
97e5779998SDaniel Mack 	int err;
98e5779998SDaniel Mack 
99e5779998SDaniel Mack 	alts = &iface->altsetting[0];
100e5779998SDaniel Mack 	altsd = get_iface_desc(alts);
101e8e8babfSDaniel Mack 	err = snd_usb_parse_audio_interface(chip, altsd->bInterfaceNumber);
102e5779998SDaniel Mack 	if (err < 0) {
1030ba41d91STakashi Iwai 		usb_audio_err(chip, "cannot setup if %d: error %d\n",
104e5779998SDaniel Mack 			   altsd->bInterfaceNumber, err);
105e5779998SDaniel Mack 		return err;
106e5779998SDaniel Mack 	}
107e5779998SDaniel Mack 	/* reset the current interface */
108e5779998SDaniel Mack 	usb_set_interface(chip->dev, altsd->bInterfaceNumber, 0);
109e5779998SDaniel Mack 	return 0;
110e5779998SDaniel Mack }
111e5779998SDaniel Mack 
112b2345a8aSTakashi Iwai /* create the audio stream and the corresponding endpoints from the fixed
113b2345a8aSTakashi Iwai  * audioformat object; this is used for quirks with the fixed EPs
114b2345a8aSTakashi Iwai  */
add_audio_stream_from_fixed_fmt(struct snd_usb_audio * chip,struct audioformat * fp)115b2345a8aSTakashi Iwai static int add_audio_stream_from_fixed_fmt(struct snd_usb_audio *chip,
116b2345a8aSTakashi Iwai 					   struct audioformat *fp)
117b2345a8aSTakashi Iwai {
118b2345a8aSTakashi Iwai 	int stream, err;
119b2345a8aSTakashi Iwai 
120b2345a8aSTakashi Iwai 	stream = (fp->endpoint & USB_DIR_IN) ?
121b2345a8aSTakashi Iwai 		SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK;
122b2345a8aSTakashi Iwai 
123b2345a8aSTakashi Iwai 	snd_usb_audioformat_set_sync_ep(chip, fp);
124b2345a8aSTakashi Iwai 
125b2345a8aSTakashi Iwai 	err = snd_usb_add_audio_stream(chip, stream, fp);
126b2345a8aSTakashi Iwai 	if (err < 0)
127b2345a8aSTakashi Iwai 		return err;
128b2345a8aSTakashi Iwai 
129b2345a8aSTakashi Iwai 	err = snd_usb_add_endpoint(chip, fp->endpoint,
130b2345a8aSTakashi Iwai 				   SND_USB_ENDPOINT_TYPE_DATA);
131b2345a8aSTakashi Iwai 	if (err < 0)
132b2345a8aSTakashi Iwai 		return err;
133b2345a8aSTakashi Iwai 
134b2345a8aSTakashi Iwai 	if (fp->sync_ep) {
135b2345a8aSTakashi Iwai 		err = snd_usb_add_endpoint(chip, fp->sync_ep,
136b2345a8aSTakashi Iwai 					   fp->implicit_fb ?
137b2345a8aSTakashi Iwai 					   SND_USB_ENDPOINT_TYPE_DATA :
138b2345a8aSTakashi Iwai 					   SND_USB_ENDPOINT_TYPE_SYNC);
139b2345a8aSTakashi Iwai 		if (err < 0)
140b2345a8aSTakashi Iwai 			return err;
141b2345a8aSTakashi Iwai 	}
142b2345a8aSTakashi Iwai 
143b2345a8aSTakashi Iwai 	return 0;
144b2345a8aSTakashi Iwai }
145b2345a8aSTakashi Iwai 
146e5779998SDaniel Mack /*
147e5779998SDaniel Mack  * create a stream for an endpoint/altsetting without proper descriptors
148e5779998SDaniel Mack  */
create_fixed_stream_quirk(struct snd_usb_audio * chip,struct usb_interface * iface,struct usb_driver * driver,const struct snd_usb_audio_quirk * quirk)149e5779998SDaniel Mack static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
150e5779998SDaniel Mack 				     struct usb_interface *iface,
151e5779998SDaniel Mack 				     struct usb_driver *driver,
152e5779998SDaniel Mack 				     const struct snd_usb_audio_quirk *quirk)
153e5779998SDaniel Mack {
154e5779998SDaniel Mack 	struct audioformat *fp;
155e5779998SDaniel Mack 	struct usb_host_interface *alts;
15642d4ab83SEldad Zack 	struct usb_interface_descriptor *altsd;
157e5779998SDaniel Mack 	unsigned *rate_table = NULL;
158b2345a8aSTakashi Iwai 	int err;
159e5779998SDaniel Mack 
160e5779998SDaniel Mack 	fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL);
1619ecb2406SMarkus Elfring 	if (!fp)
162e5779998SDaniel Mack 		return -ENOMEM;
1639ecb2406SMarkus Elfring 
164836b34a9SVladis Dronov 	INIT_LIST_HEAD(&fp->list);
1658866f405SXi Wang 	if (fp->nr_rates > MAX_NR_RATES) {
1668866f405SXi Wang 		kfree(fp);
1678866f405SXi Wang 		return -EINVAL;
168e5779998SDaniel Mack 	}
169e5779998SDaniel Mack 	if (fp->nr_rates > 0) {
17043df2a57SThomas Meyer 		rate_table = kmemdup(fp->rate_table,
17143df2a57SThomas Meyer 				     sizeof(int) * fp->nr_rates, GFP_KERNEL);
172e5779998SDaniel Mack 		if (!rate_table) {
173e5779998SDaniel Mack 			kfree(fp);
174e5779998SDaniel Mack 			return -ENOMEM;
175e5779998SDaniel Mack 		}
176e5779998SDaniel Mack 		fp->rate_table = rate_table;
177e5779998SDaniel Mack 	}
178e5779998SDaniel Mack 
179e5779998SDaniel Mack 	if (fp->iface != get_iface_desc(&iface->altsetting[0])->bInterfaceNumber ||
180e5779998SDaniel Mack 	    fp->altset_idx >= iface->num_altsetting) {
181902eb7fdSTakashi Iwai 		err = -EINVAL;
182902eb7fdSTakashi Iwai 		goto error;
183e5779998SDaniel Mack 	}
184e5779998SDaniel Mack 	alts = &iface->altsetting[fp->altset_idx];
18542d4ab83SEldad Zack 	altsd = get_iface_desc(alts);
186eae4d054STakashi Iwai 	if (altsd->bNumEndpoints <= fp->ep_idx) {
187902eb7fdSTakashi Iwai 		err = -EINVAL;
188902eb7fdSTakashi Iwai 		goto error;
1890f886ca1STakashi Iwai 	}
1900f886ca1STakashi Iwai 
19142d4ab83SEldad Zack 	fp->protocol = altsd->bInterfaceProtocol;
19242d4ab83SEldad Zack 
19359ea586fSMark Hills 	if (fp->datainterval == 0)
194e5779998SDaniel Mack 		fp->datainterval = snd_usb_parse_datainterval(chip, alts);
19559ea586fSMark Hills 	if (fp->maxpacksize == 0)
196eae4d054STakashi Iwai 		fp->maxpacksize = le16_to_cpu(get_endpoint(alts, fp->ep_idx)->wMaxPacketSize);
197b2345a8aSTakashi Iwai 	if (!fp->fmt_type)
198b2345a8aSTakashi Iwai 		fp->fmt_type = UAC_FORMAT_TYPE_I;
199b2345a8aSTakashi Iwai 
200b2345a8aSTakashi Iwai 	err = add_audio_stream_from_fixed_fmt(chip, fp);
201b2345a8aSTakashi Iwai 	if (err < 0)
202b2345a8aSTakashi Iwai 		goto error;
203b2345a8aSTakashi Iwai 
204e5779998SDaniel Mack 	usb_set_interface(chip->dev, fp->iface, 0);
20573037c8dSTakashi Iwai 	snd_usb_init_pitch(chip, fp);
206953a446bSTakashi Iwai 	snd_usb_init_sample_rate(chip, fp, fp->rate_max);
207e5779998SDaniel Mack 	return 0;
208902eb7fdSTakashi Iwai 
209902eb7fdSTakashi Iwai  error:
210836b34a9SVladis Dronov 	list_del(&fp->list); /* unlink for avoiding double-free */
211902eb7fdSTakashi Iwai 	kfree(fp);
212902eb7fdSTakashi Iwai 	kfree(rate_table);
213902eb7fdSTakashi Iwai 	return err;
214e5779998SDaniel Mack }
215e5779998SDaniel Mack 
create_auto_pcm_quirk(struct snd_usb_audio * chip,struct usb_interface * iface,struct usb_driver * driver)216aafe77ccSClemens Ladisch static int create_auto_pcm_quirk(struct snd_usb_audio *chip,
217aafe77ccSClemens Ladisch 				 struct usb_interface *iface,
218aafe77ccSClemens Ladisch 				 struct usb_driver *driver)
219aafe77ccSClemens Ladisch {
220aafe77ccSClemens Ladisch 	struct usb_host_interface *alts;
221aafe77ccSClemens Ladisch 	struct usb_interface_descriptor *altsd;
222aafe77ccSClemens Ladisch 	struct usb_endpoint_descriptor *epd;
223aafe77ccSClemens Ladisch 	struct uac1_as_header_descriptor *ashd;
224aafe77ccSClemens Ladisch 	struct uac_format_type_i_discrete_descriptor *fmtd;
225aafe77ccSClemens Ladisch 
226aafe77ccSClemens Ladisch 	/*
227aafe77ccSClemens Ladisch 	 * Most Roland/Yamaha audio streaming interfaces have more or less
228aafe77ccSClemens Ladisch 	 * standard descriptors, but older devices might lack descriptors, and
229aafe77ccSClemens Ladisch 	 * future ones might change, so ensure that we fail silently if the
230aafe77ccSClemens Ladisch 	 * interface doesn't look exactly right.
231aafe77ccSClemens Ladisch 	 */
232aafe77ccSClemens Ladisch 
233aafe77ccSClemens Ladisch 	/* must have a non-zero altsetting for streaming */
234aafe77ccSClemens Ladisch 	if (iface->num_altsetting < 2)
235aafe77ccSClemens Ladisch 		return -ENODEV;
236aafe77ccSClemens Ladisch 	alts = &iface->altsetting[1];
237aafe77ccSClemens Ladisch 	altsd = get_iface_desc(alts);
238aafe77ccSClemens Ladisch 
239aafe77ccSClemens Ladisch 	/* must have an isochronous endpoint for streaming */
240aafe77ccSClemens Ladisch 	if (altsd->bNumEndpoints < 1)
241aafe77ccSClemens Ladisch 		return -ENODEV;
242aafe77ccSClemens Ladisch 	epd = get_endpoint(alts, 0);
243aafe77ccSClemens Ladisch 	if (!usb_endpoint_xfer_isoc(epd))
244aafe77ccSClemens Ladisch 		return -ENODEV;
245aafe77ccSClemens Ladisch 
246aafe77ccSClemens Ladisch 	/* must have format descriptors */
247aafe77ccSClemens Ladisch 	ashd = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL,
248aafe77ccSClemens Ladisch 				       UAC_AS_GENERAL);
249aafe77ccSClemens Ladisch 	fmtd = snd_usb_find_csint_desc(alts->extra, alts->extralen, NULL,
250aafe77ccSClemens Ladisch 				       UAC_FORMAT_TYPE);
251aafe77ccSClemens Ladisch 	if (!ashd || ashd->bLength < 7 ||
252aafe77ccSClemens Ladisch 	    !fmtd || fmtd->bLength < 8)
253aafe77ccSClemens Ladisch 		return -ENODEV;
254aafe77ccSClemens Ladisch 
255aafe77ccSClemens Ladisch 	return create_standard_audio_quirk(chip, iface, driver, NULL);
256aafe77ccSClemens Ladisch }
257aafe77ccSClemens Ladisch 
create_yamaha_midi_quirk(struct snd_usb_audio * chip,struct usb_interface * iface,struct usb_driver * driver,struct usb_host_interface * alts)258aafe77ccSClemens Ladisch static int create_yamaha_midi_quirk(struct snd_usb_audio *chip,
259aafe77ccSClemens Ladisch 				    struct usb_interface *iface,
260aafe77ccSClemens Ladisch 				    struct usb_driver *driver,
261aafe77ccSClemens Ladisch 				    struct usb_host_interface *alts)
262aafe77ccSClemens Ladisch {
263aafe77ccSClemens Ladisch 	static const struct snd_usb_audio_quirk yamaha_midi_quirk = {
264aafe77ccSClemens Ladisch 		.type = QUIRK_MIDI_YAMAHA
265aafe77ccSClemens Ladisch 	};
266aafe77ccSClemens Ladisch 	struct usb_midi_in_jack_descriptor *injd;
267aafe77ccSClemens Ladisch 	struct usb_midi_out_jack_descriptor *outjd;
268aafe77ccSClemens Ladisch 
269aafe77ccSClemens Ladisch 	/* must have some valid jack descriptors */
270aafe77ccSClemens Ladisch 	injd = snd_usb_find_csint_desc(alts->extra, alts->extralen,
271aafe77ccSClemens Ladisch 				       NULL, USB_MS_MIDI_IN_JACK);
272aafe77ccSClemens Ladisch 	outjd = snd_usb_find_csint_desc(alts->extra, alts->extralen,
273aafe77ccSClemens Ladisch 					NULL, USB_MS_MIDI_OUT_JACK);
274aafe77ccSClemens Ladisch 	if (!injd && !outjd)
275aafe77ccSClemens Ladisch 		return -ENODEV;
276cc9dbfa9STakashi Iwai 	if ((injd && !snd_usb_validate_midi_desc(injd)) ||
277cc9dbfa9STakashi Iwai 	    (outjd && !snd_usb_validate_midi_desc(outjd)))
27857f87706STakashi Iwai 		return -ENODEV;
279aafe77ccSClemens Ladisch 	if (injd && (injd->bLength < 5 ||
280aafe77ccSClemens Ladisch 		     (injd->bJackType != USB_MS_EMBEDDED &&
281aafe77ccSClemens Ladisch 		      injd->bJackType != USB_MS_EXTERNAL)))
282aafe77ccSClemens Ladisch 		return -ENODEV;
283aafe77ccSClemens Ladisch 	if (outjd && (outjd->bLength < 6 ||
284aafe77ccSClemens Ladisch 		      (outjd->bJackType != USB_MS_EMBEDDED &&
285aafe77ccSClemens Ladisch 		       outjd->bJackType != USB_MS_EXTERNAL)))
286aafe77ccSClemens Ladisch 		return -ENODEV;
287aafe77ccSClemens Ladisch 	return create_any_midi_quirk(chip, iface, driver, &yamaha_midi_quirk);
288aafe77ccSClemens Ladisch }
289aafe77ccSClemens Ladisch 
create_roland_midi_quirk(struct snd_usb_audio * chip,struct usb_interface * iface,struct usb_driver * driver,struct usb_host_interface * alts)290aafe77ccSClemens Ladisch static int create_roland_midi_quirk(struct snd_usb_audio *chip,
291aafe77ccSClemens Ladisch 				    struct usb_interface *iface,
292aafe77ccSClemens Ladisch 				    struct usb_driver *driver,
293aafe77ccSClemens Ladisch 				    struct usb_host_interface *alts)
294aafe77ccSClemens Ladisch {
295aafe77ccSClemens Ladisch 	static const struct snd_usb_audio_quirk roland_midi_quirk = {
296aafe77ccSClemens Ladisch 		.type = QUIRK_MIDI_ROLAND
297aafe77ccSClemens Ladisch 	};
298aafe77ccSClemens Ladisch 	u8 *roland_desc = NULL;
299aafe77ccSClemens Ladisch 
300aafe77ccSClemens Ladisch 	/* might have a vendor-specific descriptor <06 24 F1 02 ...> */
301aafe77ccSClemens Ladisch 	for (;;) {
302aafe77ccSClemens Ladisch 		roland_desc = snd_usb_find_csint_desc(alts->extra,
303aafe77ccSClemens Ladisch 						      alts->extralen,
304aafe77ccSClemens Ladisch 						      roland_desc, 0xf1);
305aafe77ccSClemens Ladisch 		if (!roland_desc)
306aafe77ccSClemens Ladisch 			return -ENODEV;
307aafe77ccSClemens Ladisch 		if (roland_desc[0] < 6 || roland_desc[3] != 2)
308aafe77ccSClemens Ladisch 			continue;
309aafe77ccSClemens Ladisch 		return create_any_midi_quirk(chip, iface, driver,
310aafe77ccSClemens Ladisch 					     &roland_midi_quirk);
311aafe77ccSClemens Ladisch 	}
312aafe77ccSClemens Ladisch }
313aafe77ccSClemens Ladisch 
create_std_midi_quirk(struct snd_usb_audio * chip,struct usb_interface * iface,struct usb_driver * driver,struct usb_host_interface * alts)314aafe77ccSClemens Ladisch static int create_std_midi_quirk(struct snd_usb_audio *chip,
315aafe77ccSClemens Ladisch 				 struct usb_interface *iface,
316aafe77ccSClemens Ladisch 				 struct usb_driver *driver,
317aafe77ccSClemens Ladisch 				 struct usb_host_interface *alts)
318aafe77ccSClemens Ladisch {
319aafe77ccSClemens Ladisch 	struct usb_ms_header_descriptor *mshd;
320aafe77ccSClemens Ladisch 	struct usb_ms_endpoint_descriptor *msepd;
321aafe77ccSClemens Ladisch 
322aafe77ccSClemens Ladisch 	/* must have the MIDIStreaming interface header descriptor*/
323aafe77ccSClemens Ladisch 	mshd = (struct usb_ms_header_descriptor *)alts->extra;
324aafe77ccSClemens Ladisch 	if (alts->extralen < 7 ||
325aafe77ccSClemens Ladisch 	    mshd->bLength < 7 ||
326aafe77ccSClemens Ladisch 	    mshd->bDescriptorType != USB_DT_CS_INTERFACE ||
327aafe77ccSClemens Ladisch 	    mshd->bDescriptorSubtype != USB_MS_HEADER)
328aafe77ccSClemens Ladisch 		return -ENODEV;
329aafe77ccSClemens Ladisch 	/* must have the MIDIStreaming endpoint descriptor*/
330aafe77ccSClemens Ladisch 	msepd = (struct usb_ms_endpoint_descriptor *)alts->endpoint[0].extra;
331aafe77ccSClemens Ladisch 	if (alts->endpoint[0].extralen < 4 ||
332aafe77ccSClemens Ladisch 	    msepd->bLength < 4 ||
333aafe77ccSClemens Ladisch 	    msepd->bDescriptorType != USB_DT_CS_ENDPOINT ||
334aafe77ccSClemens Ladisch 	    msepd->bDescriptorSubtype != UAC_MS_GENERAL ||
335aafe77ccSClemens Ladisch 	    msepd->bNumEmbMIDIJack < 1 ||
336aafe77ccSClemens Ladisch 	    msepd->bNumEmbMIDIJack > 16)
337aafe77ccSClemens Ladisch 		return -ENODEV;
338aafe77ccSClemens Ladisch 
339aafe77ccSClemens Ladisch 	return create_any_midi_quirk(chip, iface, driver, NULL);
340aafe77ccSClemens Ladisch }
341aafe77ccSClemens Ladisch 
create_auto_midi_quirk(struct snd_usb_audio * chip,struct usb_interface * iface,struct usb_driver * driver)342aafe77ccSClemens Ladisch static int create_auto_midi_quirk(struct snd_usb_audio *chip,
343aafe77ccSClemens Ladisch 				  struct usb_interface *iface,
344aafe77ccSClemens Ladisch 				  struct usb_driver *driver)
345aafe77ccSClemens Ladisch {
346aafe77ccSClemens Ladisch 	struct usb_host_interface *alts;
347aafe77ccSClemens Ladisch 	struct usb_interface_descriptor *altsd;
348aafe77ccSClemens Ladisch 	struct usb_endpoint_descriptor *epd;
349aafe77ccSClemens Ladisch 	int err;
350aafe77ccSClemens Ladisch 
351aafe77ccSClemens Ladisch 	alts = &iface->altsetting[0];
352aafe77ccSClemens Ladisch 	altsd = get_iface_desc(alts);
353aafe77ccSClemens Ladisch 
354aafe77ccSClemens Ladisch 	/* must have at least one bulk/interrupt endpoint for streaming */
355aafe77ccSClemens Ladisch 	if (altsd->bNumEndpoints < 1)
356aafe77ccSClemens Ladisch 		return -ENODEV;
357aafe77ccSClemens Ladisch 	epd = get_endpoint(alts, 0);
358aa773bfeSClemens Ladisch 	if (!usb_endpoint_xfer_bulk(epd) &&
359aafe77ccSClemens Ladisch 	    !usb_endpoint_xfer_int(epd))
360aafe77ccSClemens Ladisch 		return -ENODEV;
361aafe77ccSClemens Ladisch 
362aafe77ccSClemens Ladisch 	switch (USB_ID_VENDOR(chip->usb_id)) {
363aafe77ccSClemens Ladisch 	case 0x0499: /* Yamaha */
364aafe77ccSClemens Ladisch 		err = create_yamaha_midi_quirk(chip, iface, driver, alts);
365aa773bfeSClemens Ladisch 		if (err != -ENODEV)
366aafe77ccSClemens Ladisch 			return err;
367aafe77ccSClemens Ladisch 		break;
368aafe77ccSClemens Ladisch 	case 0x0582: /* Roland */
369aafe77ccSClemens Ladisch 		err = create_roland_midi_quirk(chip, iface, driver, alts);
370aa773bfeSClemens Ladisch 		if (err != -ENODEV)
371aafe77ccSClemens Ladisch 			return err;
372aafe77ccSClemens Ladisch 		break;
373aafe77ccSClemens Ladisch 	}
374aafe77ccSClemens Ladisch 
375aafe77ccSClemens Ladisch 	return create_std_midi_quirk(chip, iface, driver, alts);
376aafe77ccSClemens Ladisch }
377aafe77ccSClemens Ladisch 
create_autodetect_quirk(struct snd_usb_audio * chip,struct usb_interface * iface,struct usb_driver * driver,const struct snd_usb_audio_quirk * quirk)378aafe77ccSClemens Ladisch static int create_autodetect_quirk(struct snd_usb_audio *chip,
379aafe77ccSClemens Ladisch 				   struct usb_interface *iface,
380ea83ec50STakashi Iwai 				   struct usb_driver *driver,
381ea83ec50STakashi Iwai 				   const struct snd_usb_audio_quirk *quirk)
382aafe77ccSClemens Ladisch {
383aafe77ccSClemens Ladisch 	int err;
384aafe77ccSClemens Ladisch 
385aafe77ccSClemens Ladisch 	err = create_auto_pcm_quirk(chip, iface, driver);
386aafe77ccSClemens Ladisch 	if (err == -ENODEV)
387aafe77ccSClemens Ladisch 		err = create_auto_midi_quirk(chip, iface, driver);
388aafe77ccSClemens Ladisch 	return err;
389aafe77ccSClemens Ladisch }
390aafe77ccSClemens Ladisch 
391e5779998SDaniel Mack /*
392e5779998SDaniel Mack  * Create a stream for an Edirol UA-700/UA-25/UA-4FX interface.
393e5779998SDaniel Mack  * The only way to detect the sample rate is by looking at wMaxPacketSize.
394e5779998SDaniel Mack  */
create_uaxx_quirk(struct snd_usb_audio * chip,struct usb_interface * iface,struct usb_driver * driver,const struct snd_usb_audio_quirk * quirk)395e5779998SDaniel Mack static int create_uaxx_quirk(struct snd_usb_audio *chip,
396e5779998SDaniel Mack 			     struct usb_interface *iface,
397e5779998SDaniel Mack 			     struct usb_driver *driver,
398e5779998SDaniel Mack 			     const struct snd_usb_audio_quirk *quirk)
399e5779998SDaniel Mack {
400e5779998SDaniel Mack 	static const struct audioformat ua_format = {
401015eb0b0SClemens Ladisch 		.formats = SNDRV_PCM_FMTBIT_S24_3LE,
402e5779998SDaniel Mack 		.channels = 2,
403e5779998SDaniel Mack 		.fmt_type = UAC_FORMAT_TYPE_I,
404e5779998SDaniel Mack 		.altsetting = 1,
405e5779998SDaniel Mack 		.altset_idx = 1,
406e5779998SDaniel Mack 		.rates = SNDRV_PCM_RATE_CONTINUOUS,
407e5779998SDaniel Mack 	};
408e5779998SDaniel Mack 	struct usb_host_interface *alts;
409e5779998SDaniel Mack 	struct usb_interface_descriptor *altsd;
410e5779998SDaniel Mack 	struct audioformat *fp;
411b2345a8aSTakashi Iwai 	int err;
412e5779998SDaniel Mack 
413e5779998SDaniel Mack 	/* both PCM and MIDI interfaces have 2 or more altsettings */
414e5779998SDaniel Mack 	if (iface->num_altsetting < 2)
415e5779998SDaniel Mack 		return -ENXIO;
416e5779998SDaniel Mack 	alts = &iface->altsetting[1];
417e5779998SDaniel Mack 	altsd = get_iface_desc(alts);
418e5779998SDaniel Mack 
419e5779998SDaniel Mack 	if (altsd->bNumEndpoints == 2) {
420e5779998SDaniel Mack 		static const struct snd_usb_midi_endpoint_info ua700_ep = {
421e5779998SDaniel Mack 			.out_cables = 0x0003,
422e5779998SDaniel Mack 			.in_cables  = 0x0003
423e5779998SDaniel Mack 		};
424e5779998SDaniel Mack 		static const struct snd_usb_audio_quirk ua700_quirk = {
425e5779998SDaniel Mack 			.type = QUIRK_MIDI_FIXED_ENDPOINT,
426e5779998SDaniel Mack 			.data = &ua700_ep
427e5779998SDaniel Mack 		};
428e5779998SDaniel Mack 		static const struct snd_usb_midi_endpoint_info uaxx_ep = {
429e5779998SDaniel Mack 			.out_cables = 0x0001,
430e5779998SDaniel Mack 			.in_cables  = 0x0001
431e5779998SDaniel Mack 		};
432e5779998SDaniel Mack 		static const struct snd_usb_audio_quirk uaxx_quirk = {
433e5779998SDaniel Mack 			.type = QUIRK_MIDI_FIXED_ENDPOINT,
434e5779998SDaniel Mack 			.data = &uaxx_ep
435e5779998SDaniel Mack 		};
436e5779998SDaniel Mack 		const struct snd_usb_audio_quirk *quirk =
437e5779998SDaniel Mack 			chip->usb_id == USB_ID(0x0582, 0x002b)
438e5779998SDaniel Mack 			? &ua700_quirk : &uaxx_quirk;
43979289e24STakashi Iwai 		return __snd_usbmidi_create(chip->card, iface,
44079289e24STakashi Iwai 					    &chip->midi_list, quirk,
441bb1bf4faSTakashi Iwai 					    chip->usb_id,
442bb1bf4faSTakashi Iwai 					    &chip->num_rawmidis);
443e5779998SDaniel Mack 	}
444e5779998SDaniel Mack 
445e5779998SDaniel Mack 	if (altsd->bNumEndpoints != 1)
446e5779998SDaniel Mack 		return -ENXIO;
447e5779998SDaniel Mack 
44843df2a57SThomas Meyer 	fp = kmemdup(&ua_format, sizeof(*fp), GFP_KERNEL);
449e5779998SDaniel Mack 	if (!fp)
450e5779998SDaniel Mack 		return -ENOMEM;
451e5779998SDaniel Mack 
452e5779998SDaniel Mack 	fp->iface = altsd->bInterfaceNumber;
453e5779998SDaniel Mack 	fp->endpoint = get_endpoint(alts, 0)->bEndpointAddress;
454e5779998SDaniel Mack 	fp->ep_attr = get_endpoint(alts, 0)->bmAttributes;
455e5779998SDaniel Mack 	fp->datainterval = 0;
456e5779998SDaniel Mack 	fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize);
457836b34a9SVladis Dronov 	INIT_LIST_HEAD(&fp->list);
458e5779998SDaniel Mack 
459e5779998SDaniel Mack 	switch (fp->maxpacksize) {
460e5779998SDaniel Mack 	case 0x120:
461e5779998SDaniel Mack 		fp->rate_max = fp->rate_min = 44100;
462e5779998SDaniel Mack 		break;
463e5779998SDaniel Mack 	case 0x138:
464e5779998SDaniel Mack 	case 0x140:
465e5779998SDaniel Mack 		fp->rate_max = fp->rate_min = 48000;
466e5779998SDaniel Mack 		break;
467e5779998SDaniel Mack 	case 0x258:
468e5779998SDaniel Mack 	case 0x260:
469e5779998SDaniel Mack 		fp->rate_max = fp->rate_min = 96000;
470e5779998SDaniel Mack 		break;
471e5779998SDaniel Mack 	default:
4720ba41d91STakashi Iwai 		usb_audio_err(chip, "unknown sample rate\n");
473e5779998SDaniel Mack 		kfree(fp);
474e5779998SDaniel Mack 		return -ENXIO;
475e5779998SDaniel Mack 	}
476e5779998SDaniel Mack 
477b2345a8aSTakashi Iwai 	err = add_audio_stream_from_fixed_fmt(chip, fp);
478e5779998SDaniel Mack 	if (err < 0) {
479836b34a9SVladis Dronov 		list_del(&fp->list); /* unlink for avoiding double-free */
480e5779998SDaniel Mack 		kfree(fp);
481e5779998SDaniel Mack 		return err;
482e5779998SDaniel Mack 	}
483e5779998SDaniel Mack 	usb_set_interface(chip->dev, fp->iface, 0);
484e5779998SDaniel Mack 	return 0;
485e5779998SDaniel Mack }
486e5779998SDaniel Mack 
487e5779998SDaniel Mack /*
488014950b0SDaniel Mack  * Create a standard mixer for the specified interface.
489014950b0SDaniel Mack  */
create_standard_mixer_quirk(struct snd_usb_audio * chip,struct usb_interface * iface,struct usb_driver * driver,const struct snd_usb_audio_quirk * quirk)490014950b0SDaniel Mack static int create_standard_mixer_quirk(struct snd_usb_audio *chip,
491014950b0SDaniel Mack 				       struct usb_interface *iface,
492014950b0SDaniel Mack 				       struct usb_driver *driver,
493014950b0SDaniel Mack 				       const struct snd_usb_audio_quirk *quirk)
494014950b0SDaniel Mack {
495014950b0SDaniel Mack 	if (quirk->ifnum < 0)
496014950b0SDaniel Mack 		return 0;
497014950b0SDaniel Mack 
4983c69dc91STakashi Iwai 	return snd_usb_create_mixer(chip, quirk->ifnum);
499014950b0SDaniel Mack }
500014950b0SDaniel Mack 
501014950b0SDaniel Mack /*
502e5779998SDaniel Mack  * audio-interface quirks
503e5779998SDaniel Mack  *
504e5779998SDaniel Mack  * returns zero if no standard audio/MIDI parsing is needed.
50525985edcSLucas De Marchi  * returns a positive value if standard audio/midi interfaces are parsed
506e5779998SDaniel Mack  * after this.
507e5779998SDaniel Mack  * returns a negative value at error.
508e5779998SDaniel Mack  */
snd_usb_create_quirk(struct snd_usb_audio * chip,struct usb_interface * iface,struct usb_driver * driver,const struct snd_usb_audio_quirk * quirk)509e5779998SDaniel Mack int snd_usb_create_quirk(struct snd_usb_audio *chip,
510e5779998SDaniel Mack 			 struct usb_interface *iface,
511e5779998SDaniel Mack 			 struct usb_driver *driver,
512e5779998SDaniel Mack 			 const struct snd_usb_audio_quirk *quirk)
513e5779998SDaniel Mack {
514e5779998SDaniel Mack 	typedef int (*quirk_func_t)(struct snd_usb_audio *,
515e5779998SDaniel Mack 				    struct usb_interface *,
516e5779998SDaniel Mack 				    struct usb_driver *,
517e5779998SDaniel Mack 				    const struct snd_usb_audio_quirk *);
518e5779998SDaniel Mack 	static const quirk_func_t quirk_funcs[] = {
519e5779998SDaniel Mack 		[QUIRK_IGNORE_INTERFACE] = ignore_interface_quirk,
520e5779998SDaniel Mack 		[QUIRK_COMPOSITE] = create_composite_quirk,
521ea83ec50STakashi Iwai 		[QUIRK_AUTODETECT] = create_autodetect_quirk,
522e5779998SDaniel Mack 		[QUIRK_MIDI_STANDARD_INTERFACE] = create_any_midi_quirk,
523e5779998SDaniel Mack 		[QUIRK_MIDI_FIXED_ENDPOINT] = create_any_midi_quirk,
524e5779998SDaniel Mack 		[QUIRK_MIDI_YAMAHA] = create_any_midi_quirk,
525aafe77ccSClemens Ladisch 		[QUIRK_MIDI_ROLAND] = create_any_midi_quirk,
526e5779998SDaniel Mack 		[QUIRK_MIDI_MIDIMAN] = create_any_midi_quirk,
527e5779998SDaniel Mack 		[QUIRK_MIDI_NOVATION] = create_any_midi_quirk,
528c7f57216SClemens Ladisch 		[QUIRK_MIDI_RAW_BYTES] = create_any_midi_quirk,
529e5779998SDaniel Mack 		[QUIRK_MIDI_EMAGIC] = create_any_midi_quirk,
530e5779998SDaniel Mack 		[QUIRK_MIDI_CME] = create_any_midi_quirk,
5314434ade8SKrzysztof Foltman 		[QUIRK_MIDI_AKAI] = create_any_midi_quirk,
5321ef0e0a0SKristian Amlie 		[QUIRK_MIDI_FTDI] = create_any_midi_quirk,
5331ca8b201SClemens Ladisch 		[QUIRK_MIDI_CH345] = create_any_midi_quirk,
534e5779998SDaniel Mack 		[QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
535e5779998SDaniel Mack 		[QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
536e5779998SDaniel Mack 		[QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
537014950b0SDaniel Mack 		[QUIRK_AUDIO_STANDARD_MIXER] = create_standard_mixer_quirk,
538e5779998SDaniel Mack 	};
539e5779998SDaniel Mack 
540e5779998SDaniel Mack 	if (quirk->type < QUIRK_TYPE_COUNT) {
541e5779998SDaniel Mack 		return quirk_funcs[quirk->type](chip, iface, driver, quirk);
542e5779998SDaniel Mack 	} else {
5430ba41d91STakashi Iwai 		usb_audio_err(chip, "invalid quirk type %d\n", quirk->type);
544e5779998SDaniel Mack 		return -ENXIO;
545e5779998SDaniel Mack 	}
546e5779998SDaniel Mack }
547e5779998SDaniel Mack 
548e5779998SDaniel Mack /*
549e5779998SDaniel Mack  * boot quirks
550e5779998SDaniel Mack  */
551e5779998SDaniel Mack 
552e5779998SDaniel Mack #define EXTIGY_FIRMWARE_SIZE_OLD 794
553e5779998SDaniel Mack #define EXTIGY_FIRMWARE_SIZE_NEW 483
554e5779998SDaniel Mack 
snd_usb_extigy_boot_quirk(struct usb_device * dev,struct usb_interface * intf)555e5779998SDaniel Mack static int snd_usb_extigy_boot_quirk(struct usb_device *dev, struct usb_interface *intf)
556e5779998SDaniel Mack {
557e5779998SDaniel Mack 	struct usb_host_config *config = dev->actconfig;
55844a7b041SDan Carpenter 	struct usb_device_descriptor *new_device_descriptor __free(kfree) = NULL;
559e5779998SDaniel Mack 	int err;
560e5779998SDaniel Mack 
561e5779998SDaniel Mack 	if (le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_OLD ||
562e5779998SDaniel Mack 	    le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_NEW) {
5630ba41d91STakashi Iwai 		dev_dbg(&dev->dev, "sending Extigy boot sequence...\n");
564e5779998SDaniel Mack 		/* Send message to force it to reconnect with full interface. */
565e5779998SDaniel Mack 		err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev,0),
56617d900c4SClemens Ladisch 				      0x10, 0x43, 0x0001, 0x000a, NULL, 0);
5670ba41d91STakashi Iwai 		if (err < 0)
5680ba41d91STakashi Iwai 			dev_dbg(&dev->dev, "error sending boot message: %d\n", err);
56944a7b041SDan Carpenter 
57044a7b041SDan Carpenter 		new_device_descriptor = kmalloc(sizeof(*new_device_descriptor), GFP_KERNEL);
57144a7b041SDan Carpenter 		if (!new_device_descriptor)
57244a7b041SDan Carpenter 			return -ENOMEM;
573e5779998SDaniel Mack 		err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
57444a7b041SDan Carpenter 				new_device_descriptor, sizeof(*new_device_descriptor));
5750ba41d91STakashi Iwai 		if (err < 0)
5760ba41d91STakashi Iwai 			dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err);
57744a7b041SDan Carpenter 		if (new_device_descriptor->bNumConfigurations > dev->descriptor.bNumConfigurations)
578b8f8b81dSBenoît Sevens 			dev_dbg(&dev->dev, "error too large bNumConfigurations: %d\n",
57944a7b041SDan Carpenter 				new_device_descriptor->bNumConfigurations);
580b8f8b81dSBenoît Sevens 		else
58144a7b041SDan Carpenter 			memcpy(&dev->descriptor, new_device_descriptor, sizeof(dev->descriptor));
582e5779998SDaniel Mack 		err = usb_reset_configuration(dev);
5830ba41d91STakashi Iwai 		if (err < 0)
5840ba41d91STakashi Iwai 			dev_dbg(&dev->dev, "error usb_reset_configuration: %d\n", err);
5850ba41d91STakashi Iwai 		dev_dbg(&dev->dev, "extigy_boot: new boot length = %d\n",
586e5779998SDaniel Mack 			    le16_to_cpu(get_cfg_desc(config)->wTotalLength));
587e5779998SDaniel Mack 		return -ENODEV; /* quit this anyway */
588e5779998SDaniel Mack 	}
589e5779998SDaniel Mack 	return 0;
590e5779998SDaniel Mack }
591e5779998SDaniel Mack 
snd_usb_audigy2nx_boot_quirk(struct usb_device * dev)592e5779998SDaniel Mack static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev)
593e5779998SDaniel Mack {
594e5779998SDaniel Mack 	u8 buf = 1;
595e5779998SDaniel Mack 
596e5779998SDaniel Mack 	snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a,
597e5779998SDaniel Mack 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
59817d900c4SClemens Ladisch 			0, 0, &buf, 1);
599e5779998SDaniel Mack 	if (buf == 0) {
600e5779998SDaniel Mack 		snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0x29,
601e5779998SDaniel Mack 				USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
60217d900c4SClemens Ladisch 				1, 2000, NULL, 0);
603e5779998SDaniel Mack 		return -ENODEV;
604e5779998SDaniel Mack 	}
605e5779998SDaniel Mack 	return 0;
606e5779998SDaniel Mack }
607e5779998SDaniel Mack 
snd_usb_fasttrackpro_boot_quirk(struct usb_device * dev)6080f5733b0SGuillaume Pellerin static int snd_usb_fasttrackpro_boot_quirk(struct usb_device *dev)
6090f5733b0SGuillaume Pellerin {
6100f5733b0SGuillaume Pellerin 	int err;
6110f5733b0SGuillaume Pellerin 
6120f5733b0SGuillaume Pellerin 	if (dev->actconfig->desc.bConfigurationValue == 1) {
6130ba41d91STakashi Iwai 		dev_info(&dev->dev,
6140f5733b0SGuillaume Pellerin 			   "Fast Track Pro switching to config #2\n");
6150f5733b0SGuillaume Pellerin 		/* This function has to be available by the usb core module.
6160f5733b0SGuillaume Pellerin 		 * if it is not avialable the boot quirk has to be left out
6170f5733b0SGuillaume Pellerin 		 * and the configuration has to be set by udev or hotplug
6180f5733b0SGuillaume Pellerin 		 * rules
6190f5733b0SGuillaume Pellerin 		 */
6200f5733b0SGuillaume Pellerin 		err = usb_driver_set_configuration(dev, 2);
621b98ae272SDavid Henningsson 		if (err < 0)
6220ba41d91STakashi Iwai 			dev_dbg(&dev->dev,
6230ba41d91STakashi Iwai 				"error usb_driver_set_configuration: %d\n",
6240f5733b0SGuillaume Pellerin 				err);
625b98ae272SDavid Henningsson 		/* Always return an error, so that we stop creating a device
626b98ae272SDavid Henningsson 		   that will just be destroyed and recreated with a new
627b98ae272SDavid Henningsson 		   configuration */
6280f5733b0SGuillaume Pellerin 		return -ENODEV;
6290f5733b0SGuillaume Pellerin 	} else
6300ba41d91STakashi Iwai 		dev_info(&dev->dev, "Fast Track Pro config OK\n");
6310f5733b0SGuillaume Pellerin 
6320f5733b0SGuillaume Pellerin 	return 0;
6330f5733b0SGuillaume Pellerin }
6340f5733b0SGuillaume Pellerin 
635e5779998SDaniel Mack /*
636e5779998SDaniel Mack  * C-Media CM106/CM106+ have four 16-bit internal registers that are nicely
637e5779998SDaniel Mack  * documented in the device's data sheet.
638e5779998SDaniel Mack  */
snd_usb_cm106_write_int_reg(struct usb_device * dev,int reg,u16 value)639e5779998SDaniel Mack static int snd_usb_cm106_write_int_reg(struct usb_device *dev, int reg, u16 value)
640e5779998SDaniel Mack {
641e5779998SDaniel Mack 	u8 buf[4];
642e5779998SDaniel Mack 	buf[0] = 0x20;
643e5779998SDaniel Mack 	buf[1] = value & 0xff;
644e5779998SDaniel Mack 	buf[2] = (value >> 8) & 0xff;
645e5779998SDaniel Mack 	buf[3] = reg;
646e5779998SDaniel Mack 	return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION,
647e5779998SDaniel Mack 			       USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
64817d900c4SClemens Ladisch 			       0, 0, &buf, 4);
649e5779998SDaniel Mack }
650e5779998SDaniel Mack 
snd_usb_cm106_boot_quirk(struct usb_device * dev)651e5779998SDaniel Mack static int snd_usb_cm106_boot_quirk(struct usb_device *dev)
652e5779998SDaniel Mack {
653e5779998SDaniel Mack 	/*
654e5779998SDaniel Mack 	 * Enable line-out driver mode, set headphone source to front
655e5779998SDaniel Mack 	 * channels, enable stereo mic.
656e5779998SDaniel Mack 	 */
657e5779998SDaniel Mack 	return snd_usb_cm106_write_int_reg(dev, 2, 0x8004);
658e5779998SDaniel Mack }
659e5779998SDaniel Mack 
660e5779998SDaniel Mack /*
661ad43d528SLinus Walleij  * CM6206 registers from the CM6206 datasheet rev 2.1
662e5779998SDaniel Mack  */
663ad43d528SLinus Walleij #define CM6206_REG0_DMA_MASTER BIT(15)
664ad43d528SLinus Walleij #define CM6206_REG0_SPDIFO_RATE_48K (2 << 12)
665ad43d528SLinus Walleij #define CM6206_REG0_SPDIFO_RATE_96K (7 << 12)
666ad43d528SLinus Walleij /* Bit 4 thru 11 is the S/PDIF category code */
667ad43d528SLinus Walleij #define CM6206_REG0_SPDIFO_CAT_CODE_GENERAL (0 << 4)
668ad43d528SLinus Walleij #define CM6206_REG0_SPDIFO_EMPHASIS_CD BIT(3)
669ad43d528SLinus Walleij #define CM6206_REG0_SPDIFO_COPYRIGHT_NA BIT(2)
670ad43d528SLinus Walleij #define CM6206_REG0_SPDIFO_NON_AUDIO BIT(1)
671ad43d528SLinus Walleij #define CM6206_REG0_SPDIFO_PRO_FORMAT BIT(0)
672ad43d528SLinus Walleij 
673ad43d528SLinus Walleij #define CM6206_REG1_TEST_SEL_CLK BIT(14)
674ad43d528SLinus Walleij #define CM6206_REG1_PLLBIN_EN BIT(13)
675ad43d528SLinus Walleij #define CM6206_REG1_SOFT_MUTE_EN BIT(12)
676ad43d528SLinus Walleij #define CM6206_REG1_GPIO4_OUT BIT(11)
677ad43d528SLinus Walleij #define CM6206_REG1_GPIO4_OE BIT(10)
678ad43d528SLinus Walleij #define CM6206_REG1_GPIO3_OUT BIT(9)
679ad43d528SLinus Walleij #define CM6206_REG1_GPIO3_OE BIT(8)
680ad43d528SLinus Walleij #define CM6206_REG1_GPIO2_OUT BIT(7)
681ad43d528SLinus Walleij #define CM6206_REG1_GPIO2_OE BIT(6)
682ad43d528SLinus Walleij #define CM6206_REG1_GPIO1_OUT BIT(5)
683ad43d528SLinus Walleij #define CM6206_REG1_GPIO1_OE BIT(4)
684ad43d528SLinus Walleij #define CM6206_REG1_SPDIFO_INVALID BIT(3)
685ad43d528SLinus Walleij #define CM6206_REG1_SPDIF_LOOP_EN BIT(2)
686ad43d528SLinus Walleij #define CM6206_REG1_SPDIFO_DIS BIT(1)
687ad43d528SLinus Walleij #define CM6206_REG1_SPDIFI_MIX BIT(0)
688ad43d528SLinus Walleij 
689ad43d528SLinus Walleij #define CM6206_REG2_DRIVER_ON BIT(15)
690ad43d528SLinus Walleij #define CM6206_REG2_HEADP_SEL_SIDE_CHANNELS (0 << 13)
691ad43d528SLinus Walleij #define CM6206_REG2_HEADP_SEL_SURROUND_CHANNELS (1 << 13)
692ad43d528SLinus Walleij #define CM6206_REG2_HEADP_SEL_CENTER_SUBW (2 << 13)
693ad43d528SLinus Walleij #define CM6206_REG2_HEADP_SEL_FRONT_CHANNELS (3 << 13)
694ad43d528SLinus Walleij #define CM6206_REG2_MUTE_HEADPHONE_RIGHT BIT(12)
695ad43d528SLinus Walleij #define CM6206_REG2_MUTE_HEADPHONE_LEFT BIT(11)
696ad43d528SLinus Walleij #define CM6206_REG2_MUTE_REAR_SURROUND_RIGHT BIT(10)
697ad43d528SLinus Walleij #define CM6206_REG2_MUTE_REAR_SURROUND_LEFT BIT(9)
698ad43d528SLinus Walleij #define CM6206_REG2_MUTE_SIDE_SURROUND_RIGHT BIT(8)
699ad43d528SLinus Walleij #define CM6206_REG2_MUTE_SIDE_SURROUND_LEFT BIT(7)
700ad43d528SLinus Walleij #define CM6206_REG2_MUTE_SUBWOOFER BIT(6)
701ad43d528SLinus Walleij #define CM6206_REG2_MUTE_CENTER BIT(5)
702ad43d528SLinus Walleij #define CM6206_REG2_MUTE_RIGHT_FRONT BIT(3)
703ad43d528SLinus Walleij #define CM6206_REG2_MUTE_LEFT_FRONT BIT(3)
704ad43d528SLinus Walleij #define CM6206_REG2_EN_BTL BIT(2)
705ad43d528SLinus Walleij #define CM6206_REG2_MCUCLKSEL_1_5_MHZ (0)
706ad43d528SLinus Walleij #define CM6206_REG2_MCUCLKSEL_3_MHZ (1)
707ad43d528SLinus Walleij #define CM6206_REG2_MCUCLKSEL_6_MHZ (2)
708ad43d528SLinus Walleij #define CM6206_REG2_MCUCLKSEL_12_MHZ (3)
709ad43d528SLinus Walleij 
710ad43d528SLinus Walleij /* Bit 11..13 sets the sensitivity to FLY tuner volume control VP/VD signal */
711ad43d528SLinus Walleij #define CM6206_REG3_FLYSPEED_DEFAULT (2 << 11)
712ad43d528SLinus Walleij #define CM6206_REG3_VRAP25EN BIT(10)
713ad43d528SLinus Walleij #define CM6206_REG3_MSEL1 BIT(9)
714ad43d528SLinus Walleij #define CM6206_REG3_SPDIFI_RATE_44_1K BIT(0 << 7)
715ad43d528SLinus Walleij #define CM6206_REG3_SPDIFI_RATE_48K BIT(2 << 7)
716ad43d528SLinus Walleij #define CM6206_REG3_SPDIFI_RATE_32K BIT(3 << 7)
717ad43d528SLinus Walleij #define CM6206_REG3_PINSEL BIT(6)
718ad43d528SLinus Walleij #define CM6206_REG3_FOE BIT(5)
719ad43d528SLinus Walleij #define CM6206_REG3_ROE BIT(4)
720ad43d528SLinus Walleij #define CM6206_REG3_CBOE BIT(3)
721ad43d528SLinus Walleij #define CM6206_REG3_LOSE BIT(2)
722ad43d528SLinus Walleij #define CM6206_REG3_HPOE BIT(1)
723ad43d528SLinus Walleij #define CM6206_REG3_SPDIFI_CANREC BIT(0)
724ad43d528SLinus Walleij 
725ad43d528SLinus Walleij #define CM6206_REG5_DA_RSTN BIT(13)
726ad43d528SLinus Walleij #define CM6206_REG5_AD_RSTN BIT(12)
727ad43d528SLinus Walleij #define CM6206_REG5_SPDIFO_AD2SPDO BIT(12)
728ad43d528SLinus Walleij #define CM6206_REG5_SPDIFO_SEL_FRONT (0 << 9)
729ad43d528SLinus Walleij #define CM6206_REG5_SPDIFO_SEL_SIDE_SUR (1 << 9)
730ad43d528SLinus Walleij #define CM6206_REG5_SPDIFO_SEL_CEN_LFE (2 << 9)
731ad43d528SLinus Walleij #define CM6206_REG5_SPDIFO_SEL_REAR_SUR (3 << 9)
732ad43d528SLinus Walleij #define CM6206_REG5_CODECM BIT(8)
733ad43d528SLinus Walleij #define CM6206_REG5_EN_HPF BIT(7)
734ad43d528SLinus Walleij #define CM6206_REG5_T_SEL_DSDA4 BIT(6)
735ad43d528SLinus Walleij #define CM6206_REG5_T_SEL_DSDA3 BIT(5)
736ad43d528SLinus Walleij #define CM6206_REG5_T_SEL_DSDA2 BIT(4)
737ad43d528SLinus Walleij #define CM6206_REG5_T_SEL_DSDA1 BIT(3)
738ad43d528SLinus Walleij #define CM6206_REG5_T_SEL_DSDAD_NORMAL 0
739ad43d528SLinus Walleij #define CM6206_REG5_T_SEL_DSDAD_FRONT 4
740ad43d528SLinus Walleij #define CM6206_REG5_T_SEL_DSDAD_S_SURROUND 5
741ad43d528SLinus Walleij #define CM6206_REG5_T_SEL_DSDAD_CEN_LFE 6
742ad43d528SLinus Walleij #define CM6206_REG5_T_SEL_DSDAD_R_SURROUND 7
743ad43d528SLinus Walleij 
snd_usb_cm6206_boot_quirk(struct usb_device * dev)744e5779998SDaniel Mack static int snd_usb_cm6206_boot_quirk(struct usb_device *dev)
745e5779998SDaniel Mack {
746dac8f847SDaniel Mack 	int err  = 0, reg;
747ad43d528SLinus Walleij 	int val[] = {
748ad43d528SLinus Walleij 		/*
749ad43d528SLinus Walleij 		 * Values here are chosen based on sniffing USB traffic
750ad43d528SLinus Walleij 		 * under Windows.
751ad43d528SLinus Walleij 		 *
752ad43d528SLinus Walleij 		 * REG0: DAC is master, sample rate 48kHz, no copyright
753ad43d528SLinus Walleij 		 */
754ad43d528SLinus Walleij 		CM6206_REG0_SPDIFO_RATE_48K |
755ad43d528SLinus Walleij 		CM6206_REG0_SPDIFO_COPYRIGHT_NA,
756ad43d528SLinus Walleij 		/*
757ad43d528SLinus Walleij 		 * REG1: PLL binary search enable, soft mute enable.
758ad43d528SLinus Walleij 		 */
759ad43d528SLinus Walleij 		CM6206_REG1_PLLBIN_EN |
760f5c9571eSAmadeusz Sławiński 		CM6206_REG1_SOFT_MUTE_EN,
761ad43d528SLinus Walleij 		/*
762ad43d528SLinus Walleij 		 * REG2: enable output drivers,
763ad43d528SLinus Walleij 		 * select front channels to the headphone output,
764ad43d528SLinus Walleij 		 * then mute the headphone channels, run the MCU
765ad43d528SLinus Walleij 		 * at 1.5 MHz.
766ad43d528SLinus Walleij 		 */
767ad43d528SLinus Walleij 		CM6206_REG2_DRIVER_ON |
768ad43d528SLinus Walleij 		CM6206_REG2_HEADP_SEL_FRONT_CHANNELS |
769ad43d528SLinus Walleij 		CM6206_REG2_MUTE_HEADPHONE_RIGHT |
770ad43d528SLinus Walleij 		CM6206_REG2_MUTE_HEADPHONE_LEFT,
771ad43d528SLinus Walleij 		/*
772ad43d528SLinus Walleij 		 * REG3: default flyspeed, set 2.5V mic bias
773ad43d528SLinus Walleij 		 * enable all line out ports and enable SPDIF
774ad43d528SLinus Walleij 		 */
775ad43d528SLinus Walleij 		CM6206_REG3_FLYSPEED_DEFAULT |
776ad43d528SLinus Walleij 		CM6206_REG3_VRAP25EN |
777ad43d528SLinus Walleij 		CM6206_REG3_FOE |
778ad43d528SLinus Walleij 		CM6206_REG3_ROE |
779ad43d528SLinus Walleij 		CM6206_REG3_CBOE |
780ad43d528SLinus Walleij 		CM6206_REG3_LOSE |
781ad43d528SLinus Walleij 		CM6206_REG3_HPOE |
782ad43d528SLinus Walleij 		CM6206_REG3_SPDIFI_CANREC,
783ad43d528SLinus Walleij 		/* REG4 is just a bunch of GPIO lines */
784ad43d528SLinus Walleij 		0x0000,
785ad43d528SLinus Walleij 		/* REG5: de-assert AD/DA reset signals */
786ad43d528SLinus Walleij 		CM6206_REG5_DA_RSTN |
787ad43d528SLinus Walleij 		CM6206_REG5_AD_RSTN };
788e5779998SDaniel Mack 
789e5779998SDaniel Mack 	for (reg = 0; reg < ARRAY_SIZE(val); reg++) {
790e5779998SDaniel Mack 		err = snd_usb_cm106_write_int_reg(dev, reg, val[reg]);
791e5779998SDaniel Mack 		if (err < 0)
792e5779998SDaniel Mack 			return err;
793e5779998SDaniel Mack 	}
794e5779998SDaniel Mack 
795e5779998SDaniel Mack 	return err;
796e5779998SDaniel Mack }
797e5779998SDaniel Mack 
79819570d74STakashi Iwai /* quirk for Plantronics GameCom 780 with CM6302 chip */
snd_usb_gamecon780_boot_quirk(struct usb_device * dev)79919570d74STakashi Iwai static int snd_usb_gamecon780_boot_quirk(struct usb_device *dev)
80019570d74STakashi Iwai {
80119570d74STakashi Iwai 	/* set the initial volume and don't change; other values are either
80219570d74STakashi Iwai 	 * too loud or silent due to firmware bug (bko#65251)
80319570d74STakashi Iwai 	 */
804542baf94SPaul S McSpadden 	u8 buf[2] = { 0x74, 0xe3 };
80519570d74STakashi Iwai 	return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
80619570d74STakashi Iwai 			USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
80719570d74STakashi Iwai 			UAC_FU_VOLUME << 8, 9 << 8, buf, 2);
80819570d74STakashi Iwai }
80919570d74STakashi Iwai 
810e5779998SDaniel Mack /*
8115e212332SMark Hills  * Novation Twitch DJ controller
81211e424e8SEduard Gilmutdinov  * Focusrite Novation Saffire 6 USB audio card
8135e212332SMark Hills  */
snd_usb_novation_boot_quirk(struct usb_device * dev)81411e424e8SEduard Gilmutdinov static int snd_usb_novation_boot_quirk(struct usb_device *dev)
8155e212332SMark Hills {
8165e212332SMark Hills 	/* preemptively set up the device because otherwise the
8175e212332SMark Hills 	 * raw MIDI endpoints are not active */
8185e212332SMark Hills 	usb_set_interface(dev, 0, 1);
8195e212332SMark Hills 	return 0;
8205e212332SMark Hills }
8215e212332SMark Hills 
8225e212332SMark Hills /*
823e5779998SDaniel Mack  * This call will put the synth in "USB send" mode, i.e it will send MIDI
824e5779998SDaniel Mack  * messages through USB (this is disabled at startup). The synth will
825e5779998SDaniel Mack  * acknowledge by sending a sysex on endpoint 0x85 and by displaying a USB
826e5779998SDaniel Mack  * sign on its LCD. Values here are chosen based on sniffing USB traffic
827e5779998SDaniel Mack  * under Windows.
828e5779998SDaniel Mack  */
snd_usb_accessmusic_boot_quirk(struct usb_device * dev)829e5779998SDaniel Mack static int snd_usb_accessmusic_boot_quirk(struct usb_device *dev)
830e5779998SDaniel Mack {
831e5779998SDaniel Mack 	int err, actual_length;
832e5779998SDaniel Mack 	/* "midi send" enable */
833e5779998SDaniel Mack 	static const u8 seq[] = { 0x4e, 0x73, 0x52, 0x01 };
834801ebf10STakashi Iwai 	void *buf;
835e5779998SDaniel Mack 
836fcc2cc1fSGreg Kroah-Hartman 	if (usb_pipe_type_check(dev, usb_sndintpipe(dev, 0x05)))
837801ebf10STakashi Iwai 		return -EINVAL;
838801ebf10STakashi Iwai 	buf = kmemdup(seq, ARRAY_SIZE(seq), GFP_KERNEL);
839e5779998SDaniel Mack 	if (!buf)
840e5779998SDaniel Mack 		return -ENOMEM;
841e5779998SDaniel Mack 	err = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x05), buf,
842e5779998SDaniel Mack 			ARRAY_SIZE(seq), &actual_length, 1000);
843e5779998SDaniel Mack 	kfree(buf);
844e5779998SDaniel Mack 	if (err < 0)
845e5779998SDaniel Mack 		return err;
846e5779998SDaniel Mack 
847e5779998SDaniel Mack 	return 0;
848e5779998SDaniel Mack }
849e5779998SDaniel Mack 
850e5779998SDaniel Mack /*
85154a8c500SDaniel Mack  * Some sound cards from Native Instruments are in fact compliant to the USB
85254a8c500SDaniel Mack  * audio standard of version 2 and other approved USB standards, even though
85354a8c500SDaniel Mack  * they come up as vendor-specific device when first connected.
85454a8c500SDaniel Mack  *
85554a8c500SDaniel Mack  * However, they can be told to come up with a new set of descriptors
85654a8c500SDaniel Mack  * upon their next enumeration, and the interfaces announced by the new
85754a8c500SDaniel Mack  * descriptors will then be handled by the kernel's class drivers. As the
85854a8c500SDaniel Mack  * product ID will also change, no further checks are required.
85954a8c500SDaniel Mack  */
86054a8c500SDaniel Mack 
snd_usb_nativeinstruments_boot_quirk(struct usb_device * dev)86154a8c500SDaniel Mack static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev)
86254a8c500SDaniel Mack {
863801ebf10STakashi Iwai 	int ret;
864801ebf10STakashi Iwai 
865801ebf10STakashi Iwai 	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
86654a8c500SDaniel Mack 				  0xaf, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
867889d6684SEldad Zack 				  1, 0, NULL, 0, 1000);
86854a8c500SDaniel Mack 
86954a8c500SDaniel Mack 	if (ret < 0)
87054a8c500SDaniel Mack 		return ret;
87154a8c500SDaniel Mack 
87254a8c500SDaniel Mack 	usb_reset_device(dev);
87354a8c500SDaniel Mack 
87454a8c500SDaniel Mack 	/* return -EAGAIN, so the creation of an audio interface for this
87554a8c500SDaniel Mack 	 * temporary device is aborted. The device will reconnect with a
87654a8c500SDaniel Mack 	 * new product ID */
87754a8c500SDaniel Mack 	return -EAGAIN;
87854a8c500SDaniel Mack }
87954a8c500SDaniel Mack 
mbox2_setup_48_24_magic(struct usb_device * dev)880cb99864dSDamien Zammit static void mbox2_setup_48_24_magic(struct usb_device *dev)
881cb99864dSDamien Zammit {
882cb99864dSDamien Zammit 	u8 srate[3];
883cb99864dSDamien Zammit 	u8 temp[12];
884cb99864dSDamien Zammit 
885cb99864dSDamien Zammit 	/* Choose 48000Hz permanently */
886cb99864dSDamien Zammit 	srate[0] = 0x80;
887cb99864dSDamien Zammit 	srate[1] = 0xbb;
888cb99864dSDamien Zammit 	srate[2] = 0x00;
889cb99864dSDamien Zammit 
890cb99864dSDamien Zammit 	/* Send the magic! */
891cb99864dSDamien Zammit 	snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0),
892cb99864dSDamien Zammit 		0x01, 0x22, 0x0100, 0x0085, &temp, 0x0003);
893cb99864dSDamien Zammit 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
894cb99864dSDamien Zammit 		0x81, 0xa2, 0x0100, 0x0085, &srate, 0x0003);
895cb99864dSDamien Zammit 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
896cb99864dSDamien Zammit 		0x81, 0xa2, 0x0100, 0x0086, &srate, 0x0003);
897cb99864dSDamien Zammit 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
898cb99864dSDamien Zammit 		0x81, 0xa2, 0x0100, 0x0003, &srate, 0x0003);
899cb99864dSDamien Zammit 	return;
900cb99864dSDamien Zammit }
901cb99864dSDamien Zammit 
902cb99864dSDamien Zammit /* Digidesign Mbox 2 needs to load firmware onboard
903cb99864dSDamien Zammit  * and driver must wait a few seconds for initialisation.
904cb99864dSDamien Zammit  */
905cb99864dSDamien Zammit 
906cb99864dSDamien Zammit #define MBOX2_FIRMWARE_SIZE    646
907cb99864dSDamien Zammit #define MBOX2_BOOT_LOADING     0x01 /* Hard coded into the device */
908cb99864dSDamien Zammit #define MBOX2_BOOT_READY       0x02 /* Hard coded into the device */
909cb99864dSDamien Zammit 
snd_usb_mbox2_boot_quirk(struct usb_device * dev)910b7b435e8SDamien Zammit static int snd_usb_mbox2_boot_quirk(struct usb_device *dev)
911cb99864dSDamien Zammit {
912cb99864dSDamien Zammit 	struct usb_host_config *config = dev->actconfig;
91344a7b041SDan Carpenter 	struct usb_device_descriptor *new_device_descriptor __free(kfree) = NULL;
914cb99864dSDamien Zammit 	int err;
9154909a0caSJiri Slaby 	u8 bootresponse[0x12];
916cb99864dSDamien Zammit 	int fwsize;
917cb99864dSDamien Zammit 	int count;
918cb99864dSDamien Zammit 
919cb99864dSDamien Zammit 	fwsize = le16_to_cpu(get_cfg_desc(config)->wTotalLength);
920cb99864dSDamien Zammit 
921cb99864dSDamien Zammit 	if (fwsize != MBOX2_FIRMWARE_SIZE) {
9220ba41d91STakashi Iwai 		dev_err(&dev->dev, "Invalid firmware size=%d.\n", fwsize);
923cb99864dSDamien Zammit 		return -ENODEV;
924cb99864dSDamien Zammit 	}
925cb99864dSDamien Zammit 
9260ba41d91STakashi Iwai 	dev_dbg(&dev->dev, "Sending Digidesign Mbox 2 boot sequence...\n");
927cb99864dSDamien Zammit 
928cb99864dSDamien Zammit 	count = 0;
929b7b435e8SDamien Zammit 	bootresponse[0] = MBOX2_BOOT_LOADING;
930b7b435e8SDamien Zammit 	while ((bootresponse[0] == MBOX2_BOOT_LOADING) && (count < 10)) {
931cb99864dSDamien Zammit 		msleep(500); /* 0.5 second delay */
932cb99864dSDamien Zammit 		snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0),
933cb99864dSDamien Zammit 			/* Control magic - load onboard firmware */
934cb99864dSDamien Zammit 			0x85, 0xc0, 0x0001, 0x0000, &bootresponse, 0x0012);
935b7b435e8SDamien Zammit 		if (bootresponse[0] == MBOX2_BOOT_READY)
936cb99864dSDamien Zammit 			break;
9370ba41d91STakashi Iwai 		dev_dbg(&dev->dev, "device not ready, resending boot sequence...\n");
938cb99864dSDamien Zammit 		count++;
939cb99864dSDamien Zammit 	}
940cb99864dSDamien Zammit 
941b7b435e8SDamien Zammit 	if (bootresponse[0] != MBOX2_BOOT_READY) {
9420ba41d91STakashi Iwai 		dev_err(&dev->dev, "Unknown bootresponse=%d, or timed out, ignoring device.\n", bootresponse[0]);
943cb99864dSDamien Zammit 		return -ENODEV;
944cb99864dSDamien Zammit 	}
945cb99864dSDamien Zammit 
9460ba41d91STakashi Iwai 	dev_dbg(&dev->dev, "device initialised!\n");
947cb99864dSDamien Zammit 
94844a7b041SDan Carpenter 	new_device_descriptor = kmalloc(sizeof(*new_device_descriptor), GFP_KERNEL);
94944a7b041SDan Carpenter 	if (!new_device_descriptor)
95044a7b041SDan Carpenter 		return -ENOMEM;
95144a7b041SDan Carpenter 
952cb99864dSDamien Zammit 	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
95344a7b041SDan Carpenter 		new_device_descriptor, sizeof(*new_device_descriptor));
954cb99864dSDamien Zammit 	if (err < 0)
9550ba41d91STakashi Iwai 		dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err);
95644a7b041SDan Carpenter 	if (new_device_descriptor->bNumConfigurations > dev->descriptor.bNumConfigurations)
957b8f8b81dSBenoît Sevens 		dev_dbg(&dev->dev, "error too large bNumConfigurations: %d\n",
95844a7b041SDan Carpenter 			new_device_descriptor->bNumConfigurations);
959b8f8b81dSBenoît Sevens 	else
96044a7b041SDan Carpenter 		memcpy(&dev->descriptor, new_device_descriptor, sizeof(dev->descriptor));
961cb99864dSDamien Zammit 
962cb99864dSDamien Zammit 	err = usb_reset_configuration(dev);
963cb99864dSDamien Zammit 	if (err < 0)
9640ba41d91STakashi Iwai 		dev_dbg(&dev->dev, "error usb_reset_configuration: %d\n", err);
9650ba41d91STakashi Iwai 	dev_dbg(&dev->dev, "mbox2_boot: new boot length = %d\n",
966cb99864dSDamien Zammit 		le16_to_cpu(get_cfg_desc(config)->wTotalLength));
967cb99864dSDamien Zammit 
968cb99864dSDamien Zammit 	mbox2_setup_48_24_magic(dev);
969cb99864dSDamien Zammit 
9700ba41d91STakashi Iwai 	dev_info(&dev->dev, "Digidesign Mbox 2: 24bit 48kHz");
971cb99864dSDamien Zammit 
972cb99864dSDamien Zammit 	return 0; /* Successful boot */
973cb99864dSDamien Zammit }
974cb99864dSDamien Zammit 
snd_usb_axefx3_boot_quirk(struct usb_device * dev)97516bafa79SAlberto Aguirre static int snd_usb_axefx3_boot_quirk(struct usb_device *dev)
97616bafa79SAlberto Aguirre {
97716bafa79SAlberto Aguirre 	int err;
97816bafa79SAlberto Aguirre 
97916bafa79SAlberto Aguirre 	dev_dbg(&dev->dev, "Waiting for Axe-Fx III to boot up...\n");
98016bafa79SAlberto Aguirre 
98116bafa79SAlberto Aguirre 	/* If the Axe-Fx III has not fully booted, it will timeout when trying
98216bafa79SAlberto Aguirre 	 * to enable the audio streaming interface. A more generous timeout is
98316bafa79SAlberto Aguirre 	 * used here to detect when the Axe-Fx III has finished booting as the
98416bafa79SAlberto Aguirre 	 * set interface message will be acked once it has
98516bafa79SAlberto Aguirre 	 */
98616bafa79SAlberto Aguirre 	err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
98716bafa79SAlberto Aguirre 				USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE,
98816bafa79SAlberto Aguirre 				1, 1, NULL, 0, 120000);
98916bafa79SAlberto Aguirre 	if (err < 0) {
99016bafa79SAlberto Aguirre 		dev_err(&dev->dev,
99116bafa79SAlberto Aguirre 			"failed waiting for Axe-Fx III to boot: %d\n", err);
99216bafa79SAlberto Aguirre 		return err;
99316bafa79SAlberto Aguirre 	}
99416bafa79SAlberto Aguirre 
99516bafa79SAlberto Aguirre 	dev_dbg(&dev->dev, "Axe-Fx III is now ready\n");
99616bafa79SAlberto Aguirre 
99716bafa79SAlberto Aguirre 	err = usb_set_interface(dev, 1, 0);
99816bafa79SAlberto Aguirre 	if (err < 0)
99916bafa79SAlberto Aguirre 		dev_dbg(&dev->dev,
100016bafa79SAlberto Aguirre 			"error stopping Axe-Fx III interface: %d\n", err);
100116bafa79SAlberto Aguirre 
100216bafa79SAlberto Aguirre 	return 0;
100316bafa79SAlberto Aguirre }
100416bafa79SAlberto Aguirre 
mbox3_setup_48_24_magic(struct usb_device * dev)1005b01104fcSConner Knox static void mbox3_setup_48_24_magic(struct usb_device *dev)
1006b01104fcSConner Knox {
1007b01104fcSConner Knox 	/* The Mbox 3 is "little endian" */
1008b01104fcSConner Knox 	/* max volume is: 0x0000. */
1009b01104fcSConner Knox 	/* min volume is: 0x0080 (shown in little endian form) */
1010b01104fcSConner Knox 
1011b01104fcSConner Knox 
1012b01104fcSConner Knox 	/* Load 48000Hz rate into buffer */
1013b01104fcSConner Knox 	u8 com_buff[4] = {0x80, 0xbb, 0x00, 0x00};
1014b01104fcSConner Knox 
1015b01104fcSConner Knox 	/* Set 48000Hz sample rate */
1016b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1017b01104fcSConner Knox 			0x01, 0x21, 0x0100, 0x0001, &com_buff, 4);  //Is this really needed?
1018b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1019b01104fcSConner Knox 			0x01, 0x21, 0x0100, 0x8101, &com_buff, 4);
1020b01104fcSConner Knox 
1021b01104fcSConner Knox 	/* Deactivate Tuner */
1022b01104fcSConner Knox 	/* on  = 0x01*/
1023b01104fcSConner Knox 	/* off = 0x00*/
1024b01104fcSConner Knox 	com_buff[0] = 0x00;
1025b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1026b01104fcSConner Knox 		0x01, 0x21, 0x0003, 0x2001, &com_buff, 1);
1027b01104fcSConner Knox 
1028b01104fcSConner Knox 	/* Set clock source to Internal (as opposed to S/PDIF) */
1029b01104fcSConner Knox 	com_buff[0] = 0x01;
1030b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1031b01104fcSConner Knox 			1, 0x21, 0x0100, 0x8001, &com_buff, 1);
1032b01104fcSConner Knox 
1033b01104fcSConner Knox 	/* Mute the hardware loopbacks to start the device in a known state. */
1034b01104fcSConner Knox 	com_buff[0] = 0x00;
1035b01104fcSConner Knox 	com_buff[1] = 0x80;
1036b01104fcSConner Knox 	/* Analogue input 1 left channel: */
1037b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1038b01104fcSConner Knox 			1, 0x21, 0x0110, 0x4001, &com_buff, 2);
1039b01104fcSConner Knox 	/* Analogue input 1 right channel: */
1040b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1041b01104fcSConner Knox 			1, 0x21, 0x0111, 0x4001, &com_buff, 2);
1042b01104fcSConner Knox 	/* Analogue input 2 left channel: */
1043b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1044b01104fcSConner Knox 			1, 0x21, 0x0114, 0x4001, &com_buff, 2);
1045b01104fcSConner Knox 	/* Analogue input 2 right channel: */
1046b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1047b01104fcSConner Knox 			1, 0x21, 0x0115, 0x4001, &com_buff, 2);
1048b01104fcSConner Knox 	/* Analogue input 3 left channel: */
1049b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1050b01104fcSConner Knox 			1, 0x21, 0x0118, 0x4001, &com_buff, 2);
1051b01104fcSConner Knox 	/* Analogue input 3 right channel: */
1052b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1053b01104fcSConner Knox 			1, 0x21, 0x0119, 0x4001, &com_buff, 2);
1054b01104fcSConner Knox 	/* Analogue input 4 left channel: */
1055b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1056b01104fcSConner Knox 			1, 0x21, 0x011c, 0x4001, &com_buff, 2);
1057b01104fcSConner Knox 	/* Analogue input 4 right channel: */
1058b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1059b01104fcSConner Knox 			1, 0x21, 0x011d, 0x4001, &com_buff, 2);
1060b01104fcSConner Knox 
1061b01104fcSConner Knox 	/* Set software sends to output */
1062b01104fcSConner Knox 	com_buff[0] = 0x00;
1063b01104fcSConner Knox 	com_buff[1] = 0x00;
1064b01104fcSConner Knox 	/* Analogue software return 1 left channel: */
1065b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1066b01104fcSConner Knox 			1, 0x21, 0x0100, 0x4001, &com_buff, 2);
1067b01104fcSConner Knox 	com_buff[0] = 0x00;
1068b01104fcSConner Knox 	com_buff[1] = 0x80;
1069b01104fcSConner Knox 	/* Analogue software return 1 right channel: */
1070b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1071b01104fcSConner Knox 			1, 0x21, 0x0101, 0x4001, &com_buff, 2);
1072b01104fcSConner Knox 	com_buff[0] = 0x00;
1073b01104fcSConner Knox 	com_buff[1] = 0x80;
1074b01104fcSConner Knox 	/* Analogue software return 2 left channel: */
1075b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1076b01104fcSConner Knox 			1, 0x21, 0x0104, 0x4001, &com_buff, 2);
1077b01104fcSConner Knox 	com_buff[0] = 0x00;
1078b01104fcSConner Knox 	com_buff[1] = 0x00;
1079b01104fcSConner Knox 	/* Analogue software return 2 right channel: */
1080b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1081b01104fcSConner Knox 			1, 0x21, 0x0105, 0x4001, &com_buff, 2);
1082b01104fcSConner Knox 
1083b01104fcSConner Knox 	com_buff[0] = 0x00;
1084b01104fcSConner Knox 	com_buff[1] = 0x80;
1085b01104fcSConner Knox 	/* Analogue software return 3 left channel: */
1086b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1087b01104fcSConner Knox 			1, 0x21, 0x0108, 0x4001, &com_buff, 2);
1088b01104fcSConner Knox 	/* Analogue software return 3 right channel: */
1089b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1090b01104fcSConner Knox 			1, 0x21, 0x0109, 0x4001, &com_buff, 2);
1091b01104fcSConner Knox 	/* Analogue software return 4 left channel: */
1092b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1093b01104fcSConner Knox 			1, 0x21, 0x010c, 0x4001, &com_buff, 2);
1094b01104fcSConner Knox 	/* Analogue software return 4 right channel: */
1095b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1096b01104fcSConner Knox 			1, 0x21, 0x010d, 0x4001, &com_buff, 2);
1097b01104fcSConner Knox 
1098b01104fcSConner Knox 	/* Return to muting sends */
1099b01104fcSConner Knox 	com_buff[0] = 0x00;
1100b01104fcSConner Knox 	com_buff[1] = 0x80;
1101b01104fcSConner Knox 	/* Analogue fx return left channel: */
1102b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1103b01104fcSConner Knox 			1, 0x21, 0x0120, 0x4001, &com_buff, 2);
1104b01104fcSConner Knox 	/* Analogue fx return right channel: */
1105b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1106b01104fcSConner Knox 			1, 0x21, 0x0121, 0x4001, &com_buff, 2);
1107b01104fcSConner Knox 
1108b01104fcSConner Knox 	/* Analogue software input 1 fx send: */
1109b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1110b01104fcSConner Knox 			1, 0x21, 0x0100, 0x4201, &com_buff, 2);
1111b01104fcSConner Knox 	/* Analogue software input 2 fx send: */
1112b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1113b01104fcSConner Knox 			1, 0x21, 0x0101, 0x4201, &com_buff, 2);
1114b01104fcSConner Knox 	/* Analogue software input 3 fx send: */
1115b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1116b01104fcSConner Knox 			1, 0x21, 0x0102, 0x4201, &com_buff, 2);
1117b01104fcSConner Knox 	/* Analogue software input 4 fx send: */
1118b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1119b01104fcSConner Knox 			1, 0x21, 0x0103, 0x4201, &com_buff, 2);
1120b01104fcSConner Knox 	/* Analogue input 1 fx send: */
1121b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1122b01104fcSConner Knox 			1, 0x21, 0x0104, 0x4201, &com_buff, 2);
1123b01104fcSConner Knox 	/* Analogue input 2 fx send: */
1124b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1125b01104fcSConner Knox 			1, 0x21, 0x0105, 0x4201, &com_buff, 2);
1126b01104fcSConner Knox 	/* Analogue input 3 fx send: */
1127b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1128b01104fcSConner Knox 			1, 0x21, 0x0106, 0x4201, &com_buff, 2);
1129b01104fcSConner Knox 	/* Analogue input 4 fx send: */
1130b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1131b01104fcSConner Knox 			1, 0x21, 0x0107, 0x4201, &com_buff, 2);
1132b01104fcSConner Knox 
1133b01104fcSConner Knox 	/* Toggle allowing host control */
1134b01104fcSConner Knox 	com_buff[0] = 0x02;
1135b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1136b01104fcSConner Knox 			3, 0x21, 0x0000, 0x2001, &com_buff, 1);
1137b01104fcSConner Knox 
1138b01104fcSConner Knox 	/* Do not dim fx returns */
1139b01104fcSConner Knox 	com_buff[0] = 0x00;
1140b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1141b01104fcSConner Knox 			3, 0x21, 0x0002, 0x2001, &com_buff, 1);
1142b01104fcSConner Knox 
1143b01104fcSConner Knox 	/* Do not set fx returns to mono */
1144b01104fcSConner Knox 	com_buff[0] = 0x00;
1145b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1146b01104fcSConner Knox 			3, 0x21, 0x0001, 0x2001, &com_buff, 1);
1147b01104fcSConner Knox 
1148b01104fcSConner Knox 	/* Mute the S/PDIF hardware loopback
1149b01104fcSConner Knox 	 * same odd volume logic here as above
1150b01104fcSConner Knox 	 */
1151b01104fcSConner Knox 	com_buff[0] = 0x00;
1152b01104fcSConner Knox 	com_buff[1] = 0x80;
1153b01104fcSConner Knox 	/* S/PDIF hardware input 1 left channel */
1154b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1155b01104fcSConner Knox 			1, 0x21, 0x0112, 0x4001, &com_buff, 2);
1156b01104fcSConner Knox 	/* S/PDIF hardware input 1 right channel */
1157b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1158b01104fcSConner Knox 			1, 0x21, 0x0113, 0x4001, &com_buff, 2);
1159b01104fcSConner Knox 	/* S/PDIF hardware input 2 left channel */
1160b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1161b01104fcSConner Knox 			1, 0x21, 0x0116, 0x4001, &com_buff, 2);
1162b01104fcSConner Knox 	/* S/PDIF hardware input 2 right channel */
1163b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1164b01104fcSConner Knox 			1, 0x21, 0x0117, 0x4001, &com_buff, 2);
1165b01104fcSConner Knox 	/* S/PDIF hardware input 3 left channel */
1166b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1167b01104fcSConner Knox 			1, 0x21, 0x011a, 0x4001, &com_buff, 2);
1168b01104fcSConner Knox 	/* S/PDIF hardware input 3 right channel */
1169b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1170b01104fcSConner Knox 			1, 0x21, 0x011b, 0x4001, &com_buff, 2);
1171b01104fcSConner Knox 	/* S/PDIF hardware input 4 left channel */
1172b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1173b01104fcSConner Knox 			1, 0x21, 0x011e, 0x4001, &com_buff, 2);
1174b01104fcSConner Knox 	/* S/PDIF hardware input 4 right channel */
1175b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1176b01104fcSConner Knox 			1, 0x21, 0x011f, 0x4001, &com_buff, 2);
1177b01104fcSConner Knox 	/* S/PDIF software return 1 left channel */
1178b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1179b01104fcSConner Knox 			1, 0x21, 0x0102, 0x4001, &com_buff, 2);
1180b01104fcSConner Knox 	/* S/PDIF software return 1 right channel */
1181b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1182b01104fcSConner Knox 			1, 0x21, 0x0103, 0x4001, &com_buff, 2);
1183b01104fcSConner Knox 	/* S/PDIF software return 2 left channel */
1184b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1185b01104fcSConner Knox 			1, 0x21, 0x0106, 0x4001, &com_buff, 2);
1186b01104fcSConner Knox 	/* S/PDIF software return 2 right channel */
1187b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1188b01104fcSConner Knox 			1, 0x21, 0x0107, 0x4001, &com_buff, 2);
1189b01104fcSConner Knox 
1190b01104fcSConner Knox 	com_buff[0] = 0x00;
1191b01104fcSConner Knox 	com_buff[1] = 0x00;
1192b01104fcSConner Knox 	/* S/PDIF software return 3 left channel */
1193b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1194b01104fcSConner Knox 			1, 0x21, 0x010a, 0x4001, &com_buff, 2);
1195b01104fcSConner Knox 
1196b01104fcSConner Knox 	com_buff[0] = 0x00;
1197b01104fcSConner Knox 	com_buff[1] = 0x80;
1198b01104fcSConner Knox 	/* S/PDIF software return 3 right channel */
1199b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1200b01104fcSConner Knox 			1, 0x21, 0x010b, 0x4001, &com_buff, 2);
1201b01104fcSConner Knox 	/* S/PDIF software return 4 left channel */
1202b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1203b01104fcSConner Knox 			1, 0x21, 0x010e, 0x4001, &com_buff, 2);
1204b01104fcSConner Knox 
1205b01104fcSConner Knox 	com_buff[0] = 0x00;
1206b01104fcSConner Knox 	com_buff[1] = 0x00;
1207b01104fcSConner Knox 	/* S/PDIF software return 4 right channel */
1208b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1209b01104fcSConner Knox 			1, 0x21, 0x010f, 0x4001, &com_buff, 2);
1210b01104fcSConner Knox 
1211b01104fcSConner Knox 	com_buff[0] = 0x00;
1212b01104fcSConner Knox 	com_buff[1] = 0x80;
1213b01104fcSConner Knox 	/* S/PDIF fx returns left channel */
1214b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1215b01104fcSConner Knox 			1, 0x21, 0x0122, 0x4001, &com_buff, 2);
1216b01104fcSConner Knox 	/* S/PDIF fx returns right channel */
1217b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1218b01104fcSConner Knox 			1, 0x21, 0x0123, 0x4001, &com_buff, 2);
1219b01104fcSConner Knox 
1220b01104fcSConner Knox 	/* Set the dropdown "Effect" to the first option */
1221b01104fcSConner Knox 	/* Room1  = 0x00 */
1222b01104fcSConner Knox 	/* Room2  = 0x01 */
1223b01104fcSConner Knox 	/* Room3  = 0x02 */
1224b01104fcSConner Knox 	/* Hall 1 = 0x03 */
1225b01104fcSConner Knox 	/* Hall 2 = 0x04 */
1226b01104fcSConner Knox 	/* Plate  = 0x05 */
1227b01104fcSConner Knox 	/* Delay  = 0x06 */
1228b01104fcSConner Knox 	/* Echo   = 0x07 */
1229b01104fcSConner Knox 	com_buff[0] = 0x00;
1230b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1231b01104fcSConner Knox 			1, 0x21, 0x0200, 0x4301, &com_buff, 1);	/* max is 0xff */
1232b01104fcSConner Knox 	/* min is 0x00 */
1233b01104fcSConner Knox 
1234b01104fcSConner Knox 
1235b01104fcSConner Knox 	/* Set the effect duration to 0 */
1236b01104fcSConner Knox 	/* max is 0xffff */
1237b01104fcSConner Knox 	/* min is 0x0000 */
1238b01104fcSConner Knox 	com_buff[0] = 0x00;
1239b01104fcSConner Knox 	com_buff[1] = 0x00;
1240b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1241b01104fcSConner Knox 			1, 0x21, 0x0400, 0x4301, &com_buff, 2);
1242b01104fcSConner Knox 
1243b01104fcSConner Knox 	/* Set the effect volume and feedback to 0 */
1244b01104fcSConner Knox 	/* max is 0xff */
1245b01104fcSConner Knox 	/* min is 0x00 */
1246b01104fcSConner Knox 	com_buff[0] = 0x00;
1247b01104fcSConner Knox 	/* feedback: */
1248b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1249b01104fcSConner Knox 			1, 0x21, 0x0500, 0x4301, &com_buff, 1);
1250b01104fcSConner Knox 	/* volume: */
1251b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1252b01104fcSConner Knox 			1, 0x21, 0x0300, 0x4301, &com_buff, 1);
1253b01104fcSConner Knox 
1254b01104fcSConner Knox 	/* Set soft button hold duration */
1255b01104fcSConner Knox 	/* 0x03 = 250ms */
1256b01104fcSConner Knox 	/* 0x05 = 500ms DEFAULT */
1257b01104fcSConner Knox 	/* 0x08 = 750ms */
1258b01104fcSConner Knox 	/* 0x0a = 1sec */
1259b01104fcSConner Knox 	com_buff[0] = 0x05;
1260b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1261b01104fcSConner Knox 			3, 0x21, 0x0005, 0x2001, &com_buff, 1);
1262b01104fcSConner Knox 
1263b01104fcSConner Knox 	/* Use dim LEDs for button of state */
1264b01104fcSConner Knox 	com_buff[0] = 0x00;
1265b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1266b01104fcSConner Knox 			3, 0x21, 0x0004, 0x2001, &com_buff, 1);
1267b01104fcSConner Knox }
1268b01104fcSConner Knox 
1269b01104fcSConner Knox #define MBOX3_DESCRIPTOR_SIZE	464
1270b01104fcSConner Knox 
snd_usb_mbox3_boot_quirk(struct usb_device * dev)1271b01104fcSConner Knox static int snd_usb_mbox3_boot_quirk(struct usb_device *dev)
1272b01104fcSConner Knox {
1273b01104fcSConner Knox 	struct usb_host_config *config = dev->actconfig;
127444a7b041SDan Carpenter 	struct usb_device_descriptor *new_device_descriptor __free(kfree) = NULL;
1275b01104fcSConner Knox 	int err;
1276b01104fcSConner Knox 	int descriptor_size;
1277b01104fcSConner Knox 
1278b01104fcSConner Knox 	descriptor_size = le16_to_cpu(get_cfg_desc(config)->wTotalLength);
1279b01104fcSConner Knox 
1280b01104fcSConner Knox 	if (descriptor_size != MBOX3_DESCRIPTOR_SIZE) {
1281b01104fcSConner Knox 		dev_err(&dev->dev, "Invalid descriptor size=%d.\n", descriptor_size);
1282b01104fcSConner Knox 		return -ENODEV;
1283b01104fcSConner Knox 	}
1284b01104fcSConner Knox 
1285b01104fcSConner Knox 	dev_dbg(&dev->dev, "device initialised!\n");
1286b01104fcSConner Knox 
128744a7b041SDan Carpenter 	new_device_descriptor = kmalloc(sizeof(*new_device_descriptor), GFP_KERNEL);
128844a7b041SDan Carpenter 	if (!new_device_descriptor)
128944a7b041SDan Carpenter 		return -ENOMEM;
129044a7b041SDan Carpenter 
1291b01104fcSConner Knox 	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
129244a7b041SDan Carpenter 		new_device_descriptor, sizeof(*new_device_descriptor));
1293b01104fcSConner Knox 	if (err < 0)
1294b01104fcSConner Knox 		dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err);
129544a7b041SDan Carpenter 	if (new_device_descriptor->bNumConfigurations > dev->descriptor.bNumConfigurations)
1296b8f8b81dSBenoît Sevens 		dev_dbg(&dev->dev, "error too large bNumConfigurations: %d\n",
129744a7b041SDan Carpenter 			new_device_descriptor->bNumConfigurations);
1298b8f8b81dSBenoît Sevens 	else
129944a7b041SDan Carpenter 		memcpy(&dev->descriptor, new_device_descriptor, sizeof(dev->descriptor));
1300b01104fcSConner Knox 
1301b01104fcSConner Knox 	err = usb_reset_configuration(dev);
1302b01104fcSConner Knox 	if (err < 0)
1303b01104fcSConner Knox 		dev_dbg(&dev->dev, "error usb_reset_configuration: %d\n", err);
1304b01104fcSConner Knox 	dev_dbg(&dev->dev, "mbox3_boot: new boot length = %d\n",
1305b01104fcSConner Knox 		le16_to_cpu(get_cfg_desc(config)->wTotalLength));
1306b01104fcSConner Knox 
1307b01104fcSConner Knox 	mbox3_setup_48_24_magic(dev);
1308b01104fcSConner Knox 	dev_info(&dev->dev, "Digidesign Mbox 3: 24bit 48kHz");
1309b01104fcSConner Knox 
1310b01104fcSConner Knox 	return 0; /* Successful boot */
1311b01104fcSConner Knox }
1312a634090aSManuel Reinhardt 
1313a634090aSManuel Reinhardt #define MICROBOOK_BUF_SIZE 128
1314a634090aSManuel Reinhardt 
snd_usb_motu_microbookii_communicate(struct usb_device * dev,u8 * buf,int buf_size,int * length)1315a634090aSManuel Reinhardt static int snd_usb_motu_microbookii_communicate(struct usb_device *dev, u8 *buf,
1316a634090aSManuel Reinhardt 						int buf_size, int *length)
1317a634090aSManuel Reinhardt {
1318a634090aSManuel Reinhardt 	int err, actual_length;
1319a634090aSManuel Reinhardt 
1320fcc2cc1fSGreg Kroah-Hartman 	if (usb_pipe_type_check(dev, usb_sndintpipe(dev, 0x01)))
1321801ebf10STakashi Iwai 		return -EINVAL;
1322a634090aSManuel Reinhardt 	err = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x01), buf, *length,
1323a634090aSManuel Reinhardt 				&actual_length, 1000);
1324a634090aSManuel Reinhardt 	if (err < 0)
1325a634090aSManuel Reinhardt 		return err;
1326a634090aSManuel Reinhardt 
1327a634090aSManuel Reinhardt 	print_hex_dump(KERN_DEBUG, "MicroBookII snd: ", DUMP_PREFIX_NONE, 16, 1,
1328a634090aSManuel Reinhardt 		       buf, actual_length, false);
1329a634090aSManuel Reinhardt 
1330a634090aSManuel Reinhardt 	memset(buf, 0, buf_size);
1331a634090aSManuel Reinhardt 
1332fcc2cc1fSGreg Kroah-Hartman 	if (usb_pipe_type_check(dev, usb_rcvintpipe(dev, 0x82)))
1333801ebf10STakashi Iwai 		return -EINVAL;
1334a634090aSManuel Reinhardt 	err = usb_interrupt_msg(dev, usb_rcvintpipe(dev, 0x82), buf, buf_size,
1335a634090aSManuel Reinhardt 				&actual_length, 1000);
1336a634090aSManuel Reinhardt 	if (err < 0)
1337a634090aSManuel Reinhardt 		return err;
1338a634090aSManuel Reinhardt 
1339a634090aSManuel Reinhardt 	print_hex_dump(KERN_DEBUG, "MicroBookII rcv: ", DUMP_PREFIX_NONE, 16, 1,
1340a634090aSManuel Reinhardt 		       buf, actual_length, false);
1341a634090aSManuel Reinhardt 
1342a634090aSManuel Reinhardt 	*length = actual_length;
1343a634090aSManuel Reinhardt 	return 0;
1344a634090aSManuel Reinhardt }
1345a634090aSManuel Reinhardt 
snd_usb_motu_microbookii_boot_quirk(struct usb_device * dev)1346a634090aSManuel Reinhardt static int snd_usb_motu_microbookii_boot_quirk(struct usb_device *dev)
1347a634090aSManuel Reinhardt {
1348a634090aSManuel Reinhardt 	int err, actual_length, poll_attempts = 0;
1349a634090aSManuel Reinhardt 	static const u8 set_samplerate_seq[] = { 0x00, 0x00, 0x00, 0x00,
1350a634090aSManuel Reinhardt 						 0x00, 0x00, 0x0b, 0x14,
1351a634090aSManuel Reinhardt 						 0x00, 0x00, 0x00, 0x01 };
1352a634090aSManuel Reinhardt 	static const u8 poll_ready_seq[] = { 0x00, 0x04, 0x00, 0x00,
1353a634090aSManuel Reinhardt 					     0x00, 0x00, 0x0b, 0x18 };
1354a634090aSManuel Reinhardt 	u8 *buf = kzalloc(MICROBOOK_BUF_SIZE, GFP_KERNEL);
1355a634090aSManuel Reinhardt 
1356a634090aSManuel Reinhardt 	if (!buf)
1357a634090aSManuel Reinhardt 		return -ENOMEM;
1358a634090aSManuel Reinhardt 
1359a634090aSManuel Reinhardt 	dev_info(&dev->dev, "Waiting for MOTU Microbook II to boot up...\n");
1360a634090aSManuel Reinhardt 
1361a634090aSManuel Reinhardt 	/* First we tell the device which sample rate to use. */
1362a634090aSManuel Reinhardt 	memcpy(buf, set_samplerate_seq, sizeof(set_samplerate_seq));
1363a634090aSManuel Reinhardt 	actual_length = sizeof(set_samplerate_seq);
1364a634090aSManuel Reinhardt 	err = snd_usb_motu_microbookii_communicate(dev, buf, MICROBOOK_BUF_SIZE,
1365a634090aSManuel Reinhardt 						   &actual_length);
1366a634090aSManuel Reinhardt 
1367a634090aSManuel Reinhardt 	if (err < 0) {
1368a634090aSManuel Reinhardt 		dev_err(&dev->dev,
1369a634090aSManuel Reinhardt 			"failed setting the sample rate for Motu MicroBook II: %d\n",
1370a634090aSManuel Reinhardt 			err);
1371a634090aSManuel Reinhardt 		goto free_buf;
1372a634090aSManuel Reinhardt 	}
1373a634090aSManuel Reinhardt 
1374a634090aSManuel Reinhardt 	/* Then we poll every 100 ms until the device informs of its readiness. */
1375a634090aSManuel Reinhardt 	while (true) {
1376a634090aSManuel Reinhardt 		if (++poll_attempts > 100) {
1377a634090aSManuel Reinhardt 			dev_err(&dev->dev,
1378a634090aSManuel Reinhardt 				"failed booting Motu MicroBook II: timeout\n");
1379a634090aSManuel Reinhardt 			err = -ENODEV;
1380a634090aSManuel Reinhardt 			goto free_buf;
1381a634090aSManuel Reinhardt 		}
1382a634090aSManuel Reinhardt 
1383a634090aSManuel Reinhardt 		memset(buf, 0, MICROBOOK_BUF_SIZE);
1384a634090aSManuel Reinhardt 		memcpy(buf, poll_ready_seq, sizeof(poll_ready_seq));
1385a634090aSManuel Reinhardt 
1386a634090aSManuel Reinhardt 		actual_length = sizeof(poll_ready_seq);
1387a634090aSManuel Reinhardt 		err = snd_usb_motu_microbookii_communicate(
1388a634090aSManuel Reinhardt 			dev, buf, MICROBOOK_BUF_SIZE, &actual_length);
1389a634090aSManuel Reinhardt 		if (err < 0) {
1390a634090aSManuel Reinhardt 			dev_err(&dev->dev,
1391a634090aSManuel Reinhardt 				"failed booting Motu MicroBook II: communication error %d\n",
1392a634090aSManuel Reinhardt 				err);
1393a634090aSManuel Reinhardt 			goto free_buf;
1394a634090aSManuel Reinhardt 		}
1395a634090aSManuel Reinhardt 
1396a634090aSManuel Reinhardt 		/* the device signals its readiness through a message of the
1397a634090aSManuel Reinhardt 		 * form
1398a634090aSManuel Reinhardt 		 *           XX 06 00 00 00 00 0b 18  00 00 00 01
1399a634090aSManuel Reinhardt 		 * If the device is not yet ready to accept audio data, the
1400a634090aSManuel Reinhardt 		 * last byte of that sequence is 00.
1401a634090aSManuel Reinhardt 		 */
1402a634090aSManuel Reinhardt 		if (actual_length == 12 && buf[actual_length - 1] == 1)
1403a634090aSManuel Reinhardt 			break;
1404a634090aSManuel Reinhardt 
1405a634090aSManuel Reinhardt 		msleep(100);
1406a634090aSManuel Reinhardt 	}
1407a634090aSManuel Reinhardt 
1408a634090aSManuel Reinhardt 	dev_info(&dev->dev, "MOTU MicroBook II ready\n");
1409a634090aSManuel Reinhardt 
1410a634090aSManuel Reinhardt free_buf:
1411a634090aSManuel Reinhardt 	kfree(buf);
1412a634090aSManuel Reinhardt 	return err;
1413a634090aSManuel Reinhardt }
1414a634090aSManuel Reinhardt 
snd_usb_motu_m_series_boot_quirk(struct usb_device * dev)141573ac9f5eSAlexander Tsoy static int snd_usb_motu_m_series_boot_quirk(struct usb_device *dev)
141673ac9f5eSAlexander Tsoy {
1417e8e214d0SJeremie Knuesel 	msleep(4000);
141873ac9f5eSAlexander Tsoy 
141973ac9f5eSAlexander Tsoy 	return 0;
142073ac9f5eSAlexander Tsoy }
142173ac9f5eSAlexander Tsoy 
142254a8c500SDaniel Mack /*
1423e5779998SDaniel Mack  * Setup quirks
1424e5779998SDaniel Mack  */
14250f5733b0SGuillaume Pellerin #define MAUDIO_SET		0x01 /* parse device_setup */
14260f5733b0SGuillaume Pellerin #define MAUDIO_SET_COMPATIBLE	0x80 /* use only "win-compatible" interfaces */
14270f5733b0SGuillaume Pellerin #define MAUDIO_SET_DTS		0x02 /* enable DTS Digital Output */
14285ff40e6dSAlexander Tsoy #define MAUDIO_SET_96K		0x04 /* 48-96kHz rate if set, 8-48kHz otherwise */
14290f5733b0SGuillaume Pellerin #define MAUDIO_SET_24B		0x08 /* 24bits sample if set, 16bits otherwise */
14300f5733b0SGuillaume Pellerin #define MAUDIO_SET_DI		0x10 /* enable Digital Input */
14310f5733b0SGuillaume Pellerin #define MAUDIO_SET_MASK		0x1f /* bit mask for setup value */
14325ff40e6dSAlexander Tsoy #define MAUDIO_SET_24B_48K_DI	 0x19 /* 24bits+48kHz+Digital Input */
14335ff40e6dSAlexander Tsoy #define MAUDIO_SET_24B_48K_NOTDI 0x09 /* 24bits+48kHz+No Digital Input */
14345ff40e6dSAlexander Tsoy #define MAUDIO_SET_16B_48K_DI	 0x11 /* 16bits+48kHz+Digital Input */
14355ff40e6dSAlexander Tsoy #define MAUDIO_SET_16B_48K_NOTDI 0x01 /* 16bits+48kHz+No Digital Input */
14360f5733b0SGuillaume Pellerin 
quattro_skip_setting_quirk(struct snd_usb_audio * chip,int iface,int altno)14370f5733b0SGuillaume Pellerin static int quattro_skip_setting_quirk(struct snd_usb_audio *chip,
14380f5733b0SGuillaume Pellerin 				      int iface, int altno)
14390f5733b0SGuillaume Pellerin {
14400f5733b0SGuillaume Pellerin 	/* Reset ALL ifaces to 0 altsetting.
14410f5733b0SGuillaume Pellerin 	 * Call it for every possible altsetting of every interface.
14420f5733b0SGuillaume Pellerin 	 */
14430f5733b0SGuillaume Pellerin 	usb_set_interface(chip->dev, iface, 0);
14440f5733b0SGuillaume Pellerin 	if (chip->setup & MAUDIO_SET) {
14450f5733b0SGuillaume Pellerin 		if (chip->setup & MAUDIO_SET_COMPATIBLE) {
14460f5733b0SGuillaume Pellerin 			if (iface != 1 && iface != 2)
14470f5733b0SGuillaume Pellerin 				return 1; /* skip all interfaces but 1 and 2 */
14480f5733b0SGuillaume Pellerin 		} else {
14490f5733b0SGuillaume Pellerin 			unsigned int mask;
14500f5733b0SGuillaume Pellerin 			if (iface == 1 || iface == 2)
14510f5733b0SGuillaume Pellerin 				return 1; /* skip interfaces 1 and 2 */
14520f5733b0SGuillaume Pellerin 			if ((chip->setup & MAUDIO_SET_96K) && altno != 1)
14530f5733b0SGuillaume Pellerin 				return 1; /* skip this altsetting */
14540f5733b0SGuillaume Pellerin 			mask = chip->setup & MAUDIO_SET_MASK;
14550f5733b0SGuillaume Pellerin 			if (mask == MAUDIO_SET_24B_48K_DI && altno != 2)
14560f5733b0SGuillaume Pellerin 				return 1; /* skip this altsetting */
14570f5733b0SGuillaume Pellerin 			if (mask == MAUDIO_SET_24B_48K_NOTDI && altno != 3)
14580f5733b0SGuillaume Pellerin 				return 1; /* skip this altsetting */
14590f5733b0SGuillaume Pellerin 			if (mask == MAUDIO_SET_16B_48K_NOTDI && altno != 4)
14600f5733b0SGuillaume Pellerin 				return 1; /* skip this altsetting */
14610f5733b0SGuillaume Pellerin 		}
14620f5733b0SGuillaume Pellerin 	}
14630ba41d91STakashi Iwai 	usb_audio_dbg(chip,
14640f5733b0SGuillaume Pellerin 		    "using altsetting %d for interface %d config %d\n",
14650f5733b0SGuillaume Pellerin 		    altno, iface, chip->setup);
14660f5733b0SGuillaume Pellerin 	return 0; /* keep this altsetting */
14670f5733b0SGuillaume Pellerin }
1468e5779998SDaniel Mack 
audiophile_skip_setting_quirk(struct snd_usb_audio * chip,int iface,int altno)1469e5779998SDaniel Mack static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
1470e5779998SDaniel Mack 					 int iface,
1471e5779998SDaniel Mack 					 int altno)
1472e5779998SDaniel Mack {
1473e5779998SDaniel Mack 	/* Reset ALL ifaces to 0 altsetting.
1474e5779998SDaniel Mack 	 * Call it for every possible altsetting of every interface.
1475e5779998SDaniel Mack 	 */
1476e5779998SDaniel Mack 	usb_set_interface(chip->dev, iface, 0);
1477e5779998SDaniel Mack 
14780f5733b0SGuillaume Pellerin 	if (chip->setup & MAUDIO_SET) {
14790f5733b0SGuillaume Pellerin 		unsigned int mask;
14800f5733b0SGuillaume Pellerin 		if ((chip->setup & MAUDIO_SET_DTS) && altno != 6)
1481e5779998SDaniel Mack 			return 1; /* skip this altsetting */
14820f5733b0SGuillaume Pellerin 		if ((chip->setup & MAUDIO_SET_96K) && altno != 1)
1483e5779998SDaniel Mack 			return 1; /* skip this altsetting */
14840f5733b0SGuillaume Pellerin 		mask = chip->setup & MAUDIO_SET_MASK;
14850f5733b0SGuillaume Pellerin 		if (mask == MAUDIO_SET_24B_48K_DI && altno != 2)
1486e5779998SDaniel Mack 			return 1; /* skip this altsetting */
14870f5733b0SGuillaume Pellerin 		if (mask == MAUDIO_SET_24B_48K_NOTDI && altno != 3)
1488e5779998SDaniel Mack 			return 1; /* skip this altsetting */
14890f5733b0SGuillaume Pellerin 		if (mask == MAUDIO_SET_16B_48K_DI && altno != 4)
1490e5779998SDaniel Mack 			return 1; /* skip this altsetting */
14910f5733b0SGuillaume Pellerin 		if (mask == MAUDIO_SET_16B_48K_NOTDI && altno != 5)
1492e5779998SDaniel Mack 			return 1; /* skip this altsetting */
1493e5779998SDaniel Mack 	}
1494e5779998SDaniel Mack 
1495e5779998SDaniel Mack 	return 0; /* keep this altsetting */
1496e5779998SDaniel Mack }
1497e5779998SDaniel Mack 
fasttrackpro_skip_setting_quirk(struct snd_usb_audio * chip,int iface,int altno)14980f5733b0SGuillaume Pellerin static int fasttrackpro_skip_setting_quirk(struct snd_usb_audio *chip,
14990f5733b0SGuillaume Pellerin 					   int iface, int altno)
15000f5733b0SGuillaume Pellerin {
15010f5733b0SGuillaume Pellerin 	/* Reset ALL ifaces to 0 altsetting.
15020f5733b0SGuillaume Pellerin 	 * Call it for every possible altsetting of every interface.
15030f5733b0SGuillaume Pellerin 	 */
15040f5733b0SGuillaume Pellerin 	usb_set_interface(chip->dev, iface, 0);
15050f5733b0SGuillaume Pellerin 
15060f5733b0SGuillaume Pellerin 	/* possible configuration where both inputs and only one output is
15070f5733b0SGuillaume Pellerin 	 *used is not supported by the current setup
15080f5733b0SGuillaume Pellerin 	 */
15090f5733b0SGuillaume Pellerin 	if (chip->setup & (MAUDIO_SET | MAUDIO_SET_24B)) {
15100f5733b0SGuillaume Pellerin 		if (chip->setup & MAUDIO_SET_96K) {
15110f5733b0SGuillaume Pellerin 			if (altno != 3 && altno != 6)
15120f5733b0SGuillaume Pellerin 				return 1;
15130f5733b0SGuillaume Pellerin 		} else if (chip->setup & MAUDIO_SET_DI) {
15140f5733b0SGuillaume Pellerin 			if (iface == 4)
15150f5733b0SGuillaume Pellerin 				return 1; /* no analog input */
15160f5733b0SGuillaume Pellerin 			if (altno != 2 && altno != 5)
15170f5733b0SGuillaume Pellerin 				return 1; /* enable only altsets 2 and 5 */
15180f5733b0SGuillaume Pellerin 		} else {
15190f5733b0SGuillaume Pellerin 			if (iface == 5)
15200f5733b0SGuillaume Pellerin 				return 1; /* disable digialt input */
15210f5733b0SGuillaume Pellerin 			if (altno != 2 && altno != 5)
15220f5733b0SGuillaume Pellerin 				return 1; /* enalbe only altsets 2 and 5 */
15230f5733b0SGuillaume Pellerin 		}
15240f5733b0SGuillaume Pellerin 	} else {
15250f5733b0SGuillaume Pellerin 		/* keep only 16-Bit mode */
15260f5733b0SGuillaume Pellerin 		if (altno != 1)
15270f5733b0SGuillaume Pellerin 			return 1;
15280f5733b0SGuillaume Pellerin 	}
15290f5733b0SGuillaume Pellerin 
15300ba41d91STakashi Iwai 	usb_audio_dbg(chip,
15310f5733b0SGuillaume Pellerin 		    "using altsetting %d for interface %d config %d\n",
15320f5733b0SGuillaume Pellerin 		    altno, iface, chip->setup);
15330f5733b0SGuillaume Pellerin 	return 0; /* keep this altsetting */
15340f5733b0SGuillaume Pellerin }
15350f5733b0SGuillaume Pellerin 
s1810c_skip_setting_quirk(struct snd_usb_audio * chip,int iface,int altno)15368dc5efe3SNick Kossifidis static int s1810c_skip_setting_quirk(struct snd_usb_audio *chip,
15378dc5efe3SNick Kossifidis 					   int iface, int altno)
15388dc5efe3SNick Kossifidis {
15398dc5efe3SNick Kossifidis 	/*
15408dc5efe3SNick Kossifidis 	 * Altno settings:
15418dc5efe3SNick Kossifidis 	 *
15428dc5efe3SNick Kossifidis 	 * Playback (Interface 1):
15438dc5efe3SNick Kossifidis 	 * 1: 6 Analog + 2 S/PDIF
15448dc5efe3SNick Kossifidis 	 * 2: 6 Analog + 2 S/PDIF
15458dc5efe3SNick Kossifidis 	 * 3: 6 Analog
15468dc5efe3SNick Kossifidis 	 *
15478dc5efe3SNick Kossifidis 	 * Capture (Interface 2):
15488dc5efe3SNick Kossifidis 	 * 1: 8 Analog + 2 S/PDIF + 8 ADAT
15498dc5efe3SNick Kossifidis 	 * 2: 8 Analog + 2 S/PDIF + 4 ADAT
15508dc5efe3SNick Kossifidis 	 * 3: 8 Analog
15518dc5efe3SNick Kossifidis 	 */
15528dc5efe3SNick Kossifidis 
15538dc5efe3SNick Kossifidis 	/*
15548dc5efe3SNick Kossifidis 	 * I'll leave 2 as the default one and
15558dc5efe3SNick Kossifidis 	 * use device_setup to switch to the
15568dc5efe3SNick Kossifidis 	 * other two.
15578dc5efe3SNick Kossifidis 	 */
15588dc5efe3SNick Kossifidis 	if ((chip->setup == 0 || chip->setup > 2) && altno != 2)
15598dc5efe3SNick Kossifidis 		return 1;
15608dc5efe3SNick Kossifidis 	else if (chip->setup == 1 && altno != 1)
15618dc5efe3SNick Kossifidis 		return 1;
15628dc5efe3SNick Kossifidis 	else if (chip->setup == 2 && altno != 3)
15638dc5efe3SNick Kossifidis 		return 1;
15648dc5efe3SNick Kossifidis 
15658dc5efe3SNick Kossifidis 	return 0;
15668dc5efe3SNick Kossifidis }
15678dc5efe3SNick Kossifidis 
snd_usb_apply_interface_quirk(struct snd_usb_audio * chip,int iface,int altno)1568e5779998SDaniel Mack int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
1569e5779998SDaniel Mack 				  int iface,
1570e5779998SDaniel Mack 				  int altno)
1571e5779998SDaniel Mack {
1572e5779998SDaniel Mack 	/* audiophile usb: skip altsets incompatible with device_setup */
1573e5779998SDaniel Mack 	if (chip->usb_id == USB_ID(0x0763, 0x2003))
1574e5779998SDaniel Mack 		return audiophile_skip_setting_quirk(chip, iface, altno);
15750f5733b0SGuillaume Pellerin 	/* quattro usb: skip altsets incompatible with device_setup */
15760f5733b0SGuillaume Pellerin 	if (chip->usb_id == USB_ID(0x0763, 0x2001))
15770f5733b0SGuillaume Pellerin 		return quattro_skip_setting_quirk(chip, iface, altno);
15780f5733b0SGuillaume Pellerin 	/* fasttrackpro usb: skip altsets incompatible with device_setup */
15790f5733b0SGuillaume Pellerin 	if (chip->usb_id == USB_ID(0x0763, 0x2012))
15800f5733b0SGuillaume Pellerin 		return fasttrackpro_skip_setting_quirk(chip, iface, altno);
15818dc5efe3SNick Kossifidis 	/* presonus studio 1810c: skip altsets incompatible with device_setup */
15821e583aefSTakashi Iwai 	if (chip->usb_id == USB_ID(0x194f, 0x010c))
15838dc5efe3SNick Kossifidis 		return s1810c_skip_setting_quirk(chip, iface, altno);
15848dc5efe3SNick Kossifidis 
1585e5779998SDaniel Mack 
1586e5779998SDaniel Mack 	return 0;
1587e5779998SDaniel Mack }
1588e5779998SDaniel Mack 
snd_usb_apply_boot_quirk(struct usb_device * dev,struct usb_interface * intf,const struct snd_usb_audio_quirk * quirk,unsigned int id)1589e5779998SDaniel Mack int snd_usb_apply_boot_quirk(struct usb_device *dev,
1590e5779998SDaniel Mack 			     struct usb_interface *intf,
159179289e24STakashi Iwai 			     const struct snd_usb_audio_quirk *quirk,
159279289e24STakashi Iwai 			     unsigned int id)
1593e5779998SDaniel Mack {
15943347b26cSDaniel Mack 	switch (id) {
15953347b26cSDaniel Mack 	case USB_ID(0x041e, 0x3000):
1596e5779998SDaniel Mack 		/* SB Extigy needs special boot-up sequence */
1597e5779998SDaniel Mack 		/* if more models come, this will go to the quirk list. */
1598e5779998SDaniel Mack 		return snd_usb_extigy_boot_quirk(dev, intf);
1599e5779998SDaniel Mack 
16003347b26cSDaniel Mack 	case USB_ID(0x041e, 0x3020):
1601e5779998SDaniel Mack 		/* SB Audigy 2 NX needs its own boot-up magic, too */
1602e5779998SDaniel Mack 		return snd_usb_audigy2nx_boot_quirk(dev);
1603e5779998SDaniel Mack 
16043347b26cSDaniel Mack 	case USB_ID(0x10f5, 0x0200):
1605e5779998SDaniel Mack 		/* C-Media CM106 / Turtle Beach Audio Advantage Roadie */
1606e5779998SDaniel Mack 		return snd_usb_cm106_boot_quirk(dev);
1607e5779998SDaniel Mack 
16083347b26cSDaniel Mack 	case USB_ID(0x0d8c, 0x0102):
1609e5779998SDaniel Mack 		/* C-Media CM6206 / CM106-Like Sound Device */
16108129e79eSWolfgang Breyha 	case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */
1611e5779998SDaniel Mack 		return snd_usb_cm6206_boot_quirk(dev);
1612e5779998SDaniel Mack 
1613cb99864dSDamien Zammit 	case USB_ID(0x0dba, 0x3000):
1614cb99864dSDamien Zammit 		/* Digidesign Mbox 2 */
1615cb99864dSDamien Zammit 		return snd_usb_mbox2_boot_quirk(dev);
1616b01104fcSConner Knox 	case USB_ID(0x0dba, 0x5000):
1617b01104fcSConner Knox 		/* Digidesign Mbox 3 */
1618b01104fcSConner Knox 		return snd_usb_mbox3_boot_quirk(dev);
1619b01104fcSConner Knox 
1620cb99864dSDamien Zammit 
162111e424e8SEduard Gilmutdinov 	case USB_ID(0x1235, 0x0010): /* Focusrite Novation Saffire 6 USB */
162211e424e8SEduard Gilmutdinov 	case USB_ID(0x1235, 0x0018): /* Focusrite Novation Twitch */
162311e424e8SEduard Gilmutdinov 		return snd_usb_novation_boot_quirk(dev);
16245e212332SMark Hills 
16253347b26cSDaniel Mack 	case USB_ID(0x133e, 0x0815):
1626e5779998SDaniel Mack 		/* Access Music VirusTI Desktop */
1627e5779998SDaniel Mack 		return snd_usb_accessmusic_boot_quirk(dev);
1628e5779998SDaniel Mack 
1629759e890fSDaniel Mack 	case USB_ID(0x17cc, 0x1000): /* Komplete Audio 6 */
16303347b26cSDaniel Mack 	case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */
16313347b26cSDaniel Mack 	case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */
163254a8c500SDaniel Mack 		return snd_usb_nativeinstruments_boot_quirk(dev);
16330f5733b0SGuillaume Pellerin 	case USB_ID(0x0763, 0x2012):  /* M-Audio Fast Track Pro USB */
16340f5733b0SGuillaume Pellerin 		return snd_usb_fasttrackpro_boot_quirk(dev);
163519570d74STakashi Iwai 	case USB_ID(0x047f, 0xc010): /* Plantronics Gamecom 780 */
163619570d74STakashi Iwai 		return snd_usb_gamecon780_boot_quirk(dev);
163716bafa79SAlberto Aguirre 	case USB_ID(0x2466, 0x8010): /* Fractal Audio Axe-Fx 3 */
163816bafa79SAlberto Aguirre 		return snd_usb_axefx3_boot_quirk(dev);
1639a634090aSManuel Reinhardt 	case USB_ID(0x07fd, 0x0004): /* MOTU MicroBook II */
16402edb84e3SAlexander Tsoy 		/*
16412edb84e3SAlexander Tsoy 		 * For some reason interface 3 with vendor-spec class is
16422edb84e3SAlexander Tsoy 		 * detected on MicroBook IIc.
16432edb84e3SAlexander Tsoy 		 */
16442edb84e3SAlexander Tsoy 		if (get_iface_desc(intf->altsetting)->bInterfaceClass ==
16452edb84e3SAlexander Tsoy 		    USB_CLASS_VENDOR_SPEC &&
16462edb84e3SAlexander Tsoy 		    get_iface_desc(intf->altsetting)->bInterfaceNumber < 3)
1647a634090aSManuel Reinhardt 			return snd_usb_motu_microbookii_boot_quirk(dev);
16482edb84e3SAlexander Tsoy 		break;
16493347b26cSDaniel Mack 	}
165054a8c500SDaniel Mack 
1651e5779998SDaniel Mack 	return 0;
1652e5779998SDaniel Mack }
1653e5779998SDaniel Mack 
snd_usb_apply_boot_quirk_once(struct usb_device * dev,struct usb_interface * intf,const struct snd_usb_audio_quirk * quirk,unsigned int id)165473ac9f5eSAlexander Tsoy int snd_usb_apply_boot_quirk_once(struct usb_device *dev,
165573ac9f5eSAlexander Tsoy 				  struct usb_interface *intf,
165673ac9f5eSAlexander Tsoy 				  const struct snd_usb_audio_quirk *quirk,
165773ac9f5eSAlexander Tsoy 				  unsigned int id)
165873ac9f5eSAlexander Tsoy {
165973ac9f5eSAlexander Tsoy 	switch (id) {
1660e8e214d0SJeremie Knuesel 	case USB_ID(0x07fd, 0x0008): /* MOTU M Series, 1st hardware version */
166173ac9f5eSAlexander Tsoy 		return snd_usb_motu_m_series_boot_quirk(dev);
166273ac9f5eSAlexander Tsoy 	}
166373ac9f5eSAlexander Tsoy 
166473ac9f5eSAlexander Tsoy 	return 0;
166573ac9f5eSAlexander Tsoy }
166673ac9f5eSAlexander Tsoy 
1667e5779998SDaniel Mack /*
1668e5779998SDaniel Mack  * check if the device uses big-endian samples
1669e5779998SDaniel Mack  */
snd_usb_is_big_endian_format(struct snd_usb_audio * chip,const struct audioformat * fp)1670cab941b7STakashi Iwai int snd_usb_is_big_endian_format(struct snd_usb_audio *chip,
1671cab941b7STakashi Iwai 				 const struct audioformat *fp)
1672e5779998SDaniel Mack {
167348fc7f7eSAdam Buchbinder 	/* it depends on altsetting whether the device is big-endian or not */
1674e5779998SDaniel Mack 	switch (chip->usb_id) {
1675e5779998SDaniel Mack 	case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */
16760f5733b0SGuillaume Pellerin 		if (fp->altsetting == 2 || fp->altsetting == 3 ||
16770f5733b0SGuillaume Pellerin 			fp->altsetting == 5 || fp->altsetting == 6)
1678e5779998SDaniel Mack 			return 1;
1679e5779998SDaniel Mack 		break;
1680e5779998SDaniel Mack 	case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
1681e5779998SDaniel Mack 		if (chip->setup == 0x00 ||
16820f5733b0SGuillaume Pellerin 			fp->altsetting == 1 || fp->altsetting == 2 ||
16830f5733b0SGuillaume Pellerin 			fp->altsetting == 3)
1684e5779998SDaniel Mack 			return 1;
16850f5733b0SGuillaume Pellerin 		break;
16860f5733b0SGuillaume Pellerin 	case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro */
16870f5733b0SGuillaume Pellerin 		if (fp->altsetting == 2 || fp->altsetting == 3 ||
16880f5733b0SGuillaume Pellerin 			fp->altsetting == 5 || fp->altsetting == 6)
16890f5733b0SGuillaume Pellerin 			return 1;
16900f5733b0SGuillaume Pellerin 		break;
1691e5779998SDaniel Mack 	}
1692e5779998SDaniel Mack 	return 0;
1693e5779998SDaniel Mack }
1694e5779998SDaniel Mack 
1695e5779998SDaniel Mack /*
16961cdfa9f3SJoseph Teichman  * For E-Mu 0404USB/0202USB/TrackerPre/0204 sample rate should be set for device,
1697e5779998SDaniel Mack  * not for interface.
1698e5779998SDaniel Mack  */
1699e5779998SDaniel Mack 
1700e5779998SDaniel Mack enum {
1701e5779998SDaniel Mack 	EMU_QUIRK_SR_44100HZ = 0,
1702e5779998SDaniel Mack 	EMU_QUIRK_SR_48000HZ,
1703e5779998SDaniel Mack 	EMU_QUIRK_SR_88200HZ,
1704e5779998SDaniel Mack 	EMU_QUIRK_SR_96000HZ,
1705e5779998SDaniel Mack 	EMU_QUIRK_SR_176400HZ,
1706e5779998SDaniel Mack 	EMU_QUIRK_SR_192000HZ
1707e5779998SDaniel Mack };
1708e5779998SDaniel Mack 
set_format_emu_quirk(struct snd_usb_substream * subs,const struct audioformat * fmt)1709e5779998SDaniel Mack static void set_format_emu_quirk(struct snd_usb_substream *subs,
1710cab941b7STakashi Iwai 				 const struct audioformat *fmt)
1711e5779998SDaniel Mack {
1712e5779998SDaniel Mack 	unsigned char emu_samplerate_id = 0;
1713e5779998SDaniel Mack 
1714e5779998SDaniel Mack 	/* When capture is active
1715e5779998SDaniel Mack 	 * sample rate shouldn't be changed
1716e5779998SDaniel Mack 	 * by playback substream
1717e5779998SDaniel Mack 	 */
1718e5779998SDaniel Mack 	if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
17196aa719d1STakashi Iwai 		if (subs->stream->substream[SNDRV_PCM_STREAM_CAPTURE].cur_audiofmt)
1720e5779998SDaniel Mack 			return;
1721e5779998SDaniel Mack 	}
1722e5779998SDaniel Mack 
1723e5779998SDaniel Mack 	switch (fmt->rate_min) {
1724e5779998SDaniel Mack 	case 48000:
1725e5779998SDaniel Mack 		emu_samplerate_id = EMU_QUIRK_SR_48000HZ;
1726e5779998SDaniel Mack 		break;
1727e5779998SDaniel Mack 	case 88200:
1728e5779998SDaniel Mack 		emu_samplerate_id = EMU_QUIRK_SR_88200HZ;
1729e5779998SDaniel Mack 		break;
1730e5779998SDaniel Mack 	case 96000:
1731e5779998SDaniel Mack 		emu_samplerate_id = EMU_QUIRK_SR_96000HZ;
1732e5779998SDaniel Mack 		break;
1733e5779998SDaniel Mack 	case 176400:
1734e5779998SDaniel Mack 		emu_samplerate_id = EMU_QUIRK_SR_176400HZ;
1735e5779998SDaniel Mack 		break;
1736e5779998SDaniel Mack 	case 192000:
1737e5779998SDaniel Mack 		emu_samplerate_id = EMU_QUIRK_SR_192000HZ;
1738e5779998SDaniel Mack 		break;
1739e5779998SDaniel Mack 	default:
1740e5779998SDaniel Mack 		emu_samplerate_id = EMU_QUIRK_SR_44100HZ;
1741e5779998SDaniel Mack 		break;
1742e5779998SDaniel Mack 	}
1743e5779998SDaniel Mack 	snd_emuusb_set_samplerate(subs->stream->chip, emu_samplerate_id);
17441539d4f8SCalvin Owens 	subs->pkt_offset_adj = (emu_samplerate_id >= EMU_QUIRK_SR_176400HZ) ? 4 : 0;
1745e5779998SDaniel Mack }
1746e5779998SDaniel Mack 
pioneer_djm_set_format_quirk(struct snd_usb_substream * subs,u16 windex)17473b85f5fcSOlivia Mackintosh static int pioneer_djm_set_format_quirk(struct snd_usb_substream *subs,
17483b85f5fcSOlivia Mackintosh 					u16 windex)
17493b85f5fcSOlivia Mackintosh {
17503b85f5fcSOlivia Mackintosh 	unsigned int cur_rate = subs->data_endpoint->cur_rate;
17513b85f5fcSOlivia Mackintosh 	u8 sr[3];
17523b85f5fcSOlivia Mackintosh 	// Convert to little endian
17533b85f5fcSOlivia Mackintosh 	sr[0] = cur_rate & 0xff;
17543b85f5fcSOlivia Mackintosh 	sr[1] = (cur_rate >> 8) & 0xff;
17553b85f5fcSOlivia Mackintosh 	sr[2] = (cur_rate >> 16) & 0xff;
17563b85f5fcSOlivia Mackintosh 	usb_set_interface(subs->dev, 0, 1);
17573b85f5fcSOlivia Mackintosh 	// we should derive windex from fmt-sync_ep but it's not set
17583b85f5fcSOlivia Mackintosh 	snd_usb_ctl_msg(subs->stream->chip->dev,
17592c911900SNicolas MURE 		usb_sndctrlpipe(subs->stream->chip->dev, 0),
17603b85f5fcSOlivia Mackintosh 		0x01, 0x22, 0x0100, windex, &sr, 0x0003);
17613b85f5fcSOlivia Mackintosh 	return 0;
17623b85f5fcSOlivia Mackintosh }
17633b85f5fcSOlivia Mackintosh 
snd_usb_set_format_quirk(struct snd_usb_substream * subs,const struct audioformat * fmt)1764e5779998SDaniel Mack void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
1765cab941b7STakashi Iwai 			      const struct audioformat *fmt)
1766e5779998SDaniel Mack {
1767e5779998SDaniel Mack 	switch (subs->stream->chip->usb_id) {
1768e5779998SDaniel Mack 	case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
1769e5779998SDaniel Mack 	case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
1770e5779998SDaniel Mack 	case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
17711cdfa9f3SJoseph Teichman 	case USB_ID(0x041e, 0x3f19): /* E-Mu 0204 USB */
1772e5779998SDaniel Mack 		set_format_emu_quirk(subs, fmt);
1773e5779998SDaniel Mack 		break;
17746e2c9105SJohn Veness 	case USB_ID(0x534d, 0x0021): /* MacroSilicon MS2100/MS2106 */
17751b7ecc24SHector Martin 	case USB_ID(0x534d, 0x2109): /* MacroSilicon MS2109 */
17761b7ecc24SHector Martin 		subs->stream_offset_adj = 2;
17771b7ecc24SHector Martin 		break;
1778*e9839cf1SDmitry Panchenko 	case USB_ID(0x2b73, 0x000a): /* Pioneer DJM-900NXS2 */
17793b85f5fcSOlivia Mackintosh 	case USB_ID(0x2b73, 0x0013): /* Pioneer DJM-450 */
17803b85f5fcSOlivia Mackintosh 		pioneer_djm_set_format_quirk(subs, 0x0082);
17813b85f5fcSOlivia Mackintosh 		break;
1782e7df7df5SOlivia Mackintosh 	case USB_ID(0x08e4, 0x017f): /* Pioneer DJM-750 */
17831a2a94a4SNicolas MURE 	case USB_ID(0x08e4, 0x0163): /* Pioneer DJM-850 */
17841a2a94a4SNicolas MURE 		pioneer_djm_set_format_quirk(subs, 0x0086);
17851a2a94a4SNicolas MURE 		break;
1786e5779998SDaniel Mack 	}
1787e5779998SDaniel Mack }
1788e5779998SDaniel Mack 
snd_usb_select_mode_quirk(struct snd_usb_audio * chip,const struct audioformat * fmt)1789d767aba2STakashi Iwai int snd_usb_select_mode_quirk(struct snd_usb_audio *chip,
1790cab941b7STakashi Iwai 			      const struct audioformat *fmt)
17916874daadSJurgen Kramer {
1792d767aba2STakashi Iwai 	struct usb_device *dev = chip->dev;
17936874daadSJurgen Kramer 	int err;
17946874daadSJurgen Kramer 
17952de00d5aSTakashi Iwai 	if (chip->quirk_flags & QUIRK_FLAG_ITF_USB_DSD_DAC) {
17966874daadSJurgen Kramer 		/* First switch to alt set 0, otherwise the mode switch cmd
17976874daadSJurgen Kramer 		 * will not be accepted by the DAC
17986874daadSJurgen Kramer 		 */
17996874daadSJurgen Kramer 		err = usb_set_interface(dev, fmt->iface, 0);
18006874daadSJurgen Kramer 		if (err < 0)
18016874daadSJurgen Kramer 			return err;
18026874daadSJurgen Kramer 
1803df3f0347SJia-Ju Bai 		msleep(20); /* Delay needed after setting the interface */
18046874daadSJurgen Kramer 
18057f38ca04SNobutaka Okabe 		/* Vendor mode switch cmd is required. */
1806f3b906d7SNobutaka Okabe 		if (fmt->formats & SNDRV_PCM_FMTBIT_DSD_U32_BE) {
1807f3b906d7SNobutaka Okabe 			/* DSD mode (DSD_U32) requested */
18087f38ca04SNobutaka Okabe 			err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0,
18097f38ca04SNobutaka Okabe 					      USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
18107f38ca04SNobutaka Okabe 					      1, 1, NULL, 0);
18117f38ca04SNobutaka Okabe 			if (err < 0)
18127f38ca04SNobutaka Okabe 				return err;
18137f38ca04SNobutaka Okabe 
1814f3b906d7SNobutaka Okabe 		} else {
1815f3b906d7SNobutaka Okabe 			/* PCM or DOP mode (S32) requested */
1816f3b906d7SNobutaka Okabe 			/* PCM mode (S16) requested */
18177f38ca04SNobutaka Okabe 			err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0,
18187f38ca04SNobutaka Okabe 					      USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
18197f38ca04SNobutaka Okabe 					      0, 1, NULL, 0);
18207f38ca04SNobutaka Okabe 			if (err < 0)
18217f38ca04SNobutaka Okabe 				return err;
1822f3b906d7SNobutaka Okabe 
18237f38ca04SNobutaka Okabe 		}
1824df3f0347SJia-Ju Bai 		msleep(20);
18256874daadSJurgen Kramer 	}
18266874daadSJurgen Kramer 	return 0;
18276874daadSJurgen Kramer }
18286874daadSJurgen Kramer 
snd_usb_endpoint_start_quirk(struct snd_usb_endpoint * ep)18292b58fd5bSDaniel Mack void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep)
18302b58fd5bSDaniel Mack {
18312b58fd5bSDaniel Mack 	/*
18322b58fd5bSDaniel Mack 	 * "Playback Design" products send bogus feedback data at the start
18332b58fd5bSDaniel Mack 	 * of the stream. Ignore them.
18342b58fd5bSDaniel Mack 	 */
183579289e24STakashi Iwai 	if (USB_ID_VENDOR(ep->chip->usb_id) == 0x23ba &&
18362b58fd5bSDaniel Mack 	    ep->type == SND_USB_ENDPOINT_TYPE_SYNC)
18372b58fd5bSDaniel Mack 		ep->skip_packets = 4;
183883e3acd4SEldad Zack 
183983e3acd4SEldad Zack 	/*
1840e9a25e04SMatt Gruskin 	 * M-Audio Fast Track C400/C600 - when packets are not skipped, real
18415ff40e6dSAlexander Tsoy 	 * world latency varies by approx. +/- 50 frames (at 96kHz) each time
1842e9a25e04SMatt Gruskin 	 * the stream is (re)started. When skipping packets 16 at endpoint
1843e9a25e04SMatt Gruskin 	 * start up, the real world latency is stable within +/- 1 frame (also
184483e3acd4SEldad Zack 	 * across power cycles).
184583e3acd4SEldad Zack 	 */
1846e9a25e04SMatt Gruskin 	if ((ep->chip->usb_id == USB_ID(0x0763, 0x2030) ||
1847e9a25e04SMatt Gruskin 	     ep->chip->usb_id == USB_ID(0x0763, 0x2031)) &&
184883e3acd4SEldad Zack 	    ep->type == SND_USB_ENDPOINT_TYPE_DATA)
184983e3acd4SEldad Zack 		ep->skip_packets = 16;
18509abc1341SDaniel Mack 
18519abc1341SDaniel Mack 	/* Work around devices that report unreasonable feedback data */
1852ca0dd273SDaniel Mack 	if ((ep->chip->usb_id == USB_ID(0x0644, 0x8038) ||  /* TEAC UD-H01 */
1853ca0dd273SDaniel Mack 	     ep->chip->usb_id == USB_ID(0x1852, 0x5034)) && /* T+A Dac8 */
18549abc1341SDaniel Mack 	    ep->syncmaxsize == 4)
1855ca0dd273SDaniel Mack 		ep->tenor_fb_quirk = 1;
18562b58fd5bSDaniel Mack }
18572b58fd5bSDaniel Mack 
185879289e24STakashi Iwai /* quirk applied after snd_usb_ctl_msg(); not applied during boot quirks */
snd_usb_ctl_msg_quirk(struct usb_device * dev,unsigned int pipe,__u8 request,__u8 requesttype,__u16 value,__u16 index,void * data,__u16 size)18592b58fd5bSDaniel Mack void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe,
18602b58fd5bSDaniel Mack 			   __u8 request, __u8 requesttype, __u16 value,
18612b58fd5bSDaniel Mack 			   __u16 index, void *data, __u16 size)
18622b58fd5bSDaniel Mack {
186379289e24STakashi Iwai 	struct snd_usb_audio *chip = dev_get_drvdata(&dev->dev);
186479289e24STakashi Iwai 
1865f7483854STakashi Iwai 	if (!chip || (requesttype & USB_TYPE_MASK) != USB_TYPE_CLASS)
186679289e24STakashi Iwai 		return;
18676e84a8d7SJurgen Kramer 
1868f7483854STakashi Iwai 	if (chip->quirk_flags & QUIRK_FLAG_CTL_MSG_DELAY)
1869df3f0347SJia-Ju Bai 		msleep(20);
1870f7483854STakashi Iwai 	else if (chip->quirk_flags & QUIRK_FLAG_CTL_MSG_DELAY_1M)
1871df3f0347SJia-Ju Bai 		usleep_range(1000, 2000);
1872f7483854STakashi Iwai 	else if (chip->quirk_flags & QUIRK_FLAG_CTL_MSG_DELAY_5M)
1873a32a1fc9SMacpaul Lin 		usleep_range(5000, 6000);
18742b58fd5bSDaniel Mack }
18752b58fd5bSDaniel Mack 
1876126825e7SDaniel Mack /*
1877126825e7SDaniel Mack  * snd_usb_interface_dsd_format_quirks() is called from format.c to
1878126825e7SDaniel Mack  * augment the PCM format bit-field for DSD types. The UAC standards
1879126825e7SDaniel Mack  * don't have a designated bit field to denote DSD-capable interfaces,
1880126825e7SDaniel Mack  * hence all hardware that is known to support this format has to be
1881126825e7SDaniel Mack  * listed here.
1882126825e7SDaniel Mack  */
snd_usb_interface_dsd_format_quirks(struct snd_usb_audio * chip,struct audioformat * fp,unsigned int sample_bytes)1883126825e7SDaniel Mack u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
1884126825e7SDaniel Mack 					struct audioformat *fp,
1885126825e7SDaniel Mack 					unsigned int sample_bytes)
1886126825e7SDaniel Mack {
1887f3b906d7SNobutaka Okabe 	struct usb_interface *iface;
1888f3b906d7SNobutaka Okabe 
1889126825e7SDaniel Mack 	/* Playback Designs */
1890eb7505d5SJussi Laako 	if (USB_ID_VENDOR(chip->usb_id) == 0x23ba &&
1891eb7505d5SJussi Laako 	    USB_ID_PRODUCT(chip->usb_id) < 0x0110) {
1892126825e7SDaniel Mack 		switch (fp->altsetting) {
1893126825e7SDaniel Mack 		case 1:
1894126825e7SDaniel Mack 			fp->dsd_dop = true;
1895126825e7SDaniel Mack 			return SNDRV_PCM_FMTBIT_DSD_U16_LE;
1896126825e7SDaniel Mack 		case 2:
1897126825e7SDaniel Mack 			fp->dsd_bitrev = true;
1898126825e7SDaniel Mack 			return SNDRV_PCM_FMTBIT_DSD_U8;
1899126825e7SDaniel Mack 		case 3:
1900126825e7SDaniel Mack 			fp->dsd_bitrev = true;
1901126825e7SDaniel Mack 			return SNDRV_PCM_FMTBIT_DSD_U16_LE;
1902126825e7SDaniel Mack 		}
1903126825e7SDaniel Mack 	}
1904126825e7SDaniel Mack 
1905848f3a82SJurgen Kramer 	/* XMOS based USB DACs */
1906848f3a82SJurgen Kramer 	switch (chip->usb_id) {
1907f7fea075SJussi Laako 	case USB_ID(0x139f, 0x5504): /* Nagra DAC */
1908f7fea075SJussi Laako 	case USB_ID(0x20b1, 0x3089): /* Mola-Mola DAC */
1909f7fea075SJussi Laako 	case USB_ID(0x2522, 0x0007): /* LH Labs Geek Out 1V5 */
1910f7fea075SJussi Laako 	case USB_ID(0x2522, 0x0009): /* LH Labs Geek Pulse X Inifinity 2V0 */
1911f656891cSDaniel Mack 	case USB_ID(0x2522, 0x0012): /* LH Labs VI DAC Infinity */
19129bb201a5SJussi Laako 	case USB_ID(0x2772, 0x0230): /* Pro-Ject Pre Box S2 Digital */
1913848f3a82SJurgen Kramer 		if (fp->altsetting == 2)
1914d42472ecSJussi Laako 			return SNDRV_PCM_FMTBIT_DSD_U32_BE;
1915848f3a82SJurgen Kramer 		break;
19163b7e5c7eSJurgen Kramer 
1917f656891cSDaniel Mack 	case USB_ID(0x0d8c, 0x0316): /* Hegel HD12 DSD */
1918202e69e6SJussi Laako 	case USB_ID(0x10cb, 0x0103): /* The Bit Opus #3; with fp->dsd_raw */
1919547d2c9cSTakashi Iwai 	case USB_ID(0x16d0, 0x06b2): /* NuPrime DAC-10 */
1920f7fea075SJussi Laako 	case USB_ID(0x16d0, 0x06b4): /* NuPrime Audio HD-AVP/AVA */
1921f656891cSDaniel Mack 	case USB_ID(0x16d0, 0x0733): /* Furutech ADL Stratos */
1922f7fea075SJussi Laako 	case USB_ID(0x16d0, 0x09d8): /* NuPrime IDA-8 */
1923f656891cSDaniel Mack 	case USB_ID(0x16d0, 0x09db): /* NuPrime Audio DAC-9 */
1924f7fea075SJussi Laako 	case USB_ID(0x16d0, 0x09dd): /* Encore mDSD */
1925f656891cSDaniel Mack 	case USB_ID(0x1db5, 0x0003): /* Bryston BDA3 */
1926f7fea075SJussi Laako 	case USB_ID(0x20a0, 0x4143): /* WaveIO USB Audio 2.0 */
1927f656891cSDaniel Mack 	case USB_ID(0x22e1, 0xca01): /* HDTA Serenade DSD */
1928f656891cSDaniel Mack 	case USB_ID(0x249c, 0x9326): /* M2Tech Young MkIII */
1929ad678b4cSJurgen Kramer 	case USB_ID(0x2616, 0x0106): /* PS Audio NuWave DAC */
1930f656891cSDaniel Mack 	case USB_ID(0x2622, 0x0041): /* Audiolab M-DAC+ */
1931f7fea075SJussi Laako 	case USB_ID(0x278b, 0x5100): /* Rotel RC-1590 */
1932f656891cSDaniel Mack 	case USB_ID(0x27f7, 0x3002): /* W4S DAC-2v2SE */
1933f656891cSDaniel Mack 	case USB_ID(0x29a2, 0x0086): /* Mutec MC3+ USB */
1934f656891cSDaniel Mack 	case USB_ID(0x6b42, 0x0042): /* MSB Technology */
1935848f3a82SJurgen Kramer 		if (fp->altsetting == 3)
1936d42472ecSJussi Laako 			return SNDRV_PCM_FMTBIT_DSD_U32_BE;
1937848f3a82SJurgen Kramer 		break;
19383eff682dSJussi Laako 
19397c74866bSDaniel Mack 	/* Amanero Combo384 USB based DACs with native DSD support */
19407c74866bSDaniel Mack 	case USB_ID(0x16d0, 0x071a):  /* Amanero - Combo384 */
19413eff682dSJussi Laako 		if (fp->altsetting == 2) {
1942f83914fdSJohan Hovold 			switch (le16_to_cpu(chip->dev->descriptor.bcdDevice)) {
19433eff682dSJussi Laako 			case 0x199:
19443eff682dSJussi Laako 				return SNDRV_PCM_FMTBIT_DSD_U32_LE;
19453eff682dSJussi Laako 			case 0x19b:
1946f5ce8179SJussi Laako 			case 0x203:
19473eff682dSJussi Laako 				return SNDRV_PCM_FMTBIT_DSD_U32_BE;
19483eff682dSJussi Laako 			default:
19493eff682dSJussi Laako 				break;
19503eff682dSJussi Laako 			}
19513eff682dSJussi Laako 		}
19523eff682dSJussi Laako 		break;
1953ed993c6fSJussi Laako 	case USB_ID(0x16d0, 0x0a23):
1954ed993c6fSJussi Laako 		if (fp->altsetting == 2)
1955ed993c6fSJussi Laako 			return SNDRV_PCM_FMTBIT_DSD_U32_BE;
1956ed993c6fSJussi Laako 		break;
19573eff682dSJussi Laako 
1958848f3a82SJurgen Kramer 	default:
1959848f3a82SJurgen Kramer 		break;
1960848f3a82SJurgen Kramer 	}
1961848f3a82SJurgen Kramer 
1962f3b906d7SNobutaka Okabe 	/* ITF-USB DSD based DACs */
19632de00d5aSTakashi Iwai 	if (chip->quirk_flags & QUIRK_FLAG_ITF_USB_DSD_DAC) {
1964f3b906d7SNobutaka Okabe 		iface = usb_ifnum_to_if(chip->dev, fp->iface);
19657a2e9ddcSJurgen Kramer 
1966f3b906d7SNobutaka Okabe 		/* Altsetting 2 support native DSD if the num of altsets is
1967f3b906d7SNobutaka Okabe 		 * three (0-2),
1968f3b906d7SNobutaka Okabe 		 * Altsetting 3 support native DSD if the num of altsets is
1969f3b906d7SNobutaka Okabe 		 * four (0-3).
1970f3b906d7SNobutaka Okabe 		 */
1971f3b906d7SNobutaka Okabe 		if (fp->altsetting == iface->num_altsetting - 1)
19727f38ca04SNobutaka Okabe 			return SNDRV_PCM_FMTBIT_DSD_U32_BE;
19737f38ca04SNobutaka Okabe 	}
19747f38ca04SNobutaka Okabe 
197568e851eeSTakashi Iwai 	/* Mostly generic method to detect many DSD-capable implementations */
197668e851eeSTakashi Iwai 	if ((chip->quirk_flags & QUIRK_FLAG_DSD_RAW) && fp->dsd_raw)
19773a572d94SJussi Laako 		return SNDRV_PCM_FMTBIT_DSD_U32_BE;
19783a572d94SJussi Laako 
1979126825e7SDaniel Mack 	return 0;
1980126825e7SDaniel Mack }
1981ceb18f51SRuslan Bilovol 
snd_usb_audioformat_attributes_quirk(struct snd_usb_audio * chip,struct audioformat * fp,int stream)1982ceb18f51SRuslan Bilovol void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip,
1983ceb18f51SRuslan Bilovol 					  struct audioformat *fp,
1984ceb18f51SRuslan Bilovol 					  int stream)
1985ceb18f51SRuslan Bilovol {
1986ceb18f51SRuslan Bilovol 	switch (chip->usb_id) {
1987ceb18f51SRuslan Bilovol 	case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */
1988ceb18f51SRuslan Bilovol 		/* Optoplay sets the sample rate attribute although
1989ceb18f51SRuslan Bilovol 		 * it seems not supporting it in fact.
1990ceb18f51SRuslan Bilovol 		 */
1991ceb18f51SRuslan Bilovol 		fp->attributes &= ~UAC_EP_CS_ATTR_SAMPLE_RATE;
1992ceb18f51SRuslan Bilovol 		break;
1993ceb18f51SRuslan Bilovol 	case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */
1994ceb18f51SRuslan Bilovol 	case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
1995ceb18f51SRuslan Bilovol 		/* doesn't set the sample rate attribute, but supports it */
1996ceb18f51SRuslan Bilovol 		fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
1997ceb18f51SRuslan Bilovol 		break;
1998ceb18f51SRuslan Bilovol 	case USB_ID(0x0763, 0x2001):  /* M-Audio Quattro USB */
1999ceb18f51SRuslan Bilovol 	case USB_ID(0x0763, 0x2012):  /* M-Audio Fast Track Pro USB */
2000ceb18f51SRuslan Bilovol 	case USB_ID(0x047f, 0x0ca1): /* plantronics headset */
2001ceb18f51SRuslan Bilovol 	case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is
2002ceb18f51SRuslan Bilovol 					an older model 77d:223) */
2003ceb18f51SRuslan Bilovol 	/*
2004ceb18f51SRuslan Bilovol 	 * plantronics headset and Griffin iMic have set adaptive-in
2005ceb18f51SRuslan Bilovol 	 * although it's really not...
2006ceb18f51SRuslan Bilovol 	 */
2007ceb18f51SRuslan Bilovol 		fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE;
2008ceb18f51SRuslan Bilovol 		if (stream == SNDRV_PCM_STREAM_PLAYBACK)
2009ceb18f51SRuslan Bilovol 			fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE;
2010ceb18f51SRuslan Bilovol 		else
2011ceb18f51SRuslan Bilovol 			fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC;
2012ceb18f51SRuslan Bilovol 		break;
20132edb84e3SAlexander Tsoy 	case USB_ID(0x07fd, 0x0004):  /* MOTU MicroBook IIc */
20142edb84e3SAlexander Tsoy 		/*
20152edb84e3SAlexander Tsoy 		 * MaxPacketsOnly attribute is erroneously set in endpoint
20162edb84e3SAlexander Tsoy 		 * descriptors. As a result this card produces noise with
20175ff40e6dSAlexander Tsoy 		 * all sample rates other than 96 kHz.
20182edb84e3SAlexander Tsoy 		 */
20192edb84e3SAlexander Tsoy 		fp->attributes &= ~UAC_EP_CS_ATTR_FILL_MAX;
20202edb84e3SAlexander Tsoy 		break;
202129664923SMarco Giunta 	case USB_ID(0x1224, 0x2a25):  /* Jieli Technology USB PHY 2.0 */
202229664923SMarco Giunta 		/* mic works only when ep packet size is set to wMaxPacketSize */
202329664923SMarco Giunta 		fp->attributes |= UAC_EP_CS_ATTR_FILL_MAX;
202429664923SMarco Giunta 		break;
20256a83d6f3SWhaleChang 	case USB_ID(0x3511, 0x2b1e): /* Opencomm2 UC USB Bluetooth dongle */
20266a83d6f3SWhaleChang 		/* mic works only when ep pitch control is not set */
20276a83d6f3SWhaleChang 		if (stream == SNDRV_PCM_STREAM_CAPTURE)
20286a83d6f3SWhaleChang 			fp->attributes &= ~UAC_EP_CS_ATTR_PITCH_CONTROL;
20296a83d6f3SWhaleChang 		break;
2030ceb18f51SRuslan Bilovol 	}
2031ceb18f51SRuslan Bilovol }
203255f73261SChris Wulff 
2033d8695bc5STakashi Iwai /*
20344d4dee0aSTakashi Iwai  * driver behavior quirk flags
20354d4dee0aSTakashi Iwai  */
20364d4dee0aSTakashi Iwai struct usb_audio_quirk_flags_table {
20374d4dee0aSTakashi Iwai 	u32 id;
20384d4dee0aSTakashi Iwai 	u32 flags;
20394d4dee0aSTakashi Iwai };
20404d4dee0aSTakashi Iwai 
20414d4dee0aSTakashi Iwai #define DEVICE_FLG(vid, pid, _flags) \
20424d4dee0aSTakashi Iwai 	{ .id = USB_ID(vid, pid), .flags = (_flags) }
20434d4dee0aSTakashi Iwai #define VENDOR_FLG(vid, _flags) DEVICE_FLG(vid, 0, _flags)
20444d4dee0aSTakashi Iwai 
20454d4dee0aSTakashi Iwai static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
20464d4dee0aSTakashi Iwai 	/* Device matches */
2047e639fe49STakashi Iwai 	DEVICE_FLG(0x03f0, 0x654a, /* HP 320 FHD Webcam */
204883c45de6STakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_MIC_RES_16),
20493c69dc91STakashi Iwai 	DEVICE_FLG(0x041e, 0x3000, /* Creative SB Extigy */
20503c69dc91STakashi Iwai 		   QUIRK_FLAG_IGNORE_CTL_ERROR),
20514d4dee0aSTakashi Iwai 	DEVICE_FLG(0x041e, 0x4080, /* Creative Live Cam VF0610 */
20524d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
20533da43506STakashi Iwai 	DEVICE_FLG(0x045e, 0x083c, /* MS USB Link headset */
20543da43506STakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_CTL_MSG_DELAY |
20553da43506STakashi Iwai 		   QUIRK_FLAG_DISABLE_AUTOSUSPEND),
205683c45de6STakashi Iwai 	DEVICE_FLG(0x046d, 0x0807, /* Logitech Webcam C500 */
205783c45de6STakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_MIC_RES_384),
205883c45de6STakashi Iwai 	DEVICE_FLG(0x046d, 0x0808, /* Logitech Webcam C600 */
205983c45de6STakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_MIC_RES_384),
206083c45de6STakashi Iwai 	DEVICE_FLG(0x046d, 0x0809,
206183c45de6STakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_MIC_RES_384),
206283c45de6STakashi Iwai 	DEVICE_FLG(0x046d, 0x0819, /* Logitech Webcam C210 */
206383c45de6STakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_MIC_RES_384),
206483c45de6STakashi Iwai 	DEVICE_FLG(0x046d, 0x081b, /* HD Webcam c310 */
206583c45de6STakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_MIC_RES_384),
206683c45de6STakashi Iwai 	DEVICE_FLG(0x046d, 0x081d, /* HD Webcam c510 */
206783c45de6STakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_MIC_RES_384),
206883c45de6STakashi Iwai 	DEVICE_FLG(0x046d, 0x0825, /* HD Webcam c270 */
206983c45de6STakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_MIC_RES_384),
207083c45de6STakashi Iwai 	DEVICE_FLG(0x046d, 0x0826, /* HD Webcam c525 */
207183c45de6STakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_MIC_RES_384),
20724d4dee0aSTakashi Iwai 	DEVICE_FLG(0x046d, 0x084c, /* Logitech ConferenceCam Connect */
2073f7483854STakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_CTL_MSG_DELAY_1M),
207483c45de6STakashi Iwai 	DEVICE_FLG(0x046d, 0x08ca, /* Logitech Quickcam Fusion */
207583c45de6STakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_MIC_RES_384),
20763c69dc91STakashi Iwai 	DEVICE_FLG(0x046d, 0x0991, /* Logitech QuickCam Pro */
207783c45de6STakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_IGNORE_CTL_ERROR |
207883c45de6STakashi Iwai 		   QUIRK_FLAG_MIC_RES_384),
207983c45de6STakashi Iwai 	DEVICE_FLG(0x046d, 0x09a2, /* QuickCam Communicate Deluxe/S7500 */
208083c45de6STakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_MIC_RES_384),
20813c69dc91STakashi Iwai 	DEVICE_FLG(0x046d, 0x09a4, /* Logitech QuickCam E 3500 */
20823c69dc91STakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_IGNORE_CTL_ERROR),
2083e6c33847SJaakko Salo 	DEVICE_FLG(0x0499, 0x1506, /* Yamaha THR5 */
2084e6c33847SJaakko Salo 		   QUIRK_FLAG_GENERIC_IMPLICIT_FB),
208567d64069STakashi Iwai 	DEVICE_FLG(0x0499, 0x1509, /* Steinberg UR22 */
208667d64069STakashi Iwai 		   QUIRK_FLAG_GENERIC_IMPLICIT_FB),
208749ab71baSJulian Sikorski 	DEVICE_FLG(0x0499, 0x3108, /* Yamaha YIT-W12TX */
208849ab71baSJulian Sikorski 		   QUIRK_FLAG_GET_SAMPLE_RATE),
20894d4dee0aSTakashi Iwai 	DEVICE_FLG(0x04d8, 0xfeea, /* Benchmark DAC1 Pre */
20904d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
2091f21dca85STakashi Iwai 	DEVICE_FLG(0x04e8, 0xa051, /* Samsung USBC Headset (AKG) */
2092f7483854STakashi Iwai 		   QUIRK_FLAG_SKIP_CLOCK_SELECTOR | QUIRK_FLAG_CTL_MSG_DELAY_5M),
20932fbdc116STakashi Iwai 	DEVICE_FLG(0x0525, 0xa4ad, /* Hamedal C20 usb camero */
20942fbdc116STakashi Iwai 		   QUIRK_FLAG_IFACE_SKIP_CLOSE),
20956e413409STakashi Iwai 	DEVICE_FLG(0x054c, 0x0b8c, /* Sony WALKMAN NW-A45 DAC */
20966e413409STakashi Iwai 		   QUIRK_FLAG_SET_IFACE_FIRST),
20974d4dee0aSTakashi Iwai 	DEVICE_FLG(0x0556, 0x0014, /* Phoenix Audio TMX320VC */
20984d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
20994d4dee0aSTakashi Iwai 	DEVICE_FLG(0x05a3, 0x9420, /* ELP HD USB Camera */
21004d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
21014d4dee0aSTakashi Iwai 	DEVICE_FLG(0x05a7, 0x1020, /* Bose Companion 5 */
21024d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
2103af158a7fSTakashi Iwai 	DEVICE_FLG(0x05e1, 0x0408, /* Syntek STK1160 */
2104af158a7fSTakashi Iwai 		   QUIRK_FLAG_ALIGN_TRANSFER),
2105ce47d47eSTakashi Iwai 	DEVICE_FLG(0x05e1, 0x0480, /* Hauppauge Woodbury */
2106af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
21072de00d5aSTakashi Iwai 	DEVICE_FLG(0x0644, 0x8043, /* TEAC UD-501/UD-501V2/UD-503/NT-503 */
21081f074fe5STakashi Iwai 		   QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY |
21091f074fe5STakashi Iwai 		   QUIRK_FLAG_IFACE_DELAY),
21102de00d5aSTakashi Iwai 	DEVICE_FLG(0x0644, 0x8044, /* Esoteric D-05X */
21111f074fe5STakashi Iwai 		   QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY |
21121f074fe5STakashi Iwai 		   QUIRK_FLAG_IFACE_DELAY),
21132de00d5aSTakashi Iwai 	DEVICE_FLG(0x0644, 0x804a, /* TEAC UD-301 */
21141f074fe5STakashi Iwai 		   QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY |
21151f074fe5STakashi Iwai 		   QUIRK_FLAG_IFACE_DELAY),
211667df411dSJohn Keeping 	DEVICE_FLG(0x0644, 0x805f, /* TEAC Model 12 */
211767df411dSJohn Keeping 		   QUIRK_FLAG_FORCE_IFACE_RESET),
2118f7fea075SJussi Laako 	DEVICE_FLG(0x0644, 0x806b, /* TEAC UD-701 */
2119f7fea075SJussi Laako 		   QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY |
2120f7fea075SJussi Laako 		   QUIRK_FLAG_IFACE_DELAY),
21213c69dc91STakashi Iwai 	DEVICE_FLG(0x06f8, 0xb000, /* Hercules DJ Console (Windows Edition) */
21223c69dc91STakashi Iwai 		   QUIRK_FLAG_IGNORE_CTL_ERROR),
21233c69dc91STakashi Iwai 	DEVICE_FLG(0x06f8, 0xd002, /* Hercules DJ Console (Macintosh Edition) */
21243c69dc91STakashi Iwai 		   QUIRK_FLAG_IGNORE_CTL_ERROR),
2125d7be2138SForest Crossman 	DEVICE_FLG(0x0711, 0x5800, /* MCT Trigger 5 USB-to-HDMI */
2126d7be2138SForest Crossman 		   QUIRK_FLAG_GET_SAMPLE_RATE),
21274d4dee0aSTakashi Iwai 	DEVICE_FLG(0x074d, 0x3553, /* Outlaw RR2150 (Micronas UAC3553B) */
21284d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
212967d64069STakashi Iwai 	DEVICE_FLG(0x0763, 0x2030, /* M-Audio Fast Track C400 */
213067d64069STakashi Iwai 		   QUIRK_FLAG_GENERIC_IMPLICIT_FB),
213167d64069STakashi Iwai 	DEVICE_FLG(0x0763, 0x2031, /* M-Audio Fast Track C600 */
213267d64069STakashi Iwai 		   QUIRK_FLAG_GENERIC_IMPLICIT_FB),
2133790053c7SAlexander Tsoy 	DEVICE_FLG(0x07fd, 0x000b, /* MOTU M Series 2nd hardware revision */
2134790053c7SAlexander Tsoy 		   QUIRK_FLAG_CTL_MSG_DELAY_1M),
21353c69dc91STakashi Iwai 	DEVICE_FLG(0x08bb, 0x2702, /* LineX FM Transmitter */
21363c69dc91STakashi Iwai 		   QUIRK_FLAG_IGNORE_CTL_ERROR),
2137f7483854STakashi Iwai 	DEVICE_FLG(0x0951, 0x16ad, /* Kingston HyperX */
2138f7483854STakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY_1M),
2139f7483854STakashi Iwai 	DEVICE_FLG(0x0b0e, 0x0349, /* Jabra 550a */
2140f7483854STakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY_1M),
2141fe3a28bfSwangdicheng 	DEVICE_FLG(0x0c45, 0x6340, /* Sonix HD USB Camera */
2142fe3a28bfSwangdicheng 		   QUIRK_FLAG_GET_SAMPLE_RATE),
2143cca07b29SLianqin Hu 	DEVICE_FLG(0x0d8c, 0x0014, /* USB Audio Device */
2144cca07b29SLianqin Hu 		   QUIRK_FLAG_CTL_MSG_DELAY_1M),
21452fbdc116STakashi Iwai 	DEVICE_FLG(0x0ecb, 0x205c, /* JBL Quantum610 Wireless */
21462fbdc116STakashi Iwai 		   QUIRK_FLAG_FIXED_RATE),
21472fbdc116STakashi Iwai 	DEVICE_FLG(0x0ecb, 0x2069, /* JBL Quantum810 Wireless */
21482fbdc116STakashi Iwai 		   QUIRK_FLAG_FIXED_RATE),
2149ce47d47eSTakashi Iwai 	DEVICE_FLG(0x0fd9, 0x0008, /* Hauppauge HVR-950Q */
2150af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
21512fbdc116STakashi Iwai 	DEVICE_FLG(0x1224, 0x2a25, /* Jieli Technology USB PHY 2.0 */
215283c45de6STakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_MIC_RES_16),
21534d4dee0aSTakashi Iwai 	DEVICE_FLG(0x1395, 0x740a, /* Sennheiser DECT */
21544d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
2155e086c37fSTakashi Iwai 	DEVICE_FLG(0x1397, 0x0507, /* Behringer UMC202HD */
2156e086c37fSTakashi Iwai 		   QUIRK_FLAG_PLAYBACK_FIRST | QUIRK_FLAG_GENERIC_IMPLICIT_FB),
2157ae8b1631STakashi Iwai 	DEVICE_FLG(0x1397, 0x0508, /* Behringer UMC204HD */
2158ae8b1631STakashi Iwai 		   QUIRK_FLAG_PLAYBACK_FIRST | QUIRK_FLAG_GENERIC_IMPLICIT_FB),
2159ae8b1631STakashi Iwai 	DEVICE_FLG(0x1397, 0x0509, /* Behringer UMC404HD */
2160ae8b1631STakashi Iwai 		   QUIRK_FLAG_PLAYBACK_FIRST | QUIRK_FLAG_GENERIC_IMPLICIT_FB),
21613c69dc91STakashi Iwai 	DEVICE_FLG(0x13e5, 0x0001, /* Serato Phono */
21623c69dc91STakashi Iwai 		   QUIRK_FLAG_IGNORE_CTL_ERROR),
21632de00d5aSTakashi Iwai 	DEVICE_FLG(0x154e, 0x1002, /* Denon DCD-1500RE */
2164f7483854STakashi Iwai 		   QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY),
21652de00d5aSTakashi Iwai 	DEVICE_FLG(0x154e, 0x1003, /* Denon DA-300USB */
2166f7483854STakashi Iwai 		   QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY),
21672de00d5aSTakashi Iwai 	DEVICE_FLG(0x154e, 0x3005, /* Marantz HD-DAC1 */
2168f7483854STakashi Iwai 		   QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY),
21692de00d5aSTakashi Iwai 	DEVICE_FLG(0x154e, 0x3006, /* Marantz SA-14S1 */
2170f7483854STakashi Iwai 		   QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY),
2171f7fea075SJussi Laako 	DEVICE_FLG(0x154e, 0x300b, /* Marantz SA-KI RUBY / SA-12 */
2172f7fea075SJussi Laako 		   QUIRK_FLAG_DSD_RAW),
2173f21dca85STakashi Iwai 	DEVICE_FLG(0x154e, 0x500e, /* Denon DN-X1600 */
2174f21dca85STakashi Iwai 		   QUIRK_FLAG_IGNORE_CLOCK_SOURCE),
2175c1b034a4STakashi Iwai 	DEVICE_FLG(0x1686, 0x00dd, /* Zoom R16/24 */
2176f7483854STakashi Iwai 		   QUIRK_FLAG_TX_LENGTH | QUIRK_FLAG_CTL_MSG_DELAY_1M),
217744e6fc64STakashi Iwai 	DEVICE_FLG(0x17aa, 0x1046, /* Lenovo ThinkStation P620 Rear Line-in, Line-out and Microphone */
217844e6fc64STakashi Iwai 		   QUIRK_FLAG_DISABLE_AUTOSUSPEND),
217944e6fc64STakashi Iwai 	DEVICE_FLG(0x17aa, 0x104d, /* Lenovo ThinkStation P620 Internal Speaker + Front Headset */
218044e6fc64STakashi Iwai 		   QUIRK_FLAG_DISABLE_AUTOSUSPEND),
2181228a8b95SJan Lalinsky 	DEVICE_FLG(0x1852, 0x5062, /* Luxman D-08u */
2182228a8b95SJan Lalinsky 		   QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY),
21832de00d5aSTakashi Iwai 	DEVICE_FLG(0x1852, 0x5065, /* Luxman DA-06 */
2184f7483854STakashi Iwai 		   QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY),
21854d4dee0aSTakashi Iwai 	DEVICE_FLG(0x1901, 0x0191, /* GE B850V3 CP2114 audio interface */
21864d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
21872fbdc116STakashi Iwai 	DEVICE_FLG(0x19f7, 0x0035, /* RODE NT-USB+ */
21882fbdc116STakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
21893e81a7a9STakashi Iwai 	DEVICE_FLG(0x1bcf, 0x2281, /* HD Webcam */
219083c45de6STakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_MIC_RES_16),
21912fbdc116STakashi Iwai 	DEVICE_FLG(0x1bcf, 0x2283, /* NexiGo N930AF FHD Webcam */
219283c45de6STakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_MIC_RES_16),
2193ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x7200, /* Hauppauge HVR-950Q */
2194af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2195ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x7201, /* Hauppauge HVR-950Q-MXL */
2196af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2197ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x7210, /* Hauppauge HVR-950Q */
2198af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2199ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x7211, /* Hauppauge HVR-950Q-MXL */
2200af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2201ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x7213, /* Hauppauge HVR-950Q */
2202af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2203ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x7217, /* Hauppauge HVR-950Q */
2204af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2205ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x721b, /* Hauppauge HVR-950Q */
2206af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2207ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x721e, /* Hauppauge HVR-950Q */
2208af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2209ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x721f, /* Hauppauge HVR-950Q */
2210af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2211ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x7240, /* Hauppauge HVR-850 */
2212af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2213ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x7260, /* Hauppauge HVR-950Q */
2214af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2215ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x7270, /* Hauppauge HVR-950Q */
2216af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2217ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x7280, /* Hauppauge HVR-950Q */
2218af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2219ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x7281, /* Hauppauge HVR-950Q-MXL */
2220af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2221ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x8200, /* Hauppauge Woodbury */
2222af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
22234d4dee0aSTakashi Iwai 	DEVICE_FLG(0x21b4, 0x0081, /* AudioQuest DragonFly */
22244d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
2225f7fea075SJussi Laako 	DEVICE_FLG(0x21b4, 0x0230, /* Ayre QB-9 Twenty */
2226f7fea075SJussi Laako 		   QUIRK_FLAG_DSD_RAW),
2227f7fea075SJussi Laako 	DEVICE_FLG(0x21b4, 0x0232, /* Ayre QX-5 Twenty */
2228f7fea075SJussi Laako 		   QUIRK_FLAG_DSD_RAW),
22295f3d9e81STakashi Iwai 	DEVICE_FLG(0x2522, 0x0007, /* LH Labs Geek Out HD Audio 1V5 */
22305f3d9e81STakashi Iwai 		   QUIRK_FLAG_SET_IFACE_FIRST),
2231325370beSAdrian Ratiu 	DEVICE_FLG(0x262a, 0x9302, /* ddHiFi TC44C */
2232325370beSAdrian Ratiu 		   QUIRK_FLAG_DSD_RAW),
2233df0380b9STakashi Iwai 	DEVICE_FLG(0x2708, 0x0002, /* Audient iD14 */
2234df0380b9STakashi Iwai 		   QUIRK_FLAG_IGNORE_CTL_ERROR),
22354d4dee0aSTakashi Iwai 	DEVICE_FLG(0x2912, 0x30c8, /* Audioengine D1 */
22364d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
22372fbdc116STakashi Iwai 	DEVICE_FLG(0x2b53, 0x0023, /* Fiero SC-01 (firmware v1.0.0 @ 48 kHz) */
22382fbdc116STakashi Iwai 		   QUIRK_FLAG_GENERIC_IMPLICIT_FB),
22392fbdc116STakashi Iwai 	DEVICE_FLG(0x2b53, 0x0024, /* Fiero SC-01 (firmware v1.0.0 @ 96 kHz) */
22402fbdc116STakashi Iwai 		   QUIRK_FLAG_GENERIC_IMPLICIT_FB),
22412fbdc116STakashi Iwai 	DEVICE_FLG(0x2b53, 0x0031, /* Fiero SC-01 (firmware v1.1.0) */
22422fbdc116STakashi Iwai 		   QUIRK_FLAG_GENERIC_IMPLICIT_FB),
22439d125aabSLianqin Hu 	DEVICE_FLG(0x2d95, 0x8011, /* VIVO USB-C HEADSET */
22449d125aabSLianqin Hu 		   QUIRK_FLAG_CTL_MSG_DELAY_1M),
224582d06b81SLianqin Hu 	DEVICE_FLG(0x2d95, 0x8021, /* VIVO USB-C-XE710 HEADSET */
224682d06b81SLianqin Hu 		   QUIRK_FLAG_CTL_MSG_DELAY_1M),
22475e75091aSLianqin Hu 	DEVICE_FLG(0x2fc6, 0xf0b7, /* iBasso DC07 Pro */
22485e75091aSLianqin Hu 		   QUIRK_FLAG_CTL_MSG_DELAY_1M),
224922390ce7SGreg Kroah-Hartman 	DEVICE_FLG(0x30be, 0x0101, /* Schiit Hel */
225022390ce7SGreg Kroah-Hartman 		   QUIRK_FLAG_IGNORE_CTL_ERROR),
22514d4dee0aSTakashi Iwai 	DEVICE_FLG(0x413c, 0xa506, /* Dell AE515 sound bar */
22524d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
22536e2c9105SJohn Veness 	DEVICE_FLG(0x534d, 0x0021, /* MacroSilicon MS2100/MS2106 */
22546e2c9105SJohn Veness 		   QUIRK_FLAG_ALIGN_TRANSFER),
2255af158a7fSTakashi Iwai 	DEVICE_FLG(0x534d, 0x2109, /* MacroSilicon MS2109 */
2256af158a7fSTakashi Iwai 		   QUIRK_FLAG_ALIGN_TRANSFER),
22574d4dee0aSTakashi Iwai 
22584d4dee0aSTakashi Iwai 	/* Vendor matches */
22594d4dee0aSTakashi Iwai 	VENDOR_FLG(0x045e, /* MS Lifecam */
22604d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
2261f7483854STakashi Iwai 	VENDOR_FLG(0x046d, /* Logitech */
2262f7483854STakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY_1M),
22634d4dee0aSTakashi Iwai 	VENDOR_FLG(0x047f, /* Plantronics */
2264f7483854STakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_CTL_MSG_DELAY),
2265f7483854STakashi Iwai 	VENDOR_FLG(0x0644, /* TEAC Corp. */
22661f074fe5STakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY | QUIRK_FLAG_IFACE_DELAY),
22678bfe17adSTakashi Iwai 	VENDOR_FLG(0x07fd, /* MOTU */
22688bfe17adSTakashi Iwai 		   QUIRK_FLAG_VALIDATE_RATES),
22695963e526STakashi Iwai 	VENDOR_FLG(0x1235, /* Focusrite Novation */
22705963e526STakashi Iwai 		   QUIRK_FLAG_VALIDATE_RATES),
2271f7fea075SJussi Laako 	VENDOR_FLG(0x1511, /* AURALiC */
2272f7fea075SJussi Laako 		   QUIRK_FLAG_DSD_RAW),
227368e851eeSTakashi Iwai 	VENDOR_FLG(0x152a, /* Thesycon devices */
227468e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
2275f7fea075SJussi Laako 	VENDOR_FLG(0x18d1, /* iBasso devices */
2276f7fea075SJussi Laako 		   QUIRK_FLAG_DSD_RAW),
22774d4dee0aSTakashi Iwai 	VENDOR_FLG(0x1de7, /* Phoenix Audio */
22784d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
227968e851eeSTakashi Iwai 	VENDOR_FLG(0x20b1, /* XMOS based devices */
228068e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
2281f7fea075SJussi Laako 	VENDOR_FLG(0x21ed, /* Accuphase Laboratory */
2282f7fea075SJussi Laako 		   QUIRK_FLAG_DSD_RAW),
228368e851eeSTakashi Iwai 	VENDOR_FLG(0x22d9, /* Oppo */
228468e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
2285f7483854STakashi Iwai 	VENDOR_FLG(0x23ba, /* Playback Design */
228668e851eeSTakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY | QUIRK_FLAG_IFACE_DELAY |
228768e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
228868e851eeSTakashi Iwai 	VENDOR_FLG(0x25ce, /* Mytek devices */
228968e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
229068e851eeSTakashi Iwai 	VENDOR_FLG(0x278b, /* Rotel? */
229168e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
229268e851eeSTakashi Iwai 	VENDOR_FLG(0x292b, /* Gustard/Ess based devices */
229368e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
229468e851eeSTakashi Iwai 	VENDOR_FLG(0x2972, /* FiiO devices */
229568e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
229668e851eeSTakashi Iwai 	VENDOR_FLG(0x2ab6, /* T+A devices */
229768e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
2298aa771b1eSMax McCarthy 	VENDOR_FLG(0x2afd, /* McIntosh Laboratory, Inc. */
2299aa771b1eSMax McCarthy 		   QUIRK_FLAG_DSD_RAW),
2300f7fea075SJussi Laako 	VENDOR_FLG(0x2d87, /* Cayin device */
2301f7fea075SJussi Laako 		   QUIRK_FLAG_DSD_RAW),
2302122e2cb7SLukasz Tyl 	VENDOR_FLG(0x3336, /* HEM devices */
2303122e2cb7SLukasz Tyl 		   QUIRK_FLAG_DSD_RAW),
230468e851eeSTakashi Iwai 	VENDOR_FLG(0x3353, /* Khadas devices */
230568e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
2306f7fea075SJussi Laako 	VENDOR_FLG(0x35f4, /* MSB Technology */
2307f7fea075SJussi Laako 		   QUIRK_FLAG_DSD_RAW),
230868e851eeSTakashi Iwai 	VENDOR_FLG(0x3842, /* EVGA */
230968e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
231068e851eeSTakashi Iwai 	VENDOR_FLG(0xc502, /* HiBy devices */
231168e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
23124d4dee0aSTakashi Iwai 
23134d4dee0aSTakashi Iwai 	{} /* terminator */
23144d4dee0aSTakashi Iwai };
23154d4dee0aSTakashi Iwai 
snd_usb_init_quirk_flags(struct snd_usb_audio * chip)23164d4dee0aSTakashi Iwai void snd_usb_init_quirk_flags(struct snd_usb_audio *chip)
23174d4dee0aSTakashi Iwai {
23184d4dee0aSTakashi Iwai 	const struct usb_audio_quirk_flags_table *p;
23194d4dee0aSTakashi Iwai 
23204d4dee0aSTakashi Iwai 	for (p = quirk_flags_table; p->id; p++) {
23214d4dee0aSTakashi Iwai 		if (chip->usb_id == p->id ||
23224d4dee0aSTakashi Iwai 		    (!USB_ID_PRODUCT(p->id) &&
23234d4dee0aSTakashi Iwai 		     USB_ID_VENDOR(chip->usb_id) == USB_ID_VENDOR(p->id))) {
23244d4dee0aSTakashi Iwai 			usb_audio_dbg(chip,
23254d4dee0aSTakashi Iwai 				      "Set quirk_flags 0x%x for device %04x:%04x\n",
23264d4dee0aSTakashi Iwai 				      p->flags, USB_ID_VENDOR(chip->usb_id),
23274d4dee0aSTakashi Iwai 				      USB_ID_PRODUCT(chip->usb_id));
23284d4dee0aSTakashi Iwai 			chip->quirk_flags |= p->flags;
23294d4dee0aSTakashi Iwai 			return;
23304d4dee0aSTakashi Iwai 		}
23314d4dee0aSTakashi Iwai 	}
23324d4dee0aSTakashi Iwai }
2333