📄 patch_analog.c
字号:
{ "Line", 0x4 }, { "Mix", 0x5 }, { "Mono", 0x6 }, { "Phone", 0x7 }, },};static struct hda_bind_ctls ad1986a_bind_pcm_vol = { .ops = &snd_hda_bind_vol, .values = { HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT), HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT), HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT), 0 },};static struct hda_bind_ctls ad1986a_bind_pcm_sw = { .ops = &snd_hda_bind_sw, .values = { HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT), HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT), HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT), 0 },};/* * mixers */static struct snd_kcontrol_new ad1986a_mixers[] = { /* * bind volumes/mutes of 3 DACs as a single PCM control for simplicity */ HDA_BIND_VOL("PCM Playback Volume", &ad1986a_bind_pcm_vol), HDA_BIND_SW("PCM Playback Switch", &ad1986a_bind_pcm_sw), HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Surround Playback Switch", 0x1c, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x1d, 1, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x1d, 2, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x1d, 1, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x1d, 2, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x18, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x18, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Source", .info = ad198x_mux_enum_info, .get = ad198x_mux_enum_get, .put = ad198x_mux_enum_put, }, HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT), { } /* end */};/* additional mixers for 3stack mode */static struct snd_kcontrol_new ad1986a_3st_mixers[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Channel Mode", .info = ad198x_ch_mode_info, .get = ad198x_ch_mode_get, .put = ad198x_ch_mode_put, }, { } /* end */};/* laptop model - 2ch only */static hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC };/* master controls both pins 0x1a and 0x1b */static struct hda_bind_ctls ad1986a_laptop_master_vol = { .ops = &snd_hda_bind_vol, .values = { HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 0, },};static struct hda_bind_ctls ad1986a_laptop_master_sw = { .ops = &snd_hda_bind_sw, .values = { HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 0, },};static struct snd_kcontrol_new ad1986a_laptop_mixers[] = { HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw), HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), /* HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x18, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x18, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */ HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Source", .info = ad198x_mux_enum_info, .get = ad198x_mux_enum_get, .put = ad198x_mux_enum_put, }, { } /* end */};/* laptop-eapd model - 2ch only */static struct hda_input_mux ad1986a_laptop_eapd_capture_source = { .num_items = 3, .items = { { "Mic", 0x0 }, { "Internal Mic", 0x4 }, { "Mix", 0x5 }, },};static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw), HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Source", .info = ad198x_mux_enum_info, .get = ad198x_mux_enum_get, .put = ad198x_mux_enum_put, }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "External Amplifier", .info = ad198x_eapd_info, .get = ad198x_eapd_get, .put = ad198x_eapd_put, .private_value = 0x1b | (1 << 8), /* port-D, inversed */ }, { } /* end */};/* laptop-automute - 2ch only */static void ad1986a_update_hp(struct hda_codec *codec){ struct ad198x_spec *spec = codec->spec; unsigned int mute; if (spec->jack_present) mute = HDA_AMP_MUTE; /* mute internal speaker */ else /* unmute internal speaker if necessary */ mute = snd_hda_codec_amp_read(codec, 0x1a, 0, HDA_OUTPUT, 0); snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, HDA_AMP_MUTE, mute);}static void ad1986a_hp_automute(struct hda_codec *codec){ struct ad198x_spec *spec = codec->spec; unsigned int present; present = snd_hda_codec_read(codec, 0x1a, 0, AC_VERB_GET_PIN_SENSE, 0); /* Lenovo N100 seems to report the reversed bit for HP jack-sensing */ spec->jack_present = !(present & 0x80000000); ad1986a_update_hp(codec);}#define AD1986A_HP_EVENT 0x37static void ad1986a_hp_unsol_event(struct hda_codec *codec, unsigned int res){ if ((res >> 26) != AD1986A_HP_EVENT) return; ad1986a_hp_automute(codec);}static int ad1986a_hp_init(struct hda_codec *codec){ ad198x_init(codec); ad1986a_hp_automute(codec); return 0;}/* bind hp and internal speaker mute (with plug check) */static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol){ struct hda_codec *codec = snd_kcontrol_chip(kcontrol); long *valp = ucontrol->value.integer.value; int change; change = snd_hda_codec_amp_update(codec, 0x1a, 0, HDA_OUTPUT, 0, HDA_AMP_MUTE, valp[0] ? 0 : HDA_AMP_MUTE); change |= snd_hda_codec_amp_update(codec, 0x1a, 1, HDA_OUTPUT, 0, HDA_AMP_MUTE, valp[1] ? 0 : HDA_AMP_MUTE); if (change) ad1986a_update_hp(codec); return change;}static struct snd_kcontrol_new ad1986a_laptop_automute_mixers[] = { HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", .info = snd_hda_mixer_amp_switch_info, .get = snd_hda_mixer_amp_switch_get, .put = ad1986a_hp_master_sw_put, .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), }, HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Boost", 0x0f, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Beep Playback Volume", 0x18, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Beep Playback Switch", 0x18, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Source", .info = ad198x_mux_enum_info, .get = ad198x_mux_enum_get, .put = ad198x_mux_enum_put, }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "External Amplifier", .info = ad198x_eapd_info, .get = ad198x_eapd_get, .put = ad198x_eapd_put, .private_value = 0x1b | (1 << 8), /* port-D, inversed */ }, { } /* end */};/* * initialization verbs */static struct hda_verb ad1986a_init_verbs[] = { /* Front, Surround, CLFE DAC; mute as default */ {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, /* Downmix - off */ {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, /* HP, Line-Out, Surround, CLFE selectors */ {0x0a, AC_VERB_SET_CONNECT_SEL, 0x0}, {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Mono selector */ {0x0e, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Mic selector: Mic 1/2 pin */ {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Line-in selector: Line-in */ {0x10, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Mic 1/2 swap */ {0x11, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Record selector: mic */ {0x12, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Mic, Phone, CD, Aux, Line-In amp; mute as default */ {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, /* PC beep */ {0x18, AC_VERB_SET_CONNECT_SEL, 0x0}, /* HP, Line-Out, Surround, CLFE, Mono pins; mute as default */ {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, /* HP Pin */ {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* Front, Surround, CLFE Pins */ {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, /* Mono Pin */ {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, /* Mic Pin */ {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, /* Line, Aux, CD, Beep-In Pin */ {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, { } /* end */};static struct hda_verb ad1986a_ch2_init[] = { /* Surround out -> Line In */ { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line-in selectors */ { 0x10, AC_VERB_SET_CONNECT_SEL, 0x1 }, /* CLFE -> Mic in */ { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */ { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 }, { } /* end */};static struct hda_verb ad1986a_ch4_init[] = { /* Surround out -> Surround */ { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, /* CLFE -> Mic in */ { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 }, { } /* end */};static struct hda_verb ad1986a_ch6_init[] = { /* Surround out -> Surround out */ { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, /* CLFE -> CLFE */ { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x0 }, { } /* end */};static struct hda_channel_mode ad1986a_modes[3] = { { 2, ad1986a_ch2_init }, { 4, ad1986a_ch4_init }, { 6, ad1986a_ch6_init },};/* eapd initialization */static struct hda_verb ad1986a_eapd_init_verbs[] = { {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, {}};/* Ultra initialization */static struct hda_verb ad1986a_ultra_init[] = { /* eapd initialization */ { 0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* CLFE -> Mic in */ { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2 }, { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, { } /* end */};/* pin sensing on HP jack */static struct hda_verb ad1986a_hp_init_verbs[] = { {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT}, {}};/* models */enum { AD1986A_6STACK, AD1986A_3STACK, AD1986A_LAPTOP, AD1986A_LAPTOP_EAPD, AD1986A_LAPTOP_AUTOMUTE, AD1986A_ULTRA, AD1986A_MODELS};static const char *ad1986a_models[AD1986A_MODELS] = { [AD1986A_6STACK] = "6stack", [AD1986A_3STACK] = "3stack", [AD1986A_LAPTOP] = "laptop",
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -