Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b71dad18 authored by Mark Hills's avatar Mark Hills Committed by Takashi Iwai
Browse files

ALSA: usb-audio: Use a table of mixer controls



Allow mixer controls to be provided clearly in a table, to avoid
quantity of error checking at each use.

Signed-off-by: default avatarMark Hills <mark@pogo.org.uk>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 223f18e4
Loading
Loading
Loading
Loading
+49 −56
Original line number Diff line number Diff line
@@ -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)
{
@@ -113,6 +120,25 @@ static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer,
	return 0;
}

/*
 * 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++;
	}

	return 0;
}

/*
 * Sound Blaster remote control configuration
 *
@@ -916,61 +942,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 +961,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 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 },

	{ }
};

int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
{
	int err = 0;
@@ -1035,7 +1027,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;
	}