lkml.org 
[lkml]   [2020]   [Feb]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.5 333/542] ALSA: usb-audio: Add boot quirk for MOTU M Series
    Date
    From: Alexander Tsoy <alexander@tsoy.me>

    [ Upstream commit 73ac9f5e5b43a5dbadb61f27dae7a971f7ec0d22 ]

    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>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    sound/usb/card.c | 4 ++++
    sound/usb/quirks.c | 38 ++++++++++++++++++++++++++++++++++++++
    sound/usb/quirks.h | 5 +++++
    3 files changed, 47 insertions(+)

    diff --git a/sound/usb/card.c b/sound/usb/card.c
    index 9f743ebae615d..2f582ac7cf789 100644
    --- a/sound/usb/card.c
    +++ b/sound/usb/card.c
    @@ -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
    */
    diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
    index 82184036437b5..0464df785f2ee 100644
    --- a/sound/usb/quirks.c
    +++ b/sound/usb/quirks.c
    @@ -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
    */
    @@ -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
    */
    diff --git a/sound/usb/quirks.h b/sound/usb/quirks.h
    index a80e0ddd07364..df0355843a4c1 100644
    --- a/sound/usb/quirks.h
    +++ b/sound/usb/quirks.h
    @@ -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);

    --
    2.20.1
    \
     
     \ /
      Last update: 2020-02-14 16:56    [W:4.048 / U:0.356 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site