summaryrefslogtreecommitdiff
path: root/sound/usb/implicit.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2021-04-14 10:32:55 +0200
committerTakashi Iwai <tiwai@suse.de>2021-04-14 14:24:22 +0200
commitebe8dc5afb3912e2d4f5c62cf7c492a13143a77a (patch)
tree6bc1eb3e80c598688df4c4a3d7610fcb267ed578 /sound/usb/implicit.c
parent543f8d780867bdbd8b0792487fa1644d89faa19c (diff)
downloadlwn-ebe8dc5afb3912e2d4f5c62cf7c492a13143a77a.tar.gz
lwn-ebe8dc5afb3912e2d4f5c62cf7c492a13143a77a.zip
ALSA: usb-audio: Apply implicit feedback mode for BOSS devices
During the recent rewrite of the implicit feedback support, we've tested to apply the implicit fb on BOSS devices, but it failed, as the capture stream didn't start without the playback. As the end result, it got another type of quirk for tying both streams but starts playback always (commit 6234fdc1cede "ALSA: usb-audio: Quirk for BOSS GT-001"). Meanwhile, Mike Oliphant has tested the real implicit feedback mode for the playback again with the latest code, and found out that it actually works if the initial feedback sync is skipped; that is, on those BOSS devices, the playback stream has to be started at first without waiting for the capture URB completions. Otherwise it gets stuck. In the rest operations after the capture stream processed, we can take them as the implicit feedback source. This patch is an attempt to improve the support for BOSS devices with the implicit feedback mode in the way described above. It adds a new flag to snd_usb_audio, playback_first, indicating that the playback stream starts without sync with the initial capture completion. This flag is set in the quirk table with the new IMPLICIT_FB_BOTH type. Reported-and-tested-by: Mike Oliphant <oliphant@nostatic.org> Link: https://lore.kernel.org/r/20210414083255.9527-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/usb/implicit.c')
-rw-r--r--sound/usb/implicit.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/sound/usb/implicit.c b/sound/usb/implicit.c
index 19622c58b72b..4bd9c105a529 100644
--- a/sound/usb/implicit.c
+++ b/sound/usb/implicit.c
@@ -21,6 +21,7 @@ enum {
IMPLICIT_FB_NONE,
IMPLICIT_FB_GENERIC,
IMPLICIT_FB_FIXED,
+ IMPLICIT_FB_BOTH, /* generic playback + capture (for BOSS) */
};
struct snd_usb_implicit_fb_match {
@@ -36,6 +37,9 @@ struct snd_usb_implicit_fb_match {
#define IMPLICIT_FB_FIXED_DEV(vend, prod, ep, ifnum) \
{ .id = USB_ID(vend, prod), .type = IMPLICIT_FB_FIXED, .ep_num = (ep),\
.iface = (ifnum) }
+#define IMPLICIT_FB_BOTH_DEV(vend, prod, ep, ifnum) \
+ { .id = USB_ID(vend, prod), .type = IMPLICIT_FB_BOTH, .ep_num = (ep),\
+ .iface = (ifnum) }
#define IMPLICIT_FB_SKIP_DEV(vend, prod) \
{ .id = USB_ID(vend, prod), .type = IMPLICIT_FB_NONE }
@@ -75,14 +79,14 @@ static const struct snd_usb_implicit_fb_match playback_implicit_fb_quirks[] = {
/* Implicit feedback quirk table for capture: only FIXED type */
static const struct snd_usb_implicit_fb_match capture_implicit_fb_quirks[] = {
- IMPLICIT_FB_FIXED_DEV(0x0582, 0x0130, 0x0d, 0x01), /* BOSS BR-80 */
- IMPLICIT_FB_FIXED_DEV(0x0582, 0x0171, 0x0d, 0x01), /* BOSS RC-505 */
- IMPLICIT_FB_FIXED_DEV(0x0582, 0x0185, 0x0d, 0x01), /* BOSS GP-10 */
- IMPLICIT_FB_FIXED_DEV(0x0582, 0x0189, 0x0d, 0x01), /* BOSS GT-100v2 */
- IMPLICIT_FB_FIXED_DEV(0x0582, 0x01d6, 0x0d, 0x01), /* BOSS GT-1 */
- IMPLICIT_FB_FIXED_DEV(0x0582, 0x01d8, 0x0d, 0x01), /* BOSS Katana */
- IMPLICIT_FB_FIXED_DEV(0x0582, 0x01e5, 0x0d, 0x01), /* BOSS GT-001 */
- IMPLICIT_FB_FIXED_DEV(0x0582, 0x0203, 0x0d, 0x01), /* BOSS AD-10 */
+ IMPLICIT_FB_BOTH_DEV(0x0582, 0x0130, 0x0d, 0x01), /* BOSS BR-80 */
+ IMPLICIT_FB_BOTH_DEV(0x0582, 0x0171, 0x0d, 0x01), /* BOSS RC-505 */
+ IMPLICIT_FB_BOTH_DEV(0x0582, 0x0185, 0x0d, 0x01), /* BOSS GP-10 */
+ IMPLICIT_FB_BOTH_DEV(0x0582, 0x0189, 0x0d, 0x01), /* BOSS GT-100v2 */
+ IMPLICIT_FB_BOTH_DEV(0x0582, 0x01d6, 0x0d, 0x01), /* BOSS GT-1 */
+ IMPLICIT_FB_BOTH_DEV(0x0582, 0x01d8, 0x0d, 0x01), /* BOSS Katana */
+ IMPLICIT_FB_BOTH_DEV(0x0582, 0x01e5, 0x0d, 0x01), /* BOSS GT-001 */
+ IMPLICIT_FB_BOTH_DEV(0x0582, 0x0203, 0x0d, 0x01), /* BOSS AD-10 */
{} /* terminator */
};
@@ -268,10 +272,17 @@ static int audioformat_implicit_fb_quirk(struct snd_usb_audio *chip,
}
}
- /* Don't apply playback quirks for the devices with capture quirk */
+ /* Special handling for devices with capture quirks */
p = find_implicit_fb_entry(chip, capture_implicit_fb_quirks, alts);
- if (p && p->type == IMPLICIT_FB_FIXED)
- return 0; /* no quirk */
+ if (p) {
+ switch (p->type) {
+ case IMPLICIT_FB_FIXED:
+ return 0; /* no quirk */
+ case IMPLICIT_FB_BOTH:
+ chip->playback_first = 1;
+ return add_generic_implicit_fb(chip, fmt, alts);
+ }
+ }
/* Generic UAC2 implicit feedback */
if (attr == USB_ENDPOINT_SYNC_ASYNC &&
@@ -321,7 +332,7 @@ static int audioformat_capture_quirk(struct snd_usb_audio *chip,
const struct snd_usb_implicit_fb_match *p;
p = find_implicit_fb_entry(chip, capture_implicit_fb_quirks, alts);
- if (p && p->type == IMPLICIT_FB_FIXED)
+ if (p && (p->type == IMPLICIT_FB_FIXED || p->type == IMPLICIT_FB_BOTH))
return add_implicit_fb_sync_ep(chip, fmt, p->ep_num, 0,
p->iface, NULL);
return 0;