[alsa-devel] Patch for Digidesign Mbox 2 (set sample rate)
Viktor Radnai
viktor.radnai at gmail.com
Wed Jul 19 11:35:01 CEST 2017
Hi again,
I think this patch is ready to be applied. I have kept the "magic" init
sequence but I have substituted the hexadecimal numbers with preprocessor
macros to make the code easier to read.
I will try to run without the init magic for a while and if I don't see any
issues I will submit a follow-up patch to remove the entire
mbox2_setup_48_24_magic function.
Cheers,
Vik
diff -ur linux-source-4.11-orig/sound/usb/quirks.c
linux-source-4.11/sound/usb/quirks.c
--- linux-source-4.11-orig/sound/usb/quirks.c 2017-06-17
05:47:27.000000000 +0100
+++ linux-source-4.11/sound/usb/quirks.c 2017-07-18 22:37:58.522858262
+0100
@@ -768,23 +768,32 @@
static void mbox2_setup_48_24_magic(struct usb_device *dev)
{
- u8 srate[3];
- u8 temp[12];
-
/* Choose 48000Hz permanently */
- srate[0] = 0x80;
- srate[1] = 0xbb;
- srate[2] = 0x00;
+ u8 srate[3] = { 0x80, 0xbb, 0x00 };
+ u8 temp[3];
+ int err;
/* Send the magic! */
- snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0),
- 0x01, 0x22, 0x0100, 0x0085, &temp, 0x0003);
- snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
- 0x81, 0xa2, 0x0100, 0x0085, &srate, 0x0003);
- snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
- 0x81, 0xa2, 0x0100, 0x0086, &srate, 0x0003);
- snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
- 0x81, 0xa2, 0x0100, 0x0003, &srate, 0x0003);
+ if ((err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC_SET_CUR,
+ USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT,
+ UAC_EP_CS_ATTR_SAMPLE_RATE << 8, 0x0085, &temp, sizeof(temp))) < 0)
+ dev_err(&dev->dev, "mbox2: magic setup step #1 failed\n");
+
+ if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_GET_CUR,
+ USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN,
+ UAC_EP_CS_ATTR_SAMPLE_RATE << 8, 0x0085, &srate, sizeof(srate))) <
0)
+ dev_err(&dev->dev, "mbox2: magic setup step #2 failed\n");
+
+ if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_GET_CUR,
+ USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN,
+ UAC_EP_CS_ATTR_SAMPLE_RATE << 8, 0x0086, &srate, sizeof(srate))) <
0)
+ dev_err(&dev->dev, "mbox2: magic setup step #3 failed\n");
+
+ if ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0), UAC_GET_CUR,
+ USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_IN,
+ UAC_EP_CS_ATTR_SAMPLE_RATE << 8, 0x0003, &srate, sizeof(srate))) <
0)
+ dev_err(&dev->dev, "mbox2: magic setup step #4 failed\n");
+
return;
}
@@ -815,16 +824,16 @@
count = 0;
bootresponse[0] = MBOX2_BOOT_LOADING;
- while ((bootresponse[0] == MBOX2_BOOT_LOADING) && (count < 10)) {
- msleep(500); /* 0.5 second delay */
+ do {
snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0),
/* Control magic - load onboard firmware */
- 0x85, 0xc0, 0x0001, 0x0000, &bootresponse, 0x0012);
+ UAC_GET_MEM, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
0x0001, 0x0000, &bootresponse, sizeof(bootresponse));
if (bootresponse[0] == MBOX2_BOOT_READY)
break;
+ msleep(500); /* 0.5 second delay */
dev_dbg(&dev->dev, "device not ready, resending boot
sequence...\n");
count++;
- }
+ } while ((bootresponse[0] == MBOX2_BOOT_LOADING) && (count < 10));
if (bootresponse[0] != MBOX2_BOOT_READY) {
dev_err(&dev->dev, "Unknown bootresponse=%d, or timed out,
ignoring device.\n", bootresponse[0]);
@@ -847,7 +856,7 @@
mbox2_setup_48_24_magic(dev);
- dev_info(&dev->dev, "Digidesign Mbox 2: 24bit 48kHz");
+ dev_info(&dev->dev, "Digidesign Mbox 2 configured");
return 0; /* Successful boot */
}
@@ -1111,6 +1120,26 @@
subs->pkt_offset_adj = (emu_samplerate_id >= EMU_QUIRK_SR_176400HZ) ?
4 : 0;
}
+static void set_format_mbox2_quirk(struct snd_usb_substream *subs,
+ struct audioformat *fmt)
+{
+ struct usb_device *dev = subs->dev;
+ u8 srate[3];
+ int err;
+
+ srate[0] = subs->cur_rate;
+ srate[1] = subs->cur_rate >> 8;
+ srate[2] = subs->cur_rate >> 16;
+
+ /* Set the sample rate for endpoint IN 5 (0x0085) until we succeed */
+ while ((err = snd_usb_ctl_msg(dev, usb_sndctrlpipe(dev, 0),
UAC_SET_CUR,
+ USB_TYPE_CLASS | USB_RECIP_ENDPOINT | USB_DIR_OUT,
+ UAC_EP_CS_ATTR_SAMPLE_RATE << 8, 0x0085, srate, sizeof(srate))) <
0)
+ dev_err(&dev->dev, "mbox2: set sample rate failed, retrying\n");
+
+ dev_info(&subs->dev->dev, "mbox2: set sample rate to %dHz\n",
subs->cur_rate);
+}
+
void snd_usb_set_format_quirk(struct snd_usb_substream *subs,
struct audioformat *fmt)
{
@@ -1121,6 +1150,9 @@
case USB_ID(0x041e, 0x3f19): /* E-Mu 0204 USB */
set_format_emu_quirk(subs, fmt);
break;
+ case USB_ID(0x0dba, 0x3000): /* Digidesign Mbox 2 */
+ set_format_mbox2_quirk(subs, fmt);
+ break;
}
}
diff -ur linux-source-4.11-orig/sound/usb/quirks-table.h
linux-source-4.11/sound/usb/quirks-table.h
--- linux-source-4.11-orig/sound/usb/quirks-table.h 2017-06-17
05:47:27.000000000 +0100
+++ linux-source-4.11/sound/usb/quirks-table.h 2017-07-18
17:33:57.620424012 +0100
@@ -3020,12 +3020,13 @@
.attributes = 0x00,
.endpoint = 0x03,
.ep_attr = USB_ENDPOINT_SYNC_ASYNC,
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
+ .rates = SNDRV_PCM_RATE_44100|
+ SNDRV_PCM_RATE_48000,
+ .rate_min = 44100,
.rate_max = 48000,
- .nr_rates = 1,
+ .nr_rates = 2,
.rate_table = (unsigned int[]) {
- 48000
+ 44100, 48000
}
}
},
@@ -3045,12 +3046,13 @@
.attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
.endpoint = 0x85,
.ep_attr = USB_ENDPOINT_SYNC_SYNC,
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
+ .rates = SNDRV_PCM_RATE_44100|
+ SNDRV_PCM_RATE_48000,
+ .rate_min = 44100,
.rate_max = 48000,
- .nr_rates = 1,
+ .nr_rates = 2,
.rate_table = (unsigned int[]) {
- 48000
+ 44100, 48000
}
}
},
More information about the Alsa-devel
mailing list