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

Commit 739572a5 authored by David Henningsson's avatar David Henningsson Committed by Takashi Iwai
Browse files

ALSA: hda - use both input paths on Conexant auto parser

On the Thinkpad W520 - and probably several other machines with
Conexant 506x chips - the Dock Mic and Mic are connected to the
same two selector nodes. This patch will make Dock Mic take one
selector node and Mic take the other, when possible.

Without the patch, both paths would take the first selector,
leading to the normal Mic's volume being controlled by
"Dock Mic Boost".
(On other machines, this could instead fixup similar problems between
Mic and Line In, for example.)

BugLink: https://bugs.launchpad.net/bugs/1037642


Signed-off-by: default avatarDavid Henningsson <david.henningsson@canonical.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent c1051439
Loading
Loading
Loading
Loading
+16 −4
Original line number Original line Diff line number Diff line
@@ -3540,8 +3540,9 @@ static int __select_input_connection(struct hda_codec *codec, hda_nid_t mux,
				     hda_nid_t pin, hda_nid_t *srcp,
				     hda_nid_t pin, hda_nid_t *srcp,
				     bool do_select, int depth)
				     bool do_select, int depth)
{
{
	struct conexant_spec *spec = codec->spec;
	hda_nid_t conn[HDA_MAX_NUM_INPUTS];
	hda_nid_t conn[HDA_MAX_NUM_INPUTS];
	int i, nums;
	int startidx, i, nums;


	switch (get_wcaps_type(get_wcaps(codec, mux))) {
	switch (get_wcaps_type(get_wcaps(codec, mux))) {
	case AC_WID_AUD_IN:
	case AC_WID_AUD_IN:
@@ -3565,14 +3566,25 @@ static int __select_input_connection(struct hda_codec *codec, hda_nid_t mux,
	depth++;
	depth++;
	if (depth == 2)
	if (depth == 2)
		return -1;
		return -1;

	/* Try to rotate around connections to avoid one boost controlling
	   another input path as well */
	startidx = 0;
	for (i = 0; i < spec->private_imux.num_items; i++)
		if (spec->imux_info[i].pin == pin) {
			startidx = i;
			break;
		}

	for (i = 0; i < nums; i++) {
	for (i = 0; i < nums; i++) {
		int ret  = __select_input_connection(codec, conn[i], pin, srcp,
		int j = (i + startidx) % nums;
		int ret  = __select_input_connection(codec, conn[j], pin, srcp,
						     do_select, depth);
						     do_select, depth);
		if (ret >= 0) {
		if (ret >= 0) {
			if (do_select)
			if (do_select)
				snd_hda_codec_write(codec, mux, 0,
				snd_hda_codec_write(codec, mux, 0,
						    AC_VERB_SET_CONNECT_SEL, i);
						    AC_VERB_SET_CONNECT_SEL, j);
			return i;
			return j;
		}
		}
	}
	}
	return -1;
	return -1;