Skip to content

Commit 167c9dc

Browse files
committed
ALSA: usb-audio: Fix implicit feedback sync setup for Pioneer devices
Pioneer devices have both playback and capture streams sharing the same iface/altsetting, and those need to be paired as implicit feedback. Instead of a half-baked (and broken) static quirk entry, set up more generically for those devices by checking the number of endpoints and the attribute of the secondary EP. Fixes: bf6313a ("ALSA: usb-audio: Refactor endpoint management") Reported-by: František Kučera <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent eae4d05 commit 167c9dc

File tree

1 file changed

+38
-10
lines changed

1 file changed

+38
-10
lines changed

sound/usb/implicit.c

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,6 @@ static const struct snd_usb_implicit_fb_match playback_implicit_fb_quirks[] = {
5858
IMPLICIT_FB_FIXED_DEV(0x0499, 0x172f, 0x81, 2), /* Steinberg UR22C */
5959
IMPLICIT_FB_FIXED_DEV(0x0d9a, 0x00df, 0x81, 2), /* RTX6001 */
6060
IMPLICIT_FB_FIXED_DEV(0x22f0, 0x0006, 0x81, 3), /* Allen&Heath Qu-16 */
61-
IMPLICIT_FB_FIXED_DEV(0x2b73, 0x000a, 0x82, 0), /* Pioneer DJ DJM-900NXS2 */
62-
IMPLICIT_FB_FIXED_DEV(0x2b73, 0x0017, 0x82, 0), /* Pioneer DJ DJM-250MK2 */
6361
IMPLICIT_FB_FIXED_DEV(0x1686, 0xf029, 0x82, 2), /* Zoom UAC-2 */
6462
IMPLICIT_FB_FIXED_DEV(0x2466, 0x8003, 0x86, 2), /* Fractal Audio Axe-Fx II */
6563
IMPLICIT_FB_FIXED_DEV(0x0499, 0x172a, 0x86, 2), /* Yamaha MODX */
@@ -100,7 +98,7 @@ static const struct snd_usb_implicit_fb_match capture_implicit_fb_quirks[] = {
10098
/* set up sync EP information on the audioformat */
10199
static int add_implicit_fb_sync_ep(struct snd_usb_audio *chip,
102100
struct audioformat *fmt,
103-
int ep, int ifnum,
101+
int ep, int ep_idx, int ifnum,
104102
const struct usb_host_interface *alts)
105103
{
106104
struct usb_interface *iface;
@@ -115,7 +113,7 @@ static int add_implicit_fb_sync_ep(struct snd_usb_audio *chip,
115113
fmt->sync_ep = ep;
116114
fmt->sync_iface = ifnum;
117115
fmt->sync_altsetting = alts->desc.bAlternateSetting;
118-
fmt->sync_ep_idx = 0;
116+
fmt->sync_ep_idx = ep_idx;
119117
fmt->implicit_fb = 1;
120118
usb_audio_dbg(chip,
121119
"%d:%d: added %s implicit_fb sync_ep %x, iface %d:%d\n",
@@ -147,7 +145,7 @@ static int add_generic_uac2_implicit_fb(struct snd_usb_audio *chip,
147145
(epd->bmAttributes & USB_ENDPOINT_USAGE_MASK) !=
148146
USB_ENDPOINT_USAGE_IMPLICIT_FB)
149147
return 0;
150-
return add_implicit_fb_sync_ep(chip, fmt, epd->bEndpointAddress,
148+
return add_implicit_fb_sync_ep(chip, fmt, epd->bEndpointAddress, 0,
151149
ifnum, alts);
152150
}
153151

@@ -173,10 +171,32 @@ static int add_roland_implicit_fb(struct snd_usb_audio *chip,
173171
(epd->bmAttributes & USB_ENDPOINT_USAGE_MASK) !=
174172
USB_ENDPOINT_USAGE_IMPLICIT_FB)
175173
return 0;
176-
return add_implicit_fb_sync_ep(chip, fmt, epd->bEndpointAddress,
174+
return add_implicit_fb_sync_ep(chip, fmt, epd->bEndpointAddress, 0,
177175
ifnum, alts);
178176
}
179177

178+
/* Pioneer devices: playback and capture streams sharing the same iface/altset
179+
*/
180+
static int add_pioneer_implicit_fb(struct snd_usb_audio *chip,
181+
struct audioformat *fmt,
182+
struct usb_host_interface *alts)
183+
{
184+
struct usb_endpoint_descriptor *epd;
185+
186+
if (alts->desc.bNumEndpoints != 2)
187+
return 0;
188+
189+
epd = get_endpoint(alts, 1);
190+
if (!usb_endpoint_is_isoc_in(epd) ||
191+
(epd->bmAttributes & USB_ENDPOINT_SYNCTYPE) != USB_ENDPOINT_SYNC_ASYNC ||
192+
((epd->bmAttributes & USB_ENDPOINT_USAGE_MASK) !=
193+
USB_ENDPOINT_USAGE_DATA &&
194+
(epd->bmAttributes & USB_ENDPOINT_USAGE_MASK) !=
195+
USB_ENDPOINT_USAGE_IMPLICIT_FB))
196+
return 0;
197+
return add_implicit_fb_sync_ep(chip, fmt, epd->bEndpointAddress, 1,
198+
alts->desc.bInterfaceNumber, alts);
199+
}
180200

181201
static int __add_generic_implicit_fb(struct snd_usb_audio *chip,
182202
struct audioformat *fmt,
@@ -197,7 +217,7 @@ static int __add_generic_implicit_fb(struct snd_usb_audio *chip,
197217
if (!usb_endpoint_is_isoc_in(epd) ||
198218
(epd->bmAttributes & USB_ENDPOINT_SYNCTYPE) != USB_ENDPOINT_SYNC_ASYNC)
199219
return 0;
200-
return add_implicit_fb_sync_ep(chip, fmt, epd->bEndpointAddress,
220+
return add_implicit_fb_sync_ep(chip, fmt, epd->bEndpointAddress, 0,
201221
iface, alts);
202222
}
203223

@@ -250,7 +270,7 @@ static int audioformat_implicit_fb_quirk(struct snd_usb_audio *chip,
250270
case IMPLICIT_FB_NONE:
251271
return 0; /* No quirk */
252272
case IMPLICIT_FB_FIXED:
253-
return add_implicit_fb_sync_ep(chip, fmt, p->ep_num,
273+
return add_implicit_fb_sync_ep(chip, fmt, p->ep_num, 0,
254274
p->iface, NULL);
255275
}
256276
}
@@ -278,6 +298,14 @@ static int audioformat_implicit_fb_quirk(struct snd_usb_audio *chip,
278298
return 1;
279299
}
280300

301+
/* Pioneer devices implicit feedback with vendor spec class */
302+
if (attr == USB_ENDPOINT_SYNC_ASYNC &&
303+
alts->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC &&
304+
USB_ID_VENDOR(chip->usb_id) == 0x2b73 /* Pioneer */) {
305+
if (add_pioneer_implicit_fb(chip, fmt, alts))
306+
return 1;
307+
}
308+
281309
/* Try the generic implicit fb if available */
282310
if (chip->generic_implicit_fb)
283311
return add_generic_implicit_fb(chip, fmt, alts);
@@ -295,8 +323,8 @@ static int audioformat_capture_quirk(struct snd_usb_audio *chip,
295323

296324
p = find_implicit_fb_entry(chip, capture_implicit_fb_quirks, alts);
297325
if (p && p->type == IMPLICIT_FB_FIXED)
298-
return add_implicit_fb_sync_ep(chip, fmt, p->ep_num, p->iface,
299-
NULL);
326+
return add_implicit_fb_sync_ep(chip, fmt, p->ep_num, 0,
327+
p->iface, NULL);
300328
return 0;
301329
}
302330

0 commit comments

Comments
 (0)