alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
From: Daniel Mack <daniel@caiaq.de>
To: alsa-devel@alsa-project.org
Cc: tiwai@suse.de, gregkh@suse.de, clemens@ladisch.de
Subject: [PATCH 2/9] ALSA: usb-audio: support partially write-protected UAC2 controls
Date: Mon, 31 May 2010 13:35:37 +0200	[thread overview]
Message-ID: <1275305744-6590-2-git-send-email-daniel@caiaq.de> (raw)
In-Reply-To: <1275305744-6590-1-git-send-email-daniel@caiaq.de>

So far, UAC2 controls are marked read-only if any of the channels are
marked read-only in the descriptors. Change this behaviour and

 - mark them writeable unless all channels are read-only
 - store the read-only mask in usb_mixer_elem_info and
 - check the mask again in set_cur_mix_value(), and bail out for
   write-protected channels.

Signed-off-by: Daniel Mack <daniel@caiaq.de>
---
 sound/usb/mixer.c |   30 ++++++++++++++++++++++++------
 sound/usb/mixer.h |    2 ++
 2 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 43d6417..9149a84 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -462,6 +462,16 @@ static int set_cur_mix_value(struct usb_mixer_elem_info *cval, int channel,
 			     int index, int value)
 {
 	int err;
+	unsigned int read_only = (channel == 0) ?
+		cval->master_readonly :
+		cval->ch_readonly & (1 << (channel - 1));
+
+	if (read_only) {
+		snd_printdd(KERN_INFO "%s(): channel %d of control %d is read_only\n",
+			    __func__, channel, cval->control);
+		return 0;
+	}
+
 	err = snd_usb_mixer_set_ctl_value(cval, UAC_SET_CUR, (cval->control << 8) | channel,
 			    value);
 	if (err < 0)
@@ -958,7 +968,7 @@ static size_t append_ctl_name(struct snd_kcontrol *kctl, const char *str)
 static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
 			      unsigned int ctl_mask, int control,
 			      struct usb_audio_term *iterm, int unitid,
-			      int read_only)
+			      int readonly_mask)
 {
 	struct uac_feature_unit_descriptor *desc = raw_desc;
 	unsigned int len = 0;
@@ -989,20 +999,25 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
 	cval->control = control;
 	cval->cmask = ctl_mask;
 	cval->val_type = audio_feature_info[control-1].type;
-	if (ctl_mask == 0)
+	if (ctl_mask == 0) {
 		cval->channels = 1;	/* master channel */
-	else {
+		cval->master_readonly = readonly_mask;
+	} else {
 		int i, c = 0;
 		for (i = 0; i < 16; i++)
 			if (ctl_mask & (1 << i))
 				c++;
 		cval->channels = c;
+		cval->ch_readonly = readonly_mask;
 	}
 
 	/* get min/max values */
 	get_min_max(cval, 0);
 
-	if (read_only)
+	/* if all channels in the mask are marked read-only, make the control
+	 * read-only. set_cur_mix_value() will check the mask again and won't
+	 * issue write commands to read-only channels. */
+	if (cval->channels == readonly_mask)
 		kctl = snd_ctl_new1(&usb_feature_unit_ctl_ro, cval);
 	else
 		kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
@@ -1195,9 +1210,12 @@ static int parse_audio_feature_unit(struct mixer_build *state, int unitid, void
 				}
 			}
 
-			/* FIXME: the whole unit is read-only if any of the channels is marked read-only */
+			/* NOTE: build_feature_ctl() will mark the control read-only if all channels
+			 * are marked read-only in the descriptors. Otherwise, the control will be
+			 * reported as writeable, but the driver will not actually issue a write
+			 * command for read-only channels */
 			if (ch_bits & 1) /* the first channel must be set (for ease of programming) */
-				build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, !!ch_read_only);
+				build_feature_ctl(state, _ftr, ch_bits, i, &iterm, unitid, ch_read_only);
 			if (uac2_control_is_readable(master_bits, i))
 				build_feature_ctl(state, _ftr, 0, i, &iterm, unitid,
 						  !uac2_control_is_writeable(master_bits, i));
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
index 1301238..a7cf100 100644
--- a/sound/usb/mixer.h
+++ b/sound/usb/mixer.h
@@ -34,6 +34,8 @@ struct usb_mixer_elem_info {
 	unsigned int id;
 	unsigned int control;	/* CS or ICN (high byte) */
 	unsigned int cmask; /* channel mask bitmap: 0 = master */
+	unsigned int ch_readonly;
+	unsigned int master_readonly;
 	int channels;
 	int val_type;
 	int min, max, res;
-- 
1.7.1

  reply	other threads:[~2010-05-31 11:35 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-31 11:35 [PATCH 1/9] ALSA: usb-audio: UAC2: clean up parsing of bmaControls Daniel Mack
2010-05-31 11:35 ` Daniel Mack [this message]
2010-05-31 11:35 ` [PATCH 3/9] include/linux/usb/audio-v2.h: add more UAC2 details Daniel Mack
2010-05-31 11:35 ` [PATCH 4/9] ALSA: usb-audio: fix selector unit string index accessor Daniel Mack
2010-05-31 11:35 ` [PATCH 5/9] ALSA: usb-audio: parse clock topology of UAC2 devices Daniel Mack
2010-05-31 12:51   ` Daniel Mack
2010-05-31 11:35 ` [PATCH 6/9] ALSA: usb-audio: unify constants from specification Daniel Mack
2010-05-31 11:35 ` [PATCH 7/9] ALSA: usb-audio: add UAC2 sepecific Feature Unit controls Daniel Mack
2010-05-31 11:35 ` [PATCH 8/9] ALSA: usb-audio: clean up find_audio_control_unit() Daniel Mack
2010-05-31 11:35 ` [PATCH 9/9] ALSA: usb-audio: export UAC2 clock selectors as mixer controls Daniel Mack
2010-05-31 16:35 ` [PATCH 1/9] ALSA: usb-audio: UAC2: clean up parsing of bmaControls Takashi Iwai
2010-05-31 16:47   ` Daniel Mack
2010-05-31 20:35     ` 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=1275305744-6590-2-git-send-email-daniel@caiaq.de \
    --to=daniel@caiaq.de \
    --cc=alsa-devel@alsa-project.org \
    --cc=clemens@ladisch.de \
    --cc=gregkh@suse.de \
    --cc=tiwai@suse.de \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).