At Thu, 01 Oct 2009 15:30:16 +0200, I wrote:
Now, for some obscure reason I got confused in my previous messages when I told you the external mic is working after the update. It seems it's always the internal mic that's recording and when I plug the external mic, it makes no difference. Attached is the current alsa report.
Hm, that's odd. Could you check whether enable_msi=0 option changes the behavior?
I found the culprit. It's actually a bug happening between the analog and the digital mic switches. Try the patch below.
Takashi
=== From 02d3332285377c9de395c2b5b792805d43923fd0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai tiwai@suse.de Date: Thu, 1 Oct 2009 16:38:11 +0200 Subject: [PATCH] ALSA: hda - Fix digita/analog mic auto-switching with IDT codecs
When the auto-mic switching between an analog and a digital mic is needed with IDT codecs, the current driver doesn't reset the connection of the digital mux.
This patch fixes the behavior by checking both mux connections properly.
Signed-off-by: Takashi Iwai tiwai@suse.de --- sound/pci/hda/patch_sigmatel.c | 20 ++++++++++++++------ 1 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 826137e..a9b2682 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -182,8 +182,8 @@ struct sigmatel_jack {
struct sigmatel_mic_route { hda_nid_t pin; - unsigned char mux_idx; - unsigned char dmux_idx; + signed char mux_idx; + signed char dmux_idx; };
struct sigmatel_spec { @@ -3469,18 +3469,26 @@ static int set_mic_route(struct hda_codec *codec, break; if (i <= AUTO_PIN_FRONT_MIC) { /* analog pin */ - mic->dmux_idx = 0; i = get_connection_index(codec, spec->mux_nids[0], pin); if (i < 0) return -1; mic->mux_idx = i; + mic->dmux_idx = -1; + if (spec->dmux_nids) + mic->dmux_idx = get_connection_index(codec, + spec->dmux_nids[0], + spec->mux_nids[0]); } else if (spec->dmux_nids) { /* digital pin */ - mic->mux_idx = 0; i = get_connection_index(codec, spec->dmux_nids[0], pin); if (i < 0) return -1; mic->dmux_idx = i; + mic->mux_idx = -1; + if (spec->mux_nids) + mic->mux_idx = get_connection_index(codec, + spec->mux_nids[0], + spec->dmux_nids[0]); } return 0; } @@ -4557,11 +4565,11 @@ static void stac92xx_mic_detect(struct hda_codec *codec) mic = &spec->ext_mic; else mic = &spec->int_mic; - if (mic->dmux_idx) + if (mic->dmux_idx >= 0) snd_hda_codec_write_cache(codec, spec->dmux_nids[0], 0, AC_VERB_SET_CONNECT_SEL, mic->dmux_idx); - else + if (mic->mux_idx >= 0) snd_hda_codec_write_cache(codec, spec->mux_nids[0], 0, AC_VERB_SET_CONNECT_SEL, mic->mux_idx);