Messages in this thread Patch in this message | | | From | Arseniy Lartsev <> | Subject | [PATCH] ALSA: usb-audio: add implicit feedback quirk for Yamaha P-125 | Date | Thu, 02 Jan 2020 18:16:52 +0100 |
| |
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@alumni.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
| |