Skip to content

Commit 73ac9f5

Browse files
puleglottiwai
authored andcommitted
ALSA: usb-audio: Add boot quirk for MOTU M Series
Add delay to make sure that audio urbs are not sent too early. Otherwise the device hangs. Windows driver makes ~2s delay, so use about the same time delay value. snd_usb_apply_boot_quirk() is called 3 times for my MOTU M4, which is an overkill. Thus a quirk that is called only once is implemented. Also send two vendor-specific control messages before and after the delay. This behaviour is blindly copied from the Windows driver. Signed-off-by: Alexander Tsoy <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent 791a485 commit 73ac9f5

File tree

3 files changed

+47
-0
lines changed

3 files changed

+47
-0
lines changed

sound/usb/card.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,10 @@ static int usb_audio_probe(struct usb_interface *intf,
600600
}
601601
}
602602
if (! chip) {
603+
err = snd_usb_apply_boot_quirk_once(dev, intf, quirk, id);
604+
if (err < 0)
605+
return err;
606+
603607
/* it's a fresh one.
604608
* now look for an empty slot and create a new card instance
605609
*/

sound/usb/quirks.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,6 +1113,31 @@ static int snd_usb_motu_microbookii_boot_quirk(struct usb_device *dev)
11131113
return err;
11141114
}
11151115

1116+
static int snd_usb_motu_m_series_boot_quirk(struct usb_device *dev)
1117+
{
1118+
int ret;
1119+
1120+
if (snd_usb_pipe_sanity_check(dev, usb_sndctrlpipe(dev, 0)))
1121+
return -EINVAL;
1122+
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1123+
1, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1124+
0x0, 0, NULL, 0, 1000);
1125+
1126+
if (ret < 0)
1127+
return ret;
1128+
1129+
msleep(2000);
1130+
1131+
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1132+
1, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1133+
0x20, 0, NULL, 0, 1000);
1134+
1135+
if (ret < 0)
1136+
return ret;
1137+
1138+
return 0;
1139+
}
1140+
11161141
/*
11171142
* Setup quirks
11181143
*/
@@ -1297,6 +1322,19 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
12971322
return 0;
12981323
}
12991324

1325+
int snd_usb_apply_boot_quirk_once(struct usb_device *dev,
1326+
struct usb_interface *intf,
1327+
const struct snd_usb_audio_quirk *quirk,
1328+
unsigned int id)
1329+
{
1330+
switch (id) {
1331+
case USB_ID(0x07fd, 0x0008): /* MOTU M Series */
1332+
return snd_usb_motu_m_series_boot_quirk(dev);
1333+
}
1334+
1335+
return 0;
1336+
}
1337+
13001338
/*
13011339
* check if the device uses big-endian samples
13021340
*/

sound/usb/quirks.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
2020
const struct snd_usb_audio_quirk *quirk,
2121
unsigned int usb_id);
2222

23+
int snd_usb_apply_boot_quirk_once(struct usb_device *dev,
24+
struct usb_interface *intf,
25+
const struct snd_usb_audio_quirk *quirk,
26+
unsigned int usb_id);
27+
2328
void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
2429
struct audioformat *fmt);
2530

0 commit comments

Comments
 (0)