[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