ALSA: usb-audio: Drop implicit fb quirk entries dubbed for capture
[platform/kernel/linux-starfive.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_GENERIC,
23         IMPLICIT_FB_FIXED,
24 };
25
26 struct snd_usb_implicit_fb_match {
27         unsigned int id;
28         unsigned int iface_class;
29         unsigned int ep_num;
30         unsigned int iface;
31         int type;
32 };
33
34 #define IMPLICIT_FB_GENERIC_DEV(vend, prod) \
35         { .id = USB_ID(vend, prod), .type = IMPLICIT_FB_GENERIC }
36 #define IMPLICIT_FB_FIXED_DEV(vend, prod, ep, ifnum) \
37         { .id = USB_ID(vend, prod), .type = IMPLICIT_FB_FIXED, .ep_num = (ep),\
38             .iface = (ifnum) }
39 #define IMPLICIT_FB_SKIP_DEV(vend, prod) \
40         { .id = USB_ID(vend, prod), .type = IMPLICIT_FB_NONE }
41
42 /* Implicit feedback quirk table for playback */
43 static const struct snd_usb_implicit_fb_match playback_implicit_fb_quirks[] = {
44         /* Generic matching */
45         IMPLICIT_FB_GENERIC_DEV(0x0499, 0x1509), /* Steinberg UR22 */
46         IMPLICIT_FB_GENERIC_DEV(0x0763, 0x2080), /* M-Audio FastTrack Ultra */
47         IMPLICIT_FB_GENERIC_DEV(0x0763, 0x2081), /* M-Audio FastTrack Ultra */
48         IMPLICIT_FB_GENERIC_DEV(0x0763, 0x2030), /* M-Audio Fast Track C400 */
49         IMPLICIT_FB_GENERIC_DEV(0x0763, 0x2031), /* M-Audio Fast Track C600 */
50
51         /* Fixed EP */
52         /* FIXME: check the availability of generic matching */
53         IMPLICIT_FB_FIXED_DEV(0x1397, 0x0001, 0x81, 1), /* Behringer UFX1604 */
54         IMPLICIT_FB_FIXED_DEV(0x1397, 0x0002, 0x81, 1), /* Behringer UFX1204 */
55         IMPLICIT_FB_FIXED_DEV(0x2466, 0x8010, 0x81, 2), /* Fractal Audio Axe-Fx III */
56         IMPLICIT_FB_FIXED_DEV(0x31e9, 0x0001, 0x81, 2), /* Solid State Logic SSL2 */
57         IMPLICIT_FB_FIXED_DEV(0x31e9, 0x0002, 0x81, 2), /* Solid State Logic SSL2+ */
58         IMPLICIT_FB_FIXED_DEV(0x0499, 0x172f, 0x81, 2), /* Steinberg UR22C */
59         IMPLICIT_FB_FIXED_DEV(0x0d9a, 0x00df, 0x81, 2), /* RTX6001 */
60         IMPLICIT_FB_FIXED_DEV(0x22f0, 0x0006, 0x81, 3), /* Allen&Heath Qu-16 */
61         IMPLICIT_FB_FIXED_DEV(0x1686, 0xf029, 0x82, 2), /* Zoom UAC-2 */
62         IMPLICIT_FB_FIXED_DEV(0x2466, 0x8003, 0x86, 2), /* Fractal Audio Axe-Fx II */
63         IMPLICIT_FB_FIXED_DEV(0x0499, 0x172a, 0x86, 2), /* Yamaha MODX */
64
65         /* Special matching */
66         { .id = USB_ID(0x07fd, 0x0004), .iface_class = USB_CLASS_AUDIO,
67           .type = IMPLICIT_FB_NONE },           /* MicroBook IIc */
68         /* ep = 0x84, ifnum = 0 */
69         { .id = USB_ID(0x07fd, 0x0004), .iface_class = USB_CLASS_VENDOR_SPEC,
70           .type = IMPLICIT_FB_FIXED,
71           .ep_num = 0x84, .iface = 0 },         /* MOTU MicroBook II */
72
73         {} /* terminator */
74 };
75
76 /* Implicit feedback quirk table for capture: only FIXED type */
77 static const struct snd_usb_implicit_fb_match capture_implicit_fb_quirks[] = {
78         IMPLICIT_FB_FIXED_DEV(0x0582, 0x0130, 0x0d, 0x01), /* BOSS BR-80 */
79         IMPLICIT_FB_FIXED_DEV(0x0582, 0x0171, 0x0d, 0x01), /* BOSS RC-505 */
80         IMPLICIT_FB_FIXED_DEV(0x0582, 0x0185, 0x0d, 0x01), /* BOSS GP-10 */
81         IMPLICIT_FB_FIXED_DEV(0x0582, 0x0189, 0x0d, 0x01), /* BOSS GT-100v2 */
82         IMPLICIT_FB_FIXED_DEV(0x0582, 0x01d6, 0x0d, 0x01), /* BOSS GT-1 */
83         IMPLICIT_FB_FIXED_DEV(0x0582, 0x01d8, 0x0d, 0x01), /* BOSS Katana */
84         IMPLICIT_FB_FIXED_DEV(0x0582, 0x01e5, 0x0d, 0x01), /* BOSS GT-001 */
85         IMPLICIT_FB_FIXED_DEV(0x0582, 0x0203, 0x0d, 0x01), /* BOSS AD-10 */
86
87         {} /* terminator */
88 };
89
90 /* set up sync EP information on the audioformat */
91 static int add_implicit_fb_sync_ep(struct snd_usb_audio *chip,
92                                    struct audioformat *fmt,
93                                    int ep, int ep_idx, int ifnum,
94                                    const struct usb_host_interface *alts)
95 {
96         struct usb_interface *iface;
97
98         if (!alts) {
99                 iface = usb_ifnum_to_if(chip->dev, ifnum);
100                 if (!iface || iface->num_altsetting < 2)
101                         return 0;
102                 alts = &iface->altsetting[1];
103         }
104
105         fmt->sync_ep = ep;
106         fmt->sync_iface = ifnum;
107         fmt->sync_altsetting = alts->desc.bAlternateSetting;
108         fmt->sync_ep_idx = ep_idx;
109         fmt->implicit_fb = 1;
110         usb_audio_dbg(chip,
111                       "%d:%d: added %s implicit_fb sync_ep %x, iface %d:%d\n",
112                       fmt->iface, fmt->altsetting,
113                       (ep & USB_DIR_IN) ? "playback" : "capture",
114                       fmt->sync_ep, fmt->sync_iface, fmt->sync_altsetting);
115         return 1;
116 }
117
118 /* Check whether the given UAC2 iface:altset points to an implicit fb source */
119 static int add_generic_uac2_implicit_fb(struct snd_usb_audio *chip,
120                                         struct audioformat *fmt,
121                                         unsigned int ifnum,
122                                         unsigned int altsetting)
123 {
124         struct usb_host_interface *alts;
125         struct usb_endpoint_descriptor *epd;
126
127         alts = snd_usb_get_host_interface(chip, ifnum, altsetting);
128         if (!alts)
129                 return 0;
130         if (alts->desc.bInterfaceClass != USB_CLASS_AUDIO ||
131             alts->desc.bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING ||
132             alts->desc.bInterfaceProtocol != UAC_VERSION_2 ||
133             alts->desc.bNumEndpoints < 1)
134                 return 0;
135         epd = get_endpoint(alts, 0);
136         if (!usb_endpoint_is_isoc_in(epd) ||
137             (epd->bmAttributes & USB_ENDPOINT_USAGE_MASK) !=
138                                         USB_ENDPOINT_USAGE_IMPLICIT_FB)
139                 return 0;
140         return add_implicit_fb_sync_ep(chip, fmt, epd->bEndpointAddress, 0,
141                                        ifnum, alts);
142 }
143
144 /* Like the function above, but specific to Roland with vendor class and hack */
145 static int add_roland_implicit_fb(struct snd_usb_audio *chip,
146                                   struct audioformat *fmt,
147                                   unsigned int ifnum,
148                                   unsigned int altsetting)
149 {
150         struct usb_host_interface *alts;
151         struct usb_endpoint_descriptor *epd;
152
153         alts = snd_usb_get_host_interface(chip, ifnum, altsetting);
154         if (!alts)
155                 return 0;
156         if (alts->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC ||
157             (alts->desc.bInterfaceSubClass != 2 &&
158              alts->desc.bInterfaceProtocol != 2) ||
159             alts->desc.bNumEndpoints < 1)
160                 return 0;
161         epd = get_endpoint(alts, 0);
162         if (!usb_endpoint_is_isoc_in(epd) ||
163             (epd->bmAttributes & USB_ENDPOINT_USAGE_MASK) !=
164                                         USB_ENDPOINT_USAGE_IMPLICIT_FB)
165                 return 0;
166         return add_implicit_fb_sync_ep(chip, fmt, epd->bEndpointAddress, 0,
167                                        ifnum, alts);
168 }
169
170 /* Playback and capture EPs on Pioneer devices share the same iface/altset,
171  * but they don't seem working with the implicit fb mode well, hence we
172  * just return as if the sync were already set up.
173  */
174 static int skip_pioneer_sync_ep(struct snd_usb_audio *chip,
175                                 struct audioformat *fmt,
176                                 struct usb_host_interface *alts)
177 {
178         struct usb_endpoint_descriptor *epd;
179
180         if (alts->desc.bNumEndpoints != 2)
181                 return 0;
182
183         epd = get_endpoint(alts, 1);
184         if (!usb_endpoint_is_isoc_in(epd) ||
185             (epd->bmAttributes & USB_ENDPOINT_SYNCTYPE) != USB_ENDPOINT_SYNC_ASYNC ||
186             ((epd->bmAttributes & USB_ENDPOINT_USAGE_MASK) !=
187              USB_ENDPOINT_USAGE_DATA &&
188              (epd->bmAttributes & USB_ENDPOINT_USAGE_MASK) !=
189              USB_ENDPOINT_USAGE_IMPLICIT_FB))
190                 return 0;
191         return 1; /* don't handle with the implicit fb, just skip sync EP */
192 }
193
194 static int __add_generic_implicit_fb(struct snd_usb_audio *chip,
195                                      struct audioformat *fmt,
196                                      int iface, int altset)
197 {
198         struct usb_host_interface *alts;
199         struct usb_endpoint_descriptor *epd;
200
201         alts = snd_usb_get_host_interface(chip, iface, altset);
202         if (!alts)
203                 return 0;
204
205         if ((alts->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC &&
206              alts->desc.bInterfaceClass != USB_CLASS_AUDIO) ||
207             alts->desc.bNumEndpoints < 1)
208                 return 0;
209         epd = get_endpoint(alts, 0);
210         if (!usb_endpoint_is_isoc_in(epd) ||
211             (epd->bmAttributes & USB_ENDPOINT_SYNCTYPE) != USB_ENDPOINT_SYNC_ASYNC)
212                 return 0;
213         return add_implicit_fb_sync_ep(chip, fmt, epd->bEndpointAddress, 0,
214                                        iface, alts);
215 }
216
217 /* More generic quirk: look for the sync EP next to the data EP */
218 static int add_generic_implicit_fb(struct snd_usb_audio *chip,
219                                    struct audioformat *fmt,
220                                    struct usb_host_interface *alts)
221 {
222         if ((fmt->ep_attr & USB_ENDPOINT_SYNCTYPE) != USB_ENDPOINT_SYNC_ASYNC)
223                 return 0;
224
225         if (__add_generic_implicit_fb(chip, fmt,
226                                       alts->desc.bInterfaceNumber + 1,
227                                       alts->desc.bAlternateSetting))
228                 return 1;
229         return __add_generic_implicit_fb(chip, fmt,
230                                          alts->desc.bInterfaceNumber - 1,
231                                          alts->desc.bAlternateSetting);
232 }
233
234 static const struct snd_usb_implicit_fb_match *
235 find_implicit_fb_entry(struct snd_usb_audio *chip,
236                        const struct snd_usb_implicit_fb_match *match,
237                        const struct usb_host_interface *alts)
238 {
239         for (; match->id; match++)
240                 if (match->id == chip->usb_id &&
241                     (!match->iface_class ||
242                      (alts->desc.bInterfaceClass == match->iface_class)))
243                         return match;
244
245         return NULL;
246 }
247
248 /* Setup an implicit feedback endpoint from a quirk. Returns 0 if no quirk
249  * applies. Returns 1 if a quirk was found.
250  */
251 static int audioformat_implicit_fb_quirk(struct snd_usb_audio *chip,
252                                          struct audioformat *fmt,
253                                          struct usb_host_interface *alts)
254 {
255         const struct snd_usb_implicit_fb_match *p;
256         unsigned int attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
257
258         p = find_implicit_fb_entry(chip, playback_implicit_fb_quirks, alts);
259         if (p) {
260                 switch (p->type) {
261                 case IMPLICIT_FB_GENERIC:
262                         return add_generic_implicit_fb(chip, fmt, alts);
263                 case IMPLICIT_FB_NONE:
264                         return 0; /* No quirk */
265                 case IMPLICIT_FB_FIXED:
266                         return add_implicit_fb_sync_ep(chip, fmt, p->ep_num, 0,
267                                                        p->iface, NULL);
268                 }
269         }
270
271         /* Don't apply playback quirks for the devices with capture quirk */
272         p = find_implicit_fb_entry(chip, capture_implicit_fb_quirks, alts);
273         if (p && p->type == IMPLICIT_FB_FIXED)
274                 return 0; /* no quirk */
275
276         /* Generic UAC2 implicit feedback */
277         if (attr == USB_ENDPOINT_SYNC_ASYNC &&
278             alts->desc.bInterfaceClass == USB_CLASS_AUDIO &&
279             alts->desc.bInterfaceProtocol == UAC_VERSION_2 &&
280             alts->desc.bNumEndpoints == 1) {
281                 if (add_generic_uac2_implicit_fb(chip, fmt,
282                                                  alts->desc.bInterfaceNumber + 1,
283                                                  alts->desc.bAlternateSetting))
284                         return 1;
285         }
286
287         /* Roland/BOSS implicit feedback with vendor spec class */
288         if (attr == USB_ENDPOINT_SYNC_ASYNC &&
289             alts->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC &&
290             alts->desc.bInterfaceProtocol == 2 &&
291             alts->desc.bNumEndpoints == 1 &&
292             USB_ID_VENDOR(chip->usb_id) == 0x0582 /* Roland */) {
293                 if (add_roland_implicit_fb(chip, fmt,
294                                            alts->desc.bInterfaceNumber + 1,
295                                            alts->desc.bAlternateSetting))
296                         return 1;
297         }
298
299         /* Pioneer devices with vendor spec class */
300         if (attr == USB_ENDPOINT_SYNC_ASYNC &&
301             alts->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC &&
302             (USB_ID_VENDOR(chip->usb_id) == 0x2b73 || /* Pioneer */
303              USB_ID_VENDOR(chip->usb_id) == 0x08e4    /* Pioneer */)) {
304                 if (skip_pioneer_sync_ep(chip, fmt, alts))
305                         return 1;
306         }
307
308         /* Try the generic implicit fb if available */
309         if (chip->generic_implicit_fb)
310                 return add_generic_implicit_fb(chip, fmt, alts);
311
312         /* No quirk */
313         return 0;
314 }
315
316 /* same for capture, but only handling FIXED entry */
317 static int audioformat_capture_quirk(struct snd_usb_audio *chip,
318                                      struct audioformat *fmt,
319                                      struct usb_host_interface *alts)
320 {
321         const struct snd_usb_implicit_fb_match *p;
322
323         p = find_implicit_fb_entry(chip, capture_implicit_fb_quirks, alts);
324         if (p && p->type == IMPLICIT_FB_FIXED)
325                 return add_implicit_fb_sync_ep(chip, fmt, p->ep_num, 0,
326                                                p->iface, NULL);
327         return 0;
328 }
329
330 /*
331  * Parse altset and set up implicit feedback endpoint on the audioformat
332  */
333 int snd_usb_parse_implicit_fb_quirk(struct snd_usb_audio *chip,
334                                     struct audioformat *fmt,
335                                     struct usb_host_interface *alts)
336 {
337         if (fmt->endpoint & USB_DIR_IN)
338                 return audioformat_capture_quirk(chip, fmt, alts);
339         else
340                 return audioformat_implicit_fb_quirk(chip, fmt, alts);
341 }
342
343 /*
344  * Return the score of matching two audioformats.
345  * Veto the audioformat if:
346  * - It has no channels for some reason.
347  * - Requested PCM format is not supported.
348  * - Requested sample rate is not supported.
349  */
350 static int match_endpoint_audioformats(struct snd_usb_substream *subs,
351                                        const struct audioformat *fp,
352                                        int rate, int channels,
353                                        snd_pcm_format_t pcm_format)
354 {
355         int i, score;
356
357         if (fp->channels < 1)
358                 return 0;
359
360         if (!(fp->formats & pcm_format_to_bits(pcm_format)))
361                 return 0;
362
363         if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) {
364                 if (rate < fp->rate_min || rate > fp->rate_max)
365                         return 0;
366         } else {
367                 for (i = 0; i < fp->nr_rates; i++) {
368                         if (fp->rate_table[i] == rate)
369                                 break;
370                 }
371                 if (i >= fp->nr_rates)
372                         return 0;
373         }
374
375         score = 1;
376         if (fp->channels == channels)
377                 score++;
378
379         return score;
380 }
381
382 static struct snd_usb_substream *
383 find_matching_substream(struct snd_usb_audio *chip, int stream, int ep_num,
384                         int fmt_type)
385 {
386         struct snd_usb_stream *as;
387         struct snd_usb_substream *subs;
388
389         list_for_each_entry(as, &chip->pcm_list, list) {
390                 subs = &as->substream[stream];
391                 if (as->fmt_type == fmt_type && subs->ep_num == ep_num)
392                         return subs;
393         }
394
395         return NULL;
396 }
397
398 /*
399  * Return the audioformat that is suitable for the implicit fb
400  */
401 const struct audioformat *
402 snd_usb_find_implicit_fb_sync_format(struct snd_usb_audio *chip,
403                                      const struct audioformat *target,
404                                      const struct snd_pcm_hw_params *params,
405                                      int stream)
406 {
407         struct snd_usb_substream *subs;
408         const struct audioformat *fp, *sync_fmt = NULL;
409         int score, high_score;
410
411         /* Use the original audioformat as fallback for the shared altset */
412         if (target->iface == target->sync_iface &&
413             target->altsetting == target->sync_altsetting)
414                 sync_fmt = target;
415
416         subs = find_matching_substream(chip, stream, target->sync_ep,
417                                        target->fmt_type);
418         if (!subs)
419                 return sync_fmt;
420
421         high_score = 0;
422         list_for_each_entry(fp, &subs->fmt_list, list) {
423                 score = match_endpoint_audioformats(subs, fp,
424                                                     params_rate(params),
425                                                     params_channels(params),
426                                                     params_format(params));
427                 if (score > high_score) {
428                         sync_fmt = fp;
429                         high_score = score;
430                 }
431         }
432
433         return sync_fmt;
434 }
435