[alsa-devel] [RFC] usb-audio: Use a table of mixer controls

Takashi Iwai tiwai at suse.de
Fri May 11 21:32:17 CEST 2012


At Fri, 11 May 2012 18:28:48 +0100,
Mark Hills wrote:
> 
> Allow mixer controls to be provided clearly in a table, to avoid
> quantity of error checking at each use.
> 
> This is definitely clearer than the current code. But going forward,
> how should this work with the tables defined in mixer_maps.c?

Yeah, this looks definitely better.

> I've made this generic and tried to follow existing conventions for
> similar tables (eg. use a terminator, not array size), comments welcome.
> ---
>  sound/usb/mixer_quirks.c |  104 +++++++++++++++++++++-------------------------
>  1 files changed, 48 insertions(+), 56 deletions(-)
> 
> diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
> index 41f4b69..b80b7e7 100644
> --- a/sound/usb/mixer_quirks.c
> +++ b/sound/usb/mixer_quirks.c
> @@ -42,6 +42,13 @@
>  
>  extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl;
>  
> +struct std_mono_table {
> +	unsigned int unitid, control, cmask;
> +	int val_type;
> +	const char *name;
> +	snd_kcontrol_tlv_rw_t *tlv_callback;
> +};
> +
>  /* private_free callback */
>  static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
>  {
> @@ -114,6 +121,24 @@ static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer,
>  }
>  
>  /*
> + * Create a set of standard UAC controls from a table
> + */
> +static int snd_create_std_mono_table(struct usb_mixer_interface *mixer,
> +				struct std_mono_table *t)
> +{
> +	int err;
> +
> +	while (t->name != NULL) {
> +		err = snd_create_std_mono_ctl(mixer, t->unitid, t->control,
> +				t->cmask, t->val_type, t->name, t->tlv_callback);
> +		if (err < 0)
> +			return err;

t++ is missing?


> +	}
> +
> +	return 0;
> +}
> +
> +/*
>   * Sound Blaster remote control configuration
>   *
>   * format of remote control data:
> @@ -916,61 +941,6 @@ static int snd_ftu_create_mixer(struct usb_mixer_interface *mixer)
>  	return 0;
>  }
>  
> -
> -/*
> - * Create mixer for Electrix Ebox-44
> - *
> - * The mixer units from this device are corrupt, and even where they
> - * are valid they presents mono controls as L and R channels of
> - * stereo. So we create a good mixer in code.
> - */
> -
> -static int snd_ebox44_create_mixer(struct usb_mixer_interface *mixer)
> -{
> -	int err;
> -
> -	err = snd_create_std_mono_ctl(mixer, 4, 1, 0x0, USB_MIXER_INV_BOOLEAN,
> -				"Headphone Playback Switch", NULL);
> -	if (err < 0)
> -		return err;
> -	err = snd_create_std_mono_ctl(mixer, 4, 2, 0x1, USB_MIXER_S16,
> -				"Headphone A Mix Playback Volume", NULL);
> -	if (err < 0)
> -		return err;
> -	err = snd_create_std_mono_ctl(mixer, 4, 2, 0x2, USB_MIXER_S16,
> -				"Headphone B Mix Playback Volume", NULL);
> -	if (err < 0)
> -		return err;
> -
> -	err = snd_create_std_mono_ctl(mixer, 7, 1, 0x0, USB_MIXER_INV_BOOLEAN,
> -				"Output Playback Switch", NULL);
> -	if (err < 0)
> -		return err;
> -	err = snd_create_std_mono_ctl(mixer, 7, 2, 0x1, USB_MIXER_S16,
> -				"Output A Playback Volume", NULL);
> -	if (err < 0)
> -		return err;
> -	err = snd_create_std_mono_ctl(mixer, 7, 2, 0x2, USB_MIXER_S16,
> -				"Output B Playback Volume", NULL);
> -	if (err < 0)
> -		return err;
> -
> -	err = snd_create_std_mono_ctl(mixer, 10, 1, 0x0, USB_MIXER_INV_BOOLEAN,
> -				"Input Capture Switch", NULL);
> -	if (err < 0)
> -		return err;
> -	err = snd_create_std_mono_ctl(mixer, 10, 2, 0x1, USB_MIXER_S16,
> -				"Input A Capture Volume", NULL);
> -	if (err < 0)
> -		return err;
> -	err = snd_create_std_mono_ctl(mixer, 10, 2, 0x2, USB_MIXER_S16,
> -				"Input B Capture Volume", NULL);
> -	if (err < 0)
> -		return err;
> -
> -	return 0;
> -}
> -
>  void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
>  			       unsigned char samplerate_id)
>  {
> @@ -990,6 +960,27 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
>  	}
>  }
>  
> +/*
> + * The mixer units for Ebox-44 are corrupt, and even where they
> + * are valid they presents mono controls as L and R channels of
> + * stereo. So we create provide a good mixer here.
> + */
> +struct std_mono_table ebox44_table[] = {
> +	{ 4, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Headphone Playback Switch", NULL },
> +	{ 4, 2, 0x1, USB_MIXER_S16, "Headphone A Mix Playback Volume", NULL },
> +	{ 4, 2, 0x2, USB_MIXER_S16, "Headphone B Mix Playback Volume", NULL },
> +
> +	{ 7, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Output Playback Switch", NULL },
> +	{ 7, 2, 0x1, USB_MIXER_S16, "Output A Playback Volume", NULL },
> +	{ 7, 2, 0x2, USB_MIXER_S16, "Output B Playback Volume", NULL },
> +
> +	{ 10, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Input Capture Switch", NULL },
> +	{ 10, 2, 0x1, USB_MIXER_S16, "Input A Capture Volume", NULL },
> +	{ 10, 2, 0x2, USB_MIXER_S16, "Input B Capture Volume", NULL },
> +
> +	{ }

C99 style struct initialization is preferred.  Then NULL settings can
be omittted.

Other than that, it looks fine to me.


thanks,

Takashi

> +};
> +
>  int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
>  {
>  	int err = 0;
> @@ -1035,7 +1026,8 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
>  		break;
>  
>  	case USB_ID(0x200c, 0x1018): /* Electrix Ebox-44 */
> -		err = snd_ebox44_create_mixer(mixer);
> +		/* detection is disabled in mixer_maps.c */
> +		err = snd_create_std_mono_table(mixer, ebox44_table);
>  		break;
>  	}
>  
> -- 
> 1.7.4.4
> 
> _______________________________________________
> Alsa-devel mailing list
> Alsa-devel at alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> 


More information about the Alsa-devel mailing list