aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
authorKailang Yang <kailang@realtek.com.tw>2008-01-10 07:03:59 -0500
committerJaroslav Kysela <perex@perex.cz>2008-01-31 11:29:49 -0500
commit8c427226ed549af67396794e86246bf2d361ff8f (patch)
treedc2e241110e5e530bfb63f693ab7b93405f0ad4a /sound/pci/hda
parent17596a80d3b57763f6d111fa95416559bad9c8dc (diff)
[ALSA] hda-codec - Update realtek codec support
1. Support HP rp5700 2. Fixed alc_subsystem_id function (Bug fixed and support Desktop) 3. Support ASUS EP20 Signed-off-by: Kailang Yang <kailang@realtek.com.tw> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/patch_realtek.c151
1 files changed, 146 insertions, 5 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 5e36462ac0f9..17784952acdd 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -92,6 +92,7 @@ enum {
92 ALC262_HP_BPC_D7000_WL, 92 ALC262_HP_BPC_D7000_WL,
93 ALC262_HP_BPC_D7000_WF, 93 ALC262_HP_BPC_D7000_WF,
94 ALC262_HP_TC_T5735, 94 ALC262_HP_TC_T5735,
95 ALC262_HP_RP5700,
95 ALC262_BENQ_ED8, 96 ALC262_BENQ_ED8,
96 ALC262_SONY_ASSAMD, 97 ALC262_SONY_ASSAMD,
97 ALC262_BENQ_T31, 98 ALC262_BENQ_T31,
@@ -155,6 +156,7 @@ enum {
155 ALC662_5ST_DIG, 156 ALC662_5ST_DIG,
156 ALC662_LENOVO_101E, 157 ALC662_LENOVO_101E,
157 ALC662_ASUS_EEEPC_P701, 158 ALC662_ASUS_EEEPC_P701,
159 ALC662_ASUS_EEEPC_EP20,
158 ALC662_AUTO, 160 ALC662_AUTO,
159 ALC662_MODEL_LAST, 161 ALC662_MODEL_LAST,
160}; 162};
@@ -804,7 +806,7 @@ static void alc_subsystem_id(struct hda_codec *codec,
804 /* check sum */ 806 /* check sum */
805 tmp = 0; 807 tmp = 0;
806 for (i = 1; i < 16; i++) { 808 for (i = 1; i < 16; i++) {
807 if ((ass >> i) && 1) 809 if ((ass >> i) & 1)
808 tmp++; 810 tmp++;
809 } 811 }
810 if (((ass >> 16) & 0xf) != tmp) 812 if (((ass >> 16) & 0xf) != tmp)
@@ -893,10 +895,10 @@ do_sku:
893 break; 895 break;
894 } 896 }
895 897
896 /* is laptop and enable the function "Mute internal speaker 898 /* is laptop or Desktop and enable the function "Mute internal speaker
897 * when the external headphone out jack is plugged" 899 * when the external headphone out jack is plugged"
898 */ 900 */
899 if (!(ass & 0x4) || !(ass & 0x8000)) 901 if (!(ass & 0x8000))
900 return; 902 return;
901 /* 903 /*
902 * 10~8 : Jack location 904 * 10~8 : Jack location
@@ -906,9 +908,9 @@ do_sku:
906 * when the external headphone out jack is plugged" 908 * when the external headphone out jack is plugged"
907 */ 909 */
908 if (!spec->autocfg.speaker_pins[0]) { 910 if (!spec->autocfg.speaker_pins[0]) {
909 if (spec->multiout.dac_nids[0]) 911 if (spec->autocfg.line_out_pins[0])
910 spec->autocfg.speaker_pins[0] = 912 spec->autocfg.speaker_pins[0] =
911 spec->multiout.dac_nids[0]; 913 spec->autocfg.line_out_pins[0];
912 else 914 else
913 return; 915 return;
914 } 916 }
@@ -7952,6 +7954,57 @@ static struct hda_verb alc262_hp_t5735_verbs[] = {
7952 { } 7954 { }
7953}; 7955};
7954 7956
7957static struct hda_bind_ctls alc262_hp_rp5700_bind_front_vol = {
7958 .ops = &snd_hda_bind_vol,
7959 .values = {
7960 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
7961 HDA_COMPOSE_AMP_VAL(0x0e, 3, 0, HDA_OUTPUT),
7962 0
7963 },
7964};
7965
7966static struct hda_bind_ctls alc262_hp_rp5700_bind_front_sw = {
7967 .ops = &snd_hda_bind_sw,
7968 .values = {
7969 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
7970 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
7971 0
7972 },
7973};
7974
7975static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
7976 HDA_BIND_VOL("PCM Playback Volume", &alc262_hp_rp5700_bind_front_vol),
7977 HDA_BIND_SW("PCM Playback Switch", &alc262_hp_rp5700_bind_front_sw),
7978 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
7979 HDA_CODEC_MUTE("Master Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
7980 HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
7981 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
7982 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
7983 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
7984 { } /* end */
7985};
7986
7987static struct hda_verb alc262_hp_rp5700_verbs[] = {
7988 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7989 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7990 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7991 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7992 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7993 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
7994 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7995 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
7996 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
7997 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
7998 {}
7999};
8000
8001static struct hda_input_mux alc262_hp_rp5700_capture_source = {
8002 .num_items = 1,
8003 .items = {
8004 { "Line", 0x1 },
8005 },
8006};
8007
7955/* bind hp and internal speaker mute (with plug check) */ 8008/* bind hp and internal speaker mute (with plug check) */
7956static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol, 8009static int alc262_sony_master_sw_put(struct snd_kcontrol *kcontrol,
7957 struct snd_ctl_elem_value *ucontrol) 8010 struct snd_ctl_elem_value *ucontrol)
@@ -8794,6 +8847,7 @@ static const char *alc262_models[ALC262_MODEL_LAST] = {
8794 [ALC262_HP_BPC] = "hp-bpc", 8847 [ALC262_HP_BPC] = "hp-bpc",
8795 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000", 8848 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
8796 [ALC262_HP_TC_T5735] = "hp-tc-t5735", 8849 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
8850 [ALC262_HP_RP5700] = "hp-rp5700",
8797 [ALC262_BENQ_ED8] = "benq", 8851 [ALC262_BENQ_ED8] = "benq",
8798 [ALC262_BENQ_T31] = "benq-t31", 8852 [ALC262_BENQ_T31] = "benq-t31",
8799 [ALC262_SONY_ASSAMD] = "sony-assamd", 8853 [ALC262_SONY_ASSAMD] = "sony-assamd",
@@ -8824,6 +8878,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = {
8824 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC), 8878 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
8825 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735", 8879 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
8826 ALC262_HP_TC_T5735), 8880 ALC262_HP_TC_T5735),
8881 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
8827 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), 8882 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
8828 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO), 8883 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
8829 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), 8884 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
@@ -8929,6 +8984,15 @@ static struct alc_config_preset alc262_presets[] = {
8929 .input_mux = &alc262_capture_source, 8984 .input_mux = &alc262_capture_source,
8930 .unsol_event = alc262_hp_t5735_unsol_event, 8985 .unsol_event = alc262_hp_t5735_unsol_event,
8931 .init_hook = alc262_hp_t5735_init_hook, 8986 .init_hook = alc262_hp_t5735_init_hook,
8987 },
8988 [ALC262_HP_RP5700] = {
8989 .mixers = { alc262_hp_rp5700_mixer },
8990 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
8991 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
8992 .dac_nids = alc262_dac_nids,
8993 .num_channel_mode = ARRAY_SIZE(alc262_modes),
8994 .channel_mode = alc262_modes,
8995 .input_mux = &alc262_hp_rp5700_capture_source,
8932 }, 8996 },
8933 [ALC262_BENQ_ED8] = { 8997 [ALC262_BENQ_ED8] = {
8934 .mixers = { alc262_base_mixer }, 8998 .mixers = { alc262_base_mixer },
@@ -12520,6 +12584,24 @@ static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
12520 { } /* end */ 12584 { } /* end */
12521}; 12585};
12522 12586
12587static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
12588 HDA_CODEC_VOLUME("LineOut Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12589 HDA_CODEC_MUTE("LineOut Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12590 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12591 HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT),
12592 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
12593 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
12594 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT),
12595 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT),
12596 HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
12597 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
12598 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
12599 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
12600 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12601 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12602 { } /* end */
12603};
12604
12523static struct snd_kcontrol_new alc662_chmode_mixer[] = { 12605static struct snd_kcontrol_new alc662_chmode_mixer[] = {
12524 { 12606 {
12525 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 12607 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
@@ -12605,6 +12687,13 @@ static struct hda_verb alc662_eeepc_sue_init_verbs[] = {
12605 {} 12687 {}
12606}; 12688};
12607 12689
12690/* Set Unsolicited Event*/
12691static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
12692 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12693 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12694 {}
12695};
12696
12608/* 12697/*
12609 * generic initialization of ADC, input mixers and output mixers 12698 * generic initialization of ADC, input mixers and output mixers
12610 */ 12699 */
@@ -12741,6 +12830,40 @@ static void alc662_eeepc_inithook(struct hda_codec *codec)
12741 alc662_eeepc_mic_automute(codec); 12830 alc662_eeepc_mic_automute(codec);
12742} 12831}
12743 12832
12833static void alc662_eeepc_ep20_automute(struct hda_codec *codec)
12834{
12835 unsigned int mute;
12836 unsigned int present;
12837
12838 snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0);
12839 present = snd_hda_codec_read(codec, 0x14, 0,
12840 AC_VERB_GET_PIN_SENSE, 0);
12841 present = (present & 0x80000000) != 0;
12842 if (present) {
12843 /* mute internal speaker */
12844 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
12845 HDA_AMP_MUTE, HDA_AMP_MUTE);
12846 } else {
12847 /* unmute internal speaker if necessary */
12848 mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0);
12849 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
12850 HDA_AMP_MUTE, mute);
12851 }
12852}
12853
12854/* unsolicited event for HP jack sensing */
12855static void alc662_eeepc_ep20_unsol_event(struct hda_codec *codec,
12856 unsigned int res)
12857{
12858 if ((res >> 26) == ALC880_HP_EVENT)
12859 alc662_eeepc_ep20_automute(codec);
12860}
12861
12862static void alc662_eeepc_ep20_inithook(struct hda_codec *codec)
12863{
12864 alc662_eeepc_ep20_automute(codec);
12865}
12866
12744#ifdef CONFIG_SND_HDA_POWER_SAVE 12867#ifdef CONFIG_SND_HDA_POWER_SAVE
12745#define alc662_loopbacks alc880_loopbacks 12868#define alc662_loopbacks alc880_loopbacks
12746#endif 12869#endif
@@ -12762,11 +12885,13 @@ static const char *alc662_models[ALC662_MODEL_LAST] = {
12762 [ALC662_5ST_DIG] = "6stack-dig", 12885 [ALC662_5ST_DIG] = "6stack-dig",
12763 [ALC662_LENOVO_101E] = "lenovo-101e", 12886 [ALC662_LENOVO_101E] = "lenovo-101e",
12764 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", 12887 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
12888 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
12765 [ALC662_AUTO] = "auto", 12889 [ALC662_AUTO] = "auto",
12766}; 12890};
12767 12891
12768static struct snd_pci_quirk alc662_cfg_tbl[] = { 12892static struct snd_pci_quirk alc662_cfg_tbl[] = {
12769 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701), 12893 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
12894 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
12770 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), 12895 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
12771 {} 12896 {}
12772}; 12897};
@@ -12854,6 +12979,21 @@ static struct alc_config_preset alc662_presets[] = {
12854 .unsol_event = alc662_eeepc_unsol_event, 12979 .unsol_event = alc662_eeepc_unsol_event,
12855 .init_hook = alc662_eeepc_inithook, 12980 .init_hook = alc662_eeepc_inithook,
12856 }, 12981 },
12982 [ALC662_ASUS_EEEPC_EP20] = {
12983 .mixers = { alc662_eeepc_ep20_mixer, alc662_capture_mixer,
12984 alc662_chmode_mixer },
12985 .init_verbs = { alc662_init_verbs,
12986 alc662_eeepc_ep20_sue_init_verbs },
12987 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
12988 .dac_nids = alc662_dac_nids,
12989 .num_adc_nids = ARRAY_SIZE(alc662_adc_nids),
12990 .adc_nids = alc662_adc_nids,
12991 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
12992 .channel_mode = alc662_3ST_6ch_modes,
12993 .input_mux = &alc662_lenovo_101e_capture_source,
12994 .unsol_event = alc662_eeepc_ep20_unsol_event,
12995 .init_hook = alc662_eeepc_ep20_inithook,
12996 },
12857 12997
12858}; 12998};
12859 12999
@@ -13013,6 +13153,7 @@ static void alc662_auto_init_multi_out(struct hda_codec *codec)
13013 struct alc_spec *spec = codec->spec; 13153 struct alc_spec *spec = codec->spec;
13014 int i; 13154 int i;
13015 13155
13156 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
13016 for (i = 0; i <= HDA_SIDE; i++) { 13157 for (i = 0; i <= HDA_SIDE; i++) {
13017 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 13158 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13018 int pin_type = get_pin_type(spec->autocfg.line_out_type); 13159 int pin_type = get_pin_type(spec->autocfg.line_out_type);