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