diff options
author | Takashi Iwai <tiwai@suse.de> | 2013-08-12 08:44:59 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-08-13 03:11:04 -0400 |
commit | e80c60f3cbe76fa95029abc53b1a29172b51b96a (patch) | |
tree | 80ece245698dc8e88da0eae405009af5e03d1e53 /sound/pci | |
parent | bc2eee29fc8224ffad495d0c68ead0ce603309e3 (diff) |
ALSA: hda - Mute the right widget in auto_mute_via_amp mode
The current generic parser code assumes that always a pin widget
controls the mute for an output blindly although it might be a
different widget in the middle. Instead of the fixed assumption,
check each parsed path and just pick up the right widget that has been
already defined as a mute control.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/hda_generic.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 6ed2209c9142..fd1965c8cda9 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c | |||
@@ -3768,7 +3768,7 @@ static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) | |||
3768 | 3768 | ||
3769 | /* standard HP/line-out auto-mute helper */ | 3769 | /* standard HP/line-out auto-mute helper */ |
3770 | static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, | 3770 | static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, |
3771 | bool mute) | 3771 | int *paths, bool mute) |
3772 | { | 3772 | { |
3773 | struct hda_gen_spec *spec = codec->spec; | 3773 | struct hda_gen_spec *spec = codec->spec; |
3774 | int i; | 3774 | int i; |
@@ -3780,10 +3780,19 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, | |||
3780 | break; | 3780 | break; |
3781 | 3781 | ||
3782 | if (spec->auto_mute_via_amp) { | 3782 | if (spec->auto_mute_via_amp) { |
3783 | struct nid_path *path; | ||
3784 | hda_nid_t mute_nid; | ||
3785 | |||
3786 | path = snd_hda_get_path_from_idx(codec, paths[i]); | ||
3787 | if (!path) | ||
3788 | continue; | ||
3789 | mute_nid = get_amp_nid_(path->ctls[NID_PATH_MUTE_CTL]); | ||
3790 | if (!mute_nid) | ||
3791 | continue; | ||
3783 | if (mute) | 3792 | if (mute) |
3784 | spec->mute_bits |= (1ULL << nid); | 3793 | spec->mute_bits |= (1ULL << mute_nid); |
3785 | else | 3794 | else |
3786 | spec->mute_bits &= ~(1ULL << nid); | 3795 | spec->mute_bits &= ~(1ULL << mute_nid); |
3787 | set_pin_eapd(codec, nid, !mute); | 3796 | set_pin_eapd(codec, nid, !mute); |
3788 | continue; | 3797 | continue; |
3789 | } | 3798 | } |
@@ -3814,14 +3823,19 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, | |||
3814 | void snd_hda_gen_update_outputs(struct hda_codec *codec) | 3823 | void snd_hda_gen_update_outputs(struct hda_codec *codec) |
3815 | { | 3824 | { |
3816 | struct hda_gen_spec *spec = codec->spec; | 3825 | struct hda_gen_spec *spec = codec->spec; |
3826 | int *paths; | ||
3817 | int on; | 3827 | int on; |
3818 | 3828 | ||
3819 | /* Control HP pins/amps depending on master_mute state; | 3829 | /* Control HP pins/amps depending on master_mute state; |
3820 | * in general, HP pins/amps control should be enabled in all cases, | 3830 | * in general, HP pins/amps control should be enabled in all cases, |
3821 | * but currently set only for master_mute, just to be safe | 3831 | * but currently set only for master_mute, just to be safe |
3822 | */ | 3832 | */ |
3833 | if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT) | ||
3834 | paths = spec->out_paths; | ||
3835 | else | ||
3836 | paths = spec->hp_paths; | ||
3823 | do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), | 3837 | do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), |
3824 | spec->autocfg.hp_pins, spec->master_mute); | 3838 | spec->autocfg.hp_pins, paths, spec->master_mute); |
3825 | 3839 | ||
3826 | if (!spec->automute_speaker) | 3840 | if (!spec->automute_speaker) |
3827 | on = 0; | 3841 | on = 0; |
@@ -3829,8 +3843,12 @@ void snd_hda_gen_update_outputs(struct hda_codec *codec) | |||
3829 | on = spec->hp_jack_present | spec->line_jack_present; | 3843 | on = spec->hp_jack_present | spec->line_jack_present; |
3830 | on |= spec->master_mute; | 3844 | on |= spec->master_mute; |
3831 | spec->speaker_muted = on; | 3845 | spec->speaker_muted = on; |
3846 | if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) | ||
3847 | paths = spec->out_paths; | ||
3848 | else | ||
3849 | paths = spec->speaker_paths; | ||
3832 | do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins), | 3850 | do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins), |
3833 | spec->autocfg.speaker_pins, on); | 3851 | spec->autocfg.speaker_pins, paths, on); |
3834 | 3852 | ||
3835 | /* toggle line-out mutes if needed, too */ | 3853 | /* toggle line-out mutes if needed, too */ |
3836 | /* if LO is a copy of either HP or Speaker, don't need to handle it */ | 3854 | /* if LO is a copy of either HP or Speaker, don't need to handle it */ |
@@ -3843,8 +3861,9 @@ void snd_hda_gen_update_outputs(struct hda_codec *codec) | |||
3843 | on = spec->hp_jack_present; | 3861 | on = spec->hp_jack_present; |
3844 | on |= spec->master_mute; | 3862 | on |= spec->master_mute; |
3845 | spec->line_out_muted = on; | 3863 | spec->line_out_muted = on; |
3864 | paths = spec->out_paths; | ||
3846 | do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), | 3865 | do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), |
3847 | spec->autocfg.line_out_pins, on); | 3866 | spec->autocfg.line_out_pins, paths, on); |
3848 | } | 3867 | } |
3849 | EXPORT_SYMBOL_HDA(snd_hda_gen_update_outputs); | 3868 | EXPORT_SYMBOL_HDA(snd_hda_gen_update_outputs); |
3850 | 3869 | ||