Commit 9c7a083d authored by Takashi Iwai's avatar Takashi Iwai

ALSA: hda - Change all ADCs for dual-adc switching mode for Realtek

When the dual-adc switching mode is active in Realtek auto-parser,
we need to couple all ADCs as a single capture-volume.  Currently, the
volume control changes only the first ADC, thus others may remain silent.
This patch fixes the problem.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 4f3c7a18
...@@ -2715,17 +2715,30 @@ typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol, ...@@ -2715,17 +2715,30 @@ typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol, struct snd_ctl_elem_value *ucontrol,
getput_call_t func) getput_call_t func, bool check_adc_switch)
{ {
struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
struct alc_spec *spec = codec->spec; struct alc_spec *spec = codec->spec;
unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); int i, err;
int err;
mutex_lock(&codec->control_mutex); mutex_lock(&codec->control_mutex);
kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx], if (check_adc_switch && spec->dual_adc_switch) {
for (i = 0; i < spec->num_adc_nids; i++) {
kcontrol->private_value =
HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
3, 0, HDA_INPUT);
err = func(kcontrol, ucontrol);
if (err < 0)
goto error;
}
} else {
i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
kcontrol->private_value =
HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
3, 0, HDA_INPUT); 3, 0, HDA_INPUT);
err = func(kcontrol, ucontrol); err = func(kcontrol, ucontrol);
}
error:
mutex_unlock(&codec->control_mutex); mutex_unlock(&codec->control_mutex);
return err; return err;
} }
...@@ -2734,14 +2747,14 @@ static int alc_cap_vol_get(struct snd_kcontrol *kcontrol, ...@@ -2734,14 +2747,14 @@ static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) struct snd_ctl_elem_value *ucontrol)
{ {
return alc_cap_getput_caller(kcontrol, ucontrol, return alc_cap_getput_caller(kcontrol, ucontrol,
snd_hda_mixer_amp_volume_get); snd_hda_mixer_amp_volume_get, false);
} }
static int alc_cap_vol_put(struct snd_kcontrol *kcontrol, static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) struct snd_ctl_elem_value *ucontrol)
{ {
return alc_cap_getput_caller(kcontrol, ucontrol, return alc_cap_getput_caller(kcontrol, ucontrol,
snd_hda_mixer_amp_volume_put); snd_hda_mixer_amp_volume_put, true);
} }
/* capture mixer elements */ /* capture mixer elements */
...@@ -2751,14 +2764,14 @@ static int alc_cap_sw_get(struct snd_kcontrol *kcontrol, ...@@ -2751,14 +2764,14 @@ static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) struct snd_ctl_elem_value *ucontrol)
{ {
return alc_cap_getput_caller(kcontrol, ucontrol, return alc_cap_getput_caller(kcontrol, ucontrol,
snd_hda_mixer_amp_switch_get); snd_hda_mixer_amp_switch_get, false);
} }
static int alc_cap_sw_put(struct snd_kcontrol *kcontrol, static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) struct snd_ctl_elem_value *ucontrol)
{ {
return alc_cap_getput_caller(kcontrol, ucontrol, return alc_cap_getput_caller(kcontrol, ucontrol,
snd_hda_mixer_amp_switch_put); snd_hda_mixer_amp_switch_put, true);
} }
#define _DEFINE_CAPMIX(num) \ #define _DEFINE_CAPMIX(num) \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment