aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-04-22 10:31:35 -0400
committerTakashi Iwai <tiwai@suse.de>2009-04-27 12:00:30 -0400
commit4a79ba34cada6a5a4ee86ed53aa8a73ba1e6fc51 (patch)
tree868cafef688fb7a2d3969f648416667a990021b6 /sound
parent3b1db01990f0e533d1ed548dc1796eb84beddc20 (diff)
ALSA: hda - Add amp initialization for realtek auto mode
In the realtek auto-probing mode, the initialization of amp with some magic COEF or EAPD verbs is applied only when the codec SSID has valid values to satisfy the realtek's definition. However, many devices don't provide in that way, thus the device doesn't work as is. This patch allows the same initialization code even if the SSID doesn't pass the bit test. Also, alc_subsystem_id() is changed just to check and define the type, so that it's called in the parser, instead of the initializer. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-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 583603f449b4..3a6306302c70 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