[<prev] [next>] [day] [month] [year] [list]
Message-ID: <6288884.Nqi5ZcYBqQ@newline.site>
Date: Thu, 02 Jan 2020 18:16:52 +0100
From: Arseniy Lartsev <arseniy@...mni.chalmers.se>
To: linux-kernel@...r.kernel.org
Subject: [PATCH] ALSA: usb-audio: add implicit feedback quirk for Yamaha P-125
This digital piano has audio playback function with implicit feedback
endpoint.
On this device in particular, if USB host sends samples slightly too fast due
to lack of synchronization (50% chance of that happening), playback will fail
after a few minutes. This patch fixes the problem.
The feedback endpoint is, in fact, very nearly standard-compliant, but
set_sync_endpoint function currently uses different logic for feedback
endpoint discovery - the patch also adds a comment to clarify this behaviour.
Signed-off-by: Arseniy Lartsev <arseniy@...mni.chalmers.se>
---
sound/usb/pcm.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 9c8930b..47ccea6 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -351,6 +351,10 @@ static int set_sync_ep_implicit_fb_quirk(struct
snd_usb_substream *subs,
case USB_ID(0x0582, 0x01d8): /* BOSS Katana */
/* BOSS Katana amplifiers do not need quirks */
return 0;
+ case USB_ID(0x0499, 0x1718): /* Yamaha P-125 digital piano */
+ ep = 0x86;
+ ifnum = 2;
+ goto add_sync_ep_from_ifnum;
}
if (attr == USB_ENDPOINT_SYNC_ASYNC &&
@@ -427,6 +431,21 @@ static int set_sync_endpoint(struct snd_usb_substream
*subs,
if (err > 0)
return 0;
+ /*
+ * Actually, what USB 2.0 standard says is this:
+ *
+ * A feedback endpoint (explicit or implicit) needs to be associated with
+ * one (or more) isochronous data endpoints to which it provides feedback
+ * service. <...> The first data endpoint and the feedback endpoint must
+ * have the same endpoint number (and opposite direction). This ensures
+ * that a data endpoint can uniquely identify its feedback endpoint by
+ * searching for the first feedback endpoint that has an endpoint number
+ * equal or less than its own endpoint number.
+ *
+ * However, it looks like hardware vendors never follow this except by
+ * accident, so we may as well give up on it too. Look for a feedback
+ * endpoint as a second endpoint on the same interface.
+ */
if (altsd->bNumEndpoints < 2)
return 0;
--
2.10.0
Powered by blists - more mailing lists