[alsa-devel] [PATCH 1/2] sound: usb: add UAC2 clock sources as mixer controls
Takashi Iwai
tiwai at suse.de
Sat Apr 9 10:43:52 CEST 2016
On Fri, 08 Apr 2016 19:52:01 +0200,
Daniel Mack wrote:
>
> 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 at zonque.org>
> ---
> sound/usb/mixer.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 65 insertions(+), 1 deletion(-)
>
> diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
> index 4f85757..973274b 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,68 @@ 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[100];
No need for 100. SNDRV_CTL_ELEM_ID_NAME_MAXLEN should suffice.
> + int ret;
> +
> + if (state->mixer->protocol != UAC_VERSION_2)
> + return -EINVAL;
> +
> + if (hdr->bLength != sizeof(*hdr))
> + return -EINVAL;
I wonder whether we should abort here and return an error.
It's a wacky firmware, and no kernel error, after all.
> + /*
> + * 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);
Each word in control name is usually starting with a capital letter.
thanks,
Takashi
More information about the Alsa-devel
mailing list