Commit e80c60f3 authored by Takashi Iwai's avatar Takashi Iwai

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: default avatarTakashi Iwai <tiwai@suse.de>
parent bc2eee29
...@@ -3768,7 +3768,7 @@ static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) ...@@ -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 */ /* standard HP/line-out auto-mute helper */
static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, 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; struct hda_gen_spec *spec = codec->spec;
int i; int i;
...@@ -3780,10 +3780,19 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, ...@@ -3780,10 +3780,19 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
break; break;
if (spec->auto_mute_via_amp) { 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) if (mute)
spec->mute_bits |= (1ULL << nid); spec->mute_bits |= (1ULL << mute_nid);
else else
spec->mute_bits &= ~(1ULL << nid); spec->mute_bits &= ~(1ULL << mute_nid);
set_pin_eapd(codec, nid, !mute); set_pin_eapd(codec, nid, !mute);
continue; continue;
} }
...@@ -3814,14 +3823,19 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, ...@@ -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) void snd_hda_gen_update_outputs(struct hda_codec *codec)
{ {
struct hda_gen_spec *spec = codec->spec; struct hda_gen_spec *spec = codec->spec;
int *paths;
int on; int on;
/* Control HP pins/amps depending on master_mute state; /* Control HP pins/amps depending on master_mute state;
* in general, HP pins/amps control should be enabled in all cases, * in general, HP pins/amps control should be enabled in all cases,
* but currently set only for master_mute, just to be safe * 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), 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) if (!spec->automute_speaker)
on = 0; on = 0;
...@@ -3829,8 +3843,12 @@ void snd_hda_gen_update_outputs(struct hda_codec *codec) ...@@ -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->hp_jack_present | spec->line_jack_present;
on |= spec->master_mute; on |= spec->master_mute;
spec->speaker_muted = on; 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), 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 */ /* toggle line-out mutes if needed, too */
/* if LO is a copy of either HP or Speaker, don't need to handle it */ /* 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,8 +3861,9 @@ void snd_hda_gen_update_outputs(struct hda_codec *codec)
on = spec->hp_jack_present; on = spec->hp_jack_present;
on |= spec->master_mute; on |= spec->master_mute;
spec->line_out_muted = on; spec->line_out_muted = on;
paths = spec->out_paths;
do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), 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); EXPORT_SYMBOL_HDA(snd_hda_gen_update_outputs);
......
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