[054/129] ALSA: virtuoso: fix setting of Xonar DS line-in/mic-in controls

From: Greg KH
Date: Sat Sep 18 2010 - 15:30:46 EST


2.6.35-stable review patch. If anyone has any objections, please let us know.

------------------

From: Clemens Ladisch <clemens@xxxxxxxxxx>

commit fe6ce80ae25953d95ebaf9bce27b585218cda25c upstream.

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@xxxxxxxxxx>
Reported-and-tested-by: Nathan Schagen
Signed-off-by: Takashi Iwai <tiwai@xxxxxxx>
Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxx>

---
sound/pci/oxygen/xonar_wm87x6.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)

--- a/sound/pci/oxygen/xonar_wm87x6.c
+++ b/sound/pci/oxygen/xonar_wm87x6.c
@@ -53,6 +53,8 @@ struct xonar_wm87x6 {
struct xonar_generic generic;
u16 wm8776_regs[0x17];
u16 wm8766_regs[0x10];
+ struct snd_kcontrol *line_adcmux_control;
+ struct snd_kcontrol *mic_adcmux_control;
struct snd_kcontrol *lc_controls[13];
};

@@ -604,6 +606,7 @@ static int wm8776_input_mux_put(struct s
{
struct oxygen *chip = ctl->private_data;
struct xonar_wm87x6 *data = chip->model_data;
+ struct snd_kcontrol *other_ctl;
unsigned int mux_bit = ctl->private_value;
u16 reg;
int changed;
@@ -611,8 +614,18 @@ static int wm8776_input_mux_put(struct s
mutex_lock(&chip->mutex);
reg = data->wm8776_regs[WM8776_ADCMUX];
if (value->value.integer.value[0]) {
- reg &= ~0x003;
reg |= mux_bit;
+ /* line-in and mic-in are exclusive */
+ mux_bit ^= 3;
+ if (reg & mux_bit) {
+ reg &= ~mux_bit;
+ if (mux_bit == 1)
+ other_ctl = data->line_adcmux_control;
+ else
+ other_ctl = data->mic_adcmux_control;
+ snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
+ &other_ctl->id);
+ }
} else
reg &= ~mux_bit;
changed = reg != data->wm8776_regs[WM8776_ADCMUX];
@@ -964,7 +977,13 @@ static int xonar_ds_mixer_init(struct ox
err = snd_ctl_add(chip->card, ctl);
if (err < 0)
return err;
+ if (!strcmp(ctl->id.name, "Line Capture Switch"))
+ data->line_adcmux_control = ctl;
+ else if (!strcmp(ctl->id.name, "Mic Capture Switch"))
+ data->mic_adcmux_control = ctl;
}
+ if (!data->line_adcmux_control || !data->mic_adcmux_control)
+ return -ENXIO;
BUILD_BUG_ON(ARRAY_SIZE(lc_controls) != ARRAY_SIZE(data->lc_controls));
for (i = 0; i < ARRAY_SIZE(lc_controls); ++i) {
ctl = snd_ctl_new1(&lc_controls[i], chip);


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/