aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-04-28 03:51:57 -0400
committerTakashi Iwai <tiwai@suse.de>2009-04-28 03:51:57 -0400
commit299f293b3428ae6d73406642cd7d41f08d524c83 (patch)
tree963317e71c1bafc9a5dba20a6999ab1b08869128
parent1103f9b241447845e63d798e6ba652b4d55b700c (diff)
parent4a79ba34cada6a5a4ee86ed53aa8a73ba1e6fc51 (diff)
Merge branch 'topic/hda-realtek-amp' into topic/hda
-rw-r--r--sound/pci/hda/patch_realtek.c239
1 files changed, 145 insertions, 94 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 583603f449b..3a6306302c7 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -253,6 +253,15 @@ enum {
253/* for GPIO Poll */ 253/* for GPIO Poll */
254#define GPIO_MASK 0x03 254#define GPIO_MASK 0x03
255 255
256/* extra amp-initialization sequence types */
257enum {
258 ALC_INIT_NONE,
259 ALC_INIT_DEFAULT,
260 ALC_INIT_GPIO1,
261 ALC_INIT_GPIO2,
262 ALC_INIT_GPIO3,
263};
264
256struct alc_spec { 265struct alc_spec {
257 /* codec parameterization */ 266 /* codec parameterization */
258 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ 267 struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
@@ -322,6 +331,7 @@ struct alc_spec {
322 331
323 /* other flags */ 332 /* other flags */
324 unsigned int no_analog :1; /* digital I/O only */ 333 unsigned int no_analog :1; /* digital I/O only */
334 int init_amp;
325 335
326 /* for virtual master */ 336 /* for virtual master */
327 hda_nid_t vmaster_nid; 337 hda_nid_t vmaster_nid;
@@ -994,74 +1004,21 @@ static void alc888_coef_init(struct hda_codec *codec)
994 AC_VERB_SET_PROC_COEF, 0x3030); 1004 AC_VERB_SET_PROC_COEF, 0x3030);
995} 1005}
996 1006
997/* 32-bit subsystem ID for BIOS loading in HD Audio codec. 1007static void alc_auto_init_amp(struct hda_codec *codec, int type)
998 * 31 ~ 16 : Manufacture ID
999 * 15 ~ 8 : SKU ID
1000 * 7 ~ 0 : Assembly ID
1001 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1002 */
1003static void alc_subsystem_id(struct hda_codec *codec,
1004 unsigned int porta, unsigned int porte,
1005 unsigned int portd)
1006{ 1008{
1007 unsigned int ass, tmp, i; 1009 unsigned int tmp;
1008 unsigned nid;
1009 struct alc_spec *spec = codec->spec;
1010
1011 ass = codec->subsystem_id & 0xffff;
1012 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1013 goto do_sku;
1014
1015 /*
1016 * 31~30 : port conetcivity
1017 * 29~21 : reserve
1018 * 20 : PCBEEP input
1019 * 19~16 : Check sum (15:1)
1020 * 15~1 : Custom
1021 * 0 : override
1022 */
1023 nid = 0x1d;
1024 if (codec->vendor_id == 0x10ec0260)
1025 nid = 0x17;
1026 ass = snd_hda_codec_get_pincfg(codec, nid);
1027 snd_printd("realtek: No valid SSID, "
1028 "checking pincfg 0x%08x for NID 0x%x\n",
1029 ass, nid);
1030 if (!(ass & 1) && !(ass & 0x100000))
1031 return;
1032 if ((ass >> 30) != 1) /* no physical connection */
1033 return;
1034 1010
1035 /* check sum */ 1011 switch (type) {
1036 tmp = 0; 1012 case ALC_INIT_GPIO1:
1037 for (i = 1; i < 16; i++) {
1038 if ((ass >> i) & 1)
1039 tmp++;
1040 }
1041 if (((ass >> 16) & 0xf) != tmp)
1042 return;
1043do_sku:
1044 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1045 ass & 0xffff, codec->vendor_id);
1046 /*
1047 * 0 : override
1048 * 1 : Swap Jack
1049 * 2 : 0 --> Desktop, 1 --> Laptop
1050 * 3~5 : External Amplifier control
1051 * 7~6 : Reserved
1052 */
1053 tmp = (ass & 0x38) >> 3; /* external Amp control */
1054 switch (tmp) {
1055 case 1:
1056 snd_hda_sequence_write(codec, alc_gpio1_init_verbs); 1013 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1057 break; 1014 break;
1058 case 3: 1015 case ALC_INIT_GPIO2:
1059 snd_hda_sequence_write(codec, alc_gpio2_init_verbs); 1016 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1060 break; 1017 break;
1061 case 7: 1018 case ALC_INIT_GPIO3:
1062 snd_hda_sequence_write(codec, alc_gpio3_init_verbs); 1019 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1063 break; 1020 break;
1064 case 5: /* set EAPD output high */ 1021 case ALC_INIT_DEFAULT:
1065 switch (codec->vendor_id) { 1022 switch (codec->vendor_id) {
1066 case 0x10ec0260: 1023 case 0x10ec0260:
1067 snd_hda_codec_write(codec, 0x0f, 0, 1024 snd_hda_codec_write(codec, 0x0f, 0,
@@ -1115,7 +1072,7 @@ do_sku:
1115 tmp | 0x2010); 1072 tmp | 0x2010);
1116 break; 1073 break;
1117 case 0x10ec0888: 1074 case 0x10ec0888:
1118 /*alc888_coef_init(codec);*/ /* called in alc_init() */ 1075 alc888_coef_init(codec);
1119 break; 1076 break;
1120 case 0x10ec0267: 1077 case 0x10ec0267:
1121 case 0x10ec0268: 1078 case 0x10ec0268:
@@ -1130,7 +1087,104 @@ do_sku:
1130 tmp | 0x3000); 1087 tmp | 0x3000);
1131 break; 1088 break;
1132 } 1089 }
1133 default: 1090 break;
1091 }
1092}
1093
1094static void alc_init_auto_hp(struct hda_codec *codec)
1095{
1096 struct alc_spec *spec = codec->spec;
1097
1098 if (!spec->autocfg.hp_pins[0])
1099 return;
1100
1101 if (!spec->autocfg.speaker_pins[0]) {
1102 if (spec->autocfg.line_out_pins[0])
1103 spec->autocfg.speaker_pins[0] =
1104 spec->autocfg.line_out_pins[0];
1105 else
1106 return;
1107 }
1108
1109 snd_hda_codec_write_cache(codec, spec->autocfg.hp_pins[0], 0,
1110 AC_VERB_SET_UNSOLICITED_ENABLE,
1111 AC_USRSP_EN | ALC880_HP_EVENT);
1112 spec->unsol_event = alc_sku_unsol_event;
1113}
1114
1115/* check subsystem ID and set up device-specific initialization;
1116 * return 1 if initialized, 0 if invalid SSID
1117 */
1118/* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1119 * 31 ~ 16 : Manufacture ID
1120 * 15 ~ 8 : SKU ID
1121 * 7 ~ 0 : Assembly ID
1122 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1123 */
1124static int alc_subsystem_id(struct hda_codec *codec,
1125 hda_nid_t porta, hda_nid_t porte,
1126 hda_nid_t portd)
1127{
1128 unsigned int ass, tmp, i;
1129 unsigned nid;
1130 struct alc_spec *spec = codec->spec;
1131
1132 ass = codec->subsystem_id & 0xffff;
1133 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1134 goto do_sku;
1135
1136 /* invalid SSID, check the special NID pin defcfg instead */
1137 /*
1138 * 31~30 : port conetcivity
1139 * 29~21 : reserve
1140 * 20 : PCBEEP input
1141 * 19~16 : Check sum (15:1)
1142 * 15~1 : Custom
1143 * 0 : override
1144 */
1145 nid = 0x1d;
1146 if (codec->vendor_id == 0x10ec0260)
1147 nid = 0x17;
1148 ass = snd_hda_codec_get_pincfg(codec, nid);
1149 snd_printd("realtek: No valid SSID, "
1150 "checking pincfg 0x%08x for NID 0x%x\n",
1151 nid, ass);
1152 if (!(ass & 1) && !(ass & 0x100000))
1153 return 0;
1154 if ((ass >> 30) != 1) /* no physical connection */
1155 return 0;
1156
1157 /* check sum */
1158 tmp = 0;
1159 for (i = 1; i < 16; i++) {
1160 if ((ass >> i) & 1)
1161 tmp++;
1162 }
1163 if (((ass >> 16) & 0xf) != tmp)
1164 return 0;
1165do_sku:
1166 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1167 ass & 0xffff, codec->vendor_id);
1168 /*
1169 * 0 : override
1170 * 1 : Swap Jack
1171 * 2 : 0 --> Desktop, 1 --> Laptop
1172 * 3~5 : External Amplifier control
1173 * 7~6 : Reserved
1174 */
1175 tmp = (ass & 0x38) >> 3; /* external Amp control */
1176 switch (tmp) {
1177 case 1:
1178 spec->init_amp = ALC_INIT_GPIO1;
1179 break;
1180 case 3:
1181 spec->init_amp = ALC_INIT_GPIO2;
1182 break;
1183 case 7:
1184 spec->init_amp = ALC_INIT_GPIO3;
1185 break;
1186 case 5:
1187 spec->init_amp = ALC_INIT_DEFAULT;
1134 break; 1188 break;
1135 } 1189 }
1136 1190
@@ -1138,7 +1192,7 @@ do_sku:
1138 * when the external headphone out jack is plugged" 1192 * when the external headphone out jack is plugged"
1139 */ 1193 */
1140 if (!(ass & 0x8000)) 1194 if (!(ass & 0x8000))
1141 return; 1195 return 1;
1142 /* 1196 /*
1143 * 10~8 : Jack location 1197 * 10~8 : Jack location
1144 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered 1198 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
@@ -1146,14 +1200,6 @@ do_sku:
1146 * 15 : 1 --> enable the function "Mute internal speaker 1200 * 15 : 1 --> enable the function "Mute internal speaker
1147 * when the external headphone out jack is plugged" 1201 * when the external headphone out jack is plugged"
1148 */ 1202 */
1149 if (!spec->autocfg.speaker_pins[0]) {
1150 if (spec->autocfg.line_out_pins[0])
1151 spec->autocfg.speaker_pins[0] =
1152 spec->autocfg.line_out_pins[0];
1153 else
1154 return;
1155 }
1156
1157 if (!spec->autocfg.hp_pins[0]) { 1203 if (!spec->autocfg.hp_pins[0]) {
1158 tmp = (ass >> 11) & 0x3; /* HP to chassis */ 1204 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1159 if (tmp == 0) 1205 if (tmp == 0)
@@ -1163,23 +1209,23 @@ do_sku:
1163 else if (tmp == 2) 1209 else if (tmp == 2)
1164 spec->autocfg.hp_pins[0] = portd; 1210 spec->autocfg.hp_pins[0] = portd;
1165 else 1211 else
1166 return; 1212 return 1;
1167 } 1213 }
1168 if (spec->autocfg.hp_pins[0])
1169 snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0,
1170 AC_VERB_SET_UNSOLICITED_ENABLE,
1171 AC_USRSP_EN | ALC880_HP_EVENT);
1172 1214
1173#if 0 /* it's broken in some acses -- temporarily disabled */ 1215 alc_init_auto_hp(codec);
1174 if (spec->autocfg.input_pins[AUTO_PIN_MIC] && 1216 return 1;
1175 spec->autocfg.input_pins[AUTO_PIN_FRONT_MIC]) 1217}
1176 snd_hda_codec_write(codec,
1177 spec->autocfg.input_pins[AUTO_PIN_MIC], 0,
1178 AC_VERB_SET_UNSOLICITED_ENABLE,
1179 AC_USRSP_EN | ALC880_MIC_EVENT);
1180#endif /* disabled */
1181 1218
1182 spec->unsol_event = alc_sku_unsol_event; 1219static void alc_ssid_check(struct hda_codec *codec,
1220 hda_nid_t porta, hda_nid_t porte, hda_nid_t portd)
1221{
1222 if (!alc_subsystem_id(codec, porta, porte, portd)) {
1223 struct alc_spec *spec = codec->spec;
1224 snd_printd("realtek: "
1225 "Enable default setup for auto mode as fallback\n");
1226 spec->init_amp = ALC_INIT_DEFAULT;
1227 alc_init_auto_hp(codec);
1228 }
1183} 1229}
1184 1230
1185/* 1231/*
@@ -2923,8 +2969,7 @@ static int alc_init(struct hda_codec *codec)
2923 unsigned int i; 2969 unsigned int i;
2924 2970
2925 alc_fix_pll(codec); 2971 alc_fix_pll(codec);
2926 if (codec->vendor_id == 0x10ec0888) 2972 alc_auto_init_amp(codec, spec->init_amp);
2927 alc888_coef_init(codec);
2928 2973
2929 for (i = 0; i < spec->num_init_verbs; i++) 2974 for (i = 0; i < spec->num_init_verbs; i++)
2930 snd_hda_sequence_write(codec, spec->init_verbs[i]); 2975 snd_hda_sequence_write(codec, spec->init_verbs[i]);
@@ -4198,7 +4243,6 @@ static void alc880_auto_init_multi_out(struct hda_codec *codec)
4198 struct alc_spec *spec = codec->spec; 4243 struct alc_spec *spec = codec->spec;
4199 int i; 4244 int i;
4200 4245
4201 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
4202 for (i = 0; i < spec->autocfg.line_outs; i++) { 4246 for (i = 0; i < spec->autocfg.line_outs; i++) {
4203 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 4247 hda_nid_t nid = spec->autocfg.line_out_pins[i];
4204 int pin_type = get_pin_type(spec->autocfg.line_out_type); 4248 int pin_type = get_pin_type(spec->autocfg.line_out_type);
@@ -4303,6 +4347,8 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
4303 spec->num_mux_defs = 1; 4347 spec->num_mux_defs = 1;
4304 spec->input_mux = &spec->private_imux[0]; 4348 spec->input_mux = &spec->private_imux[0];
4305 4349
4350 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
4351
4306 return 1; 4352 return 1;
4307} 4353}
4308 4354
@@ -5678,7 +5724,6 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec)
5678 struct alc_spec *spec = codec->spec; 5724 struct alc_spec *spec = codec->spec;
5679 hda_nid_t nid; 5725 hda_nid_t nid;
5680 5726
5681 alc_subsystem_id(codec, 0x10, 0x15, 0x0f);
5682 nid = spec->autocfg.line_out_pins[0]; 5727 nid = spec->autocfg.line_out_pins[0];
5683 if (nid) { 5728 if (nid) {
5684 int pin_type = get_pin_type(spec->autocfg.line_out_type); 5729 int pin_type = get_pin_type(spec->autocfg.line_out_type);
@@ -5788,6 +5833,8 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
5788 spec->num_mux_defs = 1; 5833 spec->num_mux_defs = 1;
5789 spec->input_mux = &spec->private_imux[0]; 5834 spec->input_mux = &spec->private_imux[0];
5790 5835
5836 alc_ssid_check(codec, 0x10, 0x15, 0x0f);
5837
5791 return 1; 5838 return 1;
5792} 5839}
5793 5840
@@ -7013,7 +7060,6 @@ static void alc882_auto_init_multi_out(struct hda_codec *codec)
7013 struct alc_spec *spec = codec->spec; 7060 struct alc_spec *spec = codec->spec;
7014 int i; 7061 int i;
7015 7062
7016 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
7017 for (i = 0; i <= HDA_SIDE; i++) { 7063 for (i = 0; i <= HDA_SIDE; i++) {
7018 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 7064 hda_nid_t nid = spec->autocfg.line_out_pins[i];
7019 int pin_type = get_pin_type(spec->autocfg.line_out_type); 7065 int pin_type = get_pin_type(spec->autocfg.line_out_type);
@@ -9154,7 +9200,6 @@ static void alc883_auto_init_multi_out(struct hda_codec *codec)
9154 struct alc_spec *spec = codec->spec; 9200 struct alc_spec *spec = codec->spec;
9155 int i; 9201 int i;
9156 9202
9157 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
9158 for (i = 0; i <= HDA_SIDE; i++) { 9203 for (i = 0; i <= HDA_SIDE; i++) {
9159 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 9204 hda_nid_t nid = spec->autocfg.line_out_pins[i];
9160 int pin_type = get_pin_type(spec->autocfg.line_out_type); 9205 int pin_type = get_pin_type(spec->autocfg.line_out_type);
@@ -9317,6 +9362,7 @@ static int patch_alc883(struct hda_codec *codec)
9317 if (!spec->capsrc_nids) 9362 if (!spec->capsrc_nids)
9318 spec->capsrc_nids = alc883_capsrc_nids; 9363 spec->capsrc_nids = alc883_capsrc_nids;
9319 spec->capture_style = CAPT_MIX; /* matrix-style capture */ 9364 spec->capture_style = CAPT_MIX; /* matrix-style capture */
9365 spec->init_amp = ALC_INIT_DEFAULT; /* always initialize */
9320 break; 9366 break;
9321 case 0x10ec0889: 9367 case 0x10ec0889:
9322 spec->stream_name_analog = "ALC889 Analog"; 9368 spec->stream_name_analog = "ALC889 Analog";
@@ -10842,6 +10888,8 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
10842 if (err < 0) 10888 if (err < 0)
10843 return err; 10889 return err;
10844 10890
10891 alc_ssid_check(codec, 0x15, 0x14, 0x1b);
10892
10845 return 1; 10893 return 1;
10846} 10894}
10847 10895
@@ -13925,7 +13973,6 @@ static void alc861_auto_init_multi_out(struct hda_codec *codec)
13925 struct alc_spec *spec = codec->spec; 13973 struct alc_spec *spec = codec->spec;
13926 int i; 13974 int i;
13927 13975
13928 alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b);
13929 for (i = 0; i < spec->autocfg.line_outs; i++) { 13976 for (i = 0; i < spec->autocfg.line_outs; i++) {
13930 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 13977 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13931 int pin_type = get_pin_type(spec->autocfg.line_out_type); 13978 int pin_type = get_pin_type(spec->autocfg.line_out_type);
@@ -14008,6 +14055,8 @@ static int alc861_parse_auto_config(struct hda_codec *codec)
14008 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids); 14055 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
14009 set_capture_mixer(spec); 14056 set_capture_mixer(spec);
14010 14057
14058 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b);
14059
14011 return 1; 14060 return 1;
14012} 14061}
14013 14062
@@ -14889,7 +14938,6 @@ static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
14889 struct alc_spec *spec = codec->spec; 14938 struct alc_spec *spec = codec->spec;
14890 int i; 14939 int i;
14891 14940
14892 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
14893 for (i = 0; i <= HDA_SIDE; i++) { 14941 for (i = 0; i <= HDA_SIDE; i++) {
14894 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 14942 hda_nid_t nid = spec->autocfg.line_out_pins[i];
14895 int pin_type = get_pin_type(spec->autocfg.line_out_type); 14943 int pin_type = get_pin_type(spec->autocfg.line_out_type);
@@ -15107,6 +15155,8 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
15107 if (err < 0) 15155 if (err < 0)
15108 return err; 15156 return err;
15109 15157
15158 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
15159
15110 return 1; 15160 return 1;
15111} 15161}
15112 15162
@@ -16931,7 +16981,6 @@ static void alc662_auto_init_multi_out(struct hda_codec *codec)
16931 struct alc_spec *spec = codec->spec; 16981 struct alc_spec *spec = codec->spec;
16932 int i; 16982 int i;
16933 16983
16934 alc_subsystem_id(codec, 0x15, 0x1b, 0x14);
16935 for (i = 0; i <= HDA_SIDE; i++) { 16984 for (i = 0; i <= HDA_SIDE; i++) {
16936 hda_nid_t nid = spec->autocfg.line_out_pins[i]; 16985 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16937 int pin_type = get_pin_type(spec->autocfg.line_out_type); 16986 int pin_type = get_pin_type(spec->autocfg.line_out_type);
@@ -17028,6 +17077,8 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
17028 if (err < 0) 17077 if (err < 0)
17029 return err; 17078 return err;
17030 17079
17080 alc_ssid_check(codec, 0x15, 0x1b, 0x14);
17081
17031 return 1; 17082 return 1;
17032} 17083}
17033 17084