All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3 v4] Digidesign Mbox 1 enhancements
@ 2014-11-10  9:40 Damien Zammit
  2014-11-10  9:40 ` [PATCH 1/3 v4] ALSA: usb-audio: Move mutex define to more general location Damien Zammit
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Damien Zammit @ 2014-11-10  9:40 UTC (permalink / raw)
  To: alsa-devel; +Cc: tiwai, Damien Zammit, clemens

This is fourth revision based on all reviews/tweaks so far.  

Damien Zammit (3):
  ALSA: usb-audio: Move mutex define to more general location
  ALSA: usb-audio: Add mixer control for Digidesign mbox 1 clock source
  ALSA: usb-audio: Add duplex mode for Digidesign Mbox 1 and enable
    mixer

 sound/usb/card.c         |   1 -
 sound/usb/mixer_maps.c   |   9 +++
 sound/usb/mixer_quirks.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++
 sound/usb/quirks-table.h |  43 ++++++++++----
 sound/usb/usbaudio.h     |   2 +
 5 files changed, 188 insertions(+), 11 deletions(-)

-- 
1.9.1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/3 v4] ALSA: usb-audio: Move mutex define to more general location
  2014-11-10  9:40 [PATCH 0/3 v4] Digidesign Mbox 1 enhancements Damien Zammit
@ 2014-11-10  9:40 ` Damien Zammit
  2014-11-10  9:47   ` Clemens Ladisch
  2014-11-10  9:48   ` Takashi Iwai
  2014-11-10  9:40 ` [PATCH 2/3 v4] ALSA: usb-audio: Add mixer control for Digidesign mbox 1 clock source Damien Zammit
  2014-11-10  9:40 ` [PATCH 3/3 v4] ALSA: usb-audio: Add duplex mode for Digidesign Mbox 1 and enable mixer Damien Zammit
  2 siblings, 2 replies; 8+ messages in thread
From: Damien Zammit @ 2014-11-10  9:40 UTC (permalink / raw)
  To: alsa-devel; +Cc: tiwai, Damien Zammit, clemens

Allow quirks to lock/unlock the usb audio register mutex by moving
its definition to usbaudio.h

