0001
0002
0003
0004
0005
0006 #include <linux/init.h>
0007 #include <linux/usb.h>
0008 #include <linux/usb/audio.h>
0009 #include <linux/usb/audio-v2.h>
0010
0011 #include <sound/core.h>
0012 #include <sound/pcm.h>
0013 #include <sound/pcm_params.h>
0014
0015 #include "usbaudio.h"
0016 #include "card.h"
0017 #include "helper.h"
0018 #include "implicit.h"
0019
0020 enum {
0021 IMPLICIT_FB_NONE,
0022 IMPLICIT_FB_GENERIC,
0023 IMPLICIT_FB_FIXED,
0024 IMPLICIT_FB_BOTH,
0025 };
0026
0027 struct snd_usb_implicit_fb_match {
0028 unsigned int id;
0029 unsigned int iface_class;
0030 unsigned int ep_num;
0031 unsigned int iface;
0032 int type;
0033 };
0034
0035 #define IMPLICIT_FB_GENERIC_DEV(vend, prod) \
0036 { .id = USB_ID(vend, prod), .type = IMPLICIT_FB_GENERIC }
0037 #define IMPLICIT_FB_FIXED_DEV(vend, prod, ep, ifnum) \
0038 { .id = USB_ID(vend, prod), .type = IMPLICIT_FB_FIXED, .ep_num = (ep),\
0039 .iface = (ifnum) }
0040 #define IMPLICIT_FB_BOTH_DEV(vend, prod, ep, ifnum) \
0041 { .id = USB_ID(vend, prod), .type = IMPLICIT_FB_BOTH, .ep_num = (ep),\
0042 .iface = (ifnum) }
0043 #define IMPLICIT_FB_SKIP_DEV(vend, prod) \
0044 { .id = USB_ID(vend, prod), .type = IMPLICIT_FB_NONE }
0045
0046
0047 static const struct snd_usb_implicit_fb_match playback_implicit_fb_quirks[] = {
0048
0049
0050 IMPLICIT_FB_FIXED_DEV(0x0763, 0x2080, 0x81, 2),
0051 IMPLICIT_FB_FIXED_DEV(0x0763, 0x2081, 0x81, 2),
0052 IMPLICIT_FB_FIXED_DEV(0x2466, 0x8010, 0x81, 2),
0053 IMPLICIT_FB_FIXED_DEV(0x31e9, 0x0001, 0x81, 2),
0054 IMPLICIT_FB_FIXED_DEV(0x31e9, 0x0002, 0x81, 2),
0055 IMPLICIT_FB_FIXED_DEV(0x0499, 0x172f, 0x81, 2),
0056 IMPLICIT_FB_FIXED_DEV(0x0d9a, 0x00df, 0x81, 2),
0057 IMPLICIT_FB_FIXED_DEV(0x22f0, 0x0006, 0x81, 3),
0058 IMPLICIT_FB_FIXED_DEV(0x1686, 0xf029, 0x82, 2),
0059 IMPLICIT_FB_FIXED_DEV(0x2466, 0x8003, 0x86, 2),
0060 IMPLICIT_FB_FIXED_DEV(0x0499, 0x172a, 0x86, 2),
0061
0062
0063 { .id = USB_ID(0x07fd, 0x0004), .iface_class = USB_CLASS_AUDIO,
0064 .type = IMPLICIT_FB_NONE },
0065
0066 { .id = USB_ID(0x07fd, 0x0004), .iface_class = USB_CLASS_VENDOR_SPEC,
0067 .type = IMPLICIT_FB_FIXED,
0068 .ep_num = 0x84, .iface = 0 },
0069
0070 {}
0071 };
0072
0073
0074 static const struct snd_usb_implicit_fb_match capture_implicit_fb_quirks[] = {
0075 {}
0076 };
0077
0078
0079 static int add_implicit_fb_sync_ep(struct snd_usb_audio *chip,
0080 struct audioformat *fmt,
0081 int ep, int ep_idx, int ifnum,
0082 const struct usb_host_interface *alts)
0083 {
0084 struct usb_interface *iface;
0085
0086 if (!alts) {
0087 iface = usb_ifnum_to_if(chip->dev, ifnum);
0088 if (!iface || iface->num_altsetting < 2)
0089 return 0;
0090 alts = &iface->altsetting[1];
0091 }
0092
0093 fmt->sync_ep = ep;
0094 fmt->sync_iface = ifnum;
0095 fmt->sync_altsetting = alts->desc.bAlternateSetting;
0096 fmt->sync_ep_idx = ep_idx;
0097 fmt->implicit_fb = 1;
0098 usb_audio_dbg(chip,
0099 "%d:%d: added %s implicit_fb sync_ep %x, iface %d:%d\n",
0100 fmt->iface, fmt->altsetting,
0101 (ep & USB_DIR_IN) ? "playback" : "capture",
0102 fmt->sync_ep, fmt->sync_iface, fmt->sync_altsetting);
0103 return 1;
0104 }
0105
0106
0107 static int add_generic_uac2_implicit_fb(struct snd_usb_audio *chip,
0108 struct audioformat *fmt,
0109 unsigned int ifnum,
0110 unsigned int altsetting)
0111 {
0112 struct usb_host_interface *alts;
0113 struct usb_endpoint_descriptor *epd;
0114
0115 alts = snd_usb_get_host_interface(chip, ifnum, altsetting);
0116 if (!alts)
0117 return 0;
0118 if (alts->desc.bInterfaceClass != USB_CLASS_AUDIO ||
0119 alts->desc.bInterfaceSubClass != USB_SUBCLASS_AUDIOSTREAMING ||
0120 alts->desc.bInterfaceProtocol != UAC_VERSION_2 ||
0121 alts->desc.bNumEndpoints < 1)
0122 return 0;
0123 epd = get_endpoint(alts, 0);
0124 if (!usb_endpoint_is_isoc_in(epd) ||
0125 (epd->bmAttributes & USB_ENDPOINT_USAGE_MASK) !=
0126 USB_ENDPOINT_USAGE_IMPLICIT_FB)
0127 return 0;
0128 return add_implicit_fb_sync_ep(chip, fmt, epd->bEndpointAddress, 0,
0129 ifnum, alts);
0130 }
0131
0132 static bool roland_sanity_check_iface(struct usb_host_interface *alts)
0133 {
0134 if (alts->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC ||
0135 (alts->desc.bInterfaceSubClass != 2 &&
0136 alts->desc.bInterfaceProtocol != 2) ||
0137 alts->desc.bNumEndpoints < 1)
0138 return false;
0139 return true;
0140 }
0141
0142
0143 static int add_roland_implicit_fb(struct snd_usb_audio *chip,
0144 struct audioformat *fmt,
0145 struct usb_host_interface *alts)
0146 {
0147 struct usb_endpoint_descriptor *epd;
0148
0149 if (!roland_sanity_check_iface(alts))
0150 return 0;
0151
0152 epd = get_endpoint(alts, 0);
0153 if (!usb_endpoint_is_isoc_out(epd) ||
0154 (epd->bmAttributes & USB_ENDPOINT_SYNCTYPE) != USB_ENDPOINT_SYNC_ASYNC)
0155 return 0;
0156
0157
0158 alts = snd_usb_get_host_interface(chip,
0159 alts->desc.bInterfaceNumber + 1,
0160 alts->desc.bAlternateSetting);
0161 if (!alts || !roland_sanity_check_iface(alts))
0162 return 0;
0163 epd = get_endpoint(alts, 0);
0164 if (!usb_endpoint_is_isoc_in(epd) ||
0165 (epd->bmAttributes & USB_ENDPOINT_SYNCTYPE) != USB_ENDPOINT_SYNC_ASYNC)
0166 return 0;
0167 chip->quirk_flags |= QUIRK_FLAG_PLAYBACK_FIRST;
0168 return add_implicit_fb_sync_ep(chip, fmt, epd->bEndpointAddress, 0,
0169 alts->desc.bInterfaceNumber, alts);
0170 }
0171
0172
0173 static int add_roland_capture_quirk(struct snd_usb_audio *chip,
0174 struct audioformat *fmt,
0175 struct usb_host_interface *alts)
0176 {
0177 struct usb_endpoint_descriptor *epd;
0178
0179 if (!roland_sanity_check_iface(alts))
0180 return 0;
0181 epd = get_endpoint(alts, 0);
0182 if (!usb_endpoint_is_isoc_in(epd) ||
0183 (epd->bmAttributes & USB_ENDPOINT_SYNCTYPE) != USB_ENDPOINT_SYNC_ASYNC)
0184 return 0;
0185
0186 alts = snd_usb_get_host_interface(chip,
0187 alts->desc.bInterfaceNumber - 1,
0188 alts->desc.bAlternateSetting);
0189 if (!alts || !roland_sanity_check_iface(alts))
0190 return 0;
0191 epd = get_endpoint(alts, 0);
0192 if (!usb_endpoint_is_isoc_out(epd))
0193 return 0;
0194 return add_implicit_fb_sync_ep(chip, fmt, epd->bEndpointAddress, 0,
0195 alts->desc.bInterfaceNumber, alts);
0196 }
0197
0198
0199
0200
0201 static bool is_pioneer_implicit_fb(struct snd_usb_audio *chip,
0202 struct usb_host_interface *alts)
0203
0204 {
0205 struct usb_endpoint_descriptor *epd;
0206
0207 if (USB_ID_VENDOR(chip->usb_id) != 0x2b73 &&
0208 USB_ID_VENDOR(chip->usb_id) != 0x08e4)
0209 return false;
0210 if (alts->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
0211 return false;
0212 if (alts->desc.bNumEndpoints != 2)
0213 return false;
0214
0215 epd = get_endpoint(alts, 0);
0216 if (!usb_endpoint_is_isoc_out(epd) ||
0217 (epd->bmAttributes & USB_ENDPOINT_SYNCTYPE) != USB_ENDPOINT_SYNC_ASYNC)
0218 return false;
0219
0220 epd = get_endpoint(alts, 1);
0221 if (!usb_endpoint_is_isoc_in(epd) ||
0222 (epd->bmAttributes & USB_ENDPOINT_SYNCTYPE) != USB_ENDPOINT_SYNC_ASYNC ||
0223 ((epd->bmAttributes & USB_ENDPOINT_USAGE_MASK) !=
0224 USB_ENDPOINT_USAGE_DATA &&
0225 (epd->bmAttributes & USB_ENDPOINT_USAGE_MASK) !=
0226 USB_ENDPOINT_USAGE_IMPLICIT_FB))
0227 return false;
0228
0229 return true;
0230 }
0231
0232 static int __add_generic_implicit_fb(struct snd_usb_audio *chip,
0233 struct audioformat *fmt,
0234 int iface, int altset)
0235 {
0236 struct usb_host_interface *alts;
0237 struct usb_endpoint_descriptor *epd;
0238
0239 alts = snd_usb_get_host_interface(chip, iface, altset);
0240 if (!alts)
0241 return 0;
0242
0243 if ((alts->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC &&
0244 alts->desc.bInterfaceClass != USB_CLASS_AUDIO) ||
0245 alts->desc.bNumEndpoints < 1)
0246 return 0;
0247 epd = get_endpoint(alts, 0);
0248 if (!usb_endpoint_is_isoc_in(epd) ||
0249 (epd->bmAttributes & USB_ENDPOINT_SYNCTYPE) != USB_ENDPOINT_SYNC_ASYNC)
0250 return 0;
0251 return add_implicit_fb_sync_ep(chip, fmt, epd->bEndpointAddress, 0,
0252 iface, alts);
0253 }
0254
0255
0256 static int add_generic_implicit_fb(struct snd_usb_audio *chip,
0257 struct audioformat *fmt,
0258 struct usb_host_interface *alts)
0259 {
0260 if ((fmt->ep_attr & USB_ENDPOINT_SYNCTYPE) != USB_ENDPOINT_SYNC_ASYNC)
0261 return 0;
0262
0263 if (__add_generic_implicit_fb(chip, fmt,
0264 alts->desc.bInterfaceNumber + 1,
0265 alts->desc.bAlternateSetting))
0266 return 1;
0267 return __add_generic_implicit_fb(chip, fmt,
0268 alts->desc.bInterfaceNumber - 1,
0269 alts->desc.bAlternateSetting);
0270 }
0271
0272 static const struct snd_usb_implicit_fb_match *
0273 find_implicit_fb_entry(struct snd_usb_audio *chip,
0274 const struct snd_usb_implicit_fb_match *match,
0275 const struct usb_host_interface *alts)
0276 {
0277 for (; match->id; match++)
0278 if (match->id == chip->usb_id &&
0279 (!match->iface_class ||
0280 (alts->desc.bInterfaceClass == match->iface_class)))
0281 return match;
0282
0283 return NULL;
0284 }
0285
0286
0287
0288
0289 static int audioformat_implicit_fb_quirk(struct snd_usb_audio *chip,
0290 struct audioformat *fmt,
0291 struct usb_host_interface *alts)
0292 {
0293 const struct snd_usb_implicit_fb_match *p;
0294 unsigned int attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
0295
0296 p = find_implicit_fb_entry(chip, playback_implicit_fb_quirks, alts);
0297 if (p) {
0298 switch (p->type) {
0299 case IMPLICIT_FB_GENERIC:
0300 return add_generic_implicit_fb(chip, fmt, alts);
0301 case IMPLICIT_FB_NONE:
0302 return 0;
0303 case IMPLICIT_FB_FIXED:
0304 return add_implicit_fb_sync_ep(chip, fmt, p->ep_num, 0,
0305 p->iface, NULL);
0306 }
0307 }
0308
0309
0310 p = find_implicit_fb_entry(chip, capture_implicit_fb_quirks, alts);
0311 if (p) {
0312 switch (p->type) {
0313 case IMPLICIT_FB_FIXED:
0314 return 0;
0315 case IMPLICIT_FB_BOTH:
0316 chip->quirk_flags |= QUIRK_FLAG_PLAYBACK_FIRST;
0317 return add_generic_implicit_fb(chip, fmt, alts);
0318 }
0319 }
0320
0321
0322 if (attr == USB_ENDPOINT_SYNC_ASYNC &&
0323 alts->desc.bInterfaceClass == USB_CLASS_AUDIO &&
0324 alts->desc.bInterfaceProtocol == UAC_VERSION_2 &&
0325 alts->desc.bNumEndpoints == 1) {
0326 if (add_generic_uac2_implicit_fb(chip, fmt,
0327 alts->desc.bInterfaceNumber + 1,
0328 alts->desc.bAlternateSetting))
0329 return 1;
0330 }
0331
0332
0333 if (USB_ID_VENDOR(chip->usb_id) == 0x0582) {
0334 if (add_roland_implicit_fb(chip, fmt, alts) > 0)
0335 return 1;
0336 }
0337
0338
0339 if (is_pioneer_implicit_fb(chip, alts)) {
0340 chip->quirk_flags |= QUIRK_FLAG_PLAYBACK_FIRST;
0341 return add_implicit_fb_sync_ep(chip, fmt,
0342 get_endpoint(alts, 1)->bEndpointAddress,
0343 1, alts->desc.bInterfaceNumber,
0344 alts);
0345 }
0346
0347
0348 if (chip->generic_implicit_fb ||
0349 (chip->quirk_flags & QUIRK_FLAG_GENERIC_IMPLICIT_FB))
0350 return add_generic_implicit_fb(chip, fmt, alts);
0351
0352
0353 return 0;
0354 }
0355
0356
0357 static int audioformat_capture_quirk(struct snd_usb_audio *chip,
0358 struct audioformat *fmt,
0359 struct usb_host_interface *alts)
0360 {
0361 const struct snd_usb_implicit_fb_match *p;
0362
0363 p = find_implicit_fb_entry(chip, capture_implicit_fb_quirks, alts);
0364 if (p && (p->type == IMPLICIT_FB_FIXED || p->type == IMPLICIT_FB_BOTH))
0365 return add_implicit_fb_sync_ep(chip, fmt, p->ep_num, 0,
0366 p->iface, NULL);
0367
0368
0369 if (USB_ID_VENDOR(chip->usb_id) == 0x0582) {
0370 if (add_roland_capture_quirk(chip, fmt, alts) > 0)
0371 return 1;
0372 }
0373
0374 if (is_pioneer_implicit_fb(chip, alts))
0375 return 1;
0376 return 0;
0377 }
0378
0379
0380
0381
0382 int snd_usb_parse_implicit_fb_quirk(struct snd_usb_audio *chip,
0383 struct audioformat *fmt,
0384 struct usb_host_interface *alts)
0385 {
0386 if (chip->quirk_flags & QUIRK_FLAG_SKIP_IMPLICIT_FB)
0387 return 0;
0388 if (fmt->endpoint & USB_DIR_IN)
0389 return audioformat_capture_quirk(chip, fmt, alts);
0390 else
0391 return audioformat_implicit_fb_quirk(chip, fmt, alts);
0392 }
0393
0394
0395
0396
0397
0398
0399
0400
0401 static int match_endpoint_audioformats(struct snd_usb_substream *subs,
0402 const struct audioformat *fp,
0403 int rate, int channels,
0404 snd_pcm_format_t pcm_format)
0405 {
0406 int i, score;
0407
0408 if (fp->channels < 1)
0409 return 0;
0410
0411 if (!(fp->formats & pcm_format_to_bits(pcm_format)))
0412 return 0;
0413
0414 if (fp->rates & SNDRV_PCM_RATE_CONTINUOUS) {
0415 if (rate < fp->rate_min || rate > fp->rate_max)
0416 return 0;
0417 } else {
0418 for (i = 0; i < fp->nr_rates; i++) {
0419 if (fp->rate_table[i] == rate)
0420 break;
0421 }
0422 if (i >= fp->nr_rates)
0423 return 0;
0424 }
0425
0426 score = 1;
0427 if (fp->channels == channels)
0428 score++;
0429
0430 return score;
0431 }
0432
0433 static struct snd_usb_substream *
0434 find_matching_substream(struct snd_usb_audio *chip, int stream, int ep_num,
0435 int fmt_type)
0436 {
0437 struct snd_usb_stream *as;
0438 struct snd_usb_substream *subs;
0439
0440 list_for_each_entry(as, &chip->pcm_list, list) {
0441 subs = &as->substream[stream];
0442 if (as->fmt_type == fmt_type && subs->ep_num == ep_num)
0443 return subs;
0444 }
0445
0446 return NULL;
0447 }
0448
0449
0450
0451
0452 const struct audioformat *
0453 snd_usb_find_implicit_fb_sync_format(struct snd_usb_audio *chip,
0454 const struct audioformat *target,
0455 const struct snd_pcm_hw_params *params,
0456 int stream)
0457 {
0458 struct snd_usb_substream *subs;
0459 const struct audioformat *fp, *sync_fmt = NULL;
0460 int score, high_score;
0461
0462
0463 if (target->iface == target->sync_iface &&
0464 target->altsetting == target->sync_altsetting)
0465 sync_fmt = target;
0466
0467 subs = find_matching_substream(chip, stream, target->sync_ep,
0468 target->fmt_type);
0469 if (!subs)
0470 return sync_fmt;
0471
0472 high_score = 0;
0473 list_for_each_entry(fp, &subs->fmt_list, list) {
0474 score = match_endpoint_audioformats(subs, fp,
0475 params_rate(params),
0476 params_channels(params),
0477 params_format(params));
0478 if (score > high_score) {
0479 sync_fmt = fp;
0480 high_score = score;
0481 }
0482 }
0483
0484 return sync_fmt;
0485 }
0486