diff options
author | Takashi Iwai <tiwai@suse.de> | 2011-07-07 03:25:54 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-07-07 03:25:54 -0400 |
commit | 9c7a083d94656ad6d6f2e03ba90194f2cc5bced5 (patch) | |
tree | bf4b82f484f2d5ee1ff89b843574696799ee7b59 /sound | |
parent | 4f3c7a18d9e8a287d31f828a259d713fe4859471 (diff) |
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: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d21191dcfe88..7d492713c1c1 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -2715,17 +2715,30 @@ typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol, | |||
2715 | 2715 | ||
2716 | static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, | 2716 | static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, |
2717 | struct snd_ctl_elem_value *ucontrol, | 2717 | struct snd_ctl_elem_value *ucontrol, |
2718 | getput_call_t func) | 2718 | getput_call_t func, bool check_adc_switch) |
2719 | { | 2719 | { |
2720 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 2720 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
2721 | struct alc_spec *spec = codec->spec; | 2721 | struct alc_spec *spec = codec->spec; |
2722 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | 2722 | int i, err; |
2723 | int err; | ||
2724 | 2723 | ||
2725 | mutex_lock(&codec->control_mutex); | 2724 | mutex_lock(&codec->control_mutex); |
2726 | kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx], | 2725 | if (check_adc_switch && spec->dual_adc_switch) { |
2727 | 3, 0, HDA_INPUT); | 2726 | for (i = 0; i < spec->num_adc_nids; i++) { |
2728 | err = func(kcontrol, ucontrol); | 2727 | kcontrol->private_value = |
2728 | HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], | ||
2729 | 3, 0, HDA_INPUT); | ||
2730 | err = func(kcontrol, ucontrol); | ||
2731 | if (err < 0) | ||
2732 | goto error; | ||
2733 | } | ||
2734 | } else { | ||
2735 | i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
2736 | kcontrol->private_value = | ||
2737 | HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], | ||
2738 | 3, 0, HDA_INPUT); | ||
2739 | err = func(kcontrol, ucontrol); | ||
2740 | } | ||
2741 | error: | ||
2729 | mutex_unlock(&codec->control_mutex); | 2742 | mutex_unlock(&codec->control_mutex); |
2730 | return err; | 2743 | return err; |
2731 | } | 2744 | } |
@@ -2734,14 +2747,14 @@ static int alc_cap_vol_get(struct snd_kcontrol *kcontrol, | |||
2734 | struct snd_ctl_elem_value *ucontrol) | 2747 | struct snd_ctl_elem_value *ucontrol) |
2735 | { | 2748 | { |
2736 | return alc_cap_getput_caller(kcontrol, ucontrol, | 2749 | return alc_cap_getput_caller(kcontrol, ucontrol, |
2737 | snd_hda_mixer_amp_volume_get); | 2750 | snd_hda_mixer_amp_volume_get, false); |
2738 | } | 2751 | } |
2739 | 2752 | ||
2740 | static int alc_cap_vol_put(struct snd_kcontrol *kcontrol, | 2753 | static int alc_cap_vol_put(struct snd_kcontrol *kcontrol, |
2741 | struct snd_ctl_elem_value *ucontrol) | 2754 | struct snd_ctl_elem_value *ucontrol) |
2742 | { | 2755 | { |
2743 | return alc_cap_getput_caller(kcontrol, ucontrol, | 2756 | return alc_cap_getput_caller(kcontrol, ucontrol, |
2744 | snd_hda_mixer_amp_volume_put); | 2757 | snd_hda_mixer_amp_volume_put, true); |
2745 | } | 2758 | } |
2746 | 2759 | ||
2747 | /* capture mixer elements */ | 2760 | /* capture mixer elements */ |
@@ -2751,14 +2764,14 @@ static int alc_cap_sw_get(struct snd_kcontrol *kcontrol, | |||
2751 | struct snd_ctl_elem_value *ucontrol) | 2764 | struct snd_ctl_elem_value *ucontrol) |
2752 | { | 2765 | { |
2753 | return alc_cap_getput_caller(kcontrol, ucontrol, | 2766 | return alc_cap_getput_caller(kcontrol, ucontrol, |
2754 | snd_hda_mixer_amp_switch_get); | 2767 | snd_hda_mixer_amp_switch_get, false); |
2755 | } | 2768 | } |
2756 | 2769 | ||
2757 | static int alc_cap_sw_put(struct snd_kcontrol *kcontrol, | 2770 | static int alc_cap_sw_put(struct snd_kcontrol *kcontrol, |
2758 | struct snd_ctl_elem_value *ucontrol) | 2771 | struct snd_ctl_elem_value *ucontrol) |
2759 | { | 2772 | { |
2760 | return alc_cap_getput_caller(kcontrol, ucontrol, | 2773 | return alc_cap_getput_caller(kcontrol, ucontrol, |
2761 | snd_hda_mixer_amp_switch_put); | 2774 | snd_hda_mixer_amp_switch_put, true); |
2762 | } | 2775 | } |
2763 | 2776 | ||
2764 | #define _DEFINE_CAPMIX(num) \ | 2777 | #define _DEFINE_CAPMIX(num) \ |