[alsa-devel] [PATCH] ALSA: hda - Don't be too specific for conflicting boost ctl names

Takashi Iwai tiwai at suse.de
Wed Dec 18 18:39:22 CET 2013


When a boost control influences on multiple input paths, we shouldn't
pick up the name string specific to one input but rather choose a more
generic name.  A problem seen often is that a single mic boost
controls both internal and external mics although the driver picks up
the very first name randomly like "Internal Mic Boost".  This should
have been "Mic Boost", instead.

This patch tries to correct that behavior: when a boost control is
available, check whether it conflicts with other inputs.  If it does,
use a common string ("Mic", "Line") as long as possible, or take a
generic name "Input".

Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
 sound/pci/hda/hda_generic.c | 44 ++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 40 insertions(+), 4 deletions(-)

diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 8cebdcfdcfdc..e3f934703aa2 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -3651,6 +3651,8 @@ static int parse_mic_boost(struct hda_codec *codec)
 	struct hda_gen_spec *spec = codec->spec;
 	struct auto_pin_cfg *cfg = &spec->autocfg;
 	struct hda_input_mux *imux = &spec->input_mux;
+	static const char *input_type_labels[3] = { "Mic", "Line", "Input" };
+	int input_type_idxs[3] = {};
 	int i;
 
 	if (!spec->num_adc_nids)
@@ -3659,7 +3661,9 @@ static int parse_mic_boost(struct hda_codec *codec)
 	for (i = 0; i < imux->num_items; i++) {
 		struct nid_path *path;
 		unsigned int val;
-		int idx;
+		int idx, type, j;
+		bool conflict;
+		const char *pfx;
 		char boost_label[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
 
 		idx = imux->items[i].index;
@@ -3678,11 +3682,43 @@ static int parse_mic_boost(struct hda_codec *codec)
 		if (!val)
 			continue;
 
+		/* check whether conflicting with other input paths */
+		type = cfg->inputs[idx].type;
+		conflict = false;
+		for (j = i + 1; j < imux->num_items; j++) {
+			int idx_next = imux->items[i].index;
+			int type_next;
+			struct nid_path *path_next;
+			if (idx_next >= imux->num_items)
+				continue;
+			type_next = cfg->inputs[idx_next].type;
+			if (type_next > AUTO_PIN_LINE_IN)
+				continue;
+			path_next = get_input_path(codec, 0, j);
+			if (!path_next)
+				continue;
+			/* conflicting value? */
+			if (look_for_boost_amp(codec, path_next) == val) {
+				conflict = true;
+				if (type != type_next) {
+					type = 2; /* generic input */
+					break;
+				}
+			}
+		}
+
 		/* create a boost control */
+		if (!conflict) {
+			pfx = spec->input_labels[idx];
+			idx = spec->input_label_idxs[idx];
+		} else {
+			pfx = input_type_labels[type];
+			idx = input_type_idxs[type]++;
+		}
+
 		snprintf(boost_label, sizeof(boost_label),
-			 "%s Boost Volume", spec->input_labels[idx]);
-		if (!add_control(spec, HDA_CTL_WIDGET_VOL, boost_label,
-				 spec->input_label_idxs[idx], val))
+			 "%s Boost Volume", pfx);
+		if (!add_control(spec, HDA_CTL_WIDGET_VOL, boost_label, idx, val))
 			return -ENOMEM;
 
 		path->ctls[NID_PATH_BOOST_CTL] = val;
-- 
1.8.5



More information about the Alsa-devel mailing list