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

Commit 247d85ee authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: hda - Improve naming rule for primary output



When the volume or mute control of the primary output is shared with
other (headphone or speaker) outputs, we shouldn't name it as a
specific output type but rather name it with the channel name or a
generic name like "PCM".

Also, this check should be performed individually for the volume and
the mute controls because some codecs may have shared volumes but
separate mute controls.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent ac2e8736
Loading
Loading
Loading
Loading
+42 −17
Original line number Diff line number Diff line
@@ -825,19 +825,27 @@ static int add_stereo_sw(struct hda_codec *codec, const char *pfx,
	return add_sw_ctl(codec, pfx, cidx, chs, path);
}

/* any ctl assigned to the path with the given index? */
static bool path_has_mixer(struct hda_codec *codec, int path_idx, int ctl_type)
{
	struct nid_path *path = snd_hda_get_path_from_idx(codec, path_idx);
	return path && path->ctls[ctl_type];
}

static const char * const channel_name[4] = {
	"Front", "Surround", "CLFE", "Side"
};

/* give some appropriate ctl name prefix for the given line out channel */
static const char *get_line_out_pfx(struct hda_gen_spec *spec, int ch,
				    bool can_be_master, int *index)
static const char *get_line_out_pfx(struct hda_codec *codec, int ch,
				    int *index, int ctl_type)
{
	struct hda_gen_spec *spec = codec->spec;
	struct auto_pin_cfg *cfg = &spec->autocfg;

	*index = 0;
	if (cfg->line_outs == 1 && !spec->multi_ios &&
	    !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
	    !cfg->hp_outs && !cfg->speaker_outs)
		return spec->vmaster_mute.hook ? "PCM" : "Master";

	/* if there is really a single DAC used in the whole output paths,
@@ -847,24 +855,41 @@ static const char *get_line_out_pfx(struct hda_gen_spec *spec, int ch,
	    !spec->multiout.hp_out_nid[0] && !spec->multiout.extra_out_nid[0])
		return spec->vmaster_mute.hook ? "PCM" : "Master";

	/* multi-io channels */
	if (ch >= cfg->line_outs)
		return channel_name[ch];

	switch (cfg->line_out_type) {
	case AUTO_PIN_SPEAKER_OUT:
		/* if the primary channel vol/mute is shared with HP volume,
		 * don't name it as Speaker
		 */
		if (!ch && cfg->hp_outs &&
		    !path_has_mixer(codec, spec->hp_paths[0], ctl_type))
			break;
		if (cfg->line_outs == 1)
			return "Speaker";
		if (cfg->line_outs == 2)
			return ch ? "Bass Speaker" : "Speaker";
		break;
	case AUTO_PIN_HP_OUT:
		/* if the primary channel vol/mute is shared with spk volume,
		 * don't name it as Headphone
		 */
		if (!ch && cfg->speaker_outs &&
		    !path_has_mixer(codec, spec->speaker_paths[0], ctl_type))
			break;
		/* for multi-io case, only the primary out */
		if (ch && spec->multi_ios)
			break;
		*index = ch;
		return "Headphone";
	default:
	}

	/* for a single channel output, we don't have to name the channel */
	if (cfg->line_outs == 1 && !spec->multi_ios)
		return "PCM";
		break;
	}

	if (ch >= ARRAY_SIZE(channel_name)) {
		snd_BUG();
		return "PCM";
@@ -1626,16 +1651,11 @@ static int create_multi_out_ctls(struct hda_codec *codec,
		int index;
		struct nid_path *path;

		if (i >= cfg->line_outs) {
			index = 0;
			name = channel_name[i];
		} else {
			name = get_line_out_pfx(spec, i, true, &index);
		}

		path = snd_hda_get_path_from_idx(codec, spec->out_paths[i]);
		if (!path)
			continue;

		name = get_line_out_pfx(codec, i, &index, NID_PATH_VOL_CTL);
		if (!name || !strcmp(name, "CLFE")) {
			/* Center/LFE */
			err = add_vol_ctl(codec, "Center", 0, 1, path);
@@ -1644,6 +1664,14 @@ static int create_multi_out_ctls(struct hda_codec *codec,
			err = add_vol_ctl(codec, "LFE", 0, 2, path);
			if (err < 0)
				return err;
		} else {
			err = add_stereo_vol(codec, name, index, path);
			if (err < 0)
				return err;
		}

		name = get_line_out_pfx(codec, i, &index, NID_PATH_MUTE_CTL);
		if (!name || !strcmp(name, "CLFE")) {
			err = add_sw_ctl(codec, "Center", 0, 1, path);
			if (err < 0)
				return err;
@@ -1651,9 +1679,6 @@ static int create_multi_out_ctls(struct hda_codec *codec,
			if (err < 0)
				return err;
		} else {
			err = add_stereo_vol(codec, name, index, path);
			if (err < 0)
				return err;
			err = add_stereo_sw(codec, name, index, path);
			if (err < 0)
				return err;