aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2010-09-07 07:38:49 -0400
committerTakashi Iwai <tiwai@suse.de>2010-09-08 02:26:15 -0400
commitfe6ce80ae25953d95ebaf9bce27b585218cda25c (patch)
tree89857c2174ec46f6c5eff8c4c81f09a554ae3836
parent4c25b93223340deff73381cc47f9244fb379a74d (diff)
ALSA: virtuoso: fix setting of Xonar DS line-in/mic-in controls
The Line and Mic inputs cannot be used at the same time, so the driver has to automatically disable one of them if both are set. However, it forgot to notify userspace about this change, so the mixer state would be inconsistent. To fix this, check if the other control gets muted, and send a notification event in this case. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Reported-and-tested-by: Nathan Schagen Cc: <stable@kernel.org> Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/oxygen/xonar_wm87x6.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c
index 0b89932fb8c4..b82c1cfa96f5 100644
--- a/sound/pci/oxygen/xonar_wm87x6.c
+++ b/sound/pci/oxygen/xonar_wm87x6.c
@@ -53,6 +53,8 @@ struct xonar_wm87x6 {
53 struct xonar_generic generic; 53 struct xonar_generic generic;
54 u16 wm8776_regs[0x17]; 54 u16 wm8776_regs[0x17];
55 u16 wm8766_regs[0x10]; 55 u16 wm8766_regs[0x10];
56 struct snd_kcontrol *line_adcmux_control;
57 struct snd_kcontrol *mic_adcmux_control;
56 struct snd_kcontrol *lc_controls[13]; 58 struct snd_kcontrol *lc_controls[13];
57}; 59};
58 60
@@ -604,6 +606,7 @@ static int wm8776_input_mux_put(struct snd_kcontrol *ctl,
604{ 606{
605 struct oxygen *chip = ctl->private_data; 607 struct oxygen *chip = ctl->private_data;
606 struct xonar_wm87x6 *data = chip->model_data; 608 struct xonar_wm87x6 *data = chip->model_data;
609 struct snd_kcontrol *other_ctl;
607 unsigned int mux_bit = ctl->private_value; 610 unsigned int mux_bit = ctl->private_value;
608 u16 reg; 611 u16 reg;
609 int changed; 612 int changed;
@@ -611,8 +614,18 @@ static int wm8776_input_mux_put(struct snd_kcontrol *ctl,
611 mutex_lock(&chip->mutex); 614 mutex_lock(&chip->mutex);
612 reg = data->wm8776_regs[WM8776_ADCMUX]; 615 reg = data->wm8776_regs[WM8776_ADCMUX];
613 if (value->value.integer.value[0]) { 616 if (value->value.integer.value[0]) {
614 reg &= ~0x003;
615 reg |= mux_bit; 617 reg |= mux_bit;
618 /* line-in and mic-in are exclusive */
619 mux_bit ^= 3;
620 if (reg & mux_bit) {
621 reg &= ~mux_bit;
622 if (mux_bit == 1)
623 other_ctl = data->line_adcmux_control;
624 else
625 other_ctl = data->mic_adcmux_control;
626 snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
627 &other_ctl->id);
628 }
616 } else 629 } else
617 reg &= ~mux_bit; 630 reg &= ~mux_bit;
618 changed = reg != data->wm8776_regs[WM8776_ADCMUX]; 631 changed = reg != data->wm8776_regs[WM8776_ADCMUX];
@@ -964,7 +977,13 @@ static int xonar_ds_mixer_init(struct oxygen *chip)
964 err = snd_ctl_add(chip->card, ctl); 977 err = snd_ctl_add(chip->card, ctl);
965 if (err < 0) 978 if (err < 0)
966 return err; 979 return err;
980 if (!strcmp(ctl->id.name, "Line Capture Switch"))
981 data->line_adcmux_control = ctl;
982 else if (!strcmp(ctl->id.name, "Mic Capture Switch"))
983 data->mic_adcmux_control = ctl;
967 } 984 }
985 if (!data->line_adcmux_control || !data->mic_adcmux_control)
986 return -ENXIO;
968 BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls)); 987 BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls));
969 for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) { 988 for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) {
970 ctl = snd_ctl_new1(&lc_controls[i], chip); 989 ctl = snd_ctl_new1(&lc_controls[i], chip);