[alsa-devel] [PATCH 1/3] Unify M-Audio Fast Track Ultra and Ebox-44 mixer quirks.

Takashi Iwai tiwai at suse.de
Mon Apr 23 11:43:11 CEST 2012


At Mon, 23 Apr 2012 11:16:06 +0200,
Felix Homann wrote:
> 
> Allows for specifying a TLV callback.

Too little information as the patch changelog.
Please be more specific what and how is implemented there.

> 
> Signed-off-by: Felix Homann <linuxaudio at showlabor.de>
> 
> diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
> index e2072ed..e486c51 100644
> --- a/sound/usb/mixer_quirks.c
> +++ b/sound/usb/mixer_quirks.c
> @@ -42,6 +42,85 @@
>  
>  extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl;
>  
> +/* private_free callback */
> +static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
> +{
> +	kfree(kctl->private_data);
> +	kctl->private_data = NULL;
> +}
> +
> +/* This function allows for the creation of standard UAC controls.
> + * See the quirks for M-Audio FTUs or Ebox-44.
> + * If you don't want to set a TLV callback pass NULL.
> + * 
> + * Since there doesn't seem to be a devices that needs a multichannel
> + * version, we keep it mono for simplicity.
> + */
> +static int snd_create_standard_mono_ctl(struct usb_mixer_interface *mixer,
> +				unsigned int unitid,
> +				unsigned int control,
> +				unsigned int cmask,
> +				int val_type,
> +				const char *name,
> +				snd_kcontrol_tlv_rw_t *tlv_callback)

This should be snd_create_std_mono_ctl(), no?
Each patch should be able to be built properly.  Otherwise it breaks
the bisection.


> +{
> +	int err;
> +	struct usb_mixer_elem_info *cval;
> +	struct snd_kcontrol *kctl;
> +
> +	cval = kzalloc(sizeof(*cval), GFP_KERNEL);
> +	if (!cval)
> +		return -ENOMEM;
> +
> +	cval->id = unitid;
> +	cval->mixer = mixer;
> +	cval->val_type = val_type;
> +	cval->channels = 1;
> +	cval->control = control;
> +	cval->cmask = cmask;
> +
> +	/* FIXME: Do we need this?
> +	 * The following values are for compatibility with
> +	 * Ebox-44 mixer.
> +	 * But the corresponding ebox-44 function says:
> +	 *    "Volume controls will override these values"
> +	 * 
> +	 * These values don't have any effect at all for
> +	 * M-Audio FTUs.
> +	 * So I think, we can safely omit the range settings here.
> +	 */
> +	cval->min = 0;
> +	cval->max = 1;
> +	cval->res = 0;
> +	cval->dBmin = 0;
> +	cval->dBmax = 0;
> +
> +	/* Create control */
> +	kctl = snd_ctl_new1(snd_usb_feature_unit_ctl, cval);
> +	if (!kctl) {
> +		kfree(cval);
> +		return -ENOMEM;
> +	}
> +
> +	/* Set name */
> +	snprintf(kctl->id.name, sizeof(kctl->id.name), name);
> +	kctl->private_free = usb_mixer_elem_free;
> +
> +	/* set TLV */
> +	if (tlv_callback != NULL) {

Should be "if (!tlv_callback)"

> +		kctl->tlv.c = tlv_callback;
> +		kctl->vd[0].access |=
> +			SNDRV_CTL_ELEM_ACCESS_TLV_READ |
> +			SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
> +	}
> +	/* Add control to mixer */
> +	err = snd_usb_mixer_add_control(mixer, kctl);
> +	if (err < 0)
> +		return err;
> +
> +	return 0;
> +}
> +
>  /*
>   * Sound Blaster remote control configuration
>   *
> @@ -496,59 +575,37 @@ static int snd_nativeinstruments_create_mixer(struct usb_mixer_interface *mixer,
>  
>  /* M-Audio FastTrack Ultra quirks */
>  
> -/* private_free callback */
> -static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
> -{
> -	kfree(kctl->private_data);
> -	kctl->private_data = NULL;
> -}
> -
> -static int snd_maudio_ftu_create_ctl(struct usb_mixer_interface *mixer,
> -				     int in, int out, const char *name)
> -{
> -	struct usb_mixer_elem_info *cval;
> -	struct snd_kcontrol *kctl;
> -
> -	cval = kzalloc(sizeof(*cval), GFP_KERNEL);
> -	if (!cval)
> -		return -ENOMEM;
> -
> -	cval->id = 5;
> -	cval->mixer = mixer;
> -	cval->val_type = USB_MIXER_S16;
> -	cval->channels = 1;
> -	cval->control = out + 1;
> -	cval->cmask = 1 << in;
> -
> -	kctl = snd_ctl_new1(snd_usb_feature_unit_ctl, cval);
> -	if (!kctl) {
> -		kfree(cval);
> -		return -ENOMEM;
> -	}
> -
> -	snprintf(kctl->id.name, sizeof(kctl->id.name), name);
> -	kctl->private_free = usb_mixer_elem_free;
> -	return snd_usb_mixer_add_control(mixer, kctl);
> -}
> -
> -static int snd_maudio_ftu_create_mixer(struct usb_mixer_interface *mixer)
> +/* Create a volume control for FTU devices*/
> +static int snd_maudio_ftu_create_volume_ctls(struct usb_mixer_interface *mixer)
>  {
>  	char name[64];
> -	int in, out, err;
> +	unsigned int id, control, cmask;
> +	int in, out, err, val_type;
> +
> +	id = 5;
> +	val_type = USB_MIXER_S16;

Give const.  I don't mind use such styles instead of define or
hard-coded in the function calls, but then it should be marked as
const properly.


thanks,

Takashi


>  
>  	for (out = 0; out < 8; out++) {
> +		control = out + 1;
>  		for (in = 0; in < 8; in++) {
> +			cmask = 1 << in;
>  			snprintf(name, sizeof(name),
> -				 "AIn%d - Out%d Capture Volume", in  + 1, out + 1);
> -			err = snd_maudio_ftu_create_ctl(mixer, in, out, name);
> +				"AIn%d - Out%d Capture Volume",
> +				in  + 1, out + 1);
> +			err = snd_create_std_mono_ctl(mixer, id, control,
> +							cmask, val_type, name,
> +							NULL);
>  			if (err < 0)
>  				return err;
>  		}
> -
>  		for (in = 8; in < 16; in++) {
> +			cmask = 1 << in;
>  			snprintf(name, sizeof(name),
> -				 "DIn%d - Out%d Playback Volume", in - 7, out + 1);
> -			err = snd_maudio_ftu_create_ctl(mixer, in, out, name);
> +				"DIn%d - Out%d Playback Volume",
> +				in - 7, out + 1);
> +			err = snd_create_std_mono_ctl(mixer, id, control,
> +							cmask, val_type, name,
> +							NULL);
>  			if (err < 0)
>  				return err;
>  		}
> @@ -557,44 +614,18 @@ static int snd_maudio_ftu_create_mixer(struct usb_mixer_interface *mixer)
>  	return 0;
>  }
>  
> -static int snd_ebox44_create_ctl(struct usb_mixer_interface *mixer,
> -				int unitid, int control, int cmask,
> -				int val_type, const char *name)
> +static int snd_maudio_ftu_create_mixer(struct usb_mixer_interface *mixer)
>  {
> -	struct usb_mixer_elem_info *cval;
> -	struct snd_kcontrol *kctl;
> -
> -	cval = kzalloc(sizeof(*cval), GFP_KERNEL);
> -	if (!cval)
> -		return -ENOMEM;
> -
> -	cval->id = unitid;
> -	cval->mixer = mixer;
> -
> -	cval->val_type = val_type;
> -	cval->channels = 1;
> -	cval->control = control;
> -	cval->cmask = cmask;
> -
> -	/* Volume controls will override these values */
> -	cval->min = 0;
> -	cval->max = 1;
> -	cval->res = 0;
> -
> -	cval->dBmin = 0;
> -	cval->dBmax = 0;
> +	int err;
>  
> -	kctl = snd_ctl_new1(snd_usb_feature_unit_ctl, cval);
> -	if (!kctl) {
> -		kfree(cval);
> -		return -ENOMEM;
> -	}
> +	err = snd_maudio_ftu_create_volume_ctls(mixer);
> +	if (err < 0)
> +		return err;
>  
> -	snprintf(kctl->id.name, sizeof(kctl->id.name), name);
> -	kctl->private_free = usb_mixer_elem_free;
> -	return snd_usb_mixer_add_control(mixer, kctl);
> +	return 0;
>  }
>  
> +
>  /*
>   * Create mixer for Electrix Ebox-44
>   *
> @@ -605,17 +636,17 @@ static int snd_ebox44_create_ctl(struct usb_mixer_interface *mixer,
>  
>  static int snd_ebox44_create_mixer(struct usb_mixer_interface *mixer)
>  {
> -	snd_ebox44_create_ctl(mixer, 4, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Headphone Playback Switch");
> -	snd_ebox44_create_ctl(mixer, 4, 2, 0x1, USB_MIXER_S16, "Headphone A Mix Playback Volume");
> -	snd_ebox44_create_ctl(mixer, 4, 2, 0x2, USB_MIXER_S16, "Headphone B Mix Playback Volume");
> +	snd_create_std_mono_ctl(mixer, 4, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Headphone Playback Switch", NULL);
> +	snd_create_std_mono_ctl(mixer, 4, 2, 0x1, USB_MIXER_S16, "Headphone A Mix Playback Volume", NULL);
> +	snd_create_std_mono_ctl(mixer, 4, 2, 0x2, USB_MIXER_S16, "Headphone B Mix Playback Volume", NULL);
>  
> -	snd_ebox44_create_ctl(mixer, 7, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Output Playback Switch");
> -	snd_ebox44_create_ctl(mixer, 7, 2, 0x1, USB_MIXER_S16, "Output A Playback Volume");
> -	snd_ebox44_create_ctl(mixer, 7, 2, 0x2, USB_MIXER_S16, "Output B Playback Volume");
> +	snd_create_std_mono_ctl(mixer, 7, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Output Playback Switch", NULL);
> +	snd_create_std_mono_ctl(mixer, 7, 2, 0x1, USB_MIXER_S16, "Output A Playback Volume", NULL);
> +	snd_create_std_mono_ctl(mixer, 7, 2, 0x2, USB_MIXER_S16, "Output B Playback Volume", NULL);
>  
> -	snd_ebox44_create_ctl(mixer, 10, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Input Capture Switch");
> -	snd_ebox44_create_ctl(mixer, 10, 2, 0x1, USB_MIXER_S16, "Input A Capture Volume");
> -	snd_ebox44_create_ctl(mixer, 10, 2, 0x2, USB_MIXER_S16, "Input B Capture Volume");
> +	snd_create_std_mono_ctl(mixer, 10, 1, 0x0, USB_MIXER_INV_BOOLEAN, "Input Capture Switch", NULL);
> +	snd_create_std_mono_ctl(mixer, 10, 2, 0x1, USB_MIXER_S16, "Input A Capture Volume", NULL);
> +	snd_create_std_mono_ctl(mixer, 10, 2, 0x2, USB_MIXER_S16, "Input B Capture Volume", NULL);
>  
>  	return 0;
>  }
> -- 
> 1.7.5.4
> 


More information about the Alsa-devel mailing list