[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