aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2014-11-18 10:11:37 -0500
committerTakashi Iwai <tiwai@suse.de>2014-11-21 05:57:55 -0500
commit5f503ee9e270f8251ba9024bafa8d698050066cb (patch)
treed78f2ddf1a969f505396bcaac66ef64e80cb6ce4
parent9cf3689bfe0784b6f6afb301bece95d3fc3eeb64 (diff)
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: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/usb/mixer_quirks.c84
1 files changed, 46 insertions, 38 deletions
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 41cacf889c98..f2b1c0d8ccd1 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -473,63 +473,71 @@ static int snd_emu0204_ch_switch_get(struct snd_kcontrol *kcontrol,
473 return 0; 473 return 0;
474} 474}
475 475
476static int snd_emu0204_ch_switch_put(struct snd_kcontrol *kcontrol, 476static int snd_emu0204_ch_switch_update(struct usb_mixer_interface *mixer,
477 struct snd_ctl_elem_value *ucontrol) 477 int value)
478{ 478{
479 struct usb_mixer_interface *mixer = snd_kcontrol_chip(kcontrol); 479 struct snd_usb_audio *chip = mixer->chip;
480 unsigned int value = ucontrol->value.enumerated.item[0]; 480 int err;
481 int err, changed;
482 unsigned char buf[2]; 481 unsigned char buf[2];
483 482
484 if (value > 1) 483 down_read(&chip->shutdown_rwsem);
485 return -EINVAL;
486
487 buf[0] = 0x01;
488 buf[1] = value ? 0x02 : 0x01;
489
490 changed = value != kcontrol->private_value;
491 down_read(&mixer->chip->shutdown_rwsem);
492 if (mixer->chip->shutdown) { 484 if (mixer->chip->shutdown) {
493 err = -ENODEV; 485 err = -ENODEV;
494 goto out; 486 goto out;
495 } 487 }
496 err = snd_usb_ctl_msg(mixer->chip->dev, 488
497 usb_sndctrlpipe(mixer->chip->dev, 0), UAC_SET_CUR, 489 buf[0] = 0x01;
490 buf[1] = value ? 0x02 : 0x01;
491 err = snd_usb_ctl_msg(chip->dev,
492 usb_sndctrlpipe(chip->dev, 0), UAC_SET_CUR,
498 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT, 493 USB_RECIP_INTERFACE | USB_TYPE_CLASS | USB_DIR_OUT,
499 0x0400, 0x0e00, buf, 2); 494 0x0400, 0x0e00, buf, 2);
500 out: 495 out:
501 up_read(&mixer->chip->shutdown_rwsem); 496 up_read(&chip->shutdown_rwsem);
502 if (err < 0) 497 return err;
503 return err; 498}
499
500static int snd_emu0204_ch_switch_put(struct snd_kcontrol *kcontrol,
501 struct snd_ctl_elem_value *ucontrol)
502{
503 struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
504 struct usb_mixer_interface *mixer = list->mixer;
505 unsigned int value = ucontrol->value.enumerated.item[0];
506 int err;
507
508 if (value > 1)
509 return -EINVAL;
510
511 if (value == kcontrol->private_value)
512 return 0;
513
504 kcontrol->private_value = value; 514 kcontrol->private_value = value;
505 return changed; 515 err = snd_emu0204_ch_switch_update(mixer, value);
516 return err < 0 ? err : 1;
506} 517}
507 518
519static int snd_emu0204_ch_switch_resume(struct usb_mixer_elem_list *list)
520{
521 return snd_emu0204_ch_switch_update(list->mixer,
522 list->kctl->private_value);
523}
508 524
509static struct snd_kcontrol_new snd_emu0204_controls[] = { 525static struct snd_kcontrol_new snd_emu0204_control = {
510 { 526 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
511 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 527 .name = "Front Jack Channels",
512 .name = "Front Jack Channels", 528 .info = snd_emu0204_ch_switch_info,
513 .info = snd_emu0204_ch_switch_info, 529 .get = snd_emu0204_ch_switch_get,
514 .get = snd_emu0204_ch_switch_get, 530 .put = snd_emu0204_ch_switch_put,
515 .put = snd_emu0204_ch_switch_put, 531 .private_value = 0,
516 .private_value = 0,
517 },
518}; 532};
519 533
520static int snd_emu0204_controls_create(struct usb_mixer_interface *mixer) 534static int snd_emu0204_controls_create(struct usb_mixer_interface *mixer)
521{ 535{
522 int i, err; 536 return add_single_ctl_with_resume(mixer, 0,
523 537 snd_emu0204_ch_switch_resume,
524 for (i = 0; i < ARRAY_SIZE(snd_emu0204_controls); ++i) { 538 &snd_emu0204_control, NULL);
525 err = snd_ctl_add(mixer->chip->card,
526 snd_ctl_new1(&snd_emu0204_controls[i], mixer));
527 if (err < 0)
528 return err;
529 }
530
531 return 0;
532} 539}
540
533/* ASUS Xonar U1 / U3 controls */ 541/* ASUS Xonar U1 / U3 controls */
534 542
535static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol, 543static int snd_xonar_u1_switch_get(struct snd_kcontrol *kcontrol,