* [PATCH v2 1/2] sound: usb: add UAC2 clock sources as mixer controls
@ 2016-04-09 9:21 Daniel Mack
2016-04-09 9:21 ` [PATCH v2 2/2] sound: usb: allow clock source validity interrupts Daniel Mack
0 siblings, 1 reply; 2+ messages in thread
From: Daniel Mack @ 2016-04-09 9:21 UTC (permalink / raw)
To: alsa-devel; +Cc: tiwai, orm.finnendahl, clemens, jan.baumgart, Daniel Mack
UAC2 specifies clock sources that optionally have validity controls.
This patch exposes them as mixer controls, so they can be read (and
at least in theory even be written) by userspace applications in order
to make clock selection policy decisions.
This implementation does nothing if the device is not UAC2 compliant,
or if the clock source does not define said validity control bits.
Tested with a miniDSP USBStreamer (0x2752/0x0016).
Signed-off-by: Daniel Mack <daniel@zonque.org>
---
sound/usb/mixer.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 68 insertions(+), 1 deletion(-)
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index 4f85757..cab6f52 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -45,6 +45,7 @@
#include <linux/bitops.h>
#include <linux/init.h>
#include <linux/list.h>
+#include <linux/log2.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/usb.h>
@@ -1378,6 +1379,71 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
snd_usb_mixer_add_control(&cval->head, kctl);
}
+static int parse_clock_source_unit(struct mixer_build *state, int unitid,
+ void *_ftr)
+{
+ struct uac_clock_source_descriptor *hdr = _ftr;
+ struct usb_mixer_elem_info *cval;
+ struct snd_kcontrol *kctl;
+ char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+ int ret;
+
+ if (state->mixer->protocol != UAC_VERSION_2)
+ return -EINVAL;
+
+ if (hdr->bLength != sizeof(*hdr)) {
+ usb_audio_dbg(state->chip,
+ "Bogus clock source descriptor length of %d, ignoring.\n",
+ hdr->bLength);
+ return 0;
+ }
+
+ /*
+ * The only property of this unit we are interested in is the
+ * clock source validity. If that isn't readable, just bail out.
+ */
+ if (!uac2_control_is_readable(hdr->bmControls,
+ ilog2(UAC2_CS_CONTROL_CLOCK_VALID)))
+ return 0;
+
+ cval = kzalloc(sizeof(*cval), GFP_KERNEL);
+ if (!cval)
+ return -ENOMEM;
+
+ snd_usb_mixer_elem_init_std(&cval->head, state->mixer, hdr->bClockID);
+
+ cval->min = 0;
+ cval->max = 1;
+ cval->channels = 1;
+ cval->val_type = USB_MIXER_BOOLEAN;
+ cval->control = UAC2_CS_CONTROL_CLOCK_VALID;
+
+ if (uac2_control_is_writeable(hdr->bmControls,
+ ilog2(UAC2_CS_CONTROL_CLOCK_VALID)))
+ kctl = snd_ctl_new1(&usb_feature_unit_ctl, cval);
+ else {
+ cval->master_readonly = 1;
+ kctl = snd_ctl_new1(&usb_feature_unit_ctl_ro, cval);
+ }
+
+ if (!kctl) {
+ kfree(cval);
+ return -ENOMEM;
+ }
+
+ kctl->private_free = snd_usb_mixer_elem_free;
+ ret = snd_usb_copy_string_desc(state, hdr->iClockSource,
+ name, sizeof(name));
+ if (ret > 0)
+ snprintf(kctl->id.name, sizeof(kctl->id.name),
+ "%s Validity", name);
+ else
+ snprintf(kctl->id.name, sizeof(kctl->id.name),
+ "Clock Source %d Validity", hdr->bClockID);
+
+ return snd_usb_mixer_add_control(&cval->head, kctl);
+}
+
/*
* parse a feature unit
*
@@ -2126,10 +2192,11 @@ static int parse_audio_unit(struct mixer_build *state, int unitid)
switch (p1[2]) {
case UAC_INPUT_TERMINAL:
- case UAC2_CLOCK_SOURCE:
return 0; /* NOP */
case UAC_MIXER_UNIT:
return parse_audio_mixer_unit(state, unitid, p1);
+ case UAC2_CLOCK_SOURCE:
+ return parse_clock_source_unit(state, unitid, p1);
case UAC_SELECTOR_UNIT:
case UAC2_CLOCK_SELECTOR:
return parse_audio_selector_unit(state, unitid, p1);
--
2.4.3
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH v2 2/2] sound: usb: allow clock source validity interrupts
2016-04-09 9:21 [PATCH v2 1/2] sound: usb: add UAC2 clock sources as mixer controls Daniel Mack
@ 2016-04-09 9:21 ` Daniel Mack
0 siblings, 0 replies; 2+ messages in thread
From: Daniel Mack @ 2016-04-09 9:21 UTC (permalink / raw)
To: alsa-devel; +Cc: tiwai, orm.finnendahl, clemens, jan.baumgart, Daniel Mack
miniDSP USBStreamer UAC2 devices send clock validity changes with the
control field set to zero. The current interrupt handler ignores all
packets if the control field does not match the mixer element's, but
it really should only do that in case that field is needed to
distinguish multiple elements with the same ID.
This patch implements a logic that lets notifications packets pass
if the unit ID is unique for a given device.
Signed-off-by: Daniel Mack <daniel@zonque.org>
---
sound/usb/mixer.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
index cab6f52..652e281 100644
--- a/sound/usb/mixer.c
+++ b/sound/usb/mixer.c
@@ -2389,7 +2389,13 @@ static void snd_usb_mixer_interrupt_v2(struct usb_mixer_interface *mixer,
continue;
info = (struct usb_mixer_elem_info *)list;
- if (info->control != control)
+
+ /*
+ * Allow any value of 'control' in case there is only one
+ * mixer element with the given unit ID.
+ */
+ if (info->control != control &&
+ (list != mixer->id_elems[unitid] || list->next_id_elem))
continue;
switch (attribute) {
--
2.4.3
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2016-04-09 9:21 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-04-09 9:21 [PATCH v2 1/2] sound: usb: add UAC2 clock sources as mixer controls Daniel Mack
2016-04-09 9:21 ` [PATCH v2 2/2] sound: usb: allow clock source validity interrupts Daniel Mack
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).