diff mbox

usb-audio: Duplex support for Digidesign Mbox 1 and clock source selector

Message ID 54533532.6040605@gmail.com (mailing list archive)
State Superseded
Delegated to: Takashi Iwai
Headers show

Commit Message

Damien Zammit Oct. 31, 2014, 7:07 a.m. UTC
Hi,

Please review this patch and my previous one.

This patch provides duplex support for the Digidesign Mbox 1 sound card.
This also depends on my previous patch for enabling the clock source
selector because the mixer is enabled in this patch.
I reduced the supported sampling rates to just 48kHz because the device
works better in this mode with the SPDIF external sync.

Damien
diff mbox

Patch

From 6defd3a7bfb0bc110143cef1da0b9d1757035817 Mon Sep 17 00:00:00 2001
From: Damien Zammit <damien@zamaudio.com>
Date: Fri, 31 Oct 2014 17:30:11 +1100
Subject: [PATCH] snd-usb-audio: Duplex support for Digidesign Mbox 1 and clock
 source selector

This patch provides duplex support for the Digidesign Mbox 1 sound card.
This patch also depends on my previous patch for enabling the clock source
selector because the mixer is enabled in this patch.

Signed-off-by: Damien Zammit <damien@zamaudio.com>
---
 sound/usb/card.h         |  5 ++++
 sound/usb/quirks-table.h | 73 ++++++++++++++++++++++++++++++++----------------
 sound/usb/quirks.c       | 32 ++++++++++++++++++++-
 sound/usb/usbaudio.h     |  1 +
 4 files changed, 86 insertions(+), 25 deletions(-)

diff --git a/sound/usb/card.h b/sound/usb/card.h
index 97acb90..a8fe22f 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -33,6 +33,11 @@  struct audioformat {
 	bool dsd_bitrev;		/* reverse the bits of each DSD sample */
 };
 
+struct audioformats {
+	unsigned int n_formats;
+	const struct audioformat *format;
+};
+
 struct snd_usb_substream;
 struct snd_usb_endpoint;
 
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index c657752..0b5f4fb 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -2937,43 +2937,68 @@  YAMAHA_DEVICE(0x7010, "UB99"),
 	/* Thanks to Clemens Ladisch <clemens@ladisch.de> */
 	USB_DEVICE(0x0dba, 0x1000),
 	.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
-		.vendor_name = "Digidesign",
-		.product_name = "MBox",
-		.ifnum = QUIRK_ANY_INTERFACE,
-		.type = QUIRK_COMPOSITE,
-		.data = (const struct snd_usb_audio_quirk[]){
-			{
-				.ifnum = 0,
-				.type = QUIRK_IGNORE_INTERFACE,
-			},
-			{
-				.ifnum = 1,
-				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
-				.data = &(const struct audioformat) {
+	.vendor_name = "Digidesign",
+	.product_name = "MBox",
+	.ifnum = QUIRK_ANY_INTERFACE,
+	.type = QUIRK_COMPOSITE,
+	.data = (const struct snd_usb_audio_quirk[]) {
+		{
+			.ifnum = 0,
+			.type = QUIRK_AUDIO_STANDARD_MIXER,
+		},
+		{
+			.ifnum = 1,
+			.type = QUIRK_AUDIO_FIXED_MULTI_ENDPOINT,
+			.data = &(const struct audioformats)
+			{
+				.n_formats = 2,
+				.format = (const struct audioformat[]) {
+					{
 					.formats = SNDRV_PCM_FMTBIT_S24_3BE,
 					.channels = 2,
 					.iface = 1,
 					.altsetting = 1,
 					.altset_idx = 1,
-					.attributes = UAC_EP_CS_ATTR_SAMPLE_RATE,
+					.attributes = 0x4,
 					.endpoint = 0x02,
-					.ep_attr = 0x01,
-					.rates = SNDRV_PCM_RATE_44100 |
-						 SNDRV_PCM_RATE_48000,
-					.rate_min = 44100,
+					.ep_attr = USB_ENDPOINT_XFER_ISOC |
+						USB_ENDPOINT_SYNC_SYNC,
+					.maxpacksize = 0x130,
+					.rates = SNDRV_PCM_RATE_48000,
+					.rate_min = 48000,
 					.rate_max = 48000,
-					.nr_rates = 2,
+					.nr_rates = 1,
 					.rate_table = (unsigned int[]) {
-						44100, 48000
+						48000
+					}
+					},
+					{
+					.formats = SNDRV_PCM_FMTBIT_S24_3BE,
+					.channels = 2,
+					.iface = 1,
+					.altsetting = 1,
+					.altset_idx = 1,
+					.attributes = 0x4,
+					.endpoint = 0x81,
+					.ep_attr = USB_ENDPOINT_XFER_ISOC |
+						USB_ENDPOINT_SYNC_ASYNC,
+					.maxpacksize = 0x130,
+					.rates = SNDRV_PCM_RATE_48000,
+					.rate_min = 48000,
+					.rate_max = 48000,
+					.nr_rates = 1,
+					.rate_table = (unsigned int[]) {
+						48000
+					}
 					}
 				}
-			},
-			{
-				.ifnum = -1
 			}
+		},
+		{
+			.ifnum = -1
 		}
-
 	}
+}
 },
 
 /* DIGIDESIGN MBOX 2 */
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index d2aa45a..d6c6c03 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -180,6 +180,34 @@  static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
 	return 0;
 }
 
