bc7edecff946cbf196ff024c06837d1b0bb58964
[linux-2.6-microblaze.git] / sound / usb / implicit.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 //
3 // Special handling for implicit feedback mode
4 //
5
6 #include <linux/init.h>
7 #include <linux/usb.h>
8 #include <linux/usb/audio.h>
9 #include <linux/usb/audio-v2.h>
10
11 #include <sound/core.h>
12 #include <sound/pcm.h>
13 #include <sound/pcm_params.h>
14
15 #include "usbaudio.h"
16 #include "card.h"
17 #include "helper.h"
18 #include "implicit.h"
19
20 enum {
21         IMPLICIT_FB_NONE,
22         IMPLICIT_FB_FIXED,
23 };
24
25 struct snd_usb_implicit_fb_match {
26         unsigned int id;
27         unsigned int iface_class;
28         unsigned int ep_num;
29         unsigned int iface;
30         int type;
31 };
32
33 #define IMPLICIT_FB_FIXED_DEV(vend, prod, ep, ifnum) \
34         { .id = USB_ID(vend, prod), .type = IMPLICIT_FB_FIXED, .ep_num = (ep),\
35             .iface = (ifnum) }
36 #define IMPLICIT_FB_SKIP_DEV(vend, prod) \
37         { .id = USB_ID(vend, prod), .type = IMPLICIT_FB_NONE }
38
39 /* Implicit feedback quirk table for playback */
40 static const struct snd_usb_implicit_fb_match playback_implicit_fb_quirks[] = {
41         /* Fixed EP */
42         IMPLICIT_FB_FIXED_DEV(0x1397, 0x0001, 0x81, 1), /* Behringer UFX1604 */
43         IMPLICIT_FB_FIXED_DEV(0x1397, 0x0002, 0x81, 1), /* Behringer UFX1204 */
44         IMPLICIT_FB_FIXED_DEV(0x0763, 0x2080, 0x81, 2), /* M-Audio FastTrack Ultra */
45         IMPLICIT_FB_FIXED_DEV(0x0763, 0x2081, 0x81, 2), /* M-Audio FastTrack Ultra */
46         IMPLICIT_FB_FIXED_DEV(0x2466, 0x8010, 0x81, 2), /* Fractal Audio Axe-Fx III */
47         IMPLICIT_FB_FIXED_DEV(0x07fd, 0x0008, 0x81, 2), /* MOTU M Series */
48         IMPLICIT_FB_FIXED_DEV(0x31e9, 0x0001, 0x81, 2), /* Solid State Logic SSL2 */
49         IMPLICIT_FB_FIXED_DEV(0x31e9, 0x0002, 0x81, 2), /* Solid State Logic SSL2+ */
50         IMPLICIT_FB_FIXED_DEV(0x0499, 0x172f, 0x81, 2), /* Steinberg UR22C */
51         IMPLICIT_FB_FIXED_DEV(0x0d9a, 0x00df, 0x81, 2), /* RTX6001 */
52         IMPLICIT_FB_FIXED_DEV(0x0763, 0x2030, 0x81, 3), /* M-Audio Fast Track C400 */
53         IMPLICIT_FB_FIXED_DEV(0x0763, 0x2031, 0x81, 3), /* M-Audio Fast Track C600 */
54         IMPLICIT_FB_FIXED_DEV(0x22f0, 0x0006, 0x81, 3), /* Allen&Heath Qu-16 */
55         IMPLICIT_FB_FIXED_DEV(0x2b73, 0x000a, 0x82, 0), /* Pioneer DJ DJM-900NXS2 */
56         IMPLICIT_FB_FIXED_DEV(0x2b73, 0x0017, 0x82, 0), /* Pioneer DJ DJM-250MK2 */
57         IMPLICIT_FB_FIXED_DEV(0x1686, 0xf029, 0x82, 2), /* Zoom UAC-2 */
58         IMPLICIT_FB_FIXED_DEV(0x2466, 0x8003, 0x86, 2), /* Fractal Audio Axe-Fx II */
59         IMPLICIT_FB_FIXED_DEV(0x0499, 0x172a, 0x86, 2), /* Yamaha MODX */
60
61         /* Special matching */
62         { .id = USB_ID(0x07fd, 0x0004), .iface_class = USB_CLASS_AUDIO,
63           .type = IMPLICIT_FB_NONE },           /* MicroBook IIc */
64         /* ep = 0x84, ifnum = 0 */
65         { .id = USB_ID(0x07fd, 0x0004), .iface_class = USB_CLASS_VENDOR_SPEC,
66           .type = IMPLICIT_FB_FIXED,
67           .ep_num = 0x84, .iface = 0 },         /* MOTU MicroBook II */
68
69         /* No quirk */
70         IMPLICIT_FB_SKIP_DEV(0x0582, 0x01d8),   /* BOSS Katana */
71
72         /* No quirk for playback but with capture quirk (see below) */
73         IMPLICIT_FB_SKIP_DEV(0x0582, 0x01e5),   /* BOSS GT-001 */
74
75         {} /* terminator */
76 };
77
78 /* Implicit feedback quirk table for capture */
79 static const struct snd_usb_implicit_fb_match capture_implicit_fb_quirks[] = {
80         IMPLICIT_FB_FIXED_DEV(0x0582, 0x01e5, 0x0d, 0x01), /* BOSS GT-001 */
81
82         {} /* terminator */
83 };
84
85 /* set up sync EP information on the audioformat */
86 static int add_implicit_fb_sync_ep(struct snd_usb_audio *chip,
87                                    struct audioformat *fmt,
88                                    int ep, int ifnum,
89                                    const struct usb_host_interface *alts)
90 {
91         struct usb_interface *iface;
92
93         if (!alts) {
94                 iface = usb_ifnum_to_if(chip->dev, ifnum);
95                 if (!iface || iface->num_altsetting < 2)
96                         return 0;
97                 alts = &iface->altsetting[1];
98         }
99
100         fmt->sync_ep = ep;
101         fmt->sync_iface = ifnum;
102         fmt->sync_altsetting = alts->desc.bAlternateSetting;
103         fmt->sync_ep_idx = 0;
104         fmt->implicit_fb = 1;
105         usb_audio_dbg(chip,
106                       "%d:%d: added %s implicit_fb sync_ep %x, iface %d:%d\n",
107                       fmt->iface, fmt->altsetting,
108                       (ep & USB_DIR_IN) ? "playback" : "capture",
109                       fmt->sync_ep, fmt->sync_iface, fmt->sync_altsetting);
110         return 1;
111 }
112
113 /* Check whether the given UAC2 iface:altset points to an implicit fb source */
114 static int add_generic_uac2_implicit_fb(struct snd_usb_audio *chip,
115                                         struct audioformat *fmt,
116                                         unsigned int ifnum,
117                                         unsigned int altsetting)
118 {
119         struct usb_host_interface *alts;
120         struct usb_endpoint_descriptor *epd;
121
122         alts = snd_usb_get_host_interface(chip, ifnum, altsetting);
123         if (!alts)
124                 return 0;
125         if (alts->desc.bInterfaceClass != USB_CLASS_AUDIO ||
126             alts->desc.bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING ||
127             alts->desc.bInterfaceProtocol != UAC_VERSION_2 ||
128             alts->desc.bNumEndpoints < 1)
129                 return 0;
130         epd = get_endpoint(alts, 0);
131         if (!usb_endpoint_is_isoc_in(epd) ||
132             (epd->bmAttributes & USB_ENDPOINT_USAGE_MASK) !=
133                                         USB_ENDPOINT_USAGE_IMPLICIT_FB)
134                 return 0;
135         return add_implicit_fb_sync_ep(chip, fmt, epd->bEndpointAddress,
136                                        ifnum, alts);
137 }
138
139 /* Like the function above, but specific to Roland with vendor class and hack */
140 static int add_roland_implicit_fb(struct snd_usb_audio *chip,
141                                   struct audioformat *fmt,
142                                   unsigned int ifnum,
143                                   unsigned int altsetting)
144 {
145         struct usb_host_interface *alts;
146         struct usb_endpoint_descriptor *epd;
147
148         alts = snd_usb_get_host_interface(chip, ifnum, altsetting);
149         if (!alts)
150                 return 0;
151         if (alts->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC ||
152             (alts->desc.bInterfaceSubClass != 2 &&
153              alts->desc.bInterfaceProtocol != 2) ||
154             alts->desc.bNumEndpoints < 1)
155                 return 0;
156         epd = get_endpoint(alts, 0);
157         if (!usb_endpoint_is_isoc_in(epd) ||
158             (epd->bmAttributes & USB_ENDPOINT_USAGE_MASK) !=
159                                         USB_ENDPOINT_USAGE_IMPLICIT_FB)
160                 return 0;
161         return add_implicit_fb_sync_ep(chip, fmt, epd->bEndpointAddress,
162                                        ifnum, alts);
163 }
164
165 static const struct snd_usb_implicit_fb_match *
166 find_implicit_fb_entry(struct snd_usb_audio *chip,
167                        const struct snd_usb_implicit_fb_match *match,
168                        const struct usb_host_interface *alts)
169 {
170         for (; match->id; match++)
171                 if (match->id == chip->usb_id &&
172                     (!match->iface_class ||
173                      (alts->desc.bInterfaceClass == match->iface_class)))
174                         return match;
175
176         return NULL;
177 }
178
179 /* Setup an implicit feedback endpoint from a quirk. Returns 0 if no quirk
180  * applies. Returns 1 if a quirk was found.
181  */
182 static int audioformat_implicit_fb_quirk(struct snd_usb_audio *chip,
183                                          struct audioformat *fmt,
184                                          struct usb_host_interface *alts)
185 {
186         const struct snd_usb_implicit_fb_match *p;
187         unsigned int attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
188
189         p = find_implicit_fb_entry(chip, playback_implicit_fb_quirks, alts);
190         if (p) {
191                 switch (p->type) {
192                 case IMPLICIT_FB_NONE:
193                         return 0; /* No quirk */
194                 case IMPLICIT_FB_FIXED:
195                         return add_implicit_fb_sync_ep(chip, fmt, p->ep_num,
196                                                        p->iface, NULL);
197                 }
198         }
199
200         /* Generic UAC2 implicit feedback */
201         if (attr == USB_ENDPOINT_SYNC_ASYNC &&
202             alts->desc.bInterfaceClass == USB_CLASS_AUDIO &&
203             alts->desc.bInterfaceProtocol == UAC_VERSION_2 &&
204             alts->desc.bNumEndpoints == 1) {
205                 if (add_generic_uac2_implicit_fb(chip, fmt,
206                                                  alts->desc.bInterfaceNumber + 1,
207                                                  alts->desc.bAlternateSetting))
208                         return 1;
209         }
210
211         /* Roland/BOSS implicit feedback with vendor spec class */
212         if (attr == USB_ENDPOINT_SYNC_ASYNC &&
213             alts->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC &&
214             alts->desc.bInterfaceProtocol == 2 &&
215             alts->desc.bNumEndpoints == 1 &&
216             USB_ID_VENDOR(chip->usb_id) == 0x0582 /* Roland */) {
217                 if (add_roland_implicit_fb(chip, fmt,
218                                            alts->desc.bInterfaceNumber + 1,
219                                            alts->desc.bAlternateSetting))
220                         return 1;
221         }
222
223         /* No quirk */
224         return 0;
225 }
226
227 /* same for capture, but only handling FIXED entry */
228 static int audioformat_capture_quirk(struct snd_usb_audio *chip,
229                                      struct audioformat *fmt,
230                                      struct usb_host_interface *alts)
231 {
232         const struct snd_usb_implicit_fb_match *p;
233
234         p = find_implicit_fb_entry(chip, capture_implicit_fb_quirks, alts);
235         if (p && p->type == IMPLICIT_FB_FIXED)
236                 return add_implicit_fb_sync_ep(chip, fmt, p->ep_num, p->iface,
237                                                NULL);
238         return 0;
239 }
240
241 /*
242  * Parse altset and set up implicit feedback endpoint on the audioformat
243  */
244 int snd_usb_parse_implicit_fb_quirk(struct snd_usb_audio *chip,
245                                     struct audioformat *fmt,
246                                     struct usb_host_interface *alts)
247 {
248         if (fmt->endpoint & USB_DIR_IN)
249                 return audioformat_capture_quirk(chip, fmt, alts);
250         else
251                 return audioformat_implicit_fb_quirk(chip, fmt, alts);
252 }
253
254 /*
255  * Return the score of matching two audioformats.
256  * Veto the audioformat if:
257  * - It has no channels for some reason.
258  * - Requested PCM format is not supported.
259  * - Requested sample rate is not supported.
260  */
261 static int match_endpoint_audioformats(struct snd_usb_substream *subs,
262                                        const struct audioformat *fp,
263                                        int rate, int channels,
264                                        snd_pcm_format_t pcm_format)
265 {
266         int i, score;
267
268         if (fp->channels < 1)
269                 return 0;
270
271         if (!(fp->formats & pcm_format_to_bits(pcm_format)))
272                 return 0;
273
274         if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) {
275                 if (rate < fp->rate_min || rate > fp->rate_max)
276                         return 0;
277         } else {
278                 for (i = 0; i < fp->nr_rates; i++) {
279                         if (fp->rate_table[i] == rate)
280                                 break;
281                 }
282                 if (i >= fp->nr_rates)
283                         return 0;
284         }
285
286         score = 1;
287         if (fp->channels == channels)
288                 score++;
289
290         return score;
291 }
292
293 static struct snd_usb_substream *
294 find_matching_substream(struct snd_usb_audio *chip, int stream, int ep_num,
295                         int fmt_type)
296 {
297         struct snd_usb_stream *as;
298         struct snd_usb_substream *subs;
299
300         list_for_each_entry(as, &chip->pcm_list, list) {
301                 subs = &as->substream[stream];
302                 if (as->fmt_type == fmt_type && subs->ep_num == ep_num)
303                         return subs;
304         }
305
306         return NULL;
307 }
308
309 /*
310  * Return the audioformat that is suitable for the implicit fb
311  */
312 const struct audioformat *
313 snd_usb_find_implicit_fb_sync_format(struct snd_usb_audio *chip,
314                                      const struct audioformat *target,
315                                      const struct snd_pcm_hw_params *params,
316                                      int stream)
317 {
318         struct snd_usb_substream *subs;
319         const struct audioformat *fp, *sync_fmt;
320         int score, high_score;
321
322         /* When sharing the same altset, use the original audioformat */
323         if (target->iface == target->sync_iface &&
324             target->altsetting == target->sync_altsetting)
325                 return target;
326
327         subs = find_matching_substream(chip, stream, target->sync_ep,
328                                        target->fmt_type);
329         if (!subs)
330                 return NULL;
331
332         sync_fmt = NULL;
333         high_score = 0;
334         list_for_each_entry(fp, &subs->fmt_list, list) {
335                 score = match_endpoint_audioformats(subs, fp,
336                                                     params_rate(params),
337                                                     params_channels(params),
338                                                     params_format(params));
339                 if (score > high_score) {
340                         sync_fmt = fp;
341                         high_score = score;
342                 }
343         }
344
345         return sync_fmt;
346 }
347