[alsa-devel] [PATCH 2/2] ALSA: hda - Fix ADC input-amp handling in Conexant auto-parser

Takashi Iwai tiwai at suse.de
Fri Oct 14 15:59:30 CEST 2011


It seems that Conexant chips handle only a single input-amp even when
the audio-input widget has multiple sources.  This has been never clear,
and I implemented in the current way based on the debug information I
got at the early time -- the device reacts individual input-amp values
for different sources.  But it doesn't look correct now.

This patch changes the auto-parser code to handle a single input-amp
per audio-in widget.  After applying this, you'll see only a single
"Capture" volume control instead of separate "Mic" or "Line" captures
when the device is set up to use a single ADC.

Cc: <stable at kernel.org>
Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
 sound/pci/hda/hda_proc.c       |    7 +++++--
 sound/pci/hda/patch_conexant.c |   38 +++++++++++++++++++++++++++-----------
 2 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 2c981b5..9431369 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -646,12 +646,15 @@ static void print_codec_info(struct snd_info_entry *entry,
 							   HDA_MAX_CONNECTIONS);
 
 		if (wid_caps & AC_WCAP_IN_AMP) {
+			int nums = conn_len;
 			snd_iprintf(buffer, "  Amp-In caps: ");
 			print_amp_caps(buffer, codec, nid, HDA_INPUT);
 			snd_iprintf(buffer, "  Amp-In vals: ");
+			if (wid_type == AC_WID_PIN ||
+			    (wid_type == AC_WID_AUD_IN && codec->pin_amp_workaround))
+				nums = 1;
 			print_amp_vals(buffer, codec, nid, HDA_INPUT,
-				       wid_caps & AC_WCAP_STEREO,
-				       wid_type == AC_WID_PIN ? 1 : conn_len);
+				       wid_caps & AC_WCAP_STEREO, nums);
 		}
 		if (wid_caps & AC_WCAP_OUT_AMP) {
 			snd_iprintf(buffer, "  Amp-Out caps: ");
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index feef775..f2d4933 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -4251,16 +4251,20 @@ static int cx_auto_build_input_controls(struct hda_codec *codec)
 	struct conexant_spec *spec = codec->spec;
 	struct hda_input_mux *imux = &spec->private_imux;
 	const char *prev_label;
-	int input_conn[HDA_MAX_NUM_INPUTS];
-	int i, err, cidx;
+	int i, j, err, cidx;
 	int multi_connection;
 
+	if (!imux->num_items)
+		return 0;
+
 	multi_connection = 0;
 	for (i = 0; i < imux->num_items; i++) {
 		cidx = get_input_connection(codec, spec->imux_info[i].adc,
 					    spec->imux_info[i].pin);
-		input_conn[i] = (spec->imux_info[i].adc << 8) | cidx;
-		if (i > 0 && input_conn[i] != input_conn[0])
+		if (cidx < 0)
+			continue;
+		if (i > 0 && !multi_connection &&
+		    spec->imux_info[i].adc != spec->imux_info[0].adc)
 			multi_connection = 1;
 	}
 
@@ -4282,15 +4286,27 @@ static int cx_auto_build_input_controls(struct hda_codec *codec)
 		if (err < 0)
 			return err;
 
-		if (!multi_connection) {
-			if (i > 0)
+		if (multi_connection) {
+			bool found = false;
+			for (j = 0; j < i; j++) {
+				if (spec->imux_info[j].adc == spec->imux_info[i].adc) {
+					found = true;
+					break;
+				}
+			}
+			if (found)
 				continue;
-			err = cx_auto_add_capture_volume(codec, nid,
-							 "Capture", "", cidx);
-		} else {
-			err = cx_auto_add_capture_volume(codec, nid,
-							 label, " Capture", cidx);
+			err = cx_auto_add_capture_volume(codec, nid, label,
+							 " Capture", cidx);
+			if (err < 0)
+				return err;
 		}
+	}
+
+	if (!multi_connection) {
+		err = cx_auto_add_volume_idx(codec, "Capture", "", 0,
+					     spec->imux_info[0].adc,
+					     HDA_INPUT, 0);
 		if (err < 0)
 			return err;
 	}
-- 
1.7.7



More information about the Alsa-devel mailing list