At Fri, 15 Jan 2010 00:30:41 +0100, Christian Stöveken wrote:
http://www.alsa-project.org/db/?f=87e1ba4b02f13689fb0d32a03b45fd79ebf57ef0 that's with "options snd-hda-intel power_save=10 power_save_controller=N" on 2.6.33-020633rc4-generic ... no microphone also no mic with "options snd-hda-intel power_save=10 power_save_controller=N model=auto" on that kernel http://www.alsa-project.org/db/?f=388a56455f5bd65da53f24b5f09f240082417d16
OK, then this is a bug to fix. Does the patch below work (for 2.6.33)?
Also, which mic are you testing? The built-in mic or the mic jack? It seems that BIOS sets only one pin for the mic. I don't know whether this is correct, i.e. the hardware switches the input automatically by itself and shares the same pin. If not, it's a BIOS bug that offers only one input pin.
thanks,
Takashi
--- diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 301b147..a8b4f6b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1234,6 +1234,8 @@ static void alc_init_auto_mic(struct hda_codec *codec) return; /* invalid entry */ } } + if (!ext || !fixed) + return; if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) return; /* no unsol support */ snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n", @@ -4917,6 +4919,48 @@ static void fixup_automic_adc(struct hda_codec *codec) spec->auto_mic = 0; /* disable auto-mic to be sure */ }
+/* choose the ADC/MUX containing the input pin and initialize the setup */ +static void fixup_single_adc(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + hda_nid_t pin; + int i; + + /* there must be only two mic inputs exclusively */ + for (i = 0; i < AUTO_PIN_LAST; i++) { + if (spec->autocfg.input_pins[i]) { + pin = spec->autocfg.input_pins[i]; + break; + } + } + if (!pin) + return; + + for (i = 0; i < spec->num_adc_nids; i++) { + hda_nid_t cap = spec->capsrc_nids ? + spec->capsrc_nids[i] : spec->adc_nids[i]; + int idx; + + idx = get_connection_index(codec, cap, pin); + if (idx < 0) + continue; + spec->int_mic.mux_idx = idx; + if (spec->capsrc_nids) + spec->capsrc_nids += i; + spec->adc_nids += i; + spec->num_adc_nids = 1; + /* select or unmute this route */ + if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) { + snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx, + HDA_AMP_MUTE, 0); + } else { + snd_hda_codec_write_cache(codec, cap, 0, + AC_VERB_SET_CONNECT_SEL, idx); + } + return; + } +} + static void set_capture_mixer(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -4929,14 +4973,15 @@ static void set_capture_mixer(struct hda_codec *codec) alc_capture_mixer3 }, }; if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) { - int mux; - if (spec->auto_mic) { - mux = 0; + int mux = 0; + if (spec->auto_mic) fixup_automic_adc(codec); - } else if (spec->input_mux && spec->input_mux->num_items > 1) - mux = 1; - else - mux = 0; + else if (spec->input_mux) { + if (spec->input_mux->num_items > 1) + mux = 1; + if (spec->input_mux->num_items == 1) + fixup_single_adc(codec); + } spec->cap_mixer = caps[mux][spec->num_adc_nids - 1]; } } @@ -11334,7 +11379,7 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, }
#define alc262_auto_create_input_ctls \ - alc880_auto_create_input_ctls + alc882_auto_create_input_ctls
/* * generic initialization of ADC, input mixers and output mixers