From d170db12ac67809c4f43e3f548b5564e020a5282 Mon Sep 17 00:00:00 2001 From: Shrirang Bagul Date: Mon, 25 Apr 2011 11:15:40 +0800 Subject: [PATCH] 2-mic capture for x86-Eeebot --- sound/pci/hda/patch_realtek.c | 159 +++++++++++++++++++++++++++++++++++++--- 1 files changed, 147 insertions(+), 12 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index dff209f..d14fe36 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -14152,19 +14152,33 @@ static hda_nid_t alc269_capsrc_nids[1] = { 0x23, }; -static hda_nid_t alc269vb_adc_nids[1] = { - /* ADC1 */ - 0x09, +static hda_nid_t alc269vb_adc_nids[2] = { + /* ADC1-2 */ + 0x09, 0x08, }; static hda_nid_t alc269vb_capsrc_nids[1] = { - 0x22, + 0x22, 0x23, }; static hda_nid_t alc269_adc_candidates[] = { 0x08, 0x09, 0x07, }; +static struct hda_channel_mode alc269_4ch_modes[1] = { + { 4, NULL}, +}; + +static struct hda_input_mux alc269vb_capture_sources[2] = { + { + .num_items = 2, + .items = { + {"Mic-1", 0x0}, + {"Mic-2", 0x2}, + }, + }, +}; + #define alc269_modes alc260_modes #define alc269_capture_source alc880_lg_lw_capture_source @@ -14275,6 +14289,16 @@ static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc269vb_test_laptop_analog_capture_mixer[] = { + HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME_IDX("Capture 2 Volume", 0x1, 0x9, 0x0, HDA_INPUT), + HDA_CODEC_MUTE_IDX("Capture 2 Switch", 0x1, 0x09, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic-1 Boost Volume", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic-2 Boost Volume", 0x19, 0, HDA_INPUT), + { } /* end */ +}; + static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), @@ -14463,10 +14487,10 @@ static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = { static struct hda_verb alc269vb_laptop_amic_init_verbs[] = { {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, {0x22, AC_VERB_SET_CONNECT_SEL, 0x01}, + {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, - {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, + //{0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, {} }; @@ -14567,7 +14591,7 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) static void alc269_laptop_inithook(struct hda_codec *codec) { alc269_speaker_automute(codec); - alc_mic_automute(codec); + //alc_mic_automute(codec); } /* @@ -15115,14 +15139,17 @@ static struct alc_config_preset alc269_presets[] = { }, [ALC269VB_AMIC] = { .mixers = { alc269vb_laptop_mixer }, - .cap_mixer = alc269vb_laptop_analog_capture_mixer, + .cap_mixer = alc269vb_test_laptop_analog_capture_mixer, .init_verbs = { alc269vb_init_verbs, alc269vb_laptop_amic_init_verbs }, .num_dacs = ARRAY_SIZE(alc269_dac_nids), .dac_nids = alc269_dac_nids, .hp_nid = 0x03, - .num_channel_mode = ARRAY_SIZE(alc269_modes), - .channel_mode = alc269_modes, + .num_channel_mode = ARRAY_SIZE(alc269_4ch_modes), + .channel_mode = alc269_4ch_modes, + .num_mux_defs = + ARRAY_SIZE(alc269vb_capture_sources), + .input_mux = alc269vb_capture_sources, .unsol_event = alc269_laptop_unsol_event, .setup = alc269vb_laptop_amic_setup, .init_hook = alc269_laptop_inithook, @@ -15221,6 +15248,76 @@ static int alc269_fill_coef(struct hda_codec *codec) return 0; } +static int alc269_capture_4ch_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct alc_spec *spec = codec->spec; + + snd_hda_codec_setup_stream(codec, 0x08, stream_tag, 0, format); + + return 0; +} + +static int alc269_capture_4ch_pcm_cleanup(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream) +{ + snd_hda_codec_cleanup_stream(codec, 0x08); + + return 0; +} + +static int alc269_capture_4ch_alt_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct alc_spec *spec = codec->spec; + + snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1], + stream_tag, 0, format); + + return 0; +} + +static int alc269_capture_4ch_alt_pcm_cleanup(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream) +{ + struct alc_spec *spec = codec->spec; + + snd_hda_codec_cleanup_stream(codec, + spec->adc_nids[substream->number +1]); + + return 0; +} + +static struct hda_pcm_stream alc269_pcm_analog_4ch_capture = { + .substreams = 1, + .channels_min = 2, + .channels_max = 2, + /* NID is set in alc_build_pcms */ + /*.ops = { + .prepare = alc269_capture_4ch_pcm_prepare, + .cleanup = alc269_capture_4ch_pcm_cleanup + },*/ +}; + +static struct hda_pcm_stream alc269_pcm_analog_alt_4ch_capture = { + .substreams = 2, + .channels_min = 2, + .channels_max = 2, + /* NID is set in alc_build_pcms */ + .ops = { + .prepare = alc269_capture_4ch_alt_pcm_prepare, + .cleanup = alc269_capture_4ch_alt_pcm_cleanup + }, +}; + static int patch_alc269(struct hda_codec *codec) { struct alc_spec *spec; @@ -15311,11 +15408,14 @@ static int patch_alc269(struct hda_codec *codec) spec->stream_analog_capture = &dualmic_pcm_analog_capture; } else { spec->stream_analog_playback = &alc269_pcm_analog_playback; - spec->stream_analog_capture = &alc269_pcm_analog_capture; + //spec->stream_analog_capture = &alc269_pcm_analog_capture; + spec->stream_analog_capture = &alc269_pcm_analog_4ch_capture; + spec->stream_analog_alt_capture = &alc269_pcm_analog_alt_4ch_capture; } spec->stream_digital_playback = &alc269_pcm_digital_playback; spec->stream_digital_capture = &alc269_pcm_digital_capture; +#if 1 if (!spec->adc_nids) { /* wasn't filled automatically? use default */ if (spec->codec_variant == ALC269_TYPE_NORMAL) { spec->adc_nids = alc269_adc_nids; @@ -15327,7 +15427,42 @@ static int patch_alc269(struct hda_codec *codec) spec->capsrc_nids = alc269vb_capsrc_nids; } } - +#else + // Shrirang + if (!spec->adc_nids && spec->input_mux) { + int i, j; + spec->num_adc_nids = 0; + for (i = 0; i < ARRAY_SIZE(alc269vb_adc_nids); i++) { + snd_printd("Config ADC# %d \n", i); + const struct hda_input_mux *imux = spec->input_mux; + hda_nid_t cap; + hda_nid_t items[16]; + hda_nid_t nid = alc269vb_adc_nids[i]; + unsigned int wcap = get_wcaps(codec, nid); + /* get type */ + wcap = get_wcaps_type(wcap); + if (wcap != AC_WID_AUD_IN) + continue; + spec->private_adc_nids[spec->num_adc_nids] = nid; + err = snd_hda_get_connections(codec, nid, &cap, 1); + if (err < 0) + continue; + err = snd_hda_get_connections(codec, cap, items, + ARRAY_SIZE(items)); + if (err < 0) + continue; + for (j = 0; j < imux->num_items; j++) + if (imux->items[j].index >= err) + break; + if (j < imux->num_items) + continue; + spec->private_capsrc_nids[spec->num_adc_nids] = cap; + spec->num_adc_nids++; + } + spec->adc_nids = spec->private_adc_nids; + spec->capsrc_nids = spec->private_capsrc_nids; + } +#endif if (!spec->cap_mixer) set_capture_mixer(codec); if (has_cdefine_beep(codec)) -- 1.7.1