ALSA: usb-audio: Add Xonar U1 resume support

This time it's about Xonar U1: add the proper resume support for
"Digital Playback Switch" element.

Also, the status is moved into kcontrol private_value from
usb_mixer_interface struct field.  One more cut.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Takashi Iwai 2014-11-18 16:18:15 +01:00
parent 5f503ee9e2
commit 2bfb14c3b8
2 changed files with 38 additions and 30 deletions

View File

@ -22,8 +22,6 @@ struct usb_mixer_interface {
struct urb *rc_urb; struct urb *rc_urb;
struct usb_ctrlrequest *rc_setup_packet; struct usb_ctrlrequest *rc_setup_packet;
u8 rc_buffer[6]; u8 rc_buffer[6];
u8 xonar_u1_status;
}; };
#define MAX_CHANNELS 16 /* max logical channels */ #define MAX_CHANNELS 16 /* max logical channels */

View File

@ -543,38 +543,52 @@ static int snd_emu0204_controls_create(struct usb_mixer_interface *mixer)
static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol, static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) struct snd_ctl_elem_value *ucontrol)
{ {
struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); ucontrol->value.integer.value[0] = !!(kcontrol->private_value & 0x02);
ucontrol->value.integer.value[0] = !!(mixer->xonar_u1_status & 0x02);
return 0; return 0;
} }
static int snd_xonar_u1_switch_update(struct usb_mixer_interface *mixer,
unsigned char status)
{
struct snd_usb_audio *chip = mixer->chip;
int err;
down_read(&chip->shutdown_rwsem);
if (chip->shutdown)
err = -ENODEV;
else
err = snd_usb_ctl_msg(chip->dev,
usb_sndctrlpipe(chip->dev, 0), 0x08,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
50, 0, &status, 1);
up_read(&chip->shutdown_rwsem);
return err;
}
static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol, static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) struct snd_ctl_elem_value *ucontrol)
{ {
struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
u8 old_status, new_status; u8 old_status, new_status;
int err, changed; int err;
old_status = mixer->xonar_u1_status; old_status = kcontrol->private_value;
if (ucontrol->value.integer.value[0]) if (ucontrol->value.integer.value[0])
new_status = old_status | 0x02; new_status = old_status | 0x02;
else else
new_status = old_status & ~0x02; new_status = old_status & ~0x02;
changed = new_status != old_status; if (new_status == old_status)
down_read(&mixer->chip->shutdown_rwsem); return 0;
if (mixer->chip->shutdown)
err = -ENODEV; kcontrol->private_value = new_status;
else err = snd_xonar_u1_switch_update(list->mixer, new_status);
err = snd_usb_ctl_msg(mixer->chip->dev, return err < 0 ? err : 1;
usb_sndctrlpipe(mixer->chip->dev, 0), 0x08, }
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
50, 0, &new_status, 1); static int snd_xonar_u1_switch_resume(struct usb_mixer_elem_list *list)
up_read(&mixer->chip->shutdown_rwsem); {
if (err < 0) return snd_xonar_u1_switch_update(list->mixer,
return err; list->kctl->private_value);
mixer->xonar_u1_status = new_status;
return changed;
} }
static struct snd_kcontrol_new snd_xonar_u1_output_switch = { static struct snd_kcontrol_new snd_xonar_u1_output_switch = {
@ -583,18 +597,14 @@ static struct snd_kcontrol_new snd_xonar_u1_output_switch = {
.info = snd_ctl_boolean_mono_info, .info = snd_ctl_boolean_mono_info,
.get = snd_xonar_u1_switch_get, .get = snd_xonar_u1_switch_get,
.put = snd_xonar_u1_switch_put, .put = snd_xonar_u1_switch_put,
.private_value = 0x05,
}; };
static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer) static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
{ {
int err; return add_single_ctl_with_resume(mixer, 0,
snd_xonar_u1_switch_resume,
err = snd_ctl_add(mixer->chip->card, &snd_xonar_u1_output_switch, NULL);
snd_ctl_new1(&snd_xonar_u1_output_switch, mixer));
if (err < 0)
return err;
mixer->xonar_u1_status = 0x05;
return 0;
} }
/* Digidesign Mbox 1 clock source switch (internal/spdif) */ /* Digidesign Mbox 1 clock source switch (internal/spdif) */