ALSA: usb-audio: Avoid implicit feedback on Pioneer devices
authorTakashi Iwai <tiwai@suse.de>
Mon, 18 Jan 2021 07:58:16 +0000 (08:58 +0100)
committerTakashi Iwai <tiwai@suse.de>
Mon, 18 Jan 2021 08:38:13 +0000 (09:38 +0100)
For addressing the regression on Pioneer devices, we recently
corrected the quirk code to enable the implicit feedback mode on those
devices properly.  However, the devices still showed problems with the
full duplex operations with JACK, and after debug sessions, we figured
out that the older kernels that had worked with JACK also didn't use
the implicit feedback mode at all although they had the quirk code to
enable it; instead, the old code worked just to skip the normal sync
endpoint setup that would have been detected without it.  IOW, what
broke without the implicit-fb quirk in the past was the application of
the normal sync endpoint that is actually the capture data endpoint on
these devices.

This patch covers the overseen piece: it modifies the quirk code again
not to enable the implicit feedback mode but just to make the driver
skipping the sync endpoint detection.  This made the driver working
with JACK full-duplex mode again.

Still it's not quite clear why the implicit feedback doesn't work on
those devices yet; maybe it's about some issues in the URB setup.  But
at least, with this patch, the driver should work in the level of the
older kernels again.

Fixes: 167c9dc84ec3 ("ALSA: usb-audio: Fix implicit feedback sync setup for Pioneer devices")
Link: https://lore.kernel.org/r/20210118075816.25068-4-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/usb/implicit.c

index 1ac2cc6..521cc84 100644 (file)
@@ -175,11 +175,13 @@ static int add_roland_implicit_fb(struct snd_usb_audio *chip,
                                       ifnum, alts);
 }
 
-/* Pioneer devices: playback and capture streams sharing the same iface/altset
+/* Playback and capture EPs on Pioneer devices share the same iface/altset,
+ * but they don't seem working with the implicit fb mode well, hence we
+ * just return as if the sync were already set up.
  */
-static int add_pioneer_implicit_fb(struct snd_usb_audio *chip,
-                                  struct audioformat *fmt,
-                                  struct usb_host_interface *alts)
+static int skip_pioneer_sync_ep(struct snd_usb_audio *chip,
+                               struct audioformat *fmt,
+                               struct usb_host_interface *alts)
 {
        struct usb_endpoint_descriptor *epd;
 
@@ -194,8 +196,7 @@ static int add_pioneer_implicit_fb(struct snd_usb_audio *chip,
             (epd->bmAttributes & USB_ENDPOINT_USAGE_MASK) !=
             USB_ENDPOINT_USAGE_IMPLICIT_FB))
                return 0;
-       return add_implicit_fb_sync_ep(chip, fmt, epd->bEndpointAddress, 1,
-                                      alts->desc.bInterfaceNumber, alts);
+       return 1; /* don't handle with the implicit fb, just skip sync EP */
 }
 
 static int __add_generic_implicit_fb(struct snd_usb_audio *chip,
@@ -298,11 +299,11 @@ static int audioformat_implicit_fb_quirk(struct snd_usb_audio *chip,
                        return 1;
        }
 
-       /* Pioneer devices implicit feedback with vendor spec class */
+       /* Pioneer devices with vendor spec class */
        if (attr == USB_ENDPOINT_SYNC_ASYNC &&
            alts->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC &&
            USB_ID_VENDOR(chip->usb_id) == 0x2b73 /* Pioneer */) {
-               if (add_pioneer_implicit_fb(chip, fmt, alts))
+               if (skip_pioneer_sync_ep(chip, fmt, alts))
                        return 1;
        }