Skip to content

Commit

Permalink
ALSA: usb-audio: Add boot quirk for MOTU M Series
Browse files Browse the repository at this point in the history
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 <alexander@tsoy.me>
Link: https://lore.kernel.org/r/20200112102358.18085-1-alexander@tsoy.me
Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
puleglot authored and tiwai committed Jan 13, 2020
1 parent 791a485 commit 73ac9f5
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 0 deletions.
4 changes: 4 additions & 0 deletions sound/usb/card.c
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,10 @@ static int usb_audio_probe(struct usb_interface *intf,
}
}
if (! chip) {
err = snd_usb_apply_boot_quirk_once(dev, intf, quirk, id);
if (err < 0)
return err;

/* it's a fresh one.
* now look for an empty slot and create a new card instance
*/
Expand Down
38 changes: 38 additions & 0 deletions sound/usb/quirks.c
Original file line number Diff line number Diff line change
Expand Up @@ -1113,6 +1113,31 @@ static int snd_usb_motu_microbookii_boot_quirk(struct usb_device *dev)
return err;
}

static int snd_usb_motu_m_series_boot_quirk(struct usb_device *dev)
{
int ret;

if (snd_usb_pipe_sanity_check(dev, usb_sndctrlpipe(dev, 0)))
return -EINVAL;
ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0x0, 0, NULL, 0, 1000);

if (ret < 0)
return ret;

msleep(2000);

ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1, USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0x20, 0, NULL, 0, 1000);

if (ret < 0)
return ret;

return 0;
}

/*
* Setup quirks
*/
Expand Down Expand Up @@ -1297,6 +1322,19 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
return 0;
}

int snd_usb_apply_boot_quirk_once(struct usb_device *dev,
struct usb_interface *intf,
const struct snd_usb_audio_quirk *quirk,
unsigned int id)
{
switch (id) {
case USB_ID(0x07fd, 0x0008): /* MOTU M Series */
return snd_usb_motu_m_series_boot_quirk(dev);
}

return 0;
}

/*
* check if the device uses big-endian samples
*/
Expand Down
5 changes: 5 additions & 0 deletions sound/usb/quirks.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
const struct snd_usb_audio_quirk *quirk,
unsigned int usb_id);

int snd_usb_apply_boot_quirk_once(struct usb_device *dev,
struct usb_interface *intf,
const struct snd_usb_audio_quirk *quirk,
unsigned int usb_id);

void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
struct audioformat *fmt);

Expand Down

1 comment on commit 73ac9f5

@ohel
Copy link

@ohel ohel commented on 73ac9f5 Feb 5, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just now bumped into this. Does anybody know in which situations this is really necessary? I have the M4 and I'm using the 5.4.15 kernel, everything is working fine. For maintainability, would be nice to have some kind of comment about why and when is this needed.

As the M4 is also supported by iPads and they don't have any specific driver either, it would be logical to think the devices truly don't need a driver.

Please sign in to comment.