Home Home > GIT Browse > SLE12-SP4
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2019-07-16 15:11:39 +0200
committerTakashi Iwai <tiwai@suse.de>2019-07-16 15:11:40 +0200
commitfdc7de91685e6dedbfe1c145ecaef4b303961090 (patch)
tree70c8307184dc86c8d21e8cd6c86399bd95e5bb7c
parent386559770a8db71c3c933e2fa342f7b82368beda (diff)
ALSA: usb-audio: Add quirk for MOTU MicroBook II (bsc#1051510).
-rw-r--r--patches.drivers/ALSA-usb-audio-Add-quirk-for-MOTU-MicroBook-II.patch254
-rw-r--r--series.conf1
2 files changed, 255 insertions, 0 deletions
diff --git a/patches.drivers/ALSA-usb-audio-Add-quirk-for-MOTU-MicroBook-II.patch b/patches.drivers/ALSA-usb-audio-Add-quirk-for-MOTU-MicroBook-II.patch
new file mode 100644
index 0000000000..aa3cfc8e10
--- /dev/null
+++ b/patches.drivers/ALSA-usb-audio-Add-quirk-for-MOTU-MicroBook-II.patch
@@ -0,0 +1,254 @@
+From a634090a0f242caa8ebc91967b118995a80eb13b Mon Sep 17 00:00:00 2001
+From: Manuel Reinhardt <manuel.rhdt@gmail.com>
+Date: Thu, 28 Feb 2019 20:34:04 +0100
+Subject: [PATCH] ALSA: usb-audio: Add quirk for MOTU MicroBook II
+Git-commit: a634090a0f242caa8ebc91967b118995a80eb13b
+Patch-mainline: v5.1-rc1
+References: bsc#1051510
+
+Add an entry to the quirks-table to for usb-audio to recognize the
+Microbook II (although it only exposes vendor interfaces). A simple boot
+quirk is also implemented to set up the sample rate and make sure that
+no audio urbs are sent before the device is ready.
+
+This patch only provides audio playback and capture at 96kHz sample
+rate. Notice the following shortcomings:
+
+- The sample rate is currently hardcoded to 96k although the device also
+ supports 48k and 44.1k.
+
+- The various mixer controls of the MicroBook are not made available.
+
+- The keep-iface control should be on by default because the device
+ shuts down whenever the altsetting is reset which is usually unwanted.
+ (I don't know the best way to do this)
+
+- The communication format used by the MicroBook for sample rate setting
+ and also other setup has been reverse engineered by looking at the
+ usbmon output while running the windows driver through virtualbox. In
+ this patch the first byte of every message is set to \0 while in the
+ observed communications the first byte acts as a "message-counter"
+ increasing its value with every message sent. Leaving it at \0 does
+ not seem to affect the device.
+
+Signed-off-by: Manuel Reinhardt <manuel.rhdt@gmail.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+
+---
+ sound/usb/pcm.c | 4 ++
+ sound/usb/quirks-table.h | 65 ++++++++++++++++++++++++++++++
+ sound/usb/quirks.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 170 insertions(+)
+
+diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
+index db114f3977e0..056af0a57b22 100644
+--- a/sound/usb/pcm.c
++++ b/sound/usb/pcm.c
+@@ -354,6 +354,10 @@ static int set_sync_ep_implicit_fb_quirk(struct snd_usb_substream *subs,
+ ep = 0x81;
+ ifnum = 1;
+ goto add_sync_ep_from_ifnum;
++ case USB_ID(0x07fd, 0x0004): /* MOTU MicroBook II */
++ ep = 0x84;
++ ifnum = 0;
++ goto add_sync_ep_from_ifnum;
+ }
+
+ if (attr == USB_ENDPOINT_SYNC_ASYNC &&
+diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
+index b345beb447bd..86e80916a029 100644
+--- a/sound/usb/quirks-table.h
++++ b/sound/usb/quirks-table.h
+@@ -3398,5 +3398,70 @@ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"),
+ .ifnum = QUIRK_NO_INTERFACE
+ }
+ },
++/* MOTU Microbook II */
++{
++ USB_DEVICE(0x07fd, 0x0004),
++ .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
++ .vendor_name = "MOTU",
++ .product_name = "MicroBookII",
++ .ifnum = QUIRK_ANY_INTERFACE,
++ .type = QUIRK_COMPOSITE,
++ .data = (const struct snd_usb_audio_quirk[]) {
++ {
++ .ifnum = 0,
++ .type = QUIRK_AUDIO_STANDARD_MIXER,
++ },
++ {
++ .ifnum = 0,
++ .type = QUIRK_AUDIO_FIXED_ENDPOINT,
++ .data = &(const struct audioformat) {
++ .formats = SNDRV_PCM_FMTBIT_S24_3BE,
++ .channels = 6,
++ .iface = 0,
++ .altsetting = 1,
++ .altset_idx = 1,
++ .attributes = 0,
++ .endpoint = 0x84,
++ .rates = SNDRV_PCM_RATE_96000,
++ .ep_attr = USB_ENDPOINT_XFER_ISOC |
++ USB_ENDPOINT_SYNC_ASYNC,
++ .rate_min = 96000,
++ .rate_max = 96000,
++ .nr_rates = 1,
++ .maxpacksize = 0x00d8,
++ .rate_table = (unsigned int[]) {
++ 96000
++ }
++ }
++ },
++ {
++ .ifnum = 0,
++ .type = QUIRK_AUDIO_FIXED_ENDPOINT,
++ .data = &(const struct audioformat) {
++ .formats = SNDRV_PCM_FMTBIT_S24_3BE,
++ .channels = 8,
++ .iface = 0,
++ .altsetting = 1,
++ .altset_idx = 1,
++ .attributes = 0,
++ .endpoint = 0x03,
++ .rates = SNDRV_PCM_RATE_96000,
++ .ep_attr = USB_ENDPOINT_XFER_ISOC |
++ USB_ENDPOINT_SYNC_ASYNC,
++ .rate_min = 96000,
++ .rate_max = 96000,
++ .nr_rates = 1,
++ .maxpacksize = 0x0120,
++ .rate_table = (unsigned int[]) {
++ 96000
++ }
++ }
++ },
++ {
++ .ifnum = -1
++ }
++ }
++ }
++},
+
+ #undef USB_DEVICE_VENDOR_SPEC
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
+index f372c624bbf4..e6ce1bbe6ca6 100644
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -1000,6 +1000,105 @@ static int snd_usb_axefx3_boot_quirk(struct usb_device *dev)
+ return 0;
+ }
+
++
++#define MICROBOOK_BUF_SIZE 128
++
++static int snd_usb_motu_microbookii_communicate(struct usb_device *dev, u8 *buf,
++ int buf_size, int *length)
++{
++ int err, actual_length;
++
++ err = usb_interrupt_msg(dev, usb_sndintpipe(dev, 0x01), buf, *length,
++ &actual_length, 1000);
++ if (err < 0)
++ return err;
++
++ print_hex_dump(KERN_DEBUG, "MicroBookII snd: ", DUMP_PREFIX_NONE, 16, 1,
++ buf, actual_length, false);
++
++ memset(buf, 0, buf_size);
++
++ err = usb_interrupt_msg(dev, usb_rcvintpipe(dev, 0x82), buf, buf_size,
++ &actual_length, 1000);
++ if (err < 0)
++ return err;
++
++ print_hex_dump(KERN_DEBUG, "MicroBookII rcv: ", DUMP_PREFIX_NONE, 16, 1,
++ buf, actual_length, false);
++
++ *length = actual_length;
++ return 0;
++}
++
++static int snd_usb_motu_microbookii_boot_quirk(struct usb_device *dev)
++{
++ int err, actual_length, poll_attempts = 0;
++ static const u8 set_samplerate_seq[] = { 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x00, 0x0b, 0x14,
++ 0x00, 0x00, 0x00, 0x01 };
++ static const u8 poll_ready_seq[] = { 0x00, 0x04, 0x00, 0x00,
++ 0x00, 0x00, 0x0b, 0x18 };
++ u8 *buf = kzalloc(MICROBOOK_BUF_SIZE, GFP_KERNEL);
++
++ if (!buf)
++ return -ENOMEM;
++
++ dev_info(&dev->dev, "Waiting for MOTU Microbook II to boot up...\n");
++
++ /* First we tell the device which sample rate to use. */
++ memcpy(buf, set_samplerate_seq, sizeof(set_samplerate_seq));
++ actual_length = sizeof(set_samplerate_seq);
++ err = snd_usb_motu_microbookii_communicate(dev, buf, MICROBOOK_BUF_SIZE,
++ &actual_length);
++
++ if (err < 0) {
++ dev_err(&dev->dev,
++ "failed setting the sample rate for Motu MicroBook II: %d\n",
++ err);
++ goto free_buf;
++ }
++
++ /* Then we poll every 100 ms until the device informs of its readiness. */
++ while (true) {
++ if (++poll_attempts > 100) {
++ dev_err(&dev->dev,
++ "failed booting Motu MicroBook II: timeout\n");
++ err = -ENODEV;
++ goto free_buf;
++ }
++
++ memset(buf, 0, MICROBOOK_BUF_SIZE);
++ memcpy(buf, poll_ready_seq, sizeof(poll_ready_seq));
++
++ actual_length = sizeof(poll_ready_seq);
++ err = snd_usb_motu_microbookii_communicate(
++ dev, buf, MICROBOOK_BUF_SIZE, &actual_length);
++ if (err < 0) {
++ dev_err(&dev->dev,
++ "failed booting Motu MicroBook II: communication error %d\n",
++ err);
++ goto free_buf;
++ }
++
++ /* the device signals its readiness through a message of the
++ * form
++ * XX 06 00 00 00 00 0b 18 00 00 00 01
++ * If the device is not yet ready to accept audio data, the
++ * last byte of that sequence is 00.
++ */
++ if (actual_length == 12 && buf[actual_length - 1] == 1)
++ break;
++
++ msleep(100);
++ }
++
++ dev_info(&dev->dev, "MOTU MicroBook II ready\n");
++
++free_buf:
++ kfree(buf);
++ return err;
++}
++
+ /*
+ * Setup quirks
+ */
+@@ -1177,6 +1276,8 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
+ return snd_usb_gamecon780_boot_quirk(dev);
+ case USB_ID(0x2466, 0x8010): /* Fractal Audio Axe-Fx 3 */
+ return snd_usb_axefx3_boot_quirk(dev);
++ case USB_ID(0x07fd, 0x0004): /* MOTU MicroBook II */
++ return snd_usb_motu_microbookii_boot_quirk(dev);
+ }
+
+ return 0;
+--
+2.16.4
+
diff --git a/series.conf b/series.conf
index 41e3d90a7d..b71a46bd58 100644
--- a/series.conf
+++ b/series.conf
@@ -21549,6 +21549,7 @@
patches.drivers/ASoC-msm8916-wcd-analog-add-missing-license-informat.patch
patches.drivers/SoC-imx-sgtl5000-add-missing-put_device.patch
patches.drivers/ASoC-qcom-Fix-of-node-refcount-unbalance-in-apq8016_.patch
+ patches.drivers/ALSA-usb-audio-Add-quirk-for-MOTU-MicroBook-II.patch
patches.suse/hpet-Fix-missing-character-in-the-__setup-code-of-hp.patch
patches.drivers/applicom-Fix-potential-Spectre-v1-vulnerabilities.patch
patches.drivers/nvmem-allow-to-select-i.MX-nvmem-driver-for-i.MX-7D.patch