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

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

ALSA: hda - Fix missing path between aamix and outputs in AD codecs



AD1988 family and AD1882 codecs have another mixer widget (0x21)
between the analog-loopback mixer widget (0x20) and the actual
outputs.  Due to this hole, the analog-loopbacks aren't sent properly
to the output pins.

As a band-aid fix, introduce another fields holding the aamix merge
path, and activate it.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 0db75790
Loading
Loading
Loading
Loading
+22 −1
Original line number Diff line number Diff line
@@ -688,7 +688,7 @@ static void activate_amp_in(struct hda_codec *codec, struct nid_path *path,
	 * when aa-mixer is available, we need to enable the path as well
	 */
	for (n = 0; n < nums; n++) {
		if (n != idx && (!add_aamix || conn[n] != spec->mixer_nid))
		if (n != idx && (!add_aamix || conn[n] != spec->mixer_merge_nid))
			continue;
		activate_amp(codec, nid, HDA_INPUT, n, idx, enable);
	}
@@ -2492,6 +2492,19 @@ static int new_analog_input(struct hda_codec *codec, int input_idx,

	path->active = true;
	add_loopback_list(spec, mix_nid, idx);

	if (spec->mixer_nid != spec->mixer_merge_nid &&
	    !spec->loopback_merge_path) {
		path = snd_hda_add_new_path(codec, spec->mixer_nid,
					    spec->mixer_merge_nid, 0);
		if (path) {
			print_nid_path("loopback-merge", path);
			path->active = true;
			spec->loopback_merge_path =
				snd_hda_get_path_idx(codec, path);
		}
	}

	return 0;
}

@@ -3847,6 +3860,9 @@ int snd_hda_gen_parse_auto_config(struct hda_codec *codec,

	parse_user_hints(codec);

	if (spec->mixer_nid && !spec->mixer_merge_nid)
		spec->mixer_merge_nid = spec->mixer_nid;

	if (cfg != &spec->autocfg) {
		spec->autocfg = *cfg;
		cfg = &spec->autocfg;
@@ -4673,6 +4689,11 @@ static void init_analog_input(struct hda_codec *codec)
			if (path)
				snd_hda_activate_path(codec, path,
						      path->active, false);
			path = snd_hda_get_path_from_idx(codec,
							 spec->loopback_merge_path);
			if (path)
				snd_hda_activate_path(codec, path, path->active,
						      false);
		}
	}
}
+2 −0
Original line number Diff line number Diff line
@@ -107,6 +107,7 @@ struct hda_gen_spec {
	hda_nid_t adc_nids[AUTO_CFG_MAX_INS];
	hda_nid_t dig_in_nid;		/* digital-in NID; optional */
	hda_nid_t mixer_nid;		/* analog-mixer NID */
	hda_nid_t mixer_merge_nid;	/* aamix merge-point NID (optional) */
	const char *input_labels[HDA_MAX_NUM_INPUTS];
	int input_label_idxs[HDA_MAX_NUM_INPUTS];

@@ -163,6 +164,7 @@ struct hda_gen_spec {
	int digout_paths[AUTO_CFG_MAX_OUTS];
	int input_paths[HDA_MAX_NUM_INPUTS][AUTO_CFG_MAX_INS];
	int loopback_paths[HDA_MAX_NUM_INPUTS];
	int loopback_merge_path;
	int digin_path;

	/* auto-mic stuff */
+2 −0
Original line number Diff line number Diff line
@@ -3235,6 +3235,7 @@ static int ad1988_parse_auto_config(struct hda_codec *codec)
	spec = codec->spec;

	spec->gen.mixer_nid = 0x20;
	spec->gen.mixer_merge_nid = 0x21;
	spec->beep_dev_nid = 0x10;
	set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
	err = ad198x_parse_auto_config(codec);
@@ -5153,6 +5154,7 @@ static int ad1882_parse_auto_config(struct hda_codec *codec)
	spec = codec->spec;

	spec->gen.mixer_nid = 0x20;
	spec->gen.mixer_merge_nid = 0x21;
	spec->beep_dev_nid = 0x10;
	set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
	err = ad198x_parse_auto_config(codec);