summaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-08-12 14:44:59 +0200
committerTakashi Iwai <tiwai@suse.de>2013-08-13 09:11:04 +0200
commite80c60f3cbe76fa95029abc53b1a29172b51b96a (patch)
tree80ece245698dc8e88da0eae405009af5e03d1e53 /sound/pci
parentbc2eee29fc8224ffad495d0c68ead0ce603309e3 (diff)
downloadlinux-e80c60f3cbe76fa95029abc53b1a29172b51b96a.tar.bz2
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.c31
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)
/* standard HP/line-out auto-mute helper */
static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
- bool mute)
+ int *paths, bool mute)
{
struct hda_gen_spec *spec = codec->spec;
int i;
@@ -3780,10 +3780,19 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
break;
if (spec->auto_mute_via_amp) {
+ struct nid_path *path;
+ hda_nid_t mute_nid;
+
+ path = snd_hda_get_path_from_idx(codec, paths[i]);
+ if (!path)
+ continue;
+ mute_nid = get_amp_nid_(path->ctls[NID_PATH_MUTE_CTL]);
+ if (!mute_nid)
+ continue;
if (mute)
- spec->mute_bits |= (1ULL << nid);
+ spec->mute_bits |= (1ULL << mute_nid);
else
- spec->mute_bits &= ~(1ULL << nid);
+ spec->mute_bits &= ~(1ULL << mute_nid);
set_pin_eapd(codec, nid, !mute);
continue;
}
@@ -3814,14 +3823,19 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
void snd_hda_gen_update_outputs(struct hda_codec *codec)
{
struct hda_gen_spec *spec = codec->spec;
+ int *paths;
int on;
/* Control HP pins/amps depending on master_mute state;
* in general, HP pins/amps control should be enabled in all cases,
* but currently set only for master_mute, just to be safe
*/
+ if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT)
+ paths = spec->out_paths;
+ else
+ paths = spec->hp_paths;
do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
- spec->autocfg.hp_pins, spec->master_mute);
+ spec->autocfg.hp_pins, paths, spec->master_mute);
if (!spec->automute_speaker)
on = 0;
@@ -3829,8 +3843,12 @@ void snd_hda_gen_update_outputs(struct hda_codec *codec)
on = spec->hp_jack_present | spec->line_jack_present;
on |= spec->master_mute;
spec->speaker_muted = on;
+ if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
+ paths = spec->out_paths;
+ else
+ paths = spec->speaker_paths;
do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
- spec->autocfg.speaker_pins, on);
+ spec->autocfg.speaker_pins, paths, on);
/* toggle line-out mutes if needed, too */
/* 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)
on = spec->hp_jack_present;
on |= spec->master_mute;
spec->line_out_muted = on;
+ paths = spec->out_paths;
do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
- spec->autocfg.line_out_pins, on);
+ spec->autocfg.line_out_pins, paths, on);
}
EXPORT_SYMBOL_HDA(snd_hda_gen_update_outputs);