Signed-off-by: Damien Zammit <damien@zamaudio.com>
---
 sound/usb/card.c     | 1 -
 sound/usb/usbaudio.h | 2 ++
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/sound/usb/card.c b/sound/usb/card.c
index 1fab977..d71025b 100644
--- a/sound/usb/card.c
+++ b/sound/usb/card.c
@@ -106,7 +106,6 @@ MODULE_PARM_DESC(autoclock, "Enable auto-clock selection for UAC2 devices (defau
  * the all interfaces on the same card as one sound device.
  */
 
-static DEFINE_MUTEX(register_mutex);
 static struct snd_usb_audio *usb_chip[SNDRV_CARDS];
 static struct usb_driver usb_audio_driver;
 
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
index 91d0380..229978f 100644
--- a/sound/usb/usbaudio.h
+++ b/sound/usb/usbaudio.h
@@ -115,4 +115,6 @@ struct snd_usb_audio_quirk {
 #define combine_triple(s)  (combine_word(s) | ((unsigned int)(s)[2] << 16))
 #define combine_quad(s)    (combine_triple(s) | ((unsigned int)(s)[3] << 24))
 
+static DEFINE_MUTEX(register_mutex);
+
 #endif /* __USBAUDIO_H */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/3 v4] ALSA: usb-audio: Add mixer control for Digidesign mbox 1 clock source
  2014-11-10  9:40 [PATCH 0/3 v4] Digidesign Mbox 1 enhancements Damien Zammit
  2014-11-10  9:40 ` [PATCH 1/3 v4] ALSA: usb-audio: Move mutex define to more general location Damien Zammit
@ 2014-11-10  9:40 ` Damien Zammit
  2014-11-10  9:47   ` Clemens Ladisch
  2014-11-10  9:50   ` Takashi Iwai
  2014-11-10  9:40 ` [PATCH 3/3 v4] ALSA: usb-audio: Add duplex mode for Digidesign Mbox 1 and enable mixer Damien Zammit
  2 siblings, 2 replies; 8+ messages in thread
From: Damien Zammit @ 2014-11-10  9:40 UTC (permalink / raw)
  To: alsa-devel; +Cc: tiwai, Damien Zammit, clemens

This patch provides the infrastructure for the Digidesign Mbox 1
to have a mixer control for selecting the clock source.
Valid options are Internal and S/PDIF external sync.
A non-documented command is sent to the device to enable this feature
found by reverse engineering and bus snooping.

Signed-off-by: Damien Zammit <damien@zamaudio.com>
---
 sound/usb/mixer_maps.c   |   9 +++
 sound/usb/mixer_quirks.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 153 insertions(+)

diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c
index d1d72ff..1994d41 100644
--- a/sound/usb/mixer_maps.c
+++ b/sound/usb/mixer_maps.c
@@ -179,6 +179,11 @@ static struct usbmix_name_map audigy2nx_map[] = {
 	{ 0 } /* terminator */
 };
 
+static struct usbmix_name_map mbox1_map[] = {
+	{ 1, "Clock" },
+	{ 0 } /* terminator */
+};
+
 static struct usbmix_selector_map c400_selectors[] = {
 	{
 		.id = 0x80,
@@ -416,6 +421,10 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = {
 		.map = aureon_51_2_map,
 	},
 	{
+		.id = USB_ID(0x0dba, 0x1000),
+		.map = mbox1_map,
+	},
+	{
 		.id = USB_ID(0x13e5, 0x0001),
 		.map = scratch_live_map,
 		.ignore_ctl_error = 1,
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 3980bf5..448ac42 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -28,6 +28,7 @@
  */
 
 #include <linux/init.h>
+#include <linux/mutex.h>
 #include <linux/slab.h>
 #include <linux/usb.h>
 #include <linux/usb/audio.h>
@@ -565,6 +566,145 @@ static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
 	return 0;
 }
 
+/* Digidesign Mbox 1 clock source switch (internal/spdif) */
+
+static int snd_mbox1_switch_get(struct snd_kcontrol *kctl,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	if (kctl->private_value) {
+		ucontrol->value.enumerated.item[0] = true;
+		return 0;
+	}
+
+	ucontrol->value.enumerated.item[0] = false;
+	return 0;
+}
+
+static int snd_mbox1_switch_put(struct snd_kcontrol *kctl,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_usb_audio *chip;
+	struct usb_mixer_interface *mixer;
+	int err;
+	bool changed, cur_val, new_val;
+	bool value;
+	unsigned char buff[3];
+
+	changed = false;
+	value = false;
+
+	cur_val = kctl->private_value;
+	new_val = ucontrol->value.enumerated.item[0];
+
+	mixer = snd_kcontrol_chip(kctl);
+	if (snd_BUG_ON(!mixer))
+		return -EINVAL;
+
+	chip = mixer->chip;
+	if (snd_BUG_ON(!chip))
+		return -EINVAL;
+
+	/* update value if needed */
+	if (cur_val != new_val) {
+		value = new_val;
+		down_read(&chip->shutdown_rwsem);
+		if (chip->shutdown) {
+			err = -ENODEV;
+		} else {
+			/* Prepare for magic command to toggle clock source */
+			mutex_unlock(&register_mutex);
+			err = snd_usb_ctl_msg(chip->dev,
+				usb_rcvctrlpipe(chip->dev, 0), 0x81,
+				USB_DIR_IN |
+				USB_TYPE_CLASS |
+				USB_RECIP_INTERFACE, 0x00, 0x500, buff, 1);
+			if (err < 0)
+				goto err;
+			err = snd_usb_ctl_msg(chip->dev,
+				usb_rcvctrlpipe(chip->dev, 0), 0x81,
+				USB_DIR_IN |
+				USB_TYPE_CLASS |
+				USB_RECIP_ENDPOINT, 0x100, 0x81, buff, 3);
+			if (err < 0)
+				goto err;
+			/* 2 possibilities: Internal    -> send sample rate
+			 * 		    S/PDIF sync -> send zeroes
+			 * NB: Sample rate locked to 48kHz on purpose to
+			 *     prevent user from resetting the sample rate
+			 *     while S/PDIF sync is enabled and confusing
+			 *     this configuration.
+			 */
+			if (new_val == 0) {
+				buff[0] = 0x80;
+				buff[1] = 0xbb;
+				buff[2] = 0x00;
+			} else {
+				buff[0] = buff[1] = buff[2] = 0x00;
+			}
+			/* Send the magic command to toggle the clock source */
+			err = snd_usb_ctl_msg(chip->dev,
+				usb_sndctrlpipe(chip->dev, 0), 0x1,
+				USB_TYPE_CLASS |
+				USB_RECIP_ENDPOINT, 0x100, 0x81, buff, 3);
+			if (err < 0)
+				goto err;
+			err = snd_usb_ctl_msg(chip->dev,
+				usb_rcvctrlpipe(chip->dev, 0), 0x81,
+				USB_DIR_IN |
+				USB_TYPE_CLASS |
+				USB_RECIP_ENDPOINT, 0x100, 0x81, buff, 3);
+			if (err < 0)
+				goto err;
+			err = snd_usb_ctl_msg(chip->dev,
+				usb_rcvctrlpipe(chip->dev, 0), 0x81,
+				USB_DIR_IN |
+				USB_TYPE_CLASS |
+				USB_RECIP_ENDPOINT, 0x100, 0x2, buff, 3);
+			if (err < 0)
+				goto err;
+		}
+		up_read(&chip->shutdown_rwsem);
+		if (err < 0)
+			goto err;
+		mutex_lock(&register_mutex);
+		kctl->private_value = new_val;
+		changed = true;
+	}
+
+	return changed;
+err:
+	mutex_lock(&register_mutex);
+	return err;
+}
+
+static int snd_mbox1_switch_info(struct snd_kcontrol *kcontrol,
+				 struct snd_ctl_elem_info *uinfo)
+{
+	static const char *const texts[2] = {
+		"Internal",
+		"S/PDIF"
+	};
+
+	return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
+}
+
+static struct snd_kcontrol_new snd_mbox1_switch = {
+	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+	.name = "Clock Source",
+	.index = 0,
+	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+	.info = snd_mbox1_switch_info,
+	.get = snd_mbox1_switch_get,
+	.put = snd_mbox1_switch_put,
+	.private_value = 0
+};
+
+static int snd_mbox1_create_sync_switch(struct usb_mixer_interface *mixer)
+{
+	return snd_ctl_add(mixer->chip->card,
+			snd_ctl_new1(&snd_mbox1_switch, mixer));
+}
+
 /* Native Instruments device quirks */
 
 #define _MAKE_NI_CONTROL(bRequest,wIndex) ((bRequest) << 16 | (wIndex))
@@ -1632,6 +1772,10 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
 		err = snd_microii_controls_create(mixer);
 		break;
 
+	case USB_ID(0x0dba, 0x1000): /* Digidesign Mbox 1 */
+		err = snd_mbox1_create_sync_switch(mixer);
+		break;
+
 	case USB_ID(0x17cc, 0x1011): /* Traktor Audio 6 */
 		err = snd_nativeinstruments_create_mixer(mixer,
 				snd_nativeinstruments_ta6_mixers,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/3 v4] ALSA: usb-audio: Add duplex mode for Digidesign Mbox 1 and enable mixer
  2014-11-10  9:40 [PATCH 0/3 v4] Digidesign Mbox 1 enhancements Damien Zammit
  2014-11-10  9:40 ` [PATCH 1/3 v4] ALSA: usb-audio: Move mutex define to more general location Damien Zammit
  2014-11-10  9:40 ` [PATCH 2/3 v4] ALSA: usb-audio: Add mixer control for Digidesign mbox 1 clock source Damien Zammit
@ 2014-11-10  9:40 ` Damien Zammit
  2 siblings, 0 replies; 8+ messages in thread
From: Damien Zammit @ 2014-11-10  9:40 UTC (permalink / raw)
  To: alsa-devel; +Cc: tiwai, Damien Zammit, clemens

This patch provides duplex support for the Digidesign Mbox 1 sound
card and has been a work in progress for about a year.
Users have confirmed on my website that previous versions of this patch
have worked on the hardware and I have been testing extensively.

It also enables the mixer control for providing clock source
selector based on the previous patch.

The sample rate has been hardcoded to 48kHz because it works better with
the S/PDIF sync mode when the sample rate is locked.  This is the
highest rate that the device supports and no loss of functionality
is observed by restricting the sample rate apart from the inability to select
a lower rate.

Signed-off-by: Damien Zammit <damien@zamaudio.com>
---
 sound/usb/quirks-table.h | 43 +++++++++++++++++++++++++++++++++----------
 1 file changed, 33 insertions(+), 10 deletions(-)

diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
index c657752..19eee96 100644
--- a/sound/usb/quirks-table.h
+++ b/sound/usb/quirks-table.h
@@ -2941,10 +2941,10 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 		.product_name = "MBox",
 		.ifnum = QUIRK_ANY_INTERFACE,
 		.type = QUIRK_COMPOSITE,
-		.data = (const struct snd_usb_audio_quirk[]){
+		.data = &(const struct snd_usb_audio_quirk[]){
 			{
 				.ifnum = 0,
-				.type = QUIRK_IGNORE_INTERFACE,
+				.type = QUIRK_AUDIO_STANDARD_MIXER,
 			},
 			{
 				.ifnum = 1,
@@ -2955,16 +2955,40 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 					.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
+					}
+				}
+			},
+			{
+				.ifnum = 1,
+				.type = QUIRK_AUDIO_FIXED_ENDPOINT,
+				.data = &(const struct audioformat) {
+					.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
 					}
 				}
 			},
@@ -2972,7 +2996,6 @@ YAMAHA_DEVICE(0x7010, "UB99"),
 				.ifnum = -1
 			}
 		}
-
 	}
 },
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/3 v4] ALSA: usb-audio: Add mixer control for Digidesign mbox 1 clock source
  2014-11-10  9:40 ` [PATCH 2/3 v4] ALSA: usb-audio: Add mixer control for Digidesign mbox 1 clock source Damien Zammit
@ 2014-11-10  9:47   ` Clemens Ladisch
  2014-11-10  9:50   ` Takashi Iwai
  1 sibling, 0 replies; 8+ messages in thread
From: Clemens Ladisch @ 2014-11-10  9:47 UTC (permalink / raw)
  To: Damien Zammit, alsa-devel; +Cc: tiwai, Damien Zammit

Damien Zammit wrote:
> This patch provides the infrastructure for the Digidesign Mbox 1
> to have a mixer control for selecting the clock source.
> Valid options are Internal and S/PDIF external sync.
> A non-documented command is sent to the device to enable this feature
> found by reverse engineering and bus snooping.
>
> +++ b/sound/usb/mixer_quirks.c
> +static int snd_mbox1_switch_put(struct snd_kcontrol *kctl,
> +				struct snd_ctl_elem_value *ucontrol)
> +{
> ...
> +		down_read(&chip->shutdown_rwsem);

When I wrote "semaphore", I meant this one.


Regards,
Clemens

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/3 v4] ALSA: usb-audio: Move mutex define to more general location
  2014-11-10  9:40 ` [PATCH 1/3 v4] ALSA: usb-audio: Move mutex define to more general location Damien Zammit
