xref: /openbmc/linux/sound/usb/quirks.c (revision 82d06b81)
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;
558e5779998SDaniel Mack 	int err;
559e5779998SDaniel Mack 
560e5779998SDaniel Mack 	if (le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_OLD ||
561e5779998SDaniel Mack 	    le16_to_cpu(get_cfg_desc(config)->wTotalLength) == EXTIGY_FIRMWARE_SIZE_NEW) {
5620ba41d91STakashi Iwai 		dev_dbg(&dev->dev, "sending Extigy boot sequence...\n");
563e5779998SDaniel Mack 		/* Send message to force it to reconnect with full interface. */
564e5779998SDaniel Mack 		err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev,0),
56517d900c4SClemens Ladisch 				      0x10, 0x43, 0x0001, 0x000a, NULL, 0);
5660ba41d91STakashi Iwai 		if (err < 0)
5670ba41d91STakashi Iwai 			dev_dbg(&dev->dev, "error sending boot message: %d\n", err);
568e5779998SDaniel Mack 		err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
569e5779998SDaniel Mack 				&dev->descriptor, sizeof(dev->descriptor));
570e5779998SDaniel Mack 		config = dev->actconfig;
5710ba41d91STakashi Iwai 		if (err < 0)
5720ba41d91STakashi Iwai 			dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err);
573e5779998SDaniel Mack 		err = usb_reset_configuration(dev);
5740ba41d91STakashi Iwai 		if (err < 0)
5750ba41d91STakashi Iwai 			dev_dbg(&dev->dev, "error usb_reset_configuration: %d\n", err);
5760ba41d91STakashi Iwai 		dev_dbg(&dev->dev, "extigy_boot: new boot length = %d\n",
577e5779998SDaniel Mack 			    le16_to_cpu(get_cfg_desc(config)->wTotalLength));
578e5779998SDaniel Mack 		return -ENODEV; /* quit this anyway */
579e5779998SDaniel Mack 	}
580e5779998SDaniel Mack 	return 0;
581e5779998SDaniel Mack }
582e5779998SDaniel Mack 
snd_usb_audigy2nx_boot_quirk(struct usb_device * dev)583e5779998SDaniel Mack static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev)
584e5779998SDaniel Mack {
585e5779998SDaniel Mack 	u8 buf = 1;
586e5779998SDaniel Mack 
587e5779998SDaniel Mack 	snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), 0x2a,
588e5779998SDaniel Mack 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_OTHER,
58917d900c4SClemens Ladisch 			0, 0, &buf, 1);
590e5779998SDaniel Mack 	if (buf == 0) {
591e5779998SDaniel Mack 		snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0x29,
592e5779998SDaniel Mack 				USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
59317d900c4SClemens Ladisch 				1, 2000, NULL, 0);
594e5779998SDaniel Mack 		return -ENODEV;
595e5779998SDaniel Mack 	}
596e5779998SDaniel Mack 	return 0;
597e5779998SDaniel Mack }
598e5779998SDaniel Mack 
snd_usb_fasttrackpro_boot_quirk(struct usb_device * dev)5990f5733b0SGuillaume Pellerin static int snd_usb_fasttrackpro_boot_quirk(struct usb_device *dev)
6000f5733b0SGuillaume Pellerin {
6010f5733b0SGuillaume Pellerin 	int err;
6020f5733b0SGuillaume Pellerin 
6030f5733b0SGuillaume Pellerin 	if (dev->actconfig->desc.bConfigurationValue == 1) {
6040ba41d91STakashi Iwai 		dev_info(&dev->dev,
6050f5733b0SGuillaume Pellerin 			   "Fast Track Pro switching to config #2\n");
6060f5733b0SGuillaume Pellerin 		/* This function has to be available by the usb core module.
6070f5733b0SGuillaume Pellerin 		 * if it is not avialable the boot quirk has to be left out
6080f5733b0SGuillaume Pellerin 		 * and the configuration has to be set by udev or hotplug
6090f5733b0SGuillaume Pellerin 		 * rules
6100f5733b0SGuillaume Pellerin 		 */
6110f5733b0SGuillaume Pellerin 		err = usb_driver_set_configuration(dev, 2);
612b98ae272SDavid Henningsson 		if (err < 0)
6130ba41d91STakashi Iwai 			dev_dbg(&dev->dev,
6140ba41d91STakashi Iwai 				"error usb_driver_set_configuration: %d\n",
6150f5733b0SGuillaume Pellerin 				err);
616b98ae272SDavid Henningsson 		/* Always return an error, so that we stop creating a device
617b98ae272SDavid Henningsson 		   that will just be destroyed and recreated with a new
618b98ae272SDavid Henningsson 		   configuration */
6190f5733b0SGuillaume Pellerin 		return -ENODEV;
6200f5733b0SGuillaume Pellerin 	} else
6210ba41d91STakashi Iwai 		dev_info(&dev->dev, "Fast Track Pro config OK\n");
6220f5733b0SGuillaume Pellerin 
6230f5733b0SGuillaume Pellerin 	return 0;
6240f5733b0SGuillaume Pellerin }
6250f5733b0SGuillaume Pellerin 
626e5779998SDaniel Mack /*
627e5779998SDaniel Mack  * C-Media CM106/CM106+ have four 16-bit internal registers that are nicely
628e5779998SDaniel Mack  * documented in the device's data sheet.
629e5779998SDaniel Mack  */
snd_usb_cm106_write_int_reg(struct usb_device * dev,int reg,u16 value)630e5779998SDaniel Mack static int snd_usb_cm106_write_int_reg(struct usb_device *dev, int reg, u16 value)
631e5779998SDaniel Mack {
632e5779998SDaniel Mack 	u8 buf[4];
633e5779998SDaniel Mack 	buf[0] = 0x20;
634e5779998SDaniel Mack 	buf[1] = value & 0xff;
635e5779998SDaniel Mack 	buf[2] = (value >> 8) & 0xff;
636e5779998SDaniel Mack 	buf[3] = reg;
637e5779998SDaniel Mack 	return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_CONFIGURATION,
638e5779998SDaniel Mack 			       USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_ENDPOINT,
63917d900c4SClemens Ladisch 			       0, 0, &buf, 4);
640e5779998SDaniel Mack }
641e5779998SDaniel Mack 
snd_usb_cm106_boot_quirk(struct usb_device * dev)642e5779998SDaniel Mack static int snd_usb_cm106_boot_quirk(struct usb_device *dev)
643e5779998SDaniel Mack {
644e5779998SDaniel Mack 	/*
645e5779998SDaniel Mack 	 * Enable line-out driver mode, set headphone source to front
646e5779998SDaniel Mack 	 * channels, enable stereo mic.
647e5779998SDaniel Mack 	 */
648e5779998SDaniel Mack 	return snd_usb_cm106_write_int_reg(dev, 2, 0x8004);
649e5779998SDaniel Mack }
650e5779998SDaniel Mack 
651e5779998SDaniel Mack /*
652ad43d528SLinus Walleij  * CM6206 registers from the CM6206 datasheet rev 2.1
653e5779998SDaniel Mack  */
654ad43d528SLinus Walleij #define CM6206_REG0_DMA_MASTER BIT(15)
655ad43d528SLinus Walleij #define CM6206_REG0_SPDIFO_RATE_48K (2 << 12)
656ad43d528SLinus Walleij #define CM6206_REG0_SPDIFO_RATE_96K (7 << 12)
657ad43d528SLinus Walleij /* Bit 4 thru 11 is the S/PDIF category code */
658ad43d528SLinus Walleij #define CM6206_REG0_SPDIFO_CAT_CODE_GENERAL (0 << 4)
659ad43d528SLinus Walleij #define CM6206_REG0_SPDIFO_EMPHASIS_CD BIT(3)
660ad43d528SLinus Walleij #define CM6206_REG0_SPDIFO_COPYRIGHT_NA BIT(2)
661ad43d528SLinus Walleij #define CM6206_REG0_SPDIFO_NON_AUDIO BIT(1)
662ad43d528SLinus Walleij #define CM6206_REG0_SPDIFO_PRO_FORMAT BIT(0)
663ad43d528SLinus Walleij 
664ad43d528SLinus Walleij #define CM6206_REG1_TEST_SEL_CLK BIT(14)
665ad43d528SLinus Walleij #define CM6206_REG1_PLLBIN_EN BIT(13)
666ad43d528SLinus Walleij #define CM6206_REG1_SOFT_MUTE_EN BIT(12)
667ad43d528SLinus Walleij #define CM6206_REG1_GPIO4_OUT BIT(11)
668ad43d528SLinus Walleij #define CM6206_REG1_GPIO4_OE BIT(10)
669ad43d528SLinus Walleij #define CM6206_REG1_GPIO3_OUT BIT(9)
670ad43d528SLinus Walleij #define CM6206_REG1_GPIO3_OE BIT(8)
671ad43d528SLinus Walleij #define CM6206_REG1_GPIO2_OUT BIT(7)
672ad43d528SLinus Walleij #define CM6206_REG1_GPIO2_OE BIT(6)
673ad43d528SLinus Walleij #define CM6206_REG1_GPIO1_OUT BIT(5)
674ad43d528SLinus Walleij #define CM6206_REG1_GPIO1_OE BIT(4)
675ad43d528SLinus Walleij #define CM6206_REG1_SPDIFO_INVALID BIT(3)
676ad43d528SLinus Walleij #define CM6206_REG1_SPDIF_LOOP_EN BIT(2)
677ad43d528SLinus Walleij #define CM6206_REG1_SPDIFO_DIS BIT(1)
678ad43d528SLinus Walleij #define CM6206_REG1_SPDIFI_MIX BIT(0)
679ad43d528SLinus Walleij 
680ad43d528SLinus Walleij #define CM6206_REG2_DRIVER_ON BIT(15)
681ad43d528SLinus Walleij #define CM6206_REG2_HEADP_SEL_SIDE_CHANNELS (0 << 13)
682ad43d528SLinus Walleij #define CM6206_REG2_HEADP_SEL_SURROUND_CHANNELS (1 << 13)
683ad43d528SLinus Walleij #define CM6206_REG2_HEADP_SEL_CENTER_SUBW (2 << 13)
684ad43d528SLinus Walleij #define CM6206_REG2_HEADP_SEL_FRONT_CHANNELS (3 << 13)
685ad43d528SLinus Walleij #define CM6206_REG2_MUTE_HEADPHONE_RIGHT BIT(12)
686ad43d528SLinus Walleij #define CM6206_REG2_MUTE_HEADPHONE_LEFT BIT(11)
687ad43d528SLinus Walleij #define CM6206_REG2_MUTE_REAR_SURROUND_RIGHT BIT(10)
688ad43d528SLinus Walleij #define CM6206_REG2_MUTE_REAR_SURROUND_LEFT BIT(9)
689ad43d528SLinus Walleij #define CM6206_REG2_MUTE_SIDE_SURROUND_RIGHT BIT(8)
690ad43d528SLinus Walleij #define CM6206_REG2_MUTE_SIDE_SURROUND_LEFT BIT(7)
691ad43d528SLinus Walleij #define CM6206_REG2_MUTE_SUBWOOFER BIT(6)
692ad43d528SLinus Walleij #define CM6206_REG2_MUTE_CENTER BIT(5)
693ad43d528SLinus Walleij #define CM6206_REG2_MUTE_RIGHT_FRONT BIT(3)
694ad43d528SLinus Walleij #define CM6206_REG2_MUTE_LEFT_FRONT BIT(3)
695ad43d528SLinus Walleij #define CM6206_REG2_EN_BTL BIT(2)
696ad43d528SLinus Walleij #define CM6206_REG2_MCUCLKSEL_1_5_MHZ (0)
697ad43d528SLinus Walleij #define CM6206_REG2_MCUCLKSEL_3_MHZ (1)
698ad43d528SLinus Walleij #define CM6206_REG2_MCUCLKSEL_6_MHZ (2)
699ad43d528SLinus Walleij #define CM6206_REG2_MCUCLKSEL_12_MHZ (3)
700ad43d528SLinus Walleij 
701ad43d528SLinus Walleij /* Bit 11..13 sets the sensitivity to FLY tuner volume control VP/VD signal */
702ad43d528SLinus Walleij #define CM6206_REG3_FLYSPEED_DEFAULT (2 << 11)
703ad43d528SLinus Walleij #define CM6206_REG3_VRAP25EN BIT(10)
704ad43d528SLinus Walleij #define CM6206_REG3_MSEL1 BIT(9)
705ad43d528SLinus Walleij #define CM6206_REG3_SPDIFI_RATE_44_1K BIT(0 << 7)
706ad43d528SLinus Walleij #define CM6206_REG3_SPDIFI_RATE_48K BIT(2 << 7)
707ad43d528SLinus Walleij #define CM6206_REG3_SPDIFI_RATE_32K BIT(3 << 7)
708ad43d528SLinus Walleij #define CM6206_REG3_PINSEL BIT(6)
709ad43d528SLinus Walleij #define CM6206_REG3_FOE BIT(5)
710ad43d528SLinus Walleij #define CM6206_REG3_ROE BIT(4)
711ad43d528SLinus Walleij #define CM6206_REG3_CBOE BIT(3)
712ad43d528SLinus Walleij #define CM6206_REG3_LOSE BIT(2)
713ad43d528SLinus Walleij #define CM6206_REG3_HPOE BIT(1)
714ad43d528SLinus Walleij #define CM6206_REG3_SPDIFI_CANREC BIT(0)
715ad43d528SLinus Walleij 
716ad43d528SLinus Walleij #define CM6206_REG5_DA_RSTN BIT(13)
717ad43d528SLinus Walleij #define CM6206_REG5_AD_RSTN BIT(12)
718ad43d528SLinus Walleij #define CM6206_REG5_SPDIFO_AD2SPDO BIT(12)
719ad43d528SLinus Walleij #define CM6206_REG5_SPDIFO_SEL_FRONT (0 << 9)
720ad43d528SLinus Walleij #define CM6206_REG5_SPDIFO_SEL_SIDE_SUR (1 << 9)
721ad43d528SLinus Walleij #define CM6206_REG5_SPDIFO_SEL_CEN_LFE (2 << 9)
722ad43d528SLinus Walleij #define CM6206_REG5_SPDIFO_SEL_REAR_SUR (3 << 9)
723ad43d528SLinus Walleij #define CM6206_REG5_CODECM BIT(8)
724ad43d528SLinus Walleij #define CM6206_REG5_EN_HPF BIT(7)
725ad43d528SLinus Walleij #define CM6206_REG5_T_SEL_DSDA4 BIT(6)
726ad43d528SLinus Walleij #define CM6206_REG5_T_SEL_DSDA3 BIT(5)
727ad43d528SLinus Walleij #define CM6206_REG5_T_SEL_DSDA2 BIT(4)
728ad43d528SLinus Walleij #define CM6206_REG5_T_SEL_DSDA1 BIT(3)
729ad43d528SLinus Walleij #define CM6206_REG5_T_SEL_DSDAD_NORMAL 0
730ad43d528SLinus Walleij #define CM6206_REG5_T_SEL_DSDAD_FRONT 4
731ad43d528SLinus Walleij #define CM6206_REG5_T_SEL_DSDAD_S_SURROUND 5
732ad43d528SLinus Walleij #define CM6206_REG5_T_SEL_DSDAD_CEN_LFE 6
733ad43d528SLinus Walleij #define CM6206_REG5_T_SEL_DSDAD_R_SURROUND 7
734ad43d528SLinus Walleij 
snd_usb_cm6206_boot_quirk(struct usb_device * dev)735e5779998SDaniel Mack static int snd_usb_cm6206_boot_quirk(struct usb_device *dev)
736e5779998SDaniel Mack {
737dac8f847SDaniel Mack 	int err  = 0, reg;
738ad43d528SLinus Walleij 	int val[] = {
739ad43d528SLinus Walleij 		/*
740ad43d528SLinus Walleij 		 * Values here are chosen based on sniffing USB traffic
741ad43d528SLinus Walleij 		 * under Windows.
742ad43d528SLinus Walleij 		 *
743ad43d528SLinus Walleij 		 * REG0: DAC is master, sample rate 48kHz, no copyright
744ad43d528SLinus Walleij 		 */
745ad43d528SLinus Walleij 		CM6206_REG0_SPDIFO_RATE_48K |
746ad43d528SLinus Walleij 		CM6206_REG0_SPDIFO_COPYRIGHT_NA,
747ad43d528SLinus Walleij 		/*
748ad43d528SLinus Walleij 		 * REG1: PLL binary search enable, soft mute enable.
749ad43d528SLinus Walleij 		 */
750ad43d528SLinus Walleij 		CM6206_REG1_PLLBIN_EN |
751f5c9571eSAmadeusz Sławiński 		CM6206_REG1_SOFT_MUTE_EN,
752ad43d528SLinus Walleij 		/*
753ad43d528SLinus Walleij 		 * REG2: enable output drivers,
754ad43d528SLinus Walleij 		 * select front channels to the headphone output,
755ad43d528SLinus Walleij 		 * then mute the headphone channels, run the MCU
756ad43d528SLinus Walleij 		 * at 1.5 MHz.
757ad43d528SLinus Walleij 		 */
758ad43d528SLinus Walleij 		CM6206_REG2_DRIVER_ON |
759ad43d528SLinus Walleij 		CM6206_REG2_HEADP_SEL_FRONT_CHANNELS |
760ad43d528SLinus Walleij 		CM6206_REG2_MUTE_HEADPHONE_RIGHT |
761ad43d528SLinus Walleij 		CM6206_REG2_MUTE_HEADPHONE_LEFT,
762ad43d528SLinus Walleij 		/*
763ad43d528SLinus Walleij 		 * REG3: default flyspeed, set 2.5V mic bias
764ad43d528SLinus Walleij 		 * enable all line out ports and enable SPDIF
765ad43d528SLinus Walleij 		 */
766ad43d528SLinus Walleij 		CM6206_REG3_FLYSPEED_DEFAULT |
767ad43d528SLinus Walleij 		CM6206_REG3_VRAP25EN |
768ad43d528SLinus Walleij 		CM6206_REG3_FOE |
769ad43d528SLinus Walleij 		CM6206_REG3_ROE |
770ad43d528SLinus Walleij 		CM6206_REG3_CBOE |
771ad43d528SLinus Walleij 		CM6206_REG3_LOSE |
772ad43d528SLinus Walleij 		CM6206_REG3_HPOE |
773ad43d528SLinus Walleij 		CM6206_REG3_SPDIFI_CANREC,
774ad43d528SLinus Walleij 		/* REG4 is just a bunch of GPIO lines */
775ad43d528SLinus Walleij 		0x0000,
776ad43d528SLinus Walleij 		/* REG5: de-assert AD/DA reset signals */
777ad43d528SLinus Walleij 		CM6206_REG5_DA_RSTN |
778ad43d528SLinus Walleij 		CM6206_REG5_AD_RSTN };
779e5779998SDaniel Mack 
780e5779998SDaniel Mack 	for (reg = 0; reg < ARRAY_SIZE(val); reg++) {
781e5779998SDaniel Mack 		err = snd_usb_cm106_write_int_reg(dev, reg, val[reg]);
782e5779998SDaniel Mack 		if (err < 0)
783e5779998SDaniel Mack 			return err;
784e5779998SDaniel Mack 	}
785e5779998SDaniel Mack 
786e5779998SDaniel Mack 	return err;
787e5779998SDaniel Mack }
788e5779998SDaniel Mack 
78919570d74STakashi Iwai /* quirk for Plantronics GameCom 780 with CM6302 chip */
snd_usb_gamecon780_boot_quirk(struct usb_device * dev)79019570d74STakashi Iwai static int snd_usb_gamecon780_boot_quirk(struct usb_device *dev)
79119570d74STakashi Iwai {
79219570d74STakashi Iwai 	/* set the initial volume and don't change; other values are either
79319570d74STakashi Iwai 	 * too loud or silent due to firmware bug (bko#65251)
79419570d74STakashi Iwai 	 */
795542baf94SPaul S McSpadden 	u8 buf[2] = { 0x74, 0xe3 };
79619570d74STakashi Iwai 	return snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_SET_CUR,
79719570d74STakashi Iwai 			USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
79819570d74STakashi Iwai 			UAC_FU_VOLUME << 8, 9 << 8, buf, 2);
79919570d74STakashi Iwai }
80019570d74STakashi Iwai 
801e5779998SDaniel Mack /*
8025e212332SMark Hills  * Novation Twitch DJ controller
80311e424e8SEduard Gilmutdinov  * Focusrite Novation Saffire 6 USB audio card
8045e212332SMark Hills  */
snd_usb_novation_boot_quirk(struct usb_device * dev)80511e424e8SEduard Gilmutdinov static int snd_usb_novation_boot_quirk(struct usb_device *dev)
8065e212332SMark Hills {
8075e212332SMark Hills 	/* preemptively set up the device because otherwise the
8085e212332SMark Hills 	 * raw MIDI endpoints are not active */
8095e212332SMark Hills 	usb_set_interface(dev, 0, 1);
8105e212332SMark Hills 	return 0;
8115e212332SMark Hills }
8125e212332SMark Hills 
8135e212332SMark Hills /*
814e5779998SDaniel Mack  * This call will put the synth in "USB send" mode, i.e it will send MIDI
815e5779998SDaniel Mack  * messages through USB (this is disabled at startup). The synth will
816e5779998SDaniel Mack  * acknowledge by sending a sysex on endpoint 0x85 and by displaying a USB
817e5779998SDaniel Mack  * sign on its LCD. Values here are chosen based on sniffing USB traffic
818e5779998SDaniel Mack  * under Windows.
819e5779998SDaniel Mack  */
snd_usb_accessmusic_boot_quirk(struct usb_device * dev)820e5779998SDaniel Mack static int snd_usb_accessmusic_boot_quirk(struct usb_device *dev)
821e5779998SDaniel Mack {
822e5779998SDaniel Mack 	int err, actual_length;
823e5779998SDaniel Mack 	/* "midi send" enable */
824e5779998SDaniel Mack 	static const u8 seq[] = { 0x4e, 0x73, 0x52, 0x01 };
825801ebf10STakashi Iwai 	void *buf;
826e5779998SDaniel Mack 
827fcc2cc1fSGreg Kroah-Hartman 	if (usb_pipe_type_check(dev, usb_sndintpipe(dev, 0x05)))
828801ebf10STakashi Iwai 		return -EINVAL;
829801ebf10STakashi Iwai 	buf = kmemdup(seq, ARRAY_SIZE(seq), GFP_KERNEL);
830e5779998SDaniel Mack 	if (!buf)
831e5779998SDaniel Mack 		return -ENOMEM;
832e5779998SDaniel Mack 	err = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x05), buf,
833e5779998SDaniel Mack 			ARRAY_SIZE(seq), &actual_length, 1000);
834e5779998SDaniel Mack 	kfree(buf);
835e5779998SDaniel Mack 	if (err < 0)
836e5779998SDaniel Mack 		return err;
837e5779998SDaniel Mack 
838e5779998SDaniel Mack 	return 0;
839e5779998SDaniel Mack }
840e5779998SDaniel Mack 
841e5779998SDaniel Mack /*
84254a8c500SDaniel Mack  * Some sound cards from Native Instruments are in fact compliant to the USB
84354a8c500SDaniel Mack  * audio standard of version 2 and other approved USB standards, even though
84454a8c500SDaniel Mack  * they come up as vendor-specific device when first connected.
84554a8c500SDaniel Mack  *
84654a8c500SDaniel Mack  * However, they can be told to come up with a new set of descriptors
84754a8c500SDaniel Mack  * upon their next enumeration, and the interfaces announced by the new
84854a8c500SDaniel Mack  * descriptors will then be handled by the kernel's class drivers. As the
84954a8c500SDaniel Mack  * product ID will also change, no further checks are required.
85054a8c500SDaniel Mack  */
85154a8c500SDaniel Mack 
snd_usb_nativeinstruments_boot_quirk(struct usb_device * dev)85254a8c500SDaniel Mack static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev)
85354a8c500SDaniel Mack {
854801ebf10STakashi Iwai 	int ret;
855801ebf10STakashi Iwai 
856801ebf10STakashi Iwai 	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
85754a8c500SDaniel Mack 				  0xaf, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
858889d6684SEldad Zack 				  1, 0, NULL, 0, 1000);
85954a8c500SDaniel Mack 
86054a8c500SDaniel Mack 	if (ret < 0)
86154a8c500SDaniel Mack 		return ret;
86254a8c500SDaniel Mack 
86354a8c500SDaniel Mack 	usb_reset_device(dev);
86454a8c500SDaniel Mack 
86554a8c500SDaniel Mack 	/* return -EAGAIN, so the creation of an audio interface for this
86654a8c500SDaniel Mack 	 * temporary device is aborted. The device will reconnect with a
86754a8c500SDaniel Mack 	 * new product ID */
86854a8c500SDaniel Mack 	return -EAGAIN;
86954a8c500SDaniel Mack }
87054a8c500SDaniel Mack 
mbox2_setup_48_24_magic(struct usb_device * dev)871cb99864dSDamien Zammit static void mbox2_setup_48_24_magic(struct usb_device *dev)
872cb99864dSDamien Zammit {
873cb99864dSDamien Zammit 	u8 srate[3];
874cb99864dSDamien Zammit 	u8 temp[12];
875cb99864dSDamien Zammit 
876cb99864dSDamien Zammit 	/* Choose 48000Hz permanently */
877cb99864dSDamien Zammit 	srate[0] = 0x80;
878cb99864dSDamien Zammit 	srate[1] = 0xbb;
879cb99864dSDamien Zammit 	srate[2] = 0x00;
880cb99864dSDamien Zammit 
881cb99864dSDamien Zammit 	/* Send the magic! */
882cb99864dSDamien Zammit 	snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0),
883cb99864dSDamien Zammit 		0x01, 0x22, 0x0100, 0x0085, &temp, 0x0003);
884cb99864dSDamien Zammit 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
885cb99864dSDamien Zammit 		0x81, 0xa2, 0x0100, 0x0085, &srate, 0x0003);
886cb99864dSDamien Zammit 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
887cb99864dSDamien Zammit 		0x81, 0xa2, 0x0100, 0x0086, &srate, 0x0003);
888cb99864dSDamien Zammit 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
889cb99864dSDamien Zammit 		0x81, 0xa2, 0x0100, 0x0003, &srate, 0x0003);
890cb99864dSDamien Zammit 	return;
891cb99864dSDamien Zammit }
892cb99864dSDamien Zammit 
893cb99864dSDamien Zammit /* Digidesign Mbox 2 needs to load firmware onboard
894cb99864dSDamien Zammit  * and driver must wait a few seconds for initialisation.
895cb99864dSDamien Zammit  */
896cb99864dSDamien Zammit 
897cb99864dSDamien Zammit #define MBOX2_FIRMWARE_SIZE    646
898cb99864dSDamien Zammit #define MBOX2_BOOT_LOADING     0x01 /* Hard coded into the device */
899cb99864dSDamien Zammit #define MBOX2_BOOT_READY       0x02 /* Hard coded into the device */
900cb99864dSDamien Zammit 
snd_usb_mbox2_boot_quirk(struct usb_device * dev)901b7b435e8SDamien Zammit static int snd_usb_mbox2_boot_quirk(struct usb_device *dev)
902cb99864dSDamien Zammit {
903cb99864dSDamien Zammit 	struct usb_host_config *config = dev->actconfig;
904cb99864dSDamien Zammit 	int err;
9054909a0caSJiri Slaby 	u8 bootresponse[0x12];
906cb99864dSDamien Zammit 	int fwsize;
907cb99864dSDamien Zammit 	int count;
908cb99864dSDamien Zammit 
909cb99864dSDamien Zammit 	fwsize = le16_to_cpu(get_cfg_desc(config)->wTotalLength);
910cb99864dSDamien Zammit 
911cb99864dSDamien Zammit 	if (fwsize != MBOX2_FIRMWARE_SIZE) {
9120ba41d91STakashi Iwai 		dev_err(&dev->dev, "Invalid firmware size=%d.\n", fwsize);
913cb99864dSDamien Zammit 		return -ENODEV;
914cb99864dSDamien Zammit 	}
915cb99864dSDamien Zammit 
9160ba41d91STakashi Iwai 	dev_dbg(&dev->dev, "Sending Digidesign Mbox 2 boot sequence...\n");
917cb99864dSDamien Zammit 
918cb99864dSDamien Zammit 	count = 0;
919b7b435e8SDamien Zammit 	bootresponse[0] = MBOX2_BOOT_LOADING;
920b7b435e8SDamien Zammit 	while ((bootresponse[0] == MBOX2_BOOT_LOADING) && (count < 10)) {
921cb99864dSDamien Zammit 		msleep(500); /* 0.5 second delay */
922cb99864dSDamien Zammit 		snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0),
923cb99864dSDamien Zammit 			/* Control magic - load onboard firmware */
924cb99864dSDamien Zammit 			0x85, 0xc0, 0x0001, 0x0000, &bootresponse, 0x0012);
925b7b435e8SDamien Zammit 		if (bootresponse[0] == MBOX2_BOOT_READY)
926cb99864dSDamien Zammit 			break;
9270ba41d91STakashi Iwai 		dev_dbg(&dev->dev, "device not ready, resending boot sequence...\n");
928cb99864dSDamien Zammit 		count++;
929cb99864dSDamien Zammit 	}
930cb99864dSDamien Zammit 
931b7b435e8SDamien Zammit 	if (bootresponse[0] != MBOX2_BOOT_READY) {
9320ba41d91STakashi Iwai 		dev_err(&dev->dev, "Unknown bootresponse=%d, or timed out, ignoring device.\n", bootresponse[0]);
933cb99864dSDamien Zammit 		return -ENODEV;
934cb99864dSDamien Zammit 	}
935cb99864dSDamien Zammit 
9360ba41d91STakashi Iwai 	dev_dbg(&dev->dev, "device initialised!\n");
937cb99864dSDamien Zammit 
938cb99864dSDamien Zammit 	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
939cb99864dSDamien Zammit 		&dev->descriptor, sizeof(dev->descriptor));
940cb99864dSDamien Zammit 	config = dev->actconfig;
941cb99864dSDamien Zammit 	if (err < 0)
9420ba41d91STakashi Iwai 		dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err);
943cb99864dSDamien Zammit 
944cb99864dSDamien Zammit 	err = usb_reset_configuration(dev);
945cb99864dSDamien Zammit 	if (err < 0)
9460ba41d91STakashi Iwai 		dev_dbg(&dev->dev, "error usb_reset_configuration: %d\n", err);
9470ba41d91STakashi Iwai 	dev_dbg(&dev->dev, "mbox2_boot: new boot length = %d\n",
948cb99864dSDamien Zammit 		le16_to_cpu(get_cfg_desc(config)->wTotalLength));
949cb99864dSDamien Zammit 
950cb99864dSDamien Zammit 	mbox2_setup_48_24_magic(dev);
951cb99864dSDamien Zammit 
9520ba41d91STakashi Iwai 	dev_info(&dev->dev, "Digidesign Mbox 2: 24bit 48kHz");
953cb99864dSDamien Zammit 
954cb99864dSDamien Zammit 	return 0; /* Successful boot */
955cb99864dSDamien Zammit }
956cb99864dSDamien Zammit 
snd_usb_axefx3_boot_quirk(struct usb_device * dev)95716bafa79SAlberto Aguirre static int snd_usb_axefx3_boot_quirk(struct usb_device *dev)
95816bafa79SAlberto Aguirre {
95916bafa79SAlberto Aguirre 	int err;
96016bafa79SAlberto Aguirre 
96116bafa79SAlberto Aguirre 	dev_dbg(&dev->dev, "Waiting for Axe-Fx III to boot up...\n");
96216bafa79SAlberto Aguirre 
96316bafa79SAlberto Aguirre 	/* If the Axe-Fx III has not fully booted, it will timeout when trying
96416bafa79SAlberto Aguirre 	 * to enable the audio streaming interface. A more generous timeout is
96516bafa79SAlberto Aguirre 	 * used here to detect when the Axe-Fx III has finished booting as the
96616bafa79SAlberto Aguirre 	 * set interface message will be acked once it has
96716bafa79SAlberto Aguirre 	 */
96816bafa79SAlberto Aguirre 	err = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
96916bafa79SAlberto Aguirre 				USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE,
97016bafa79SAlberto Aguirre 				1, 1, NULL, 0, 120000);
97116bafa79SAlberto Aguirre 	if (err < 0) {
97216bafa79SAlberto Aguirre 		dev_err(&dev->dev,
97316bafa79SAlberto Aguirre 			"failed waiting for Axe-Fx III to boot: %d\n", err);
97416bafa79SAlberto Aguirre 		return err;
97516bafa79SAlberto Aguirre 	}
97616bafa79SAlberto Aguirre 
97716bafa79SAlberto Aguirre 	dev_dbg(&dev->dev, "Axe-Fx III is now ready\n");
97816bafa79SAlberto Aguirre 
97916bafa79SAlberto Aguirre 	err = usb_set_interface(dev, 1, 0);
98016bafa79SAlberto Aguirre 	if (err < 0)
98116bafa79SAlberto Aguirre 		dev_dbg(&dev->dev,
98216bafa79SAlberto Aguirre 			"error stopping Axe-Fx III interface: %d\n", err);
98316bafa79SAlberto Aguirre 
98416bafa79SAlberto Aguirre 	return 0;
98516bafa79SAlberto Aguirre }
98616bafa79SAlberto Aguirre 
mbox3_setup_48_24_magic(struct usb_device * dev)987b01104fcSConner Knox static void mbox3_setup_48_24_magic(struct usb_device *dev)
988b01104fcSConner Knox {
989b01104fcSConner Knox 	/* The Mbox 3 is "little endian" */
990b01104fcSConner Knox 	/* max volume is: 0x0000. */
991b01104fcSConner Knox 	/* min volume is: 0x0080 (shown in little endian form) */
992b01104fcSConner Knox 
993b01104fcSConner Knox 
994b01104fcSConner Knox 	/* Load 48000Hz rate into buffer */
995b01104fcSConner Knox 	u8 com_buff[4] = {0x80, 0xbb, 0x00, 0x00};
996b01104fcSConner Knox 
997b01104fcSConner Knox 	/* Set 48000Hz sample rate */
998b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
999b01104fcSConner Knox 			0x01, 0x21, 0x0100, 0x0001, &com_buff, 4);  //Is this really needed?
1000b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1001b01104fcSConner Knox 			0x01, 0x21, 0x0100, 0x8101, &com_buff, 4);
1002b01104fcSConner Knox 
1003b01104fcSConner Knox 	/* Deactivate Tuner */
1004b01104fcSConner Knox 	/* on  = 0x01*/
1005b01104fcSConner Knox 	/* off = 0x00*/
1006b01104fcSConner Knox 	com_buff[0] = 0x00;
1007b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1008b01104fcSConner Knox 		0x01, 0x21, 0x0003, 0x2001, &com_buff, 1);
1009b01104fcSConner Knox 
1010b01104fcSConner Knox 	/* Set clock source to Internal (as opposed to S/PDIF) */
1011b01104fcSConner Knox 	com_buff[0] = 0x01;
1012b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1013b01104fcSConner Knox 			1, 0x21, 0x0100, 0x8001, &com_buff, 1);
1014b01104fcSConner Knox 
1015b01104fcSConner Knox 	/* Mute the hardware loopbacks to start the device in a known state. */
1016b01104fcSConner Knox 	com_buff[0] = 0x00;
1017b01104fcSConner Knox 	com_buff[1] = 0x80;
1018b01104fcSConner Knox 	/* Analogue input 1 left channel: */
1019b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1020b01104fcSConner Knox 			1, 0x21, 0x0110, 0x4001, &com_buff, 2);
1021b01104fcSConner Knox 	/* Analogue input 1 right channel: */
1022b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1023b01104fcSConner Knox 			1, 0x21, 0x0111, 0x4001, &com_buff, 2);
1024b01104fcSConner Knox 	/* Analogue input 2 left channel: */
1025b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1026b01104fcSConner Knox 			1, 0x21, 0x0114, 0x4001, &com_buff, 2);
1027b01104fcSConner Knox 	/* Analogue input 2 right channel: */
1028b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1029b01104fcSConner Knox 			1, 0x21, 0x0115, 0x4001, &com_buff, 2);
1030b01104fcSConner Knox 	/* Analogue input 3 left channel: */
1031b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1032b01104fcSConner Knox 			1, 0x21, 0x0118, 0x4001, &com_buff, 2);
1033b01104fcSConner Knox 	/* Analogue input 3 right channel: */
1034b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1035b01104fcSConner Knox 			1, 0x21, 0x0119, 0x4001, &com_buff, 2);
1036b01104fcSConner Knox 	/* Analogue input 4 left channel: */
1037b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1038b01104fcSConner Knox 			1, 0x21, 0x011c, 0x4001, &com_buff, 2);
1039b01104fcSConner Knox 	/* Analogue input 4 right channel: */
1040b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1041b01104fcSConner Knox 			1, 0x21, 0x011d, 0x4001, &com_buff, 2);
1042b01104fcSConner Knox 
1043b01104fcSConner Knox 	/* Set software sends to output */
1044b01104fcSConner Knox 	com_buff[0] = 0x00;
1045b01104fcSConner Knox 	com_buff[1] = 0x00;
1046b01104fcSConner Knox 	/* Analogue software return 1 left channel: */
1047b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1048b01104fcSConner Knox 			1, 0x21, 0x0100, 0x4001, &com_buff, 2);
1049b01104fcSConner Knox 	com_buff[0] = 0x00;
1050b01104fcSConner Knox 	com_buff[1] = 0x80;
1051b01104fcSConner Knox 	/* Analogue software return 1 right channel: */
1052b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1053b01104fcSConner Knox 			1, 0x21, 0x0101, 0x4001, &com_buff, 2);
1054b01104fcSConner Knox 	com_buff[0] = 0x00;
1055b01104fcSConner Knox 	com_buff[1] = 0x80;
1056b01104fcSConner Knox 	/* Analogue software return 2 left channel: */
1057b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1058b01104fcSConner Knox 			1, 0x21, 0x0104, 0x4001, &com_buff, 2);
1059b01104fcSConner Knox 	com_buff[0] = 0x00;
1060b01104fcSConner Knox 	com_buff[1] = 0x00;
1061b01104fcSConner Knox 	/* Analogue software return 2 right channel: */
1062b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1063b01104fcSConner Knox 			1, 0x21, 0x0105, 0x4001, &com_buff, 2);
1064b01104fcSConner Knox 
1065b01104fcSConner Knox 	com_buff[0] = 0x00;
1066b01104fcSConner Knox 	com_buff[1] = 0x80;
1067b01104fcSConner Knox 	/* Analogue software return 3 left channel: */
1068b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1069b01104fcSConner Knox 			1, 0x21, 0x0108, 0x4001, &com_buff, 2);
1070b01104fcSConner Knox 	/* Analogue software return 3 right channel: */
1071b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1072b01104fcSConner Knox 			1, 0x21, 0x0109, 0x4001, &com_buff, 2);
1073b01104fcSConner Knox 	/* Analogue software return 4 left channel: */
1074b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1075b01104fcSConner Knox 			1, 0x21, 0x010c, 0x4001, &com_buff, 2);
1076b01104fcSConner Knox 	/* Analogue software return 4 right channel: */
1077b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1078b01104fcSConner Knox 			1, 0x21, 0x010d, 0x4001, &com_buff, 2);
1079b01104fcSConner Knox 
1080b01104fcSConner Knox 	/* Return to muting sends */
1081b01104fcSConner Knox 	com_buff[0] = 0x00;
1082b01104fcSConner Knox 	com_buff[1] = 0x80;
1083b01104fcSConner Knox 	/* Analogue fx return left channel: */
1084b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1085b01104fcSConner Knox 			1, 0x21, 0x0120, 0x4001, &com_buff, 2);
1086b01104fcSConner Knox 	/* Analogue fx return right channel: */
1087b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1088b01104fcSConner Knox 			1, 0x21, 0x0121, 0x4001, &com_buff, 2);
1089b01104fcSConner Knox 
1090b01104fcSConner Knox 	/* Analogue software input 1 fx send: */
1091b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1092b01104fcSConner Knox 			1, 0x21, 0x0100, 0x4201, &com_buff, 2);
1093b01104fcSConner Knox 	/* Analogue software input 2 fx send: */
1094b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1095b01104fcSConner Knox 			1, 0x21, 0x0101, 0x4201, &com_buff, 2);
1096b01104fcSConner Knox 	/* Analogue software input 3 fx send: */
1097b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1098b01104fcSConner Knox 			1, 0x21, 0x0102, 0x4201, &com_buff, 2);
1099b01104fcSConner Knox 	/* Analogue software input 4 fx send: */
1100b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1101b01104fcSConner Knox 			1, 0x21, 0x0103, 0x4201, &com_buff, 2);
1102b01104fcSConner Knox 	/* Analogue input 1 fx send: */
1103b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1104b01104fcSConner Knox 			1, 0x21, 0x0104, 0x4201, &com_buff, 2);
1105b01104fcSConner Knox 	/* Analogue input 2 fx send: */
1106b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1107b01104fcSConner Knox 			1, 0x21, 0x0105, 0x4201, &com_buff, 2);
1108b01104fcSConner Knox 	/* Analogue input 3 fx send: */
1109b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1110b01104fcSConner Knox 			1, 0x21, 0x0106, 0x4201, &com_buff, 2);
1111b01104fcSConner Knox 	/* Analogue input 4 fx send: */
1112b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1113b01104fcSConner Knox 			1, 0x21, 0x0107, 0x4201, &com_buff, 2);
1114b01104fcSConner Knox 
1115b01104fcSConner Knox 	/* Toggle allowing host control */
1116b01104fcSConner Knox 	com_buff[0] = 0x02;
1117b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1118b01104fcSConner Knox 			3, 0x21, 0x0000, 0x2001, &com_buff, 1);
1119b01104fcSConner Knox 
1120b01104fcSConner Knox 	/* Do not dim fx returns */
1121b01104fcSConner Knox 	com_buff[0] = 0x00;
1122b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1123b01104fcSConner Knox 			3, 0x21, 0x0002, 0x2001, &com_buff, 1);
1124b01104fcSConner Knox 
1125b01104fcSConner Knox 	/* Do not set fx returns to mono */
1126b01104fcSConner Knox 	com_buff[0] = 0x00;
1127b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1128b01104fcSConner Knox 			3, 0x21, 0x0001, 0x2001, &com_buff, 1);
1129b01104fcSConner Knox 
1130b01104fcSConner Knox 	/* Mute the S/PDIF hardware loopback
1131b01104fcSConner Knox 	 * same odd volume logic here as above
1132b01104fcSConner Knox 	 */
1133b01104fcSConner Knox 	com_buff[0] = 0x00;
1134b01104fcSConner Knox 	com_buff[1] = 0x80;
1135b01104fcSConner Knox 	/* S/PDIF hardware input 1 left channel */
1136b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1137b01104fcSConner Knox 			1, 0x21, 0x0112, 0x4001, &com_buff, 2);
1138b01104fcSConner Knox 	/* S/PDIF hardware input 1 right channel */
1139b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1140b01104fcSConner Knox 			1, 0x21, 0x0113, 0x4001, &com_buff, 2);
1141b01104fcSConner Knox 	/* S/PDIF hardware input 2 left channel */
1142b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1143b01104fcSConner Knox 			1, 0x21, 0x0116, 0x4001, &com_buff, 2);
1144b01104fcSConner Knox 	/* S/PDIF hardware input 2 right channel */
1145b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1146b01104fcSConner Knox 			1, 0x21, 0x0117, 0x4001, &com_buff, 2);
1147b01104fcSConner Knox 	/* S/PDIF hardware input 3 left channel */
1148b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1149b01104fcSConner Knox 			1, 0x21, 0x011a, 0x4001, &com_buff, 2);
1150b01104fcSConner Knox 	/* S/PDIF hardware input 3 right channel */
1151b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1152b01104fcSConner Knox 			1, 0x21, 0x011b, 0x4001, &com_buff, 2);
1153b01104fcSConner Knox 	/* S/PDIF hardware input 4 left channel */
1154b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1155b01104fcSConner Knox 			1, 0x21, 0x011e, 0x4001, &com_buff, 2);
1156b01104fcSConner Knox 	/* S/PDIF hardware input 4 right channel */
1157b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1158b01104fcSConner Knox 			1, 0x21, 0x011f, 0x4001, &com_buff, 2);
1159b01104fcSConner Knox 	/* S/PDIF software return 1 left channel */
1160b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1161b01104fcSConner Knox 			1, 0x21, 0x0102, 0x4001, &com_buff, 2);
1162b01104fcSConner Knox 	/* S/PDIF software return 1 right channel */
1163b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1164b01104fcSConner Knox 			1, 0x21, 0x0103, 0x4001, &com_buff, 2);
1165b01104fcSConner Knox 	/* S/PDIF software return 2 left channel */
1166b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1167b01104fcSConner Knox 			1, 0x21, 0x0106, 0x4001, &com_buff, 2);
1168b01104fcSConner Knox 	/* S/PDIF software return 2 right channel */
1169b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1170b01104fcSConner Knox 			1, 0x21, 0x0107, 0x4001, &com_buff, 2);
1171b01104fcSConner Knox 
1172b01104fcSConner Knox 	com_buff[0] = 0x00;
1173b01104fcSConner Knox 	com_buff[1] = 0x00;
1174b01104fcSConner Knox 	/* S/PDIF software return 3 left channel */
1175b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1176b01104fcSConner Knox 			1, 0x21, 0x010a, 0x4001, &com_buff, 2);
1177b01104fcSConner Knox 
1178b01104fcSConner Knox 	com_buff[0] = 0x00;
1179b01104fcSConner Knox 	com_buff[1] = 0x80;
1180b01104fcSConner Knox 	/* S/PDIF software return 3 right channel */
1181b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1182b01104fcSConner Knox 			1, 0x21, 0x010b, 0x4001, &com_buff, 2);
1183b01104fcSConner Knox 	/* S/PDIF software return 4 left channel */
1184b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1185b01104fcSConner Knox 			1, 0x21, 0x010e, 0x4001, &com_buff, 2);
1186b01104fcSConner Knox 
1187b01104fcSConner Knox 	com_buff[0] = 0x00;
1188b01104fcSConner Knox 	com_buff[1] = 0x00;
1189b01104fcSConner Knox 	/* S/PDIF software return 4 right channel */
1190b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1191b01104fcSConner Knox 			1, 0x21, 0x010f, 0x4001, &com_buff, 2);
1192b01104fcSConner Knox 
1193b01104fcSConner Knox 	com_buff[0] = 0x00;
1194b01104fcSConner Knox 	com_buff[1] = 0x80;
1195b01104fcSConner Knox 	/* S/PDIF fx returns left channel */
1196b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1197b01104fcSConner Knox 			1, 0x21, 0x0122, 0x4001, &com_buff, 2);
1198b01104fcSConner Knox 	/* S/PDIF fx returns right channel */
1199b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1200b01104fcSConner Knox 			1, 0x21, 0x0123, 0x4001, &com_buff, 2);
1201b01104fcSConner Knox 
1202b01104fcSConner Knox 	/* Set the dropdown "Effect" to the first option */
1203b01104fcSConner Knox 	/* Room1  = 0x00 */
1204b01104fcSConner Knox 	/* Room2  = 0x01 */
1205b01104fcSConner Knox 	/* Room3  = 0x02 */
1206b01104fcSConner Knox 	/* Hall 1 = 0x03 */
1207b01104fcSConner Knox 	/* Hall 2 = 0x04 */
1208b01104fcSConner Knox 	/* Plate  = 0x05 */
1209b01104fcSConner Knox 	/* Delay  = 0x06 */
1210b01104fcSConner Knox 	/* Echo   = 0x07 */
1211b01104fcSConner Knox 	com_buff[0] = 0x00;
1212b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1213b01104fcSConner Knox 			1, 0x21, 0x0200, 0x4301, &com_buff, 1);	/* max is 0xff */
1214b01104fcSConner Knox 	/* min is 0x00 */
1215b01104fcSConner Knox 
1216b01104fcSConner Knox 
1217b01104fcSConner Knox 	/* Set the effect duration to 0 */
1218b01104fcSConner Knox 	/* max is 0xffff */
1219b01104fcSConner Knox 	/* min is 0x0000 */
1220b01104fcSConner Knox 	com_buff[0] = 0x00;
1221b01104fcSConner Knox 	com_buff[1] = 0x00;
1222b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1223b01104fcSConner Knox 			1, 0x21, 0x0400, 0x4301, &com_buff, 2);
1224b01104fcSConner Knox 
1225b01104fcSConner Knox 	/* Set the effect volume and feedback to 0 */
1226b01104fcSConner Knox 	/* max is 0xff */
1227b01104fcSConner Knox 	/* min is 0x00 */
1228b01104fcSConner Knox 	com_buff[0] = 0x00;
1229b01104fcSConner Knox 	/* feedback: */
1230b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1231b01104fcSConner Knox 			1, 0x21, 0x0500, 0x4301, &com_buff, 1);
1232b01104fcSConner Knox 	/* volume: */
1233b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1234b01104fcSConner Knox 			1, 0x21, 0x0300, 0x4301, &com_buff, 1);
1235b01104fcSConner Knox 
1236b01104fcSConner Knox 	/* Set soft button hold duration */
1237b01104fcSConner Knox 	/* 0x03 = 250ms */
1238b01104fcSConner Knox 	/* 0x05 = 500ms DEFAULT */
1239b01104fcSConner Knox 	/* 0x08 = 750ms */
1240b01104fcSConner Knox 	/* 0x0a = 1sec */
1241b01104fcSConner Knox 	com_buff[0] = 0x05;
1242b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1243b01104fcSConner Knox 			3, 0x21, 0x0005, 0x2001, &com_buff, 1);
1244b01104fcSConner Knox 
1245b01104fcSConner Knox 	/* Use dim LEDs for button of state */
1246b01104fcSConner Knox 	com_buff[0] = 0x00;
1247b01104fcSConner Knox 	snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
1248b01104fcSConner Knox 			3, 0x21, 0x0004, 0x2001, &com_buff, 1);
1249b01104fcSConner Knox }
1250b01104fcSConner Knox 
1251b01104fcSConner Knox #define MBOX3_DESCRIPTOR_SIZE	464
1252b01104fcSConner Knox 
snd_usb_mbox3_boot_quirk(struct usb_device * dev)1253b01104fcSConner Knox static int snd_usb_mbox3_boot_quirk(struct usb_device *dev)
1254b01104fcSConner Knox {
1255b01104fcSConner Knox 	struct usb_host_config *config = dev->actconfig;
1256b01104fcSConner Knox 	int err;
1257b01104fcSConner Knox 	int descriptor_size;
1258b01104fcSConner Knox 
1259b01104fcSConner Knox 	descriptor_size = le16_to_cpu(get_cfg_desc(config)->wTotalLength);
1260b01104fcSConner Knox 
1261b01104fcSConner Knox 	if (descriptor_size != MBOX3_DESCRIPTOR_SIZE) {
1262b01104fcSConner Knox 		dev_err(&dev->dev, "Invalid descriptor size=%d.\n", descriptor_size);
1263b01104fcSConner Knox 		return -ENODEV;
1264b01104fcSConner Knox 	}
1265b01104fcSConner Knox 
1266b01104fcSConner Knox 	dev_dbg(&dev->dev, "device initialised!\n");
1267b01104fcSConner Knox 
1268b01104fcSConner Knox 	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
1269b01104fcSConner Knox 		&dev->descriptor, sizeof(dev->descriptor));
1270b01104fcSConner Knox 	config = dev->actconfig;
1271b01104fcSConner Knox 	if (err < 0)
1272b01104fcSConner Knox 		dev_dbg(&dev->dev, "error usb_get_descriptor: %d\n", err);
1273b01104fcSConner Knox 
1274b01104fcSConner Knox 	err = usb_reset_configuration(dev);
1275b01104fcSConner Knox 	if (err < 0)
1276b01104fcSConner Knox 		dev_dbg(&dev->dev, "error usb_reset_configuration: %d\n", err);
1277b01104fcSConner Knox 	dev_dbg(&dev->dev, "mbox3_boot: new boot length = %d\n",
1278b01104fcSConner Knox 		le16_to_cpu(get_cfg_desc(config)->wTotalLength));
1279b01104fcSConner Knox 
1280b01104fcSConner Knox 	mbox3_setup_48_24_magic(dev);
1281b01104fcSConner Knox 	dev_info(&dev->dev, "Digidesign Mbox 3: 24bit 48kHz");
1282b01104fcSConner Knox 
1283b01104fcSConner Knox 	return 0; /* Successful boot */
1284b01104fcSConner Knox }
1285a634090aSManuel Reinhardt 
1286a634090aSManuel Reinhardt #define MICROBOOK_BUF_SIZE 128
1287a634090aSManuel Reinhardt 
snd_usb_motu_microbookii_communicate(struct usb_device * dev,u8 * buf,int buf_size,int * length)1288a634090aSManuel Reinhardt static int snd_usb_motu_microbookii_communicate(struct usb_device *dev, u8 *buf,
1289a634090aSManuel Reinhardt 						int buf_size, int *length)
1290a634090aSManuel Reinhardt {
1291a634090aSManuel Reinhardt 	int err, actual_length;
1292a634090aSManuel Reinhardt 
1293fcc2cc1fSGreg Kroah-Hartman 	if (usb_pipe_type_check(dev, usb_sndintpipe(dev, 0x01)))
1294801ebf10STakashi Iwai 		return -EINVAL;
1295a634090aSManuel Reinhardt 	err = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x01), buf, *length,
1296a634090aSManuel Reinhardt 				&actual_length, 1000);
1297a634090aSManuel Reinhardt 	if (err < 0)
1298a634090aSManuel Reinhardt 		return err;
1299a634090aSManuel Reinhardt 
1300a634090aSManuel Reinhardt 	print_hex_dump(KERN_DEBUG, "MicroBookII snd: ", DUMP_PREFIX_NONE, 16, 1,
1301a634090aSManuel Reinhardt 		       buf, actual_length, false);
1302a634090aSManuel Reinhardt 
1303a634090aSManuel Reinhardt 	memset(buf, 0, buf_size);
1304a634090aSManuel Reinhardt 
1305fcc2cc1fSGreg Kroah-Hartman 	if (usb_pipe_type_check(dev, usb_rcvintpipe(dev, 0x82)))
1306801ebf10STakashi Iwai 		return -EINVAL;
1307a634090aSManuel Reinhardt 	err = usb_interrupt_msg(dev, usb_rcvintpipe(dev, 0x82), buf, buf_size,
1308a634090aSManuel Reinhardt 				&actual_length, 1000);
1309a634090aSManuel Reinhardt 	if (err < 0)
1310a634090aSManuel Reinhardt 		return err;
1311a634090aSManuel Reinhardt 
1312a634090aSManuel Reinhardt 	print_hex_dump(KERN_DEBUG, "MicroBookII rcv: ", DUMP_PREFIX_NONE, 16, 1,
1313a634090aSManuel Reinhardt 		       buf, actual_length, false);
1314a634090aSManuel Reinhardt 
1315a634090aSManuel Reinhardt 	*length = actual_length;
1316a634090aSManuel Reinhardt 	return 0;
1317a634090aSManuel Reinhardt }
1318a634090aSManuel Reinhardt 
snd_usb_motu_microbookii_boot_quirk(struct usb_device * dev)1319a634090aSManuel Reinhardt static int snd_usb_motu_microbookii_boot_quirk(struct usb_device *dev)
1320a634090aSManuel Reinhardt {
1321a634090aSManuel Reinhardt 	int err, actual_length, poll_attempts = 0;
1322a634090aSManuel Reinhardt 	static const u8 set_samplerate_seq[] = { 0x00, 0x00, 0x00, 0x00,
1323a634090aSManuel Reinhardt 						 0x00, 0x00, 0x0b, 0x14,
1324a634090aSManuel Reinhardt 						 0x00, 0x00, 0x00, 0x01 };
1325a634090aSManuel Reinhardt 	static const u8 poll_ready_seq[] = { 0x00, 0x04, 0x00, 0x00,
1326a634090aSManuel Reinhardt 					     0x00, 0x00, 0x0b, 0x18 };
1327a634090aSManuel Reinhardt 	u8 *buf = kzalloc(MICROBOOK_BUF_SIZE, GFP_KERNEL);
1328a634090aSManuel Reinhardt 
1329a634090aSManuel Reinhardt 	if (!buf)
1330a634090aSManuel Reinhardt 		return -ENOMEM;
1331a634090aSManuel Reinhardt 
1332a634090aSManuel Reinhardt 	dev_info(&dev->dev, "Waiting for MOTU Microbook II to boot up...\n");
1333a634090aSManuel Reinhardt 
1334a634090aSManuel Reinhardt 	/* First we tell the device which sample rate to use. */
1335a634090aSManuel Reinhardt 	memcpy(buf, set_samplerate_seq, sizeof(set_samplerate_seq));
1336a634090aSManuel Reinhardt 	actual_length = sizeof(set_samplerate_seq);
1337a634090aSManuel Reinhardt 	err = snd_usb_motu_microbookii_communicate(dev, buf, MICROBOOK_BUF_SIZE,
1338a634090aSManuel Reinhardt 						   &actual_length);
1339a634090aSManuel Reinhardt 
1340a634090aSManuel Reinhardt 	if (err < 0) {
1341a634090aSManuel Reinhardt 		dev_err(&dev->dev,
1342a634090aSManuel Reinhardt 			"failed setting the sample rate for Motu MicroBook II: %d\n",
1343a634090aSManuel Reinhardt 			err);
1344a634090aSManuel Reinhardt 		goto free_buf;
1345a634090aSManuel Reinhardt 	}
1346a634090aSManuel Reinhardt 
1347a634090aSManuel Reinhardt 	/* Then we poll every 100 ms until the device informs of its readiness. */
1348a634090aSManuel Reinhardt 	while (true) {
1349a634090aSManuel Reinhardt 		if (++poll_attempts > 100) {
1350a634090aSManuel Reinhardt 			dev_err(&dev->dev,
1351a634090aSManuel Reinhardt 				"failed booting Motu MicroBook II: timeout\n");
1352a634090aSManuel Reinhardt 			err = -ENODEV;
1353a634090aSManuel Reinhardt 			goto free_buf;
1354a634090aSManuel Reinhardt 		}
1355a634090aSManuel Reinhardt 
1356a634090aSManuel Reinhardt 		memset(buf, 0, MICROBOOK_BUF_SIZE);
1357a634090aSManuel Reinhardt 		memcpy(buf, poll_ready_seq, sizeof(poll_ready_seq));
1358a634090aSManuel Reinhardt 
1359a634090aSManuel Reinhardt 		actual_length = sizeof(poll_ready_seq);
1360a634090aSManuel Reinhardt 		err = snd_usb_motu_microbookii_communicate(
1361a634090aSManuel Reinhardt 			dev, buf, MICROBOOK_BUF_SIZE, &actual_length);
1362a634090aSManuel Reinhardt 		if (err < 0) {
1363a634090aSManuel Reinhardt 			dev_err(&dev->dev,
1364a634090aSManuel Reinhardt 				"failed booting Motu MicroBook II: communication error %d\n",
1365a634090aSManuel Reinhardt 				err);
1366a634090aSManuel Reinhardt 			goto free_buf;
1367a634090aSManuel Reinhardt 		}
1368a634090aSManuel Reinhardt 
1369a634090aSManuel Reinhardt 		/* the device signals its readiness through a message of the
1370a634090aSManuel Reinhardt 		 * form
1371a634090aSManuel Reinhardt 		 *           XX 06 00 00 00 00 0b 18  00 00 00 01
1372a634090aSManuel Reinhardt 		 * If the device is not yet ready to accept audio data, the
1373a634090aSManuel Reinhardt 		 * last byte of that sequence is 00.
1374a634090aSManuel Reinhardt 		 */
1375a634090aSManuel Reinhardt 		if (actual_length == 12 && buf[actual_length - 1] == 1)
1376a634090aSManuel Reinhardt 			break;
1377a634090aSManuel Reinhardt 
1378a634090aSManuel Reinhardt 		msleep(100);
1379a634090aSManuel Reinhardt 	}
1380a634090aSManuel Reinhardt 
1381a634090aSManuel Reinhardt 	dev_info(&dev->dev, "MOTU MicroBook II ready\n");
1382a634090aSManuel Reinhardt 
1383a634090aSManuel Reinhardt free_buf:
1384a634090aSManuel Reinhardt 	kfree(buf);
1385a634090aSManuel Reinhardt 	return err;
1386a634090aSManuel Reinhardt }
1387a634090aSManuel Reinhardt 
snd_usb_motu_m_series_boot_quirk(struct usb_device * dev)138873ac9f5eSAlexander Tsoy static int snd_usb_motu_m_series_boot_quirk(struct usb_device *dev)
138973ac9f5eSAlexander Tsoy {
1390e8e214d0SJeremie Knuesel 	msleep(4000);
139173ac9f5eSAlexander Tsoy 
139273ac9f5eSAlexander Tsoy 	return 0;
139373ac9f5eSAlexander Tsoy }
139473ac9f5eSAlexander Tsoy 
139554a8c500SDaniel Mack /*
1396e5779998SDaniel Mack  * Setup quirks
1397e5779998SDaniel Mack  */
13980f5733b0SGuillaume Pellerin #define MAUDIO_SET		0x01 /* parse device_setup */
13990f5733b0SGuillaume Pellerin #define MAUDIO_SET_COMPATIBLE	0x80 /* use only "win-compatible" interfaces */
14000f5733b0SGuillaume Pellerin #define MAUDIO_SET_DTS		0x02 /* enable DTS Digital Output */
14015ff40e6dSAlexander Tsoy #define MAUDIO_SET_96K		0x04 /* 48-96kHz rate if set, 8-48kHz otherwise */
14020f5733b0SGuillaume Pellerin #define MAUDIO_SET_24B		0x08 /* 24bits sample if set, 16bits otherwise */
14030f5733b0SGuillaume Pellerin #define MAUDIO_SET_DI		0x10 /* enable Digital Input */
14040f5733b0SGuillaume Pellerin #define MAUDIO_SET_MASK		0x1f /* bit mask for setup value */
14055ff40e6dSAlexander Tsoy #define MAUDIO_SET_24B_48K_DI	 0x19 /* 24bits+48kHz+Digital Input */
14065ff40e6dSAlexander Tsoy #define MAUDIO_SET_24B_48K_NOTDI 0x09 /* 24bits+48kHz+No Digital Input */
14075ff40e6dSAlexander Tsoy #define MAUDIO_SET_16B_48K_DI	 0x11 /* 16bits+48kHz+Digital Input */
14085ff40e6dSAlexander Tsoy #define MAUDIO_SET_16B_48K_NOTDI 0x01 /* 16bits+48kHz+No Digital Input */
14090f5733b0SGuillaume Pellerin 
quattro_skip_setting_quirk(struct snd_usb_audio * chip,int iface,int altno)14100f5733b0SGuillaume Pellerin static int quattro_skip_setting_quirk(struct snd_usb_audio *chip,
14110f5733b0SGuillaume Pellerin 				      int iface, int altno)
14120f5733b0SGuillaume Pellerin {
14130f5733b0SGuillaume Pellerin 	/* Reset ALL ifaces to 0 altsetting.
14140f5733b0SGuillaume Pellerin 	 * Call it for every possible altsetting of every interface.
14150f5733b0SGuillaume Pellerin 	 */
14160f5733b0SGuillaume Pellerin 	usb_set_interface(chip->dev, iface, 0);
14170f5733b0SGuillaume Pellerin 	if (chip->setup & MAUDIO_SET) {
14180f5733b0SGuillaume Pellerin 		if (chip->setup & MAUDIO_SET_COMPATIBLE) {
14190f5733b0SGuillaume Pellerin 			if (iface != 1 && iface != 2)
14200f5733b0SGuillaume Pellerin 				return 1; /* skip all interfaces but 1 and 2 */
14210f5733b0SGuillaume Pellerin 		} else {
14220f5733b0SGuillaume Pellerin 			unsigned int mask;
14230f5733b0SGuillaume Pellerin 			if (iface == 1 || iface == 2)
14240f5733b0SGuillaume Pellerin 				return 1; /* skip interfaces 1 and 2 */
14250f5733b0SGuillaume Pellerin 			if ((chip->setup & MAUDIO_SET_96K) && altno != 1)
14260f5733b0SGuillaume Pellerin 				return 1; /* skip this altsetting */
14270f5733b0SGuillaume Pellerin 			mask = chip->setup & MAUDIO_SET_MASK;
14280f5733b0SGuillaume Pellerin 			if (mask == MAUDIO_SET_24B_48K_DI && altno != 2)
14290f5733b0SGuillaume Pellerin 				return 1; /* skip this altsetting */
14300f5733b0SGuillaume Pellerin 			if (mask == MAUDIO_SET_24B_48K_NOTDI && altno != 3)
14310f5733b0SGuillaume Pellerin 				return 1; /* skip this altsetting */
14320f5733b0SGuillaume Pellerin 			if (mask == MAUDIO_SET_16B_48K_NOTDI && altno != 4)
14330f5733b0SGuillaume Pellerin 				return 1; /* skip this altsetting */
14340f5733b0SGuillaume Pellerin 		}
14350f5733b0SGuillaume Pellerin 	}
14360ba41d91STakashi Iwai 	usb_audio_dbg(chip,
14370f5733b0SGuillaume Pellerin 		    "using altsetting %d for interface %d config %d\n",
14380f5733b0SGuillaume Pellerin 		    altno, iface, chip->setup);
14390f5733b0SGuillaume Pellerin 	return 0; /* keep this altsetting */
14400f5733b0SGuillaume Pellerin }
1441e5779998SDaniel Mack 
audiophile_skip_setting_quirk(struct snd_usb_audio * chip,int iface,int altno)1442e5779998SDaniel Mack static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
1443e5779998SDaniel Mack 					 int iface,
1444e5779998SDaniel Mack 					 int altno)
1445e5779998SDaniel Mack {
1446e5779998SDaniel Mack 	/* Reset ALL ifaces to 0 altsetting.
1447e5779998SDaniel Mack 	 * Call it for every possible altsetting of every interface.
1448e5779998SDaniel Mack 	 */
1449e5779998SDaniel Mack 	usb_set_interface(chip->dev, iface, 0);
1450e5779998SDaniel Mack 
14510f5733b0SGuillaume Pellerin 	if (chip->setup & MAUDIO_SET) {
14520f5733b0SGuillaume Pellerin 		unsigned int mask;
14530f5733b0SGuillaume Pellerin 		if ((chip->setup & MAUDIO_SET_DTS) && altno != 6)
1454e5779998SDaniel Mack 			return 1; /* skip this altsetting */
14550f5733b0SGuillaume Pellerin 		if ((chip->setup & MAUDIO_SET_96K) && altno != 1)
1456e5779998SDaniel Mack 			return 1; /* skip this altsetting */
14570f5733b0SGuillaume Pellerin 		mask = chip->setup & MAUDIO_SET_MASK;
14580f5733b0SGuillaume Pellerin 		if (mask == MAUDIO_SET_24B_48K_DI && altno != 2)
1459e5779998SDaniel Mack 			return 1; /* skip this altsetting */
14600f5733b0SGuillaume Pellerin 		if (mask == MAUDIO_SET_24B_48K_NOTDI && altno != 3)
1461e5779998SDaniel Mack 			return 1; /* skip this altsetting */
14620f5733b0SGuillaume Pellerin 		if (mask == MAUDIO_SET_16B_48K_DI && altno != 4)
1463e5779998SDaniel Mack 			return 1; /* skip this altsetting */
14640f5733b0SGuillaume Pellerin 		if (mask == MAUDIO_SET_16B_48K_NOTDI && altno != 5)
1465e5779998SDaniel Mack 			return 1; /* skip this altsetting */
1466e5779998SDaniel Mack 	}
1467e5779998SDaniel Mack 
1468e5779998SDaniel Mack 	return 0; /* keep this altsetting */
1469e5779998SDaniel Mack }
1470e5779998SDaniel Mack 
fasttrackpro_skip_setting_quirk(struct snd_usb_audio * chip,int iface,int altno)14710f5733b0SGuillaume Pellerin static int fasttrackpro_skip_setting_quirk(struct snd_usb_audio *chip,
14720f5733b0SGuillaume Pellerin 					   int iface, int altno)
14730f5733b0SGuillaume Pellerin {
14740f5733b0SGuillaume Pellerin 	/* Reset ALL ifaces to 0 altsetting.
14750f5733b0SGuillaume Pellerin 	 * Call it for every possible altsetting of every interface.
14760f5733b0SGuillaume Pellerin 	 */
14770f5733b0SGuillaume Pellerin 	usb_set_interface(chip->dev, iface, 0);
14780f5733b0SGuillaume Pellerin 
14790f5733b0SGuillaume Pellerin 	/* possible configuration where both inputs and only one output is
14800f5733b0SGuillaume Pellerin 	 *used is not supported by the current setup
14810f5733b0SGuillaume Pellerin 	 */
14820f5733b0SGuillaume Pellerin 	if (chip->setup & (MAUDIO_SET | MAUDIO_SET_24B)) {
14830f5733b0SGuillaume Pellerin 		if (chip->setup & MAUDIO_SET_96K) {
14840f5733b0SGuillaume Pellerin 			if (altno != 3 && altno != 6)
14850f5733b0SGuillaume Pellerin 				return 1;
14860f5733b0SGuillaume Pellerin 		} else if (chip->setup & MAUDIO_SET_DI) {
14870f5733b0SGuillaume Pellerin 			if (iface == 4)
14880f5733b0SGuillaume Pellerin 				return 1; /* no analog input */
14890f5733b0SGuillaume Pellerin 			if (altno != 2 && altno != 5)
14900f5733b0SGuillaume Pellerin 				return 1; /* enable only altsets 2 and 5 */
14910f5733b0SGuillaume Pellerin 		} else {
14920f5733b0SGuillaume Pellerin 			if (iface == 5)
14930f5733b0SGuillaume Pellerin 				return 1; /* disable digialt input */
14940f5733b0SGuillaume Pellerin 			if (altno != 2 && altno != 5)
14950f5733b0SGuillaume Pellerin 				return 1; /* enalbe only altsets 2 and 5 */
14960f5733b0SGuillaume Pellerin 		}
14970f5733b0SGuillaume Pellerin 	} else {
14980f5733b0SGuillaume Pellerin 		/* keep only 16-Bit mode */
14990f5733b0SGuillaume Pellerin 		if (altno != 1)
15000f5733b0SGuillaume Pellerin 			return 1;
15010f5733b0SGuillaume Pellerin 	}
15020f5733b0SGuillaume Pellerin 
15030ba41d91STakashi Iwai 	usb_audio_dbg(chip,
15040f5733b0SGuillaume Pellerin 		    "using altsetting %d for interface %d config %d\n",
15050f5733b0SGuillaume Pellerin 		    altno, iface, chip->setup);
15060f5733b0SGuillaume Pellerin 	return 0; /* keep this altsetting */
15070f5733b0SGuillaume Pellerin }
15080f5733b0SGuillaume Pellerin 
s1810c_skip_setting_quirk(struct snd_usb_audio * chip,int iface,int altno)15098dc5efe3SNick Kossifidis static int s1810c_skip_setting_quirk(struct snd_usb_audio *chip,
15108dc5efe3SNick Kossifidis 					   int iface, int altno)
15118dc5efe3SNick Kossifidis {
15128dc5efe3SNick Kossifidis 	/*
15138dc5efe3SNick Kossifidis 	 * Altno settings:
15148dc5efe3SNick Kossifidis 	 *
15158dc5efe3SNick Kossifidis 	 * Playback (Interface 1):
15168dc5efe3SNick Kossifidis 	 * 1: 6 Analog + 2 S/PDIF
15178dc5efe3SNick Kossifidis 	 * 2: 6 Analog + 2 S/PDIF
15188dc5efe3SNick Kossifidis 	 * 3: 6 Analog
15198dc5efe3SNick Kossifidis 	 *
15208dc5efe3SNick Kossifidis 	 * Capture (Interface 2):
15218dc5efe3SNick Kossifidis 	 * 1: 8 Analog + 2 S/PDIF + 8 ADAT
15228dc5efe3SNick Kossifidis 	 * 2: 8 Analog + 2 S/PDIF + 4 ADAT
15238dc5efe3SNick Kossifidis 	 * 3: 8 Analog
15248dc5efe3SNick Kossifidis 	 */
15258dc5efe3SNick Kossifidis 
15268dc5efe3SNick Kossifidis 	/*
15278dc5efe3SNick Kossifidis 	 * I'll leave 2 as the default one and
15288dc5efe3SNick Kossifidis 	 * use device_setup to switch to the
15298dc5efe3SNick Kossifidis 	 * other two.
15308dc5efe3SNick Kossifidis 	 */
15318dc5efe3SNick Kossifidis 	if ((chip->setup == 0 || chip->setup > 2) && altno != 2)
15328dc5efe3SNick Kossifidis 		return 1;
15338dc5efe3SNick Kossifidis 	else if (chip->setup == 1 && altno != 1)
15348dc5efe3SNick Kossifidis 		return 1;
15358dc5efe3SNick Kossifidis 	else if (chip->setup == 2 && altno != 3)
15368dc5efe3SNick Kossifidis 		return 1;
15378dc5efe3SNick Kossifidis 
15388dc5efe3SNick Kossifidis 	return 0;
15398dc5efe3SNick Kossifidis }
15408dc5efe3SNick Kossifidis 
snd_usb_apply_interface_quirk(struct snd_usb_audio * chip,int iface,int altno)1541e5779998SDaniel Mack int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
1542e5779998SDaniel Mack 				  int iface,
1543e5779998SDaniel Mack 				  int altno)
1544e5779998SDaniel Mack {
1545e5779998SDaniel Mack 	/* audiophile usb: skip altsets incompatible with device_setup */
1546e5779998SDaniel Mack 	if (chip->usb_id == USB_ID(0x0763, 0x2003))
1547e5779998SDaniel Mack 		return audiophile_skip_setting_quirk(chip, iface, altno);
15480f5733b0SGuillaume Pellerin 	/* quattro usb: skip altsets incompatible with device_setup */
15490f5733b0SGuillaume Pellerin 	if (chip->usb_id == USB_ID(0x0763, 0x2001))
15500f5733b0SGuillaume Pellerin 		return quattro_skip_setting_quirk(chip, iface, altno);
15510f5733b0SGuillaume Pellerin 	/* fasttrackpro usb: skip altsets incompatible with device_setup */
15520f5733b0SGuillaume Pellerin 	if (chip->usb_id == USB_ID(0x0763, 0x2012))
15530f5733b0SGuillaume Pellerin 		return fasttrackpro_skip_setting_quirk(chip, iface, altno);
15548dc5efe3SNick Kossifidis 	/* presonus studio 1810c: skip altsets incompatible with device_setup */
15551e583aefSTakashi Iwai 	if (chip->usb_id == USB_ID(0x194f, 0x010c))
15568dc5efe3SNick Kossifidis 		return s1810c_skip_setting_quirk(chip, iface, altno);
15578dc5efe3SNick Kossifidis 
1558e5779998SDaniel Mack 
1559e5779998SDaniel Mack 	return 0;
1560e5779998SDaniel Mack }
1561e5779998SDaniel Mack 
snd_usb_apply_boot_quirk(struct usb_device * dev,struct usb_interface * intf,const struct snd_usb_audio_quirk * quirk,unsigned int id)1562e5779998SDaniel Mack int snd_usb_apply_boot_quirk(struct usb_device *dev,
1563e5779998SDaniel Mack 			     struct usb_interface *intf,
156479289e24STakashi Iwai 			     const struct snd_usb_audio_quirk *quirk,
156579289e24STakashi Iwai 			     unsigned int id)
1566e5779998SDaniel Mack {
15673347b26cSDaniel Mack 	switch (id) {
15683347b26cSDaniel Mack 	case USB_ID(0x041e, 0x3000):
1569e5779998SDaniel Mack 		/* SB Extigy needs special boot-up sequence */
1570e5779998SDaniel Mack 		/* if more models come, this will go to the quirk list. */
1571e5779998SDaniel Mack 		return snd_usb_extigy_boot_quirk(dev, intf);
1572e5779998SDaniel Mack 
15733347b26cSDaniel Mack 	case USB_ID(0x041e, 0x3020):
1574e5779998SDaniel Mack 		/* SB Audigy 2 NX needs its own boot-up magic, too */
1575e5779998SDaniel Mack 		return snd_usb_audigy2nx_boot_quirk(dev);
1576e5779998SDaniel Mack 
15773347b26cSDaniel Mack 	case USB_ID(0x10f5, 0x0200):
1578e5779998SDaniel Mack 		/* C-Media CM106 / Turtle Beach Audio Advantage Roadie */
1579e5779998SDaniel Mack 		return snd_usb_cm106_boot_quirk(dev);
1580e5779998SDaniel Mack 
15813347b26cSDaniel Mack 	case USB_ID(0x0d8c, 0x0102):
1582e5779998SDaniel Mack 		/* C-Media CM6206 / CM106-Like Sound Device */
15838129e79eSWolfgang Breyha 	case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */
1584e5779998SDaniel Mack 		return snd_usb_cm6206_boot_quirk(dev);
1585e5779998SDaniel Mack 
1586cb99864dSDamien Zammit 	case USB_ID(0x0dba, 0x3000):
1587cb99864dSDamien Zammit 		/* Digidesign Mbox 2 */
1588cb99864dSDamien Zammit 		return snd_usb_mbox2_boot_quirk(dev);
1589b01104fcSConner Knox 	case USB_ID(0x0dba, 0x5000):
1590b01104fcSConner Knox 		/* Digidesign Mbox 3 */
1591b01104fcSConner Knox 		return snd_usb_mbox3_boot_quirk(dev);
1592b01104fcSConner Knox 
1593cb99864dSDamien Zammit 
159411e424e8SEduard Gilmutdinov 	case USB_ID(0x1235, 0x0010): /* Focusrite Novation Saffire 6 USB */
159511e424e8SEduard Gilmutdinov 	case USB_ID(0x1235, 0x0018): /* Focusrite Novation Twitch */
159611e424e8SEduard Gilmutdinov 		return snd_usb_novation_boot_quirk(dev);
15975e212332SMark Hills 
15983347b26cSDaniel Mack 	case USB_ID(0x133e, 0x0815):
1599e5779998SDaniel Mack 		/* Access Music VirusTI Desktop */
1600e5779998SDaniel Mack 		return snd_usb_accessmusic_boot_quirk(dev);
1601e5779998SDaniel Mack 
1602759e890fSDaniel Mack 	case USB_ID(0x17cc, 0x1000): /* Komplete Audio 6 */
16033347b26cSDaniel Mack 	case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */
16043347b26cSDaniel Mack 	case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */
160554a8c500SDaniel Mack 		return snd_usb_nativeinstruments_boot_quirk(dev);
16060f5733b0SGuillaume Pellerin 	case USB_ID(0x0763, 0x2012):  /* M-Audio Fast Track Pro USB */
16070f5733b0SGuillaume Pellerin 		return snd_usb_fasttrackpro_boot_quirk(dev);
160819570d74STakashi Iwai 	case USB_ID(0x047f, 0xc010): /* Plantronics Gamecom 780 */
160919570d74STakashi Iwai 		return snd_usb_gamecon780_boot_quirk(dev);
161016bafa79SAlberto Aguirre 	case USB_ID(0x2466, 0x8010): /* Fractal Audio Axe-Fx 3 */
161116bafa79SAlberto Aguirre 		return snd_usb_axefx3_boot_quirk(dev);
1612a634090aSManuel Reinhardt 	case USB_ID(0x07fd, 0x0004): /* MOTU MicroBook II */
16132edb84e3SAlexander Tsoy 		/*
16142edb84e3SAlexander Tsoy 		 * For some reason interface 3 with vendor-spec class is
16152edb84e3SAlexander Tsoy 		 * detected on MicroBook IIc.
16162edb84e3SAlexander Tsoy 		 */
16172edb84e3SAlexander Tsoy 		if (get_iface_desc(intf->altsetting)->bInterfaceClass ==
16182edb84e3SAlexander Tsoy 		    USB_CLASS_VENDOR_SPEC &&
16192edb84e3SAlexander Tsoy 		    get_iface_desc(intf->altsetting)->bInterfaceNumber < 3)
1620a634090aSManuel Reinhardt 			return snd_usb_motu_microbookii_boot_quirk(dev);
16212edb84e3SAlexander Tsoy 		break;
16223347b26cSDaniel Mack 	}
162354a8c500SDaniel Mack 
1624e5779998SDaniel Mack 	return 0;
1625e5779998SDaniel Mack }
1626e5779998SDaniel 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)162773ac9f5eSAlexander Tsoy int snd_usb_apply_boot_quirk_once(struct usb_device *dev,
162873ac9f5eSAlexander Tsoy 				  struct usb_interface *intf,
162973ac9f5eSAlexander Tsoy 				  const struct snd_usb_audio_quirk *quirk,
163073ac9f5eSAlexander Tsoy 				  unsigned int id)
163173ac9f5eSAlexander Tsoy {
163273ac9f5eSAlexander Tsoy 	switch (id) {
1633e8e214d0SJeremie Knuesel 	case USB_ID(0x07fd, 0x0008): /* MOTU M Series, 1st hardware version */
163473ac9f5eSAlexander Tsoy 		return snd_usb_motu_m_series_boot_quirk(dev);
163573ac9f5eSAlexander Tsoy 	}
163673ac9f5eSAlexander Tsoy 
163773ac9f5eSAlexander Tsoy 	return 0;
163873ac9f5eSAlexander Tsoy }
163973ac9f5eSAlexander Tsoy 
1640e5779998SDaniel Mack /*
1641e5779998SDaniel Mack  * check if the device uses big-endian samples
1642e5779998SDaniel Mack  */
snd_usb_is_big_endian_format(struct snd_usb_audio * chip,const struct audioformat * fp)1643cab941b7STakashi Iwai int snd_usb_is_big_endian_format(struct snd_usb_audio *chip,
1644cab941b7STakashi Iwai 				 const struct audioformat *fp)
1645e5779998SDaniel Mack {
164648fc7f7eSAdam Buchbinder 	/* it depends on altsetting whether the device is big-endian or not */
1647e5779998SDaniel Mack 	switch (chip->usb_id) {
1648e5779998SDaniel Mack 	case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */
16490f5733b0SGuillaume Pellerin 		if (fp->altsetting == 2 || fp->altsetting == 3 ||
16500f5733b0SGuillaume Pellerin 			fp->altsetting == 5 || fp->altsetting == 6)
1651e5779998SDaniel Mack 			return 1;
1652e5779998SDaniel Mack 		break;
1653e5779998SDaniel Mack 	case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
1654e5779998SDaniel Mack 		if (chip->setup == 0x00 ||
16550f5733b0SGuillaume Pellerin 			fp->altsetting == 1 || fp->altsetting == 2 ||
16560f5733b0SGuillaume Pellerin 			fp->altsetting == 3)
1657e5779998SDaniel Mack 			return 1;
16580f5733b0SGuillaume Pellerin 		break;
16590f5733b0SGuillaume Pellerin 	case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro */
16600f5733b0SGuillaume Pellerin 		if (fp->altsetting == 2 || fp->altsetting == 3 ||
16610f5733b0SGuillaume Pellerin 			fp->altsetting == 5 || fp->altsetting == 6)
16620f5733b0SGuillaume Pellerin 			return 1;
16630f5733b0SGuillaume Pellerin 		break;
1664e5779998SDaniel Mack 	}
1665e5779998SDaniel Mack 	return 0;
1666e5779998SDaniel Mack }
1667e5779998SDaniel Mack 
1668e5779998SDaniel Mack /*
16691cdfa9f3SJoseph Teichman  * For E-Mu 0404USB/0202USB/TrackerPre/0204 sample rate should be set for device,
1670e5779998SDaniel Mack  * not for interface.
1671e5779998SDaniel Mack  */
1672e5779998SDaniel Mack 
1673e5779998SDaniel Mack enum {
1674e5779998SDaniel Mack 	EMU_QUIRK_SR_44100HZ = 0,
1675e5779998SDaniel Mack 	EMU_QUIRK_SR_48000HZ,
1676e5779998SDaniel Mack 	EMU_QUIRK_SR_88200HZ,
1677e5779998SDaniel Mack 	EMU_QUIRK_SR_96000HZ,
1678e5779998SDaniel Mack 	EMU_QUIRK_SR_176400HZ,
1679e5779998SDaniel Mack 	EMU_QUIRK_SR_192000HZ
1680e5779998SDaniel Mack };
1681e5779998SDaniel Mack 
set_format_emu_quirk(struct snd_usb_substream * subs,const struct audioformat * fmt)1682e5779998SDaniel Mack static void set_format_emu_quirk(struct snd_usb_substream *subs,
1683cab941b7STakashi Iwai 				 const struct audioformat *fmt)
1684e5779998SDaniel Mack {
1685e5779998SDaniel Mack 	unsigned char emu_samplerate_id = 0;
1686e5779998SDaniel Mack 
1687e5779998SDaniel Mack 	/* When capture is active
1688e5779998SDaniel Mack 	 * sample rate shouldn't be changed
1689e5779998SDaniel Mack 	 * by playback substream
1690e5779998SDaniel Mack 	 */
1691e5779998SDaniel Mack 	if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) {
16926aa719d1STakashi Iwai 		if (subs->stream->substream[SNDRV_PCM_STREAM_CAPTURE].cur_audiofmt)
1693e5779998SDaniel Mack 			return;
1694e5779998SDaniel Mack 	}
1695e5779998SDaniel Mack 
1696e5779998SDaniel Mack 	switch (fmt->rate_min) {
1697e5779998SDaniel Mack 	case 48000:
1698e5779998SDaniel Mack 		emu_samplerate_id = EMU_QUIRK_SR_48000HZ;
1699e5779998SDaniel Mack 		break;
1700e5779998SDaniel Mack 	case 88200:
1701e5779998SDaniel Mack 		emu_samplerate_id = EMU_QUIRK_SR_88200HZ;
1702e5779998SDaniel Mack 		break;
1703e5779998SDaniel Mack 	case 96000:
1704e5779998SDaniel Mack 		emu_samplerate_id = EMU_QUIRK_SR_96000HZ;
1705e5779998SDaniel Mack 		break;
1706e5779998SDaniel Mack 	case 176400:
1707e5779998SDaniel Mack 		emu_samplerate_id = EMU_QUIRK_SR_176400HZ;
1708e5779998SDaniel Mack 		break;
1709e5779998SDaniel Mack 	case 192000:
1710e5779998SDaniel Mack 		emu_samplerate_id = EMU_QUIRK_SR_192000HZ;
1711e5779998SDaniel Mack 		break;
1712e5779998SDaniel Mack 	default:
1713e5779998SDaniel Mack 		emu_samplerate_id = EMU_QUIRK_SR_44100HZ;
1714e5779998SDaniel Mack 		break;
1715e5779998SDaniel Mack 	}
1716e5779998SDaniel Mack 	snd_emuusb_set_samplerate(subs->stream->chip, emu_samplerate_id);
17171539d4f8SCalvin Owens 	subs->pkt_offset_adj = (emu_samplerate_id >= EMU_QUIRK_SR_176400HZ) ? 4 : 0;
1718e5779998SDaniel Mack }
1719e5779998SDaniel Mack 
pioneer_djm_set_format_quirk(struct snd_usb_substream * subs,u16 windex)17203b85f5fcSOlivia Mackintosh static int pioneer_djm_set_format_quirk(struct snd_usb_substream *subs,
17213b85f5fcSOlivia Mackintosh 					u16 windex)
17223b85f5fcSOlivia Mackintosh {
17233b85f5fcSOlivia Mackintosh 	unsigned int cur_rate = subs->data_endpoint->cur_rate;
17243b85f5fcSOlivia Mackintosh 	u8 sr[3];
17253b85f5fcSOlivia Mackintosh 	// Convert to little endian
17263b85f5fcSOlivia Mackintosh 	sr[0] = cur_rate & 0xff;
17273b85f5fcSOlivia Mackintosh 	sr[1] = (cur_rate >> 8) & 0xff;
17283b85f5fcSOlivia Mackintosh 	sr[2] = (cur_rate >> 16) & 0xff;
17293b85f5fcSOlivia Mackintosh 	usb_set_interface(subs->dev, 0, 1);
17303b85f5fcSOlivia Mackintosh 	// we should derive windex from fmt-sync_ep but it's not set
17313b85f5fcSOlivia Mackintosh 	snd_usb_ctl_msg(subs->stream->chip->dev,
17322c911900SNicolas MURE 		usb_sndctrlpipe(subs->stream->chip->dev, 0),
17333b85f5fcSOlivia Mackintosh 		0x01, 0x22, 0x0100, windex, &sr, 0x0003);
17343b85f5fcSOlivia Mackintosh 	return 0;
17353b85f5fcSOlivia Mackintosh }
17363b85f5fcSOlivia Mackintosh 
snd_usb_set_format_quirk(struct snd_usb_substream * subs,const struct audioformat * fmt)1737e5779998SDaniel Mack void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
1738cab941b7STakashi Iwai 			      const struct audioformat *fmt)
1739e5779998SDaniel Mack {
1740e5779998SDaniel Mack 	switch (subs->stream->chip->usb_id) {
1741e5779998SDaniel Mack 	case USB_ID(0x041e, 0x3f02): /* E-Mu 0202 USB */
1742e5779998SDaniel Mack 	case USB_ID(0x041e, 0x3f04): /* E-Mu 0404 USB */
1743e5779998SDaniel Mack 	case USB_ID(0x041e, 0x3f0a): /* E-Mu Tracker Pre */
17441cdfa9f3SJoseph Teichman 	case USB_ID(0x041e, 0x3f19): /* E-Mu 0204 USB */
1745e5779998SDaniel Mack 		set_format_emu_quirk(subs, fmt);
1746e5779998SDaniel Mack 		break;
17476e2c9105SJohn Veness 	case USB_ID(0x534d, 0x0021): /* MacroSilicon MS2100/MS2106 */
17481b7ecc24SHector Martin 	case USB_ID(0x534d, 0x2109): /* MacroSilicon MS2109 */
17491b7ecc24SHector Martin 		subs->stream_offset_adj = 2;
17501b7ecc24SHector Martin 		break;
17513b85f5fcSOlivia Mackintosh 	case USB_ID(0x2b73, 0x0013): /* Pioneer DJM-450 */
17523b85f5fcSOlivia Mackintosh 		pioneer_djm_set_format_quirk(subs, 0x0082);
17533b85f5fcSOlivia Mackintosh 		break;
1754e7df7df5SOlivia Mackintosh 	case USB_ID(0x08e4, 0x017f): /* Pioneer DJM-750 */
17551a2a94a4SNicolas MURE 	case USB_ID(0x08e4, 0x0163): /* Pioneer DJM-850 */
17561a2a94a4SNicolas MURE 		pioneer_djm_set_format_quirk(subs, 0x0086);
17571a2a94a4SNicolas MURE 		break;
1758e5779998SDaniel Mack 	}
1759e5779998SDaniel Mack }
1760e5779998SDaniel Mack 
snd_usb_select_mode_quirk(struct snd_usb_audio * chip,const struct audioformat * fmt)1761d767aba2STakashi Iwai int snd_usb_select_mode_quirk(struct snd_usb_audio *chip,
1762cab941b7STakashi Iwai 			      const struct audioformat *fmt)
17636874daadSJurgen Kramer {
1764d767aba2STakashi Iwai 	struct usb_device *dev = chip->dev;
17656874daadSJurgen Kramer 	int err;
17666874daadSJurgen Kramer 
17672de00d5aSTakashi Iwai 	if (chip->quirk_flags & QUIRK_FLAG_ITF_USB_DSD_DAC) {
17686874daadSJurgen Kramer 		/* First switch to alt set 0, otherwise the mode switch cmd
17696874daadSJurgen Kramer 		 * will not be accepted by the DAC
17706874daadSJurgen Kramer 		 */
17716874daadSJurgen Kramer 		err = usb_set_interface(dev, fmt->iface, 0);
17726874daadSJurgen Kramer 		if (err < 0)
17736874daadSJurgen Kramer 			return err;
17746874daadSJurgen Kramer 
1775df3f0347SJia-Ju Bai 		msleep(20); /* Delay needed after setting the interface */
17766874daadSJurgen Kramer 
17777f38ca04SNobutaka Okabe 		/* Vendor mode switch cmd is required. */
1778f3b906d7SNobutaka Okabe 		if (fmt->formats & SNDRV_PCM_FMTBIT_DSD_U32_BE) {
1779f3b906d7SNobutaka Okabe 			/* DSD mode (DSD_U32) requested */
17807f38ca04SNobutaka Okabe 			err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0,
17817f38ca04SNobutaka Okabe 					      USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
17827f38ca04SNobutaka Okabe 					      1, 1, NULL, 0);
17837f38ca04SNobutaka Okabe 			if (err < 0)
17847f38ca04SNobutaka Okabe 				return err;
17857f38ca04SNobutaka Okabe 
1786f3b906d7SNobutaka Okabe 		} else {
1787f3b906d7SNobutaka Okabe 			/* PCM or DOP mode (S32) requested */
1788f3b906d7SNobutaka Okabe 			/* PCM mode (S16) requested */
17897f38ca04SNobutaka Okabe 			err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), 0,
17907f38ca04SNobutaka Okabe 					      USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
17917f38ca04SNobutaka Okabe 					      0, 1, NULL, 0);
17927f38ca04SNobutaka Okabe 			if (err < 0)
17937f38ca04SNobutaka Okabe 				return err;
1794f3b906d7SNobutaka Okabe 
17957f38ca04SNobutaka Okabe 		}
1796df3f0347SJia-Ju Bai 		msleep(20);
17976874daadSJurgen Kramer 	}
17986874daadSJurgen Kramer 	return 0;
17996874daadSJurgen Kramer }
18006874daadSJurgen Kramer 
snd_usb_endpoint_start_quirk(struct snd_usb_endpoint * ep)18012b58fd5bSDaniel Mack void snd_usb_endpoint_start_quirk(struct snd_usb_endpoint *ep)
18022b58fd5bSDaniel Mack {
18032b58fd5bSDaniel Mack 	/*
18042b58fd5bSDaniel Mack 	 * "Playback Design" products send bogus feedback data at the start
18052b58fd5bSDaniel Mack 	 * of the stream. Ignore them.
18062b58fd5bSDaniel Mack 	 */
180779289e24STakashi Iwai 	if (USB_ID_VENDOR(ep->chip->usb_id) == 0x23ba &&
18082b58fd5bSDaniel Mack 	    ep->type == SND_USB_ENDPOINT_TYPE_SYNC)
18092b58fd5bSDaniel Mack 		ep->skip_packets = 4;
181083e3acd4SEldad Zack 
181183e3acd4SEldad Zack 	/*
1812e9a25e04SMatt Gruskin 	 * M-Audio Fast Track C400/C600 - when packets are not skipped, real
18135ff40e6dSAlexander Tsoy 	 * world latency varies by approx. +/- 50 frames (at 96kHz) each time
1814e9a25e04SMatt Gruskin 	 * the stream is (re)started. When skipping packets 16 at endpoint
1815e9a25e04SMatt Gruskin 	 * start up, the real world latency is stable within +/- 1 frame (also
181683e3acd4SEldad Zack 	 * across power cycles).
181783e3acd4SEldad Zack 	 */
1818e9a25e04SMatt Gruskin 	if ((ep->chip->usb_id == USB_ID(0x0763, 0x2030) ||
1819e9a25e04SMatt Gruskin 	     ep->chip->usb_id == USB_ID(0x0763, 0x2031)) &&
182083e3acd4SEldad Zack 	    ep->type == SND_USB_ENDPOINT_TYPE_DATA)
182183e3acd4SEldad Zack 		ep->skip_packets = 16;
18229abc1341SDaniel Mack 
18239abc1341SDaniel Mack 	/* Work around devices that report unreasonable feedback data */
1824ca0dd273SDaniel Mack 	if ((ep->chip->usb_id == USB_ID(0x0644, 0x8038) ||  /* TEAC UD-H01 */
1825ca0dd273SDaniel Mack 	     ep->chip->usb_id == USB_ID(0x1852, 0x5034)) && /* T+A Dac8 */
18269abc1341SDaniel Mack 	    ep->syncmaxsize == 4)
1827ca0dd273SDaniel Mack 		ep->tenor_fb_quirk = 1;
18282b58fd5bSDaniel Mack }
18292b58fd5bSDaniel Mack 
183079289e24STakashi 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)18312b58fd5bSDaniel Mack void snd_usb_ctl_msg_quirk(struct usb_device *dev, unsigned int pipe,
18322b58fd5bSDaniel Mack 			   __u8 request, __u8 requesttype, __u16 value,
18332b58fd5bSDaniel Mack 			   __u16 index, void *data, __u16 size)
18342b58fd5bSDaniel Mack {
183579289e24STakashi Iwai 	struct snd_usb_audio *chip = dev_get_drvdata(&dev->dev);
183679289e24STakashi Iwai 
1837f7483854STakashi Iwai 	if (!chip || (requesttype & USB_TYPE_MASK) != USB_TYPE_CLASS)
183879289e24STakashi Iwai 		return;
18396e84a8d7SJurgen Kramer 
1840f7483854STakashi Iwai 	if (chip->quirk_flags & QUIRK_FLAG_CTL_MSG_DELAY)
1841df3f0347SJia-Ju Bai 		msleep(20);
1842f7483854STakashi Iwai 	else if (chip->quirk_flags & QUIRK_FLAG_CTL_MSG_DELAY_1M)
1843df3f0347SJia-Ju Bai 		usleep_range(1000, 2000);
1844f7483854STakashi Iwai 	else if (chip->quirk_flags & QUIRK_FLAG_CTL_MSG_DELAY_5M)
1845a32a1fc9SMacpaul Lin 		usleep_range(5000, 6000);
18462b58fd5bSDaniel Mack }
18472b58fd5bSDaniel Mack 
1848126825e7SDaniel Mack /*
1849126825e7SDaniel Mack  * snd_usb_interface_dsd_format_quirks() is called from format.c to
1850126825e7SDaniel Mack  * augment the PCM format bit-field for DSD types. The UAC standards
1851126825e7SDaniel Mack  * don't have a designated bit field to denote DSD-capable interfaces,
1852126825e7SDaniel Mack  * hence all hardware that is known to support this format has to be
1853126825e7SDaniel Mack  * listed here.
1854126825e7SDaniel Mack  */
snd_usb_interface_dsd_format_quirks(struct snd_usb_audio * chip,struct audioformat * fp,unsigned int sample_bytes)1855126825e7SDaniel Mack u64 snd_usb_interface_dsd_format_quirks(struct snd_usb_audio *chip,
1856126825e7SDaniel Mack 					struct audioformat *fp,
1857126825e7SDaniel Mack 					unsigned int sample_bytes)
1858126825e7SDaniel Mack {
1859f3b906d7SNobutaka Okabe 	struct usb_interface *iface;
1860f3b906d7SNobutaka Okabe 
1861126825e7SDaniel Mack 	/* Playback Designs */
1862eb7505d5SJussi Laako 	if (USB_ID_VENDOR(chip->usb_id) == 0x23ba &&
1863eb7505d5SJussi Laako 	    USB_ID_PRODUCT(chip->usb_id) < 0x0110) {
1864126825e7SDaniel Mack 		switch (fp->altsetting) {
1865126825e7SDaniel Mack 		case 1:
1866126825e7SDaniel Mack 			fp->dsd_dop = true;
1867126825e7SDaniel Mack 			return SNDRV_PCM_FMTBIT_DSD_U16_LE;
1868126825e7SDaniel Mack 		case 2:
1869126825e7SDaniel Mack 			fp->dsd_bitrev = true;
1870126825e7SDaniel Mack 			return SNDRV_PCM_FMTBIT_DSD_U8;
1871126825e7SDaniel Mack 		case 3:
1872126825e7SDaniel Mack 			fp->dsd_bitrev = true;
1873126825e7SDaniel Mack 			return SNDRV_PCM_FMTBIT_DSD_U16_LE;
1874126825e7SDaniel Mack 		}
1875126825e7SDaniel Mack 	}
1876126825e7SDaniel Mack 
1877848f3a82SJurgen Kramer 	/* XMOS based USB DACs */
1878848f3a82SJurgen Kramer 	switch (chip->usb_id) {
1879f7fea075SJussi Laako 	case USB_ID(0x139f, 0x5504): /* Nagra DAC */
1880f7fea075SJussi Laako 	case USB_ID(0x20b1, 0x3089): /* Mola-Mola DAC */
1881f7fea075SJussi Laako 	case USB_ID(0x2522, 0x0007): /* LH Labs Geek Out 1V5 */
1882f7fea075SJussi Laako 	case USB_ID(0x2522, 0x0009): /* LH Labs Geek Pulse X Inifinity 2V0 */
1883f656891cSDaniel Mack 	case USB_ID(0x2522, 0x0012): /* LH Labs VI DAC Infinity */
18849bb201a5SJussi Laako 	case USB_ID(0x2772, 0x0230): /* Pro-Ject Pre Box S2 Digital */
1885848f3a82SJurgen Kramer 		if (fp->altsetting == 2)
1886d42472ecSJussi Laako 			return SNDRV_PCM_FMTBIT_DSD_U32_BE;
1887848f3a82SJurgen Kramer 		break;
18883b7e5c7eSJurgen Kramer 
1889f656891cSDaniel Mack 	case USB_ID(0x0d8c, 0x0316): /* Hegel HD12 DSD */
1890202e69e6SJussi Laako 	case USB_ID(0x10cb, 0x0103): /* The Bit Opus #3; with fp->dsd_raw */
1891547d2c9cSTakashi Iwai 	case USB_ID(0x16d0, 0x06b2): /* NuPrime DAC-10 */
1892f7fea075SJussi Laako 	case USB_ID(0x16d0, 0x06b4): /* NuPrime Audio HD-AVP/AVA */
1893f656891cSDaniel Mack 	case USB_ID(0x16d0, 0x0733): /* Furutech ADL Stratos */
1894f7fea075SJussi Laako 	case USB_ID(0x16d0, 0x09d8): /* NuPrime IDA-8 */
1895f656891cSDaniel Mack 	case USB_ID(0x16d0, 0x09db): /* NuPrime Audio DAC-9 */
1896f7fea075SJussi Laako 	case USB_ID(0x16d0, 0x09dd): /* Encore mDSD */
1897f656891cSDaniel Mack 	case USB_ID(0x1db5, 0x0003): /* Bryston BDA3 */
1898f7fea075SJussi Laako 	case USB_ID(0x20a0, 0x4143): /* WaveIO USB Audio 2.0 */
1899f656891cSDaniel Mack 	case USB_ID(0x22e1, 0xca01): /* HDTA Serenade DSD */
1900f656891cSDaniel Mack 	case USB_ID(0x249c, 0x9326): /* M2Tech Young MkIII */
1901ad678b4cSJurgen Kramer 	case USB_ID(0x2616, 0x0106): /* PS Audio NuWave DAC */
1902f656891cSDaniel Mack 	case USB_ID(0x2622, 0x0041): /* Audiolab M-DAC+ */
1903f7fea075SJussi Laako 	case USB_ID(0x278b, 0x5100): /* Rotel RC-1590 */
1904f656891cSDaniel Mack 	case USB_ID(0x27f7, 0x3002): /* W4S DAC-2v2SE */
1905f656891cSDaniel Mack 	case USB_ID(0x29a2, 0x0086): /* Mutec MC3+ USB */
1906f656891cSDaniel Mack 	case USB_ID(0x6b42, 0x0042): /* MSB Technology */
1907848f3a82SJurgen Kramer 		if (fp->altsetting == 3)
1908d42472ecSJussi Laako 			return SNDRV_PCM_FMTBIT_DSD_U32_BE;
1909848f3a82SJurgen Kramer 		break;
19103eff682dSJussi Laako 
19117c74866bSDaniel Mack 	/* Amanero Combo384 USB based DACs with native DSD support */
19127c74866bSDaniel Mack 	case USB_ID(0x16d0, 0x071a):  /* Amanero - Combo384 */
19133eff682dSJussi Laako 		if (fp->altsetting == 2) {
1914f83914fdSJohan Hovold 			switch (le16_to_cpu(chip->dev->descriptor.bcdDevice)) {
19153eff682dSJussi Laako 			case 0x199:
19163eff682dSJussi Laako 				return SNDRV_PCM_FMTBIT_DSD_U32_LE;
19173eff682dSJussi Laako 			case 0x19b:
1918f5ce8179SJussi Laako 			case 0x203:
19193eff682dSJussi Laako 				return SNDRV_PCM_FMTBIT_DSD_U32_BE;
19203eff682dSJussi Laako 			default:
19213eff682dSJussi Laako 				break;
19223eff682dSJussi Laako 			}
19233eff682dSJussi Laako 		}
19243eff682dSJussi Laako 		break;
1925ed993c6fSJussi Laako 	case USB_ID(0x16d0, 0x0a23):
1926ed993c6fSJussi Laako 		if (fp->altsetting == 2)
1927ed993c6fSJussi Laako 			return SNDRV_PCM_FMTBIT_DSD_U32_BE;
1928ed993c6fSJussi Laako 		break;
19293eff682dSJussi Laako 
1930848f3a82SJurgen Kramer 	default:
1931848f3a82SJurgen Kramer 		break;
1932848f3a82SJurgen Kramer 	}
1933848f3a82SJurgen Kramer 
1934f3b906d7SNobutaka Okabe 	/* ITF-USB DSD based DACs */
19352de00d5aSTakashi Iwai 	if (chip->quirk_flags & QUIRK_FLAG_ITF_USB_DSD_DAC) {
1936f3b906d7SNobutaka Okabe 		iface = usb_ifnum_to_if(chip->dev, fp->iface);
19377a2e9ddcSJurgen Kramer 
1938f3b906d7SNobutaka Okabe 		/* Altsetting 2 support native DSD if the num of altsets is
1939f3b906d7SNobutaka Okabe 		 * three (0-2),
1940f3b906d7SNobutaka Okabe 		 * Altsetting 3 support native DSD if the num of altsets is
1941f3b906d7SNobutaka Okabe 		 * four (0-3).
1942f3b906d7SNobutaka Okabe 		 */
1943f3b906d7SNobutaka Okabe 		if (fp->altsetting == iface->num_altsetting - 1)
19447f38ca04SNobutaka Okabe 			return SNDRV_PCM_FMTBIT_DSD_U32_BE;
19457f38ca04SNobutaka Okabe 	}
19467f38ca04SNobutaka Okabe 
194768e851eeSTakashi Iwai 	/* Mostly generic method to detect many DSD-capable implementations */
194868e851eeSTakashi Iwai 	if ((chip->quirk_flags & QUIRK_FLAG_DSD_RAW) && fp->dsd_raw)
19493a572d94SJussi Laako 		return SNDRV_PCM_FMTBIT_DSD_U32_BE;
19503a572d94SJussi Laako 
1951126825e7SDaniel Mack 	return 0;
1952126825e7SDaniel Mack }
1953ceb18f51SRuslan Bilovol 
snd_usb_audioformat_attributes_quirk(struct snd_usb_audio * chip,struct audioformat * fp,int stream)1954ceb18f51SRuslan Bilovol void snd_usb_audioformat_attributes_quirk(struct snd_usb_audio *chip,
1955ceb18f51SRuslan Bilovol 					  struct audioformat *fp,
1956ceb18f51SRuslan Bilovol 					  int stream)
1957ceb18f51SRuslan Bilovol {
1958ceb18f51SRuslan Bilovol 	switch (chip->usb_id) {
1959ceb18f51SRuslan Bilovol 	case USB_ID(0x0a92, 0x0053): /* AudioTrak Optoplay */
1960ceb18f51SRuslan Bilovol 		/* Optoplay sets the sample rate attribute although
1961ceb18f51SRuslan Bilovol 		 * it seems not supporting it in fact.
1962ceb18f51SRuslan Bilovol 		 */
1963ceb18f51SRuslan Bilovol 		fp->attributes &= ~UAC_EP_CS_ATTR_SAMPLE_RATE;
1964ceb18f51SRuslan Bilovol 		break;
1965ceb18f51SRuslan Bilovol 	case USB_ID(0x041e, 0x3020): /* Creative SB Audigy 2 NX */
1966ceb18f51SRuslan Bilovol 	case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
1967ceb18f51SRuslan Bilovol 		/* doesn't set the sample rate attribute, but supports it */
1968ceb18f51SRuslan Bilovol 		fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
1969ceb18f51SRuslan Bilovol 		break;
1970ceb18f51SRuslan Bilovol 	case USB_ID(0x0763, 0x2001):  /* M-Audio Quattro USB */
1971ceb18f51SRuslan Bilovol 	case USB_ID(0x0763, 0x2012):  /* M-Audio Fast Track Pro USB */
1972ceb18f51SRuslan Bilovol 	case USB_ID(0x047f, 0x0ca1): /* plantronics headset */
1973ceb18f51SRuslan Bilovol 	case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is
1974ceb18f51SRuslan Bilovol 					an older model 77d:223) */
1975ceb18f51SRuslan Bilovol 	/*
1976ceb18f51SRuslan Bilovol 	 * plantronics headset and Griffin iMic have set adaptive-in
1977ceb18f51SRuslan Bilovol 	 * although it's really not...
1978ceb18f51SRuslan Bilovol 	 */
1979ceb18f51SRuslan Bilovol 		fp->ep_attr &= ~USB_ENDPOINT_SYNCTYPE;
1980ceb18f51SRuslan Bilovol 		if (stream == SNDRV_PCM_STREAM_PLAYBACK)
1981ceb18f51SRuslan Bilovol 			fp->ep_attr |= USB_ENDPOINT_SYNC_ADAPTIVE;
1982ceb18f51SRuslan Bilovol 		else
1983ceb18f51SRuslan Bilovol 			fp->ep_attr |= USB_ENDPOINT_SYNC_SYNC;
1984ceb18f51SRuslan Bilovol 		break;
19852edb84e3SAlexander Tsoy 	case USB_ID(0x07fd, 0x0004):  /* MOTU MicroBook IIc */
19862edb84e3SAlexander Tsoy 		/*
19872edb84e3SAlexander Tsoy 		 * MaxPacketsOnly attribute is erroneously set in endpoint
19882edb84e3SAlexander Tsoy 		 * descriptors. As a result this card produces noise with
19895ff40e6dSAlexander Tsoy 		 * all sample rates other than 96 kHz.
19902edb84e3SAlexander Tsoy 		 */
19912edb84e3SAlexander Tsoy 		fp->attributes &= ~UAC_EP_CS_ATTR_FILL_MAX;
19922edb84e3SAlexander Tsoy 		break;
199329664923SMarco Giunta 	case USB_ID(0x1224, 0x2a25):  /* Jieli Technology USB PHY 2.0 */
199429664923SMarco Giunta 		/* mic works only when ep packet size is set to wMaxPacketSize */
199529664923SMarco Giunta 		fp->attributes |= UAC_EP_CS_ATTR_FILL_MAX;
199629664923SMarco Giunta 		break;
19976a83d6f3SWhaleChang 	case USB_ID(0x3511, 0x2b1e): /* Opencomm2 UC USB Bluetooth dongle */
19986a83d6f3SWhaleChang 		/* mic works only when ep pitch control is not set */
19996a83d6f3SWhaleChang 		if (stream == SNDRV_PCM_STREAM_CAPTURE)
20006a83d6f3SWhaleChang 			fp->attributes &= ~UAC_EP_CS_ATTR_PITCH_CONTROL;
20016a83d6f3SWhaleChang 		break;
2002ceb18f51SRuslan Bilovol 	}
2003ceb18f51SRuslan Bilovol }
200455f73261SChris Wulff 
2005d8695bc5STakashi Iwai /*
20064d4dee0aSTakashi Iwai  * driver behavior quirk flags
20074d4dee0aSTakashi Iwai  */
20084d4dee0aSTakashi Iwai struct usb_audio_quirk_flags_table {
20094d4dee0aSTakashi Iwai 	u32 id;
20104d4dee0aSTakashi Iwai 	u32 flags;
20114d4dee0aSTakashi Iwai };
20124d4dee0aSTakashi Iwai 
20134d4dee0aSTakashi Iwai #define DEVICE_FLG(vid, pid, _flags) \
20144d4dee0aSTakashi Iwai 	{ .id = USB_ID(vid, pid), .flags = (_flags) }
20154d4dee0aSTakashi Iwai #define VENDOR_FLG(vid, _flags) DEVICE_FLG(vid, 0, _flags)
20164d4dee0aSTakashi Iwai 
20174d4dee0aSTakashi Iwai static const struct usb_audio_quirk_flags_table quirk_flags_table[] = {
20184d4dee0aSTakashi Iwai 	/* Device matches */
20193c69dc91STakashi Iwai 	DEVICE_FLG(0x041e, 0x3000, /* Creative SB Extigy */
20203c69dc91STakashi Iwai 		   QUIRK_FLAG_IGNORE_CTL_ERROR),
20214d4dee0aSTakashi Iwai 	DEVICE_FLG(0x041e, 0x4080, /* Creative Live Cam VF0610 */
20224d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
20233da43506STakashi Iwai 	DEVICE_FLG(0x045e, 0x083c, /* MS USB Link headset */
20243da43506STakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_CTL_MSG_DELAY |
20253da43506STakashi Iwai 		   QUIRK_FLAG_DISABLE_AUTOSUSPEND),
20264d4dee0aSTakashi Iwai 	DEVICE_FLG(0x046d, 0x084c, /* Logitech ConferenceCam Connect */
2027f7483854STakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_CTL_MSG_DELAY_1M),
20283c69dc91STakashi Iwai 	DEVICE_FLG(0x046d, 0x0991, /* Logitech QuickCam Pro */
20293c69dc91STakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_IGNORE_CTL_ERROR),
20303c69dc91STakashi Iwai 	DEVICE_FLG(0x046d, 0x09a4, /* Logitech QuickCam E 3500 */
20313c69dc91STakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY_1M | QUIRK_FLAG_IGNORE_CTL_ERROR),
203267d64069STakashi Iwai 	DEVICE_FLG(0x0499, 0x1509, /* Steinberg UR22 */
203367d64069STakashi Iwai 		   QUIRK_FLAG_GENERIC_IMPLICIT_FB),
203449ab71baSJulian Sikorski 	DEVICE_FLG(0x0499, 0x3108, /* Yamaha YIT-W12TX */
203549ab71baSJulian Sikorski 		   QUIRK_FLAG_GET_SAMPLE_RATE),
20364d4dee0aSTakashi Iwai 	DEVICE_FLG(0x04d8, 0xfeea, /* Benchmark DAC1 Pre */
20374d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
2038f21dca85STakashi Iwai 	DEVICE_FLG(0x04e8, 0xa051, /* Samsung USBC Headset (AKG) */
2039f7483854STakashi Iwai 		   QUIRK_FLAG_SKIP_CLOCK_SELECTOR | QUIRK_FLAG_CTL_MSG_DELAY_5M),
20402fbdc116STakashi Iwai 	DEVICE_FLG(0x0525, 0xa4ad, /* Hamedal C20 usb camero */
20412fbdc116STakashi Iwai 		   QUIRK_FLAG_IFACE_SKIP_CLOSE),
20426e413409STakashi Iwai 	DEVICE_FLG(0x054c, 0x0b8c, /* Sony WALKMAN NW-A45 DAC */
20436e413409STakashi Iwai 		   QUIRK_FLAG_SET_IFACE_FIRST),
20444d4dee0aSTakashi Iwai 	DEVICE_FLG(0x0556, 0x0014, /* Phoenix Audio TMX320VC */
20454d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
20464d4dee0aSTakashi Iwai 	DEVICE_FLG(0x05a3, 0x9420, /* ELP HD USB Camera */
20474d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
20484d4dee0aSTakashi Iwai 	DEVICE_FLG(0x05a7, 0x1020, /* Bose Companion 5 */
20494d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
2050af158a7fSTakashi Iwai 	DEVICE_FLG(0x05e1, 0x0408, /* Syntek STK1160 */
2051af158a7fSTakashi Iwai 		   QUIRK_FLAG_ALIGN_TRANSFER),
2052ce47d47eSTakashi Iwai 	DEVICE_FLG(0x05e1, 0x0480, /* Hauppauge Woodbury */
2053af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
20542de00d5aSTakashi Iwai 	DEVICE_FLG(0x0644, 0x8043, /* TEAC UD-501/UD-501V2/UD-503/NT-503 */
20551f074fe5STakashi Iwai 		   QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY |
20561f074fe5STakashi Iwai 		   QUIRK_FLAG_IFACE_DELAY),
20572de00d5aSTakashi Iwai 	DEVICE_FLG(0x0644, 0x8044, /* Esoteric D-05X */
20581f074fe5STakashi Iwai 		   QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY |
20591f074fe5STakashi Iwai 		   QUIRK_FLAG_IFACE_DELAY),
20602de00d5aSTakashi Iwai 	DEVICE_FLG(0x0644, 0x804a, /* TEAC UD-301 */
20611f074fe5STakashi Iwai 		   QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY |
20621f074fe5STakashi Iwai 		   QUIRK_FLAG_IFACE_DELAY),
206367df411dSJohn Keeping 	DEVICE_FLG(0x0644, 0x805f, /* TEAC Model 12 */
206467df411dSJohn Keeping 		   QUIRK_FLAG_FORCE_IFACE_RESET),
2065f7fea075SJussi Laako 	DEVICE_FLG(0x0644, 0x806b, /* TEAC UD-701 */
2066f7fea075SJussi Laako 		   QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY |
2067f7fea075SJussi Laako 		   QUIRK_FLAG_IFACE_DELAY),
20683c69dc91STakashi Iwai 	DEVICE_FLG(0x06f8, 0xb000, /* Hercules DJ Console (Windows Edition) */
20693c69dc91STakashi Iwai 		   QUIRK_FLAG_IGNORE_CTL_ERROR),
20703c69dc91STakashi Iwai 	DEVICE_FLG(0x06f8, 0xd002, /* Hercules DJ Console (Macintosh Edition) */
20713c69dc91STakashi Iwai 		   QUIRK_FLAG_IGNORE_CTL_ERROR),
2072d7be2138SForest Crossman 	DEVICE_FLG(0x0711, 0x5800, /* MCT Trigger 5 USB-to-HDMI */
2073d7be2138SForest Crossman 		   QUIRK_FLAG_GET_SAMPLE_RATE),
20744d4dee0aSTakashi Iwai 	DEVICE_FLG(0x074d, 0x3553, /* Outlaw RR2150 (Micronas UAC3553B) */
20754d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
207667d64069STakashi Iwai 	DEVICE_FLG(0x0763, 0x2030, /* M-Audio Fast Track C400 */
207767d64069STakashi Iwai 		   QUIRK_FLAG_GENERIC_IMPLICIT_FB),
207867d64069STakashi Iwai 	DEVICE_FLG(0x0763, 0x2031, /* M-Audio Fast Track C600 */
207967d64069STakashi Iwai 		   QUIRK_FLAG_GENERIC_IMPLICIT_FB),
2080790053c7SAlexander Tsoy 	DEVICE_FLG(0x07fd, 0x000b, /* MOTU M Series 2nd hardware revision */
2081790053c7SAlexander Tsoy 		   QUIRK_FLAG_CTL_MSG_DELAY_1M),
20823c69dc91STakashi Iwai 	DEVICE_FLG(0x08bb, 0x2702, /* LineX FM Transmitter */
20833c69dc91STakashi Iwai 		   QUIRK_FLAG_IGNORE_CTL_ERROR),
2084f7483854STakashi Iwai 	DEVICE_FLG(0x0951, 0x16ad, /* Kingston HyperX */
2085f7483854STakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY_1M),
2086f7483854STakashi Iwai 	DEVICE_FLG(0x0b0e, 0x0349, /* Jabra 550a */
2087f7483854STakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY_1M),
2088fe3a28bfSwangdicheng 	DEVICE_FLG(0x0c45, 0x6340, /* Sonix HD USB Camera */
2089fe3a28bfSwangdicheng 		   QUIRK_FLAG_GET_SAMPLE_RATE),
20902fbdc116STakashi Iwai 	DEVICE_FLG(0x0ecb, 0x205c, /* JBL Quantum610 Wireless */
20912fbdc116STakashi Iwai 		   QUIRK_FLAG_FIXED_RATE),
20922fbdc116STakashi Iwai 	DEVICE_FLG(0x0ecb, 0x2069, /* JBL Quantum810 Wireless */
20932fbdc116STakashi Iwai 		   QUIRK_FLAG_FIXED_RATE),
2094ce47d47eSTakashi Iwai 	DEVICE_FLG(0x0fd9, 0x0008, /* Hauppauge HVR-950Q */
2095af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
20962fbdc116STakashi Iwai 	DEVICE_FLG(0x1224, 0x2a25, /* Jieli Technology USB PHY 2.0 */
20972fbdc116STakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
20984d4dee0aSTakashi Iwai 	DEVICE_FLG(0x1395, 0x740a, /* Sennheiser DECT */
20994d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
2100e086c37fSTakashi Iwai 	DEVICE_FLG(0x1397, 0x0507, /* Behringer UMC202HD */
2101e086c37fSTakashi Iwai 		   QUIRK_FLAG_PLAYBACK_FIRST | QUIRK_FLAG_GENERIC_IMPLICIT_FB),
2102ae8b1631STakashi Iwai 	DEVICE_FLG(0x1397, 0x0508, /* Behringer UMC204HD */
2103ae8b1631STakashi Iwai 		   QUIRK_FLAG_PLAYBACK_FIRST | QUIRK_FLAG_GENERIC_IMPLICIT_FB),
2104ae8b1631STakashi Iwai 	DEVICE_FLG(0x1397, 0x0509, /* Behringer UMC404HD */
2105ae8b1631STakashi Iwai 		   QUIRK_FLAG_PLAYBACK_FIRST | QUIRK_FLAG_GENERIC_IMPLICIT_FB),
21063c69dc91STakashi Iwai 	DEVICE_FLG(0x13e5, 0x0001, /* Serato Phono */
21073c69dc91STakashi Iwai 		   QUIRK_FLAG_IGNORE_CTL_ERROR),
21082de00d5aSTakashi Iwai 	DEVICE_FLG(0x154e, 0x1002, /* Denon DCD-1500RE */
2109f7483854STakashi Iwai 		   QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY),
21102de00d5aSTakashi Iwai 	DEVICE_FLG(0x154e, 0x1003, /* Denon DA-300USB */
2111f7483854STakashi Iwai 		   QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY),
21122de00d5aSTakashi Iwai 	DEVICE_FLG(0x154e, 0x3005, /* Marantz HD-DAC1 */
2113f7483854STakashi Iwai 		   QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY),
21142de00d5aSTakashi Iwai 	DEVICE_FLG(0x154e, 0x3006, /* Marantz SA-14S1 */
2115f7483854STakashi Iwai 		   QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY),
2116f7fea075SJussi Laako 	DEVICE_FLG(0x154e, 0x300b, /* Marantz SA-KI RUBY / SA-12 */
2117f7fea075SJussi Laako 		   QUIRK_FLAG_DSD_RAW),
2118f21dca85STakashi Iwai 	DEVICE_FLG(0x154e, 0x500e, /* Denon DN-X1600 */
2119f21dca85STakashi Iwai 		   QUIRK_FLAG_IGNORE_CLOCK_SOURCE),
2120c1b034a4STakashi Iwai 	DEVICE_FLG(0x1686, 0x00dd, /* Zoom R16/24 */
2121f7483854STakashi Iwai 		   QUIRK_FLAG_TX_LENGTH | QUIRK_FLAG_CTL_MSG_DELAY_1M),
212244e6fc64STakashi Iwai 	DEVICE_FLG(0x17aa, 0x1046, /* Lenovo ThinkStation P620 Rear Line-in, Line-out and Microphone */
212344e6fc64STakashi Iwai 		   QUIRK_FLAG_DISABLE_AUTOSUSPEND),
212444e6fc64STakashi Iwai 	DEVICE_FLG(0x17aa, 0x104d, /* Lenovo ThinkStation P620 Internal Speaker + Front Headset */
212544e6fc64STakashi Iwai 		   QUIRK_FLAG_DISABLE_AUTOSUSPEND),
21262de00d5aSTakashi Iwai 	DEVICE_FLG(0x1852, 0x5065, /* Luxman DA-06 */
2127f7483854STakashi Iwai 		   QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY),
21284d4dee0aSTakashi Iwai 	DEVICE_FLG(0x1901, 0x0191, /* GE B850V3 CP2114 audio interface */
21294d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
21302fbdc116STakashi Iwai 	DEVICE_FLG(0x19f7, 0x0035, /* RODE NT-USB+ */
21312fbdc116STakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
21323e81a7a9STakashi Iwai 	DEVICE_FLG(0x1bcf, 0x2281, /* HD Webcam */
21333e81a7a9STakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
21342fbdc116STakashi Iwai 	DEVICE_FLG(0x1bcf, 0x2283, /* NexiGo N930AF FHD Webcam */
21352fbdc116STakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
2136ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x7200, /* Hauppauge HVR-950Q */
2137af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2138ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x7201, /* Hauppauge HVR-950Q-MXL */
2139af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2140ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x7210, /* Hauppauge HVR-950Q */
2141af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2142ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x7211, /* Hauppauge HVR-950Q-MXL */
2143af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2144ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x7213, /* Hauppauge HVR-950Q */
2145af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2146ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x7217, /* Hauppauge HVR-950Q */
2147af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2148ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x721b, /* Hauppauge HVR-950Q */
2149af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2150ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x721e, /* Hauppauge HVR-950Q */
2151af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2152ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x721f, /* Hauppauge HVR-950Q */
2153af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2154ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x7240, /* Hauppauge HVR-850 */
2155af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2156ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x7260, /* Hauppauge HVR-950Q */
2157af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2158ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x7270, /* Hauppauge HVR-950Q */
2159af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2160ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x7280, /* Hauppauge HVR-950Q */
2161af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2162ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x7281, /* Hauppauge HVR-950Q-MXL */
2163af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
2164ce47d47eSTakashi Iwai 	DEVICE_FLG(0x2040, 0x8200, /* Hauppauge Woodbury */
2165af158a7fSTakashi Iwai 		   QUIRK_FLAG_SHARE_MEDIA_DEVICE | QUIRK_FLAG_ALIGN_TRANSFER),
21664d4dee0aSTakashi Iwai 	DEVICE_FLG(0x21b4, 0x0081, /* AudioQuest DragonFly */
21674d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
2168f7fea075SJussi Laako 	DEVICE_FLG(0x21b4, 0x0230, /* Ayre QB-9 Twenty */
2169f7fea075SJussi Laako 		   QUIRK_FLAG_DSD_RAW),
2170f7fea075SJussi Laako 	DEVICE_FLG(0x21b4, 0x0232, /* Ayre QX-5 Twenty */
2171f7fea075SJussi Laako 		   QUIRK_FLAG_DSD_RAW),
21725f3d9e81STakashi Iwai 	DEVICE_FLG(0x2522, 0x0007, /* LH Labs Geek Out HD Audio 1V5 */
21735f3d9e81STakashi Iwai 		   QUIRK_FLAG_SET_IFACE_FIRST),
2174df0380b9STakashi Iwai 	DEVICE_FLG(0x2708, 0x0002, /* Audient iD14 */
2175df0380b9STakashi Iwai 		   QUIRK_FLAG_IGNORE_CTL_ERROR),
21764d4dee0aSTakashi Iwai 	DEVICE_FLG(0x2912, 0x30c8, /* Audioengine D1 */
21774d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
21782fbdc116STakashi Iwai 	DEVICE_FLG(0x2b53, 0x0023, /* Fiero SC-01 (firmware v1.0.0 @ 48 kHz) */
21792fbdc116STakashi Iwai 		   QUIRK_FLAG_GENERIC_IMPLICIT_FB),
21802fbdc116STakashi Iwai 	DEVICE_FLG(0x2b53, 0x0024, /* Fiero SC-01 (firmware v1.0.0 @ 96 kHz) */
21812fbdc116STakashi Iwai 		   QUIRK_FLAG_GENERIC_IMPLICIT_FB),
21822fbdc116STakashi Iwai 	DEVICE_FLG(0x2b53, 0x0031, /* Fiero SC-01 (firmware v1.1.0) */
21832fbdc116STakashi Iwai 		   QUIRK_FLAG_GENERIC_IMPLICIT_FB),
2184*82d06b81SLianqin Hu 	DEVICE_FLG(0x2d95, 0x8021, /* VIVO USB-C-XE710 HEADSET */
2185*82d06b81SLianqin Hu 		   QUIRK_FLAG_CTL_MSG_DELAY_1M),
218622390ce7SGreg Kroah-Hartman 	DEVICE_FLG(0x30be, 0x0101, /* Schiit Hel */
218722390ce7SGreg Kroah-Hartman 		   QUIRK_FLAG_IGNORE_CTL_ERROR),
21884d4dee0aSTakashi Iwai 	DEVICE_FLG(0x413c, 0xa506, /* Dell AE515 sound bar */
21894d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
21906e2c9105SJohn Veness 	DEVICE_FLG(0x534d, 0x0021, /* MacroSilicon MS2100/MS2106 */
21916e2c9105SJohn Veness 		   QUIRK_FLAG_ALIGN_TRANSFER),
2192af158a7fSTakashi Iwai 	DEVICE_FLG(0x534d, 0x2109, /* MacroSilicon MS2109 */
2193af158a7fSTakashi Iwai 		   QUIRK_FLAG_ALIGN_TRANSFER),
21944d4dee0aSTakashi Iwai 
21954d4dee0aSTakashi Iwai 	/* Vendor matches */
21964d4dee0aSTakashi Iwai 	VENDOR_FLG(0x045e, /* MS Lifecam */
21974d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
2198f7483854STakashi Iwai 	VENDOR_FLG(0x046d, /* Logitech */
2199f7483854STakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY_1M),
22004d4dee0aSTakashi Iwai 	VENDOR_FLG(0x047f, /* Plantronics */
2201f7483854STakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE | QUIRK_FLAG_CTL_MSG_DELAY),
2202f7483854STakashi Iwai 	VENDOR_FLG(0x0644, /* TEAC Corp. */
22031f074fe5STakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY | QUIRK_FLAG_IFACE_DELAY),
22048bfe17adSTakashi Iwai 	VENDOR_FLG(0x07fd, /* MOTU */
22058bfe17adSTakashi Iwai 		   QUIRK_FLAG_VALIDATE_RATES),
22065963e526STakashi Iwai 	VENDOR_FLG(0x1235, /* Focusrite Novation */
22075963e526STakashi Iwai 		   QUIRK_FLAG_VALIDATE_RATES),
2208f7fea075SJussi Laako 	VENDOR_FLG(0x1511, /* AURALiC */
2209f7fea075SJussi Laako 		   QUIRK_FLAG_DSD_RAW),
221068e851eeSTakashi Iwai 	VENDOR_FLG(0x152a, /* Thesycon devices */
221168e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
2212f7fea075SJussi Laako 	VENDOR_FLG(0x18d1, /* iBasso devices */
2213f7fea075SJussi Laako 		   QUIRK_FLAG_DSD_RAW),
22144d4dee0aSTakashi Iwai 	VENDOR_FLG(0x1de7, /* Phoenix Audio */
22154d4dee0aSTakashi Iwai 		   QUIRK_FLAG_GET_SAMPLE_RATE),
221668e851eeSTakashi Iwai 	VENDOR_FLG(0x20b1, /* XMOS based devices */
221768e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
2218f7fea075SJussi Laako 	VENDOR_FLG(0x21ed, /* Accuphase Laboratory */
2219f7fea075SJussi Laako 		   QUIRK_FLAG_DSD_RAW),
222068e851eeSTakashi Iwai 	VENDOR_FLG(0x22d9, /* Oppo */
222168e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
2222f7483854STakashi Iwai 	VENDOR_FLG(0x23ba, /* Playback Design */
222368e851eeSTakashi Iwai 		   QUIRK_FLAG_CTL_MSG_DELAY | QUIRK_FLAG_IFACE_DELAY |
222468e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
222568e851eeSTakashi Iwai 	VENDOR_FLG(0x25ce, /* Mytek devices */
222668e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
222768e851eeSTakashi Iwai 	VENDOR_FLG(0x278b, /* Rotel? */
222868e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
222968e851eeSTakashi Iwai 	VENDOR_FLG(0x292b, /* Gustard/Ess based devices */
223068e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
223168e851eeSTakashi Iwai 	VENDOR_FLG(0x2972, /* FiiO devices */
223268e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
223368e851eeSTakashi Iwai 	VENDOR_FLG(0x2ab6, /* T+A devices */
223468e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
2235aa771b1eSMax McCarthy 	VENDOR_FLG(0x2afd, /* McIntosh Laboratory, Inc. */
2236aa771b1eSMax McCarthy 		   QUIRK_FLAG_DSD_RAW),
2237f7fea075SJussi Laako 	VENDOR_FLG(0x2d87, /* Cayin device */
2238f7fea075SJussi Laako 		   QUIRK_FLAG_DSD_RAW),
2239122e2cb7SLukasz Tyl 	VENDOR_FLG(0x3336, /* HEM devices */
2240122e2cb7SLukasz Tyl 		   QUIRK_FLAG_DSD_RAW),
224168e851eeSTakashi Iwai 	VENDOR_FLG(0x3353, /* Khadas devices */
224268e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
2243f7fea075SJussi Laako 	VENDOR_FLG(0x35f4, /* MSB Technology */
2244f7fea075SJussi Laako 		   QUIRK_FLAG_DSD_RAW),
224568e851eeSTakashi Iwai 	VENDOR_FLG(0x3842, /* EVGA */
224668e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
224768e851eeSTakashi Iwai 	VENDOR_FLG(0xc502, /* HiBy devices */
224868e851eeSTakashi Iwai 		   QUIRK_FLAG_DSD_RAW),
22494d4dee0aSTakashi Iwai 
22504d4dee0aSTakashi Iwai 	{} /* terminator */
22514d4dee0aSTakashi Iwai };
22524d4dee0aSTakashi Iwai 
snd_usb_init_quirk_flags(struct snd_usb_audio * chip)22534d4dee0aSTakashi Iwai void snd_usb_init_quirk_flags(struct snd_usb_audio *chip)
22544d4dee0aSTakashi Iwai {
22554d4dee0aSTakashi Iwai 	const struct usb_audio_quirk_flags_table *p;
22564d4dee0aSTakashi Iwai 
22574d4dee0aSTakashi Iwai 	for (p = quirk_flags_table; p->id; p++) {
22584d4dee0aSTakashi Iwai 		if (chip->usb_id == p->id ||
22594d4dee0aSTakashi Iwai 		    (!USB_ID_PRODUCT(p->id) &&
22604d4dee0aSTakashi Iwai 		     USB_ID_VENDOR(chip->usb_id) == USB_ID_VENDOR(p->id))) {
22614d4dee0aSTakashi Iwai 			usb_audio_dbg(chip,
22624d4dee0aSTakashi Iwai 				      "Set quirk_flags 0x%x for device %04x:%04x\n",
22634d4dee0aSTakashi Iwai 				      p->flags, USB_ID_VENDOR(chip->usb_id),
22644d4dee0aSTakashi Iwai 				      USB_ID_PRODUCT(chip->usb_id));
22654d4dee0aSTakashi Iwai 			chip->quirk_flags |= p->flags;
22664d4dee0aSTakashi Iwai 			return;
22674d4dee0aSTakashi Iwai 		}
22684d4dee0aSTakashi Iwai 	}
22694d4dee0aSTakashi Iwai }
2270