All of lore.kernel.org
 help / color / mirror / Atom feed
From: Takashi Iwai <tiwai@suse.de>
To: alsa-devel@alsa-project.org
Subject: [PATCH RFC 07/10] ALSA: usb-audio: Add resume support for Native Instruments controls
Date: Thu, 20 Nov 2014 18:33:32 +0100	[thread overview]
Message-ID: <1416504815-28685-8-git-send-email-tiwai@suse.de> (raw)
In-Reply-To: <1416504815-28685-1-git-send-email-tiwai@suse.de>

The changes at this time are a bit more wider than previous ones.
Firstly, the NI controls didn't cache the values, so I had to
implement the caching.  It's stored in bit 24 of private_value.
In addition to that, the initial values have to be read from
registers.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/usb/mixer_quirks.c | 99 +++++++++++++++++++++++++-----------------------
 1 file changed, 52 insertions(+), 47 deletions(-)

diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 5491c68efbc0..29324f4b3a7b 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -742,64 +742,68 @@ static int snd_mbox1_create_sync_switch(struct usb_mixer_interface *mixer)
 
 #define _MAKE_NI_CONTROL(bRequest,wIndex) ((bRequest) << 16 | (wIndex))
 
-static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol,
-					     struct snd_ctl_elem_value *ucontrol)
+static int snd_ni_control_init_val(struct usb_mixer_interface *mixer,
+				   struct snd_kcontrol *kctl)
 {
-	struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
 	struct usb_device *dev = mixer->chip->dev;
-	u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
-	u16 wIndex = kcontrol->private_value & 0xffff;
-	u8 tmp;
-	int ret;
-
-	down_read(&mixer->chip->shutdown_rwsem);
-	if (mixer->chip->shutdown)
-		ret = -ENODEV;
-	else
-		ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), bRequest,
-				  USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
-				  0, wIndex,
-				  &tmp, sizeof(tmp), 1000);
-	up_read(&mixer->chip->shutdown_rwsem);
+	unsigned int pval = kctl->private_value;
+	u8 value;
+	int err;
 
-	if (ret < 0) {
+	err = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
+			      (pval >> 16) & 0xff,
+			      USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+			      0, pval & 0xffff, &value, 1, 1000);
+	if (err < 0) {
 		dev_err(&dev->dev,
-			"unable to issue vendor read request (ret = %d)", ret);
-		return ret;
+			"unable to issue vendor read request (ret = %d)", err);
+		return err;
 	}
 
-	ucontrol->value.integer.value[0] = tmp;
-
+	kctl->private_value |= (value << 24);
 	return 0;
 }
 
-static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol,
+static int snd_nativeinstruments_control_get(struct snd_kcontrol *kcontrol,
 					     struct snd_ctl_elem_value *ucontrol)
 {
-	struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
-	struct usb_device *dev = mixer->chip->dev;
-	u8 bRequest = (kcontrol->private_value >> 16) & 0xff;
-	u16 wIndex = kcontrol->private_value & 0xffff;
-	u16 wValue = ucontrol->value.integer.value[0];
-	int ret;
+	ucontrol->value.integer.value[0] = kcontrol->private_value >> 24;
+	return 0;
+}
 
-	down_read(&mixer->chip->shutdown_rwsem);
-	if (mixer->chip->shutdown)
-		ret = -ENODEV;
+static int snd_ni_update_cur_val(struct usb_mixer_elem_list *list)
+{
+	struct snd_usb_audio *chip = list->mixer->chip;
+	unsigned int pval = list->kctl->private_value;
+	int err;
+
+	down_read(&chip->shutdown_rwsem);
+	if (chip->shutdown)
+		err = -ENODEV;
 	else
-		ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), bRequest,
-				  USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
-				  wValue, wIndex,
-				  NULL, 0, 1000);
-	up_read(&mixer->chip->shutdown_rwsem);
+		err = usb_control_msg(chip->dev, usb_sndctrlpipe(chip->dev, 0),
+				      (pval >> 16) & 0xff,
+				      USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+				      pval >> 24, pval & 0xffff, NULL, 0, 1000);
+	up_read(&chip->shutdown_rwsem);
+	return err;
+}
 
-	if (ret < 0) {
-		dev_err(&dev->dev,
-			"unable to issue vendor write request (ret = %d)", ret);
-		return ret;
-	}
+static int snd_nativeinstruments_control_put(struct snd_kcontrol *kcontrol,
+					     struct snd_ctl_elem_value *ucontrol)
+{
+	struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
+	u8 oldval = (kcontrol->private_value >> 24) & 0xff;
+	u8 newval = ucontrol->value.integer.value[0];
+	int err;
 
-	return 0;
+	if (oldval == newval)
+		return 0;
+
+	kcontrol->private_value &= ~(0xff << 24);
+	kcontrol->private_value |= newval;
+	err = snd_ni_update_cur_val(list);
+	return err < 0 ? err : 1;
 }
 
 static struct snd_kcontrol_new snd_nativeinstruments_ta6_mixers[] = {
@@ -870,16 +874,17 @@ static int snd_nativeinstruments_create_mixer(struct usb_mixer_interface *mixer,
 	};
 
 	for (i = 0; i < count; i++) {
-		struct snd_kcontrol *c;
+		struct usb_mixer_elem_list *list;
 
 		template.name = kc[i].name;
 		template.private_value = kc[i].private_value;
 
-		c = snd_ctl_new1(&template, mixer);
-		err = snd_ctl_add(mixer->chip->card, c);
-
+		err = add_single_ctl_with_resume(mixer, 0,
+						 snd_ni_update_cur_val,
+						 &template, &list);
 		if (err < 0)
 			break;
+		snd_ni_control_init_val(mixer, list->kctl);
 	}
 
 	return err;
-- 
2.1.3

  parent reply	other threads:[~2014-11-20 17:33 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-20 17:33 [PATCH RFC 00/10] Add proper resume support to USB-audio quirks Takashi Iwai
2014-11-20 17:33 ` [PATCH RFC 01/10] ALSA: usb-audio: Refactor ignore_ctl_error checks Takashi Iwai
2014-11-20 17:33 ` [PATCH RFC 02/10] ALSA: usb-audio: Allow quirks to handle own resume and proc dump Takashi Iwai
2014-11-20 17:33 ` [PATCH RFC 03/10] ALSA: usb-audio: Add audigy2nx resume support Takashi Iwai
2014-11-20 17:33 ` [PATCH RFC 04/10] ALSA: usb-audio: Add Emu0204 channel switch " Takashi Iwai
2014-11-20 17:33 ` [PATCH RFC 05/10] ALSA: usb-audio: Add Xonar U1 " Takashi Iwai
2014-11-20 17:33 ` [PATCH RFC 06/10] ALSA: usb-audio: Add Digidesign Mbox 1 " Takashi Iwai
2014-11-20 17:33 ` Takashi Iwai [this message]
2014-11-20 17:33 ` [PATCH RFC 08/10] ALSA: usb-audio: Add resume support for FTU controls Takashi Iwai
2014-11-20 17:33 ` [PATCH RFC 09/10] ALSA: usb-audio: Add resume support for MicroII SPDIF ctls Takashi Iwai
2014-11-20 17:33 ` [PATCH RFC 10/10] ALSA: usb-audio: Add resume support for Scarlett mixers Takashi Iwai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1416504815-28685-8-git-send-email-tiwai@suse.de \
    --to=tiwai@suse.de \
    --cc=alsa-devel@alsa-project.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.