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