@ 2014-11-10  9:47   ` Clemens Ladisch
  2014-11-10  9:48   ` Takashi Iwai
  1 sibling, 0 replies; 8+ messages in thread
From: Clemens Ladisch @ 2014-11-10  9:47 UTC (permalink / raw)
  To: Damien Zammit, alsa-devel; +Cc: tiwai, Damien Zammit

Damien Zammit wrote:
> Allow quirks to lock/unlock the usb audio register mutex by moving
> its definition to usbaudio.h
>
> +++ b/sound/usb/usbaudio.h
>
> +static DEFINE_MUTEX(register_mutex);

This does not work in a header file.


Regards,
Clemens

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/3 v4] ALSA: usb-audio: Move mutex define to more general location
  2014-11-10  9:40 ` [PATCH 1/3 v4] ALSA: usb-audio: Move mutex define to more general location Damien Zammit
  2014-11-10  9:47   ` Clemens Ladisch
@ 2014-11-10  9:48   ` Takashi Iwai
  1 sibling, 0 replies; 8+ messages in thread
From: Takashi Iwai @ 2014-11-10  9:48 UTC (permalink / raw)
  To: Damien Zammit; +Cc: alsa-devel, clemens, Damien Zammit

At Mon, 10 Nov 2014 20:40:35 +1100,
Damien Zammit wrote:
> 
> Allow quirks to lock/unlock the usb audio register mutex by moving
> its definition to usbaudio.h

No, no.  The quirk shouldn't touch it at all.

(And, even if so, you should never define a static mutex in a header
 file!)


Takashi

> 
> Signed-off-by: Damien Zammit <damien@zamaudio.com>
> ---
>  sound/usb/card.c     | 1 -
>  sound/usb/usbaudio.h | 2 ++
>  2 files changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/sound/usb/card.c b/sound/usb/card.c
> index 1fab977..d71025b 100644
> --- a/sound/usb/card.c
> +++ b/sound/usb/card.c
> @@ -106,7 +106,6 @@ MODULE_PARM_DESC(autoclock, "Enable auto-clock selection for UAC2 devices (defau
>   * the all interfaces on the same card as one sound device.
>   */
>  
> -static DEFINE_MUTEX(register_mutex);
>  static struct snd_usb_audio *usb_chip[SNDRV_CARDS];
>  static struct usb_driver usb_audio_driver;
>  
> diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h
> index 91d0380..229978f 100644
> --- a/sound/usb/usbaudio.h
> +++ b/sound/usb/usbaudio.h
> @@ -115,4 +115,6 @@ struct snd_usb_audio_quirk {
>  #define combine_triple(s)  (combine_word(s) | ((unsigned int)(s)[2] << 16))
>  #define combine_quad(s)    (combine_triple(s) | ((unsigned int)(s)[3] << 24))
>  
> +static DEFINE_MUTEX(register_mutex);
> +
>  #endif /* __USBAUDIO_H */
> -- 
> 1.9.1
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/3 v4] ALSA: usb-audio: Add mixer control for Digidesign mbox 1 clock source
  2014-11-10  9:40 ` [PATCH 2/3 v4] ALSA: usb-audio: Add mixer control for Digidesign mbox 1 clock source Damien Zammit
  2014-11-10  9:47   ` Clemens Ladisch
@ 2014-11-10  9:50   ` Takashi Iwai
  1 sibling, 0 replies; 8+ messages in thread
From: Takashi Iwai @ 2014-11-10  9:50 UTC (permalink / raw)
  To: Damien Zammit; +Cc: alsa-devel, clemens, Damien Zammit

At Mon, 10 Nov 2014 20:40:36 +1100,
Damien Zammit wrote:
> 
> This patch provides the infrastructure for the Digidesign Mbox 1
> to have a mixer control for selecting the clock source.
> Valid options are Internal and S/PDIF external sync.
> A non-documented command is sent to the device to enable this feature
> found by reverse engineering and bus snooping.
> 
> Signed-off-by: Damien Zammit <damien@zamaudio.com>

Clemens suggested that you forgot to unlock chip->shutdown_rwsem in
some error paths.  It's not about register_mutex.


Takashi

> ---
>  sound/usb/mixer_maps.c   |   9 +++
>  sound/usb/mixer_quirks.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 153 insertions(+)
> 
> diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c
> index d1d72ff..1994d41 100644
> --- a/sound/usb/mixer_maps.c
> +++ b/sound/usb/mixer_maps.c
> @@ -179,6 +179,11 @@ static struct usbmix_name_map audigy2nx_map[] = {
>  	{ 0 } /* terminator */
>  };
>  
> +static struct usbmix_name_map mbox1_map[] = {
> +	{ 1, "Clock" },
> +	{ 0 } /* terminator */
> +};
> +
>  static struct usbmix_selector_map c400_selectors[] = {
>  	{
>  		.id = 0x80,
> @@ -416,6 +421,10 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = {
>  		.map = aureon_51_2_map,
>  	},
>  	{
> +		.id = USB_ID(0x0dba, 0x1000),
> +		.map = mbox1_map,
> +	},
> +	{
>  		.id = USB_ID(0x13e5, 0x0001),
>  		.map = scratch_live_map,
>  		.ignore_ctl_error = 1,
> diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
> index 3980bf5..448ac42 100644
> --- a/sound/usb/mixer_quirks.c
> +++ b/sound/usb/mixer_quirks.c
> @@ -28,6 +28,7 @@
>   */
>  
>  #include <linux/init.h>
> +#include <linux/mutex.h>
>  #include <linux/slab.h>
>  #include <linux/usb.h>
>  #include <linux/usb/audio.h>
> @@ -565,6 +566,145 @@ static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
>  	return 0;
>  }
>  
> +/* Digidesign Mbox 1 clock source switch (internal/spdif) */
> +
> +static int snd_mbox1_switch_get(struct snd_kcontrol *kctl,
> +				struct snd_ctl_elem_value *ucontrol)
> +{
> +	if (kctl->private_value) {
> +		ucontrol->value.enumerated.item[0] = true;
> +		return 0;
> +	}
> +
> +	ucontrol->value.enumerated.item[0] = false;
> +	return 0;
> +}
> +
> +static int snd_mbox1_switch_put(struct snd_kcontrol *kctl,
> +				struct snd_ctl_elem_value *ucontrol)
> +{
> +	struct snd_usb_audio *chip;
> +	struct usb_mixer_interface *mixer;
> +	int err;
> +	bool changed, cur_val, new_val;
> +	bool value;
> +	unsigned char buff[3];
> +
> +	changed = false;
> +	value = false;
> +
> +	cur_val = kctl->private_value;
> +	new_val = ucontrol->value.enumerated.item[0];
> +
> +	mixer = snd_kcontrol_chip(kctl);
> +	if (snd_BUG_ON(!mixer))
> +		return -EINVAL;
> +
> +	chip = mixer->chip;
> +	if (snd_BUG_ON(!chip))
> +		return -EINVAL;
> +
> +	/* update value if needed */
> +	if (cur_val != new_val) {
> +		value = new_val;
> +		down_read(&chip->shutdown_rwsem);
> +		if (chip->shutdown) {
> +			err = -ENODEV;
> +		} else {
> +			/* Prepare for magic command to toggle clock source */
> +			mutex_unlock(&register_mutex);
> +			err = snd_usb_ctl_msg(chip->dev,
> +				usb_rcvctrlpipe(chip->dev, 0), 0x81,
> +				USB_DIR_IN |
> +				USB_TYPE_CLASS |
> +				USB_RECIP_INTERFACE, 0x00, 0x500, buff, 1);
> +			if (err < 0)
> +				goto err;
> +			err = snd_usb_ctl_msg(chip->dev,
> +				usb_rcvctrlpipe(chip->dev, 0), 0x81,
> +				USB_DIR_IN |
> +				USB_TYPE_CLASS |
> +				USB_RECIP_ENDPOINT, 0x100, 0x81, buff, 3);
> +			if (err < 0)
> +				goto err;
> +			/* 2 possibilities: Internal    -> send sample rate
> +			 * 		    S/PDIF sync -> send zeroes
> +			 * NB: Sample rate locked to 48kHz on purpose to
> +			 *     prevent user from resetting the sample rate
> +			 *     while S/PDIF sync is enabled and confusing
> +			 *     this configuration.
> +			 */
> +			if (new_val == 0) {
> +				buff[0] = 0x80;
> +				buff[1] = 0xbb;
> +				buff[2] = 0x00;
> +			} else {
> +				buff[0] = buff[1] = buff[2] = 0x00;
> +			}
> +			/* Send the magic command to toggle the clock source */
> +			err = snd_usb_ctl_msg(chip->dev,
> +				usb_sndctrlpipe(chip->dev, 0), 0x1,
> +				USB_TYPE_CLASS |
> +				USB_RECIP_ENDPOINT, 0x100, 0x81, buff, 3);
> +			if (err < 0)
> +				goto err;
> +			err = snd_usb_ctl_msg(chip->dev,
> +				usb_rcvctrlpipe(chip->dev, 0), 0x81,
> +				USB_DIR_IN |
> +				USB_TYPE_CLASS |
> +				USB_RECIP_ENDPOINT, 0x100, 0x81, buff, 3);
> +			if (err < 0)
> +				goto err;
> +			err = snd_usb_ctl_msg(chip->dev,
> +				usb_rcvctrlpipe(chip->dev, 0), 0x81,
> +				USB_DIR_IN |
> +				USB_TYPE_CLASS |
> +				USB_RECIP_ENDPOINT, 0x100, 0x2, buff, 3);
> +			if (err < 0)
> +				goto err;
> +		}
> +		up_read(&chip->shutdown_rwsem);
> +		if (err < 0)
> +			goto err;
> +		mutex_lock(&register_mutex);
> +		kctl->private_value = new_val;
> +		changed = true;
> +	}
> +
> +	return changed;
> +err:
> +	mutex_lock(&register_mutex);
> +	return err;
> +}
> +
> +static int snd_mbox1_switch_info(struct snd_kcontrol *kcontrol,
> +				 struct snd_ctl_elem_info *uinfo)
> +{
> +	static const char *const texts[2] = {
> +		"Internal",
> +		"S/PDIF"
> +	};
> +
> +	return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
> +}
> +
> +static struct snd_kcontrol_new snd_mbox1_switch = {
> +	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
> +	.name = "Clock Source",
> +	.index = 0,
> +	.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
> +	.info = snd_mbox1_switch_info,
> +	.get = snd_mbox1_switch_get,
> +	.put = snd_mbox1_switch_put,
> +	.private_value = 0
> +};
> +
> +static int snd_mbox1_create_sync_switch(struct usb_mixer_interface *mixer)
> +{
> +	return snd_ctl_add(mixer->chip->card,
> +			snd_ctl_new1(&snd_mbox1_switch, mixer));
> +}
> +
>  /* Native Instruments device quirks */
>  
>  #define _MAKE_NI_CONTROL(bRequest,wIndex) ((bRequest) << 16 | (wIndex))
> @@ -1632,6 +1772,10 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
>  		err = snd_microii_controls_create(mixer);
>  		break;
>  
> +	case USB_ID(0x0dba, 0x1000): /* Digidesign Mbox 1 */
> +		err = snd_mbox1_create_sync_switch(mixer);
> +		break;
> +
>  	case USB_ID(0x17cc, 0x1011): /* Traktor Audio 6 */
>  		err = snd_nativeinstruments_create_mixer(mixer,
>  				snd_nativeinstruments_ta6_mixers,
> -- 
> 1.9.1
> 

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2014-11-10  9:50 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-10  9:40 [PATCH 0/3 v4] Digidesign Mbox 1 enhancements Damien Zammit
2014-11-10  9:40 ` [PATCH 1/3 v4] ALSA: usb-audio: Move mutex define to more general location Damien Zammit
2014-11-10  9:47   ` Clemens Ladisch
2014-11-10  9:48   ` Takashi Iwai
2014-11-10  9:40 ` [PATCH 2/3 v4] ALSA: usb-audio: Add mixer control for Digidesign mbox 1 clock source Damien Zammit
2014-11-10  9:47   ` Clemens Ladisch
2014-11-10  9:50   ` Takashi Iwai
2014-11-10  9:40 ` [PATCH 3/3 v4] ALSA: usb-audio: Add duplex mode for Digidesign Mbox 1 and enable mixer Damien Zammit

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.