Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e80c60f3 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

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
Loading
Loading
Loading
Loading
+25 −6
Original line number Original line Diff line number Diff line
@@ -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,
			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,
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)
		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)
		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);