+/*
+ * create N streams for an interface without proper descriptors but with
+ * multiple endpoints
+ */
+static int create_fixed_multi_stream_quirk(struct snd_usb_audio *chip,
+				     struct usb_interface *iface,
+				     struct usb_driver *driver,
+				     const struct snd_usb_audio_quirk *quirk)
+{
+	struct audioformats *fp;
+	int i;
+
+	fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL);
+	if (!fp) {
+		usb_audio_err(chip, "cannot memdup\n");
+		return -ENOMEM;
+	}
+	for (i = 0; i < fp->n_formats; i++) {
+		struct snd_usb_audio_quirk nquirk = {
+			.ifnum = quirk->ifnum,
+			.type = QUIRK_AUDIO_FIXED_MULTI_ENDPOINT,
+			.data = (const struct audioformat *) &fp->format[i]
+		};
+		create_fixed_stream_quirk(chip, iface, driver, &nquirk);
+	}
+	return 0;
+}
+
 static int create_auto_pcm_quirk(struct snd_usb_audio *chip,
 				 struct usb_interface *iface,
 				 struct usb_driver *driver)
@@ -387,7 +415,7 @@  static int create_autodetect_quirks(struct snd_usb_audio *chip,
 }
 
 /*
- * Create a stream for an Edirol UA-700/UA-25/UA-4FX interface.  
+ * Create a stream for an Edirol UA-700/UA-25/UA-4FX interface.
  * The only way to detect the sample rate is by looking at wMaxPacketSize.
  */
 static int create_uaxx_quirk(struct snd_usb_audio *chip,
@@ -528,6 +556,8 @@  int snd_usb_create_quirk(struct snd_usb_audio *chip,
 		[QUIRK_MIDI_FTDI] = create_any_midi_quirk,
 		[QUIRK_AUDIO_STANDARD_INTERFACE] = create_standard_audio_quirk,
 		[QUIRK_AUDIO_FIXED_ENDPOINT] = create_fixed_stream_quirk,
+		[QUIRK_AUDIO_FIXED_MULTI_ENDPOINT] =
+			create_fixed_multi_stream_quirk,
 		[QUIRK_AUDIO_EDIROL_UAXX] = create_uaxx_quirk,
 		[QUIRK_AUDIO_ALIGN_TRANSFER] = create_align_transfer_quirk,
 		[QUIRK_AUDIO_STANDARD_MIXER] = create_standard_mixer_quirk,
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 91d0380..31d8ff0 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -96,6 +96,7 @@  enum quirk_type {
 	QUIRK_MIDI_FTDI,
 	QUIRK_AUDIO_STANDARD_INTERFACE,
 	QUIRK_AUDIO_FIXED_ENDPOINT,
+	QUIRK_AUDIO_FIXED_MULTI_ENDPOINT,
 	QUIRK_AUDIO_EDIROL_UAXX,
 	QUIRK_AUDIO_ALIGN_TRANSFER,
 	QUIRK_AUDIO_STANDARD_MIXER,
-- 
1.9.1