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

Commit 5f503ee9 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: usb-audio: Add Emu0204 channel switch resume support



Similar as the previous fix, this adds the proper resume support to
Emu0202 "Front Jack Channels" enum mixer element.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 9cf3689b
Loading
Loading
Loading
Loading
+46 −38
Original line number Diff line number Diff line
@@ -473,63 +473,71 @@ static int snd_emu0204_ch_switch_get(struct snd_kcontrol *kcontrol,
	return 0;
}

static int snd_emu0204_ch_switch_put(struct snd_kcontrol *kcontrol,
				     struct snd_ctl_elem_value *ucontrol)
static int snd_emu0204_ch_switch_update(struct usb_mixer_interface *mixer,
					int value)
{
	struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol);
	unsigned int value = ucontrol->value.enumerated.item[0];
	int err, changed;
	struct snd_usb_audio *chip = mixer->chip;
	int err;
	unsigned char buf[2];

	if (value > 1)
		return -EINVAL;

	buf[0] = 0x01;
	buf[1] = value ? 0x02 : 0x01;

	changed = value != kcontrol->private_value;
	down_read(&mixer->chip->shutdown_rwsem);
	down_read(&chip->shutdown_rwsem);
	if (mixer->chip->shutdown) {
		err = -ENODEV;
		goto out;
	}
	err = snd_usb_ctl_msg(mixer->chip->dev,
		      usb_sndctrlpipe(mixer->chip->dev, 0), UAC_SET_CUR,

	buf[0] = 0x01;
	buf[1] = value ? 0x02 : 0x01;
	err = snd_usb_ctl_msg(chip->dev,
		      usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR,
		      USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
		      0x0400, 0x0e00, buf, 2);
 out:
	up_read(&mixer->chip->shutdown_rwsem);
	if (err < 0)
	up_read(&chip->shutdown_rwsem);
	return err;
	kcontrol->private_value = value;
	return changed;
}

static int snd_emu0204_ch_switch_put(struct snd_kcontrol *kcontrol,
				     struct snd_ctl_elem_value *ucontrol)
{
	struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
	struct usb_mixer_interface *mixer = list->mixer;
	unsigned int value = ucontrol->value.enumerated.item[0];
	int err;

	if (value > 1)
		return -EINVAL;

	if (value == kcontrol->private_value)
		return 0;

	kcontrol->private_value = value;
	err = snd_emu0204_ch_switch_update(mixer, value);
	return err < 0 ? err : 1;
}

static struct snd_kcontrol_new snd_emu0204_controls[] = {
static int snd_emu0204_ch_switch_resume(struct usb_mixer_elem_list *list)
{
	return snd_emu0204_ch_switch_update(list->mixer,
					    list->kctl->private_value);
}

static struct snd_kcontrol_new snd_emu0204_control = {
	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
	.name = "Front Jack Channels",
	.info = snd_emu0204_ch_switch_info,
	.get = snd_emu0204_ch_switch_get,
	.put = snd_emu0204_ch_switch_put,
	.private_value = 0,
	},
};

static int snd_emu0204_controls_create(struct usb_mixer_interface *mixer)
{
	int i, err;

	for (i = 0; i < ARRAY_SIZE(snd_emu0204_controls); ++i) {
		err = snd_ctl_add(mixer->chip->card,
			snd_ctl_new1(&snd_emu0204_controls[i], mixer));
		if (err < 0)
			return err;
	return add_single_ctl_with_resume(mixer, 0,
					  snd_emu0204_ch_switch_resume,
					  &snd_emu0204_control, NULL);
}

	return 0;
}
/* ASUS Xonar U1 / U3 controls */

static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol,