aboutsummaryrefslogtreecommitdiffstats
path: root/sound/usb
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2014-11-18 10:18:15 -0500
committerTakashi Iwai <tiwai@suse.de>2014-11-21 05:58:01 -0500
commit2bfb14c3b8fbc787ff4478f9d77ecee78cb922fe (patch)
tree1b181fa8f501abf62ee527da7c455bc0e3af50bd /sound/usb
parent5f503ee9e270f8251ba9024bafa8d698050066cb (diff)
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>
Diffstat (limited to 'sound/usb')
-rw-r--r--sound/usb/mixer.h2
-rw-r--r--sound/usb/mixer_quirks.c66
2 files changed, 38 insertions, 30 deletions
diff --git a/sound/usb/mixer.h b/sound/usb/mixer.h
index 0b3740ea6614..d3268f0ee2b3 100644
--- a/sound/usb/mixer.h
+++ b/sound/usb/mixer.h
@@ -22,8 +22,6 @@ struct usb_mixer_interface {
22 struct urb *rc_urb; 22 struct urb *rc_urb;
23 struct usb_ctrlrequest *rc_setup_packet; 23 struct usb_ctrlrequest *rc_setup_packet;
24 u8 rc_buffer[6]; 24 u8 rc_buffer[6];
25
26 u8 xonar_u1_status;
27}; 25};
28 26
29#define MAX_CHANNELS 16 /* max logical channels */ 27#define MAX_CHANNELS 16 /* max logical channels */
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index f2b1c0d8ccd1..4afcf096ebb2 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -543,38 +543,52 @@ static int snd_emu0204_controls_create(struct usb_mixer_interface *mixer)
543static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol, 543static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol,
544 struct snd_ctl_elem_value *ucontrol) 544 struct snd_ctl_elem_value *ucontrol)
545{ 545{
546 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); 546 ucontrol->value.integer.value[0] = !!(kcontrol->private_value & 0x02);
547
548 ucontrol->value.integer.value[0] = !!(mixer->xonar_u1_status & 0x02);
549 return 0; 547 return 0;
550} 548}
551 549
550static int snd_xonar_u1_switch_update(struct usb_mixer_interface *mixer,
551 unsigned char status)
552{
553 struct snd_usb_audio *chip = mixer->chip;
554 int err;
555
556 down_read(&chip->shutdown_rwsem);
557 if (chip->shutdown)
558 err = -ENODEV;
559 else
560 err = snd_usb_ctl_msg(chip->dev,
561 usb_sndctrlpipe(chip->dev, 0), 0x08,
562 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER,
563 50, 0, &status, 1);
564 up_read(&chip->shutdown_rwsem);
565 return err;
566}
567
552static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol, 568static int snd_xonar_u1_switch_put(struct snd_kcontrol *kcontrol,
553 struct snd_ctl_elem_value *ucontrol) 569 struct snd_ctl_elem_value *ucontrol)
554{ 570{
555 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); 571 struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
556 u8 old_status, new_status; 572 u8 old_status, new_status;
557 int err, changed; 573 int err;
558 574
559 old_status = mixer->xonar_u1_status; 575 old_status = kcontrol->private_value;
560 if (ucontrol->value.integer.value[0]) 576 if (ucontrol->value.integer.value[0])
561 new_status = old_status | 0x02; 577 new_status = old_status | 0x02;
562 else 578 else
563 new_status = old_status & ~0x02; 579 new_status = old_status & ~0x02;
564 changed = new_status != old_status; 580 if (new_status == old_status)
565 down_read(&mixer->chip->shutdown_rwsem); 581 return 0;
566 if (mixer->chip->shutdown) 582
567 err = -ENODEV; 583 kcontrol->private_value = new_status;
568 else 584 err = snd_xonar_u1_switch_update(list->mixer, new_status);
569 err = snd_usb_ctl_msg(mixer->chip->dev, 585 return err < 0 ? err : 1;
570 usb_sndctrlpipe(mixer->chip->dev, 0), 0x08, 586}
571 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, 587
572 50, 0, &new_status, 1); 588static int snd_xonar_u1_switch_resume(struct usb_mixer_elem_list *list)
573 up_read(&mixer->chip->shutdown_rwsem); 589{
574 if (err < 0) 590 return snd_xonar_u1_switch_update(list->mixer,
575 return err; 591 list->kctl->private_value);
576 mixer->xonar_u1_status = new_status;
577 return changed;
578} 592}
579 593
580static struct snd_kcontrol_new snd_xonar_u1_output_switch = { 594static struct snd_kcontrol_new snd_xonar_u1_output_switch = {
@@ -583,18 +597,14 @@ static struct snd_kcontrol_new snd_xonar_u1_output_switch = {
583 .info = snd_ctl_boolean_mono_info, 597 .info = snd_ctl_boolean_mono_info,
584 .get = snd_xonar_u1_switch_get, 598 .get = snd_xonar_u1_switch_get,
585 .put = snd_xonar_u1_switch_put, 599 .put = snd_xonar_u1_switch_put,
600 .private_value = 0x05,
586}; 601};
587 602
588static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer) 603static int snd_xonar_u1_controls_create(struct usb_mixer_interface *mixer)
589{ 604{
590 int err; 605 return add_single_ctl_with_resume(mixer, 0,
591 606 snd_xonar_u1_switch_resume,
592 err = snd_ctl_add(mixer->chip->card, 607 &snd_xonar_u1_output_switch, NULL);
593 snd_ctl_new1(&snd_xonar_u1_output_switch, mixer));
594 if (err < 0)
595 return err;
596 mixer->xonar_u1_status = 0x05;
597 return 0;
598} 608}
599 609
600/* Digidesign Mbox 1 clock source switch (internal/spdif) */ 610/* Digidesign Mbox 1 clock source switch (internal/spdif) */