diff options
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 391 |
1 files changed, 329 insertions, 62 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index caf48edaa921..b3a15d616873 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <sound/asoundef.h> | 32 | #include <sound/asoundef.h> |
33 | #include "hda_codec.h" | 33 | #include "hda_codec.h" |
34 | #include "hda_local.h" | 34 | #include "hda_local.h" |
35 | #include "hda_patch.h" | ||
35 | 36 | ||
36 | #define NUM_CONTROL_ALLOC 32 | 37 | #define NUM_CONTROL_ALLOC 32 |
37 | #define STAC_PWR_EVENT 0x20 | 38 | #define STAC_PWR_EVENT 0x20 |
@@ -39,6 +40,7 @@ | |||
39 | 40 | ||
40 | enum { | 41 | enum { |
41 | STAC_REF, | 42 | STAC_REF, |
43 | STAC_9200_OQO, | ||
42 | STAC_9200_DELL_D21, | 44 | STAC_9200_DELL_D21, |
43 | STAC_9200_DELL_D22, | 45 | STAC_9200_DELL_D22, |
44 | STAC_9200_DELL_D23, | 46 | STAC_9200_DELL_D23, |
@@ -50,6 +52,7 @@ enum { | |||
50 | STAC_9200_DELL_M26, | 52 | STAC_9200_DELL_M26, |
51 | STAC_9200_DELL_M27, | 53 | STAC_9200_DELL_M27, |
52 | STAC_9200_GATEWAY, | 54 | STAC_9200_GATEWAY, |
55 | STAC_9200_PANASONIC, | ||
53 | STAC_9200_MODELS | 56 | STAC_9200_MODELS |
54 | }; | 57 | }; |
55 | 58 | ||
@@ -63,11 +66,14 @@ enum { | |||
63 | 66 | ||
64 | enum { | 67 | enum { |
65 | STAC_92HD73XX_REF, | 68 | STAC_92HD73XX_REF, |
69 | STAC_DELL_M6, | ||
66 | STAC_92HD73XX_MODELS | 70 | STAC_92HD73XX_MODELS |
67 | }; | 71 | }; |
68 | 72 | ||
69 | enum { | 73 | enum { |
70 | STAC_92HD71BXX_REF, | 74 | STAC_92HD71BXX_REF, |
75 | STAC_DELL_M4_1, | ||
76 | STAC_DELL_M4_2, | ||
71 | STAC_92HD71BXX_MODELS | 77 | STAC_92HD71BXX_MODELS |
72 | }; | 78 | }; |
73 | 79 | ||
@@ -123,6 +129,7 @@ struct sigmatel_spec { | |||
123 | unsigned int hp_detect: 1; | 129 | unsigned int hp_detect: 1; |
124 | 130 | ||
125 | /* gpio lines */ | 131 | /* gpio lines */ |
132 | unsigned int eapd_mask; | ||
126 | unsigned int gpio_mask; | 133 | unsigned int gpio_mask; |
127 | unsigned int gpio_dir; | 134 | unsigned int gpio_dir; |
128 | unsigned int gpio_data; | 135 | unsigned int gpio_data; |
@@ -135,6 +142,7 @@ struct sigmatel_spec { | |||
135 | /* power management */ | 142 | /* power management */ |
136 | unsigned int num_pwrs; | 143 | unsigned int num_pwrs; |
137 | hda_nid_t *pwr_nids; | 144 | hda_nid_t *pwr_nids; |
145 | hda_nid_t *dac_list; | ||
138 | 146 | ||
139 | /* playback */ | 147 | /* playback */ |
140 | struct hda_input_mux *mono_mux; | 148 | struct hda_input_mux *mono_mux; |
@@ -173,6 +181,7 @@ struct sigmatel_spec { | |||
173 | /* i/o switches */ | 181 | /* i/o switches */ |
174 | unsigned int io_switch[2]; | 182 | unsigned int io_switch[2]; |
175 | unsigned int clfe_swap; | 183 | unsigned int clfe_swap; |
184 | unsigned int hp_switch; | ||
176 | unsigned int aloopback; | 185 | unsigned int aloopback; |
177 | 186 | ||
178 | struct hda_pcm pcm_rec[2]; /* PCM information */ | 187 | struct hda_pcm pcm_rec[2]; /* PCM information */ |
@@ -184,9 +193,6 @@ struct sigmatel_spec { | |||
184 | struct hda_input_mux private_dimux; | 193 | struct hda_input_mux private_dimux; |
185 | struct hda_input_mux private_imux; | 194 | struct hda_input_mux private_imux; |
186 | struct hda_input_mux private_mono_mux; | 195 | struct hda_input_mux private_mono_mux; |
187 | |||
188 | /* virtual master */ | ||
189 | unsigned int vmaster_tlv[4]; | ||
190 | }; | 196 | }; |
191 | 197 | ||
192 | static hda_nid_t stac9200_adc_nids[1] = { | 198 | static hda_nid_t stac9200_adc_nids[1] = { |
@@ -244,7 +250,7 @@ static hda_nid_t stac92hd71bxx_dmux_nids[1] = { | |||
244 | 0x1c, | 250 | 0x1c, |
245 | }; | 251 | }; |
246 | 252 | ||
247 | static hda_nid_t stac92hd71bxx_dac_nids[2] = { | 253 | static hda_nid_t stac92hd71bxx_dac_nids[1] = { |
248 | 0x10, /*0x11, */ | 254 | 0x10, /*0x11, */ |
249 | }; | 255 | }; |
250 | 256 | ||
@@ -290,6 +296,10 @@ static hda_nid_t stac927x_mux_nids[3] = { | |||
290 | 0x15, 0x16, 0x17 | 296 | 0x15, 0x16, 0x17 |
291 | }; | 297 | }; |
292 | 298 | ||
299 | static hda_nid_t stac927x_dac_nids[6] = { | ||
300 | 0x02, 0x03, 0x04, 0x05, 0x06, 0 | ||
301 | }; | ||
302 | |||
293 | static hda_nid_t stac927x_dmux_nids[1] = { | 303 | static hda_nid_t stac927x_dmux_nids[1] = { |
294 | 0x1b, | 304 | 0x1b, |
295 | }; | 305 | }; |
@@ -331,10 +341,10 @@ static hda_nid_t stac922x_pin_nids[10] = { | |||
331 | 0x0f, 0x10, 0x11, 0x15, 0x1b, | 341 | 0x0f, 0x10, 0x11, 0x15, 0x1b, |
332 | }; | 342 | }; |
333 | 343 | ||
334 | static hda_nid_t stac92hd73xx_pin_nids[12] = { | 344 | static hda_nid_t stac92hd73xx_pin_nids[13] = { |
335 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | 345 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, |
336 | 0x0f, 0x10, 0x11, 0x12, 0x13, | 346 | 0x0f, 0x10, 0x11, 0x12, 0x13, |
337 | 0x14, 0x22 | 347 | 0x14, 0x1e, 0x22 |
338 | }; | 348 | }; |
339 | 349 | ||
340 | static hda_nid_t stac92hd71bxx_pin_nids[10] = { | 350 | static hda_nid_t stac92hd71bxx_pin_nids[10] = { |
@@ -527,6 +537,43 @@ static struct hda_verb stac92hd73xx_6ch_core_init[] = { | |||
527 | {} | 537 | {} |
528 | }; | 538 | }; |
529 | 539 | ||
540 | static struct hda_verb dell_eq_core_init[] = { | ||
541 | /* set master volume to max value without distortion | ||
542 | * and direct control */ | ||
543 | { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec}, | ||
544 | /* setup audio connections */ | ||
545 | { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
546 | { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
547 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
548 | /* setup adcs to point to mixer */ | ||
549 | { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, | ||
550 | { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, | ||
551 | /* setup import muxs */ | ||
552 | { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
553 | { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
554 | { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
555 | { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
556 | {} | ||
557 | }; | ||
558 | |||
559 | static struct hda_verb dell_m6_core_init[] = { | ||
560 | /* set master volume and direct control */ | ||
561 | { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | ||
562 | /* setup audio connections */ | ||
563 | { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
564 | { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
565 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x02}, | ||
566 | /* setup adcs to point to mixer */ | ||
567 | { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, | ||
568 | { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, | ||
569 | /* setup import muxs */ | ||
570 | { 0x28, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
571 | { 0x29, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
572 | { 0x2a, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
573 | { 0x2b, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
574 | {} | ||
575 | }; | ||
576 | |||
530 | static struct hda_verb stac92hd73xx_8ch_core_init[] = { | 577 | static struct hda_verb stac92hd73xx_8ch_core_init[] = { |
531 | /* set master volume and direct control */ | 578 | /* set master volume and direct control */ |
532 | { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 579 | { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
@@ -910,6 +957,11 @@ static int stac92xx_build_controls(struct hda_codec *codec) | |||
910 | err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); | 957 | err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); |
911 | if (err < 0) | 958 | if (err < 0) |
912 | return err; | 959 | return err; |
960 | err = snd_hda_create_spdif_share_sw(codec, | ||
961 | &spec->multiout); | ||
962 | if (err < 0) | ||
963 | return err; | ||
964 | spec->multiout.share_spdif = 1; | ||
913 | } | 965 | } |
914 | if (spec->dig_in_nid) { | 966 | if (spec->dig_in_nid) { |
915 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); | 967 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); |
@@ -919,10 +971,11 @@ static int stac92xx_build_controls(struct hda_codec *codec) | |||
919 | 971 | ||
920 | /* if we have no master control, let's create it */ | 972 | /* if we have no master control, let's create it */ |
921 | if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { | 973 | if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { |
974 | unsigned int vmaster_tlv[4]; | ||
922 | snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], | 975 | snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], |
923 | HDA_OUTPUT, spec->vmaster_tlv); | 976 | HDA_OUTPUT, vmaster_tlv); |
924 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", | 977 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", |
925 | spec->vmaster_tlv, slave_vols); | 978 | vmaster_tlv, slave_vols); |
926 | if (err < 0) | 979 | if (err < 0) |
927 | return err; | 980 | return err; |
928 | } | 981 | } |
@@ -1052,9 +1105,15 @@ static unsigned int dell9200_m27_pin_configs[8] = { | |||
1052 | 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc, | 1105 | 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc, |
1053 | }; | 1106 | }; |
1054 | 1107 | ||
1108 | static unsigned int oqo9200_pin_configs[8] = { | ||
1109 | 0x40c000f0, 0x404000f1, 0x0221121f, 0x02211210, | ||
1110 | 0x90170111, 0x90a70120, 0x400000f2, 0x400000f3, | ||
1111 | }; | ||
1112 | |||
1055 | 1113 | ||
1056 | static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = { | 1114 | static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = { |
1057 | [STAC_REF] = ref9200_pin_configs, | 1115 | [STAC_REF] = ref9200_pin_configs, |
1116 | [STAC_9200_OQO] = oqo9200_pin_configs, | ||
1058 | [STAC_9200_DELL_D21] = dell9200_d21_pin_configs, | 1117 | [STAC_9200_DELL_D21] = dell9200_d21_pin_configs, |
1059 | [STAC_9200_DELL_D22] = dell9200_d22_pin_configs, | 1118 | [STAC_9200_DELL_D22] = dell9200_d22_pin_configs, |
1060 | [STAC_9200_DELL_D23] = dell9200_d23_pin_configs, | 1119 | [STAC_9200_DELL_D23] = dell9200_d23_pin_configs, |
@@ -1065,10 +1124,12 @@ static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = { | |||
1065 | [STAC_9200_DELL_M25] = dell9200_m25_pin_configs, | 1124 | [STAC_9200_DELL_M25] = dell9200_m25_pin_configs, |
1066 | [STAC_9200_DELL_M26] = dell9200_m26_pin_configs, | 1125 | [STAC_9200_DELL_M26] = dell9200_m26_pin_configs, |
1067 | [STAC_9200_DELL_M27] = dell9200_m27_pin_configs, | 1126 | [STAC_9200_DELL_M27] = dell9200_m27_pin_configs, |
1127 | [STAC_9200_PANASONIC] = ref9200_pin_configs, | ||
1068 | }; | 1128 | }; |
1069 | 1129 | ||
1070 | static const char *stac9200_models[STAC_9200_MODELS] = { | 1130 | static const char *stac9200_models[STAC_9200_MODELS] = { |
1071 | [STAC_REF] = "ref", | 1131 | [STAC_REF] = "ref", |
1132 | [STAC_9200_OQO] = "oqo", | ||
1072 | [STAC_9200_DELL_D21] = "dell-d21", | 1133 | [STAC_9200_DELL_D21] = "dell-d21", |
1073 | [STAC_9200_DELL_D22] = "dell-d22", | 1134 | [STAC_9200_DELL_D22] = "dell-d22", |
1074 | [STAC_9200_DELL_D23] = "dell-d23", | 1135 | [STAC_9200_DELL_D23] = "dell-d23", |
@@ -1080,6 +1141,7 @@ static const char *stac9200_models[STAC_9200_MODELS] = { | |||
1080 | [STAC_9200_DELL_M26] = "dell-m26", | 1141 | [STAC_9200_DELL_M26] = "dell-m26", |
1081 | [STAC_9200_DELL_M27] = "dell-m27", | 1142 | [STAC_9200_DELL_M27] = "dell-m27", |
1082 | [STAC_9200_GATEWAY] = "gateway", | 1143 | [STAC_9200_GATEWAY] = "gateway", |
1144 | [STAC_9200_PANASONIC] = "panasonic", | ||
1083 | }; | 1145 | }; |
1084 | 1146 | ||
1085 | static struct snd_pci_quirk stac9200_cfg_tbl[] = { | 1147 | static struct snd_pci_quirk stac9200_cfg_tbl[] = { |
@@ -1146,13 +1208,15 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = { | |||
1146 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6, | 1208 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f6, |
1147 | "unknown Dell", STAC_9200_DELL_M26), | 1209 | "unknown Dell", STAC_9200_DELL_M26), |
1148 | /* Panasonic */ | 1210 | /* Panasonic */ |
1149 | SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_REF), | 1211 | SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC), |
1150 | /* Gateway machines needs EAPD to be set on resume */ | 1212 | /* Gateway machines needs EAPD to be set on resume */ |
1151 | SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_GATEWAY), | 1213 | SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_GATEWAY), |
1152 | SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", | 1214 | SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", |
1153 | STAC_9200_GATEWAY), | 1215 | STAC_9200_GATEWAY), |
1154 | SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", | 1216 | SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", |
1155 | STAC_9200_GATEWAY), | 1217 | STAC_9200_GATEWAY), |
1218 | /* OQO Mobile */ | ||
1219 | SND_PCI_QUIRK(0x1106, 0x3288, "OQO Model 2", STAC_9200_OQO), | ||
1156 | {} /* terminator */ | 1220 | {} /* terminator */ |
1157 | }; | 1221 | }; |
1158 | 1222 | ||
@@ -1202,24 +1266,48 @@ static struct snd_pci_quirk stac925x_cfg_tbl[] = { | |||
1202 | {} /* terminator */ | 1266 | {} /* terminator */ |
1203 | }; | 1267 | }; |
1204 | 1268 | ||
1205 | static unsigned int ref92hd73xx_pin_configs[12] = { | 1269 | static unsigned int ref92hd73xx_pin_configs[13] = { |
1206 | 0x02214030, 0x02a19040, 0x01a19020, 0x02214030, | 1270 | 0x02214030, 0x02a19040, 0x01a19020, 0x02214030, |
1207 | 0x0181302e, 0x01014010, 0x01014020, 0x01014030, | 1271 | 0x0181302e, 0x01014010, 0x01014020, 0x01014030, |
1208 | 0x02319040, 0x90a000f0, 0x90a000f0, 0x01452050, | 1272 | 0x02319040, 0x90a000f0, 0x90a000f0, 0x01452050, |
1273 | 0x01452050, | ||
1274 | }; | ||
1275 | |||
1276 | static unsigned int dell_m6_pin_configs[13] = { | ||
1277 | 0x0321101f, 0x4f00000f, 0x4f0000f0, 0x90170110, | ||
1278 | 0x03a11020, 0x0321101f, 0x4f0000f0, 0x4f0000f0, | ||
1279 | 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0, | ||
1280 | 0x4f0000f0, | ||
1209 | }; | 1281 | }; |
1210 | 1282 | ||
1211 | static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { | 1283 | static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { |
1212 | [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs, | 1284 | [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs, |
1285 | [STAC_DELL_M6] = dell_m6_pin_configs, | ||
1213 | }; | 1286 | }; |
1214 | 1287 | ||
1215 | static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { | 1288 | static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { |
1216 | [STAC_92HD73XX_REF] = "ref", | 1289 | [STAC_92HD73XX_REF] = "ref", |
1290 | [STAC_DELL_M6] = "dell-m6", | ||
1217 | }; | 1291 | }; |
1218 | 1292 | ||
1219 | static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { | 1293 | static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { |
1220 | /* SigmaTel reference board */ | 1294 | /* SigmaTel reference board */ |
1221 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1295 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1222 | "DFI LanParty", STAC_92HD73XX_REF), | 1296 | "DFI LanParty", STAC_92HD73XX_REF), |
1297 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254, | ||
1298 | "unknown Dell", STAC_DELL_M6), | ||
1299 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255, | ||
1300 | "unknown Dell", STAC_DELL_M6), | ||
1301 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0256, | ||
1302 | "unknown Dell", STAC_DELL_M6), | ||
1303 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0257, | ||
1304 | "unknown Dell", STAC_DELL_M6), | ||
1305 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025e, | ||
1306 | "unknown Dell", STAC_DELL_M6), | ||
1307 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x025f, | ||
1308 | "unknown Dell", STAC_DELL_M6), | ||
1309 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0271, | ||
1310 | "unknown Dell", STAC_DELL_M6), | ||
1223 | {} /* terminator */ | 1311 | {} /* terminator */ |
1224 | }; | 1312 | }; |
1225 | 1313 | ||
@@ -1229,18 +1317,56 @@ static unsigned int ref92hd71bxx_pin_configs[10] = { | |||
1229 | 0x90a000f0, 0x01452050, | 1317 | 0x90a000f0, 0x01452050, |
1230 | }; | 1318 | }; |
1231 | 1319 | ||
1320 | static unsigned int dell_m4_1_pin_configs[13] = { | ||
1321 | 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, | ||
1322 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, | ||
1323 | 0x40f000f0, 0x4f0000f0, | ||
1324 | }; | ||
1325 | |||
1326 | static unsigned int dell_m4_2_pin_configs[13] = { | ||
1327 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, | ||
1328 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, | ||
1329 | 0x40f000f0, 0x044413b0, | ||
1330 | }; | ||
1331 | |||
1232 | static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { | 1332 | static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { |
1233 | [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs, | 1333 | [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs, |
1334 | [STAC_DELL_M4_1] = dell_m4_1_pin_configs, | ||
1335 | [STAC_DELL_M4_2] = dell_m4_2_pin_configs, | ||
1234 | }; | 1336 | }; |
1235 | 1337 | ||
1236 | static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { | 1338 | static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { |
1237 | [STAC_92HD71BXX_REF] = "ref", | 1339 | [STAC_92HD71BXX_REF] = "ref", |
1340 | [STAC_DELL_M4_1] = "dell-m4-1", | ||
1341 | [STAC_DELL_M4_2] = "dell-m4-2", | ||
1238 | }; | 1342 | }; |
1239 | 1343 | ||
1240 | static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { | 1344 | static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { |
1241 | /* SigmaTel reference board */ | 1345 | /* SigmaTel reference board */ |
1242 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1346 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1243 | "DFI LanParty", STAC_92HD71BXX_REF), | 1347 | "DFI LanParty", STAC_92HD71BXX_REF), |
1348 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, | ||
1349 | "unknown Dell", STAC_DELL_M4_1), | ||
1350 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234, | ||
1351 | "unknown Dell", STAC_DELL_M4_1), | ||
1352 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0250, | ||
1353 | "unknown Dell", STAC_DELL_M4_1), | ||
1354 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024f, | ||
1355 | "unknown Dell", STAC_DELL_M4_1), | ||
1356 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x024d, | ||
1357 | "unknown Dell", STAC_DELL_M4_1), | ||
1358 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0251, | ||
1359 | "unknown Dell", STAC_DELL_M4_1), | ||
1360 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0277, | ||
1361 | "unknown Dell", STAC_DELL_M4_1), | ||
1362 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0263, | ||
1363 | "unknown Dell", STAC_DELL_M4_2), | ||
1364 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0265, | ||
1365 | "unknown Dell", STAC_DELL_M4_2), | ||
1366 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0262, | ||
1367 | "unknown Dell", STAC_DELL_M4_2), | ||
1368 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0264, | ||
1369 | "unknown Dell", STAC_DELL_M4_2), | ||
1244 | {} /* terminator */ | 1370 | {} /* terminator */ |
1245 | }; | 1371 | }; |
1246 | 1372 | ||
@@ -1733,7 +1859,8 @@ static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo, | |||
1733 | struct snd_pcm_substream *substream) | 1859 | struct snd_pcm_substream *substream) |
1734 | { | 1860 | { |
1735 | struct sigmatel_spec *spec = codec->spec; | 1861 | struct sigmatel_spec *spec = codec->spec; |
1736 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream); | 1862 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, |
1863 | hinfo); | ||
1737 | } | 1864 | } |
1738 | 1865 | ||
1739 | static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | 1866 | static int stac92xx_playback_pcm_prepare(struct hda_pcm_stream *hinfo, |
@@ -1807,7 +1934,7 @@ static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
1807 | { | 1934 | { |
1808 | struct sigmatel_spec *spec = codec->spec; | 1935 | struct sigmatel_spec *spec = codec->spec; |
1809 | 1936 | ||
1810 | snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 0, 0, 0); | 1937 | snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]); |
1811 | return 0; | 1938 | return 0; |
1812 | } | 1939 | } |
1813 | 1940 | ||
@@ -1889,6 +2016,7 @@ static int stac92xx_build_pcms(struct hda_codec *codec) | |||
1889 | codec->num_pcms++; | 2016 | codec->num_pcms++; |
1890 | info++; | 2017 | info++; |
1891 | info->name = "STAC92xx Digital"; | 2018 | info->name = "STAC92xx Digital"; |
2019 | info->pcm_type = HDA_PCM_TYPE_SPDIF; | ||
1892 | if (spec->multiout.dig_out_nid) { | 2020 | if (spec->multiout.dig_out_nid) { |
1893 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback; | 2021 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback; |
1894 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; | 2022 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; |
@@ -1925,6 +2053,34 @@ static void stac92xx_auto_set_pinctl(struct hda_codec *codec, hda_nid_t nid, int | |||
1925 | AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); | 2053 | AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); |
1926 | } | 2054 | } |
1927 | 2055 | ||
2056 | #define stac92xx_hp_switch_info snd_ctl_boolean_mono_info | ||
2057 | |||
2058 | static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol, | ||
2059 | struct snd_ctl_elem_value *ucontrol) | ||
2060 | { | ||
2061 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2062 | struct sigmatel_spec *spec = codec->spec; | ||
2063 | |||
2064 | ucontrol->value.integer.value[0] = spec->hp_switch; | ||
2065 | return 0; | ||
2066 | } | ||
2067 | |||
2068 | static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol, | ||
2069 | struct snd_ctl_elem_value *ucontrol) | ||
2070 | { | ||
2071 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2072 | struct sigmatel_spec *spec = codec->spec; | ||
2073 | |||
2074 | spec->hp_switch = ucontrol->value.integer.value[0]; | ||
2075 | |||
2076 | /* check to be sure that the ports are upto date with | ||
2077 | * switch changes | ||
2078 | */ | ||
2079 | codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); | ||
2080 | |||
2081 | return 1; | ||
2082 | } | ||
2083 | |||
1928 | #define stac92xx_io_switch_info snd_ctl_boolean_mono_info | 2084 | #define stac92xx_io_switch_info snd_ctl_boolean_mono_info |
1929 | 2085 | ||
1930 | static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) | 2086 | static int stac92xx_io_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) |
@@ -1996,6 +2152,15 @@ static int stac92xx_clfe_switch_put(struct snd_kcontrol *kcontrol, | |||
1996 | return 1; | 2152 | return 1; |
1997 | } | 2153 | } |
1998 | 2154 | ||
2155 | #define STAC_CODEC_HP_SWITCH(xname) \ | ||
2156 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
2157 | .name = xname, \ | ||
2158 | .index = 0, \ | ||
2159 | .info = stac92xx_hp_switch_info, \ | ||
2160 | .get = stac92xx_hp_switch_get, \ | ||
2161 | .put = stac92xx_hp_switch_put, \ | ||
2162 | } | ||
2163 | |||
1999 | #define STAC_CODEC_IO_SWITCH(xname, xpval) \ | 2164 | #define STAC_CODEC_IO_SWITCH(xname, xpval) \ |
2000 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 2165 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
2001 | .name = xname, \ | 2166 | .name = xname, \ |
@@ -2020,6 +2185,7 @@ enum { | |||
2020 | STAC_CTL_WIDGET_VOL, | 2185 | STAC_CTL_WIDGET_VOL, |
2021 | STAC_CTL_WIDGET_MUTE, | 2186 | STAC_CTL_WIDGET_MUTE, |
2022 | STAC_CTL_WIDGET_MONO_MUX, | 2187 | STAC_CTL_WIDGET_MONO_MUX, |
2188 | STAC_CTL_WIDGET_HP_SWITCH, | ||
2023 | STAC_CTL_WIDGET_IO_SWITCH, | 2189 | STAC_CTL_WIDGET_IO_SWITCH, |
2024 | STAC_CTL_WIDGET_CLFE_SWITCH | 2190 | STAC_CTL_WIDGET_CLFE_SWITCH |
2025 | }; | 2191 | }; |
@@ -2028,6 +2194,7 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = { | |||
2028 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), | 2194 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), |
2029 | HDA_CODEC_MUTE(NULL, 0, 0, 0), | 2195 | HDA_CODEC_MUTE(NULL, 0, 0, 0), |
2030 | STAC_MONO_MUX, | 2196 | STAC_MONO_MUX, |
2197 | STAC_CODEC_HP_SWITCH(NULL), | ||
2031 | STAC_CODEC_IO_SWITCH(NULL, 0), | 2198 | STAC_CODEC_IO_SWITCH(NULL, 0), |
2032 | STAC_CODEC_CLFE_SWITCH(NULL, 0), | 2199 | STAC_CODEC_CLFE_SWITCH(NULL, 0), |
2033 | }; | 2200 | }; |
@@ -2222,6 +2389,29 @@ static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_ | |||
2222 | return 0; | 2389 | return 0; |
2223 | } | 2390 | } |
2224 | 2391 | ||
2392 | static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid) | ||
2393 | { | ||
2394 | if (!spec->multiout.hp_nid) | ||
2395 | spec->multiout.hp_nid = nid; | ||
2396 | else if (spec->multiout.num_dacs > 4) { | ||
2397 | printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid); | ||
2398 | return 1; | ||
2399 | } else { | ||
2400 | spec->multiout.dac_nids[spec->multiout.num_dacs] = nid; | ||
2401 | spec->multiout.num_dacs++; | ||
2402 | } | ||
2403 | return 0; | ||
2404 | } | ||
2405 | |||
2406 | static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) | ||
2407 | { | ||
2408 | if (is_in_dac_nids(spec, nid)) | ||
2409 | return 1; | ||
2410 | if (spec->multiout.hp_nid == nid) | ||
2411 | return 1; | ||
2412 | return 0; | ||
2413 | } | ||
2414 | |||
2225 | /* add playback controls from the parsed DAC table */ | 2415 | /* add playback controls from the parsed DAC table */ |
2226 | static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, | 2416 | static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, |
2227 | const struct auto_pin_cfg *cfg) | 2417 | const struct auto_pin_cfg *cfg) |
@@ -2236,7 +2426,7 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
2236 | unsigned int wid_caps, pincap; | 2426 | unsigned int wid_caps, pincap; |
2237 | 2427 | ||
2238 | 2428 | ||
2239 | for (i = 0; i < cfg->line_outs; i++) { | 2429 | for (i = 0; i < cfg->line_outs && i < spec->multiout.num_dacs; i++) { |
2240 | if (!spec->multiout.dac_nids[i]) | 2430 | if (!spec->multiout.dac_nids[i]) |
2241 | continue; | 2431 | continue; |
2242 | 2432 | ||
@@ -2269,6 +2459,14 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
2269 | } | 2459 | } |
2270 | } | 2460 | } |
2271 | 2461 | ||
2462 | if (cfg->hp_outs > 1) { | ||
2463 | err = stac92xx_add_control(spec, | ||
2464 | STAC_CTL_WIDGET_HP_SWITCH, | ||
2465 | "Headphone as Line Out Switch", 0); | ||
2466 | if (err < 0) | ||
2467 | return err; | ||
2468 | } | ||
2469 | |||
2272 | if (spec->line_switch) { | 2470 | if (spec->line_switch) { |
2273 | nid = cfg->input_pins[AUTO_PIN_LINE]; | 2471 | nid = cfg->input_pins[AUTO_PIN_LINE]; |
2274 | pincap = snd_hda_param_read(codec, nid, | 2472 | pincap = snd_hda_param_read(codec, nid, |
@@ -2284,10 +2482,11 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
2284 | 2482 | ||
2285 | if (spec->mic_switch) { | 2483 | if (spec->mic_switch) { |
2286 | unsigned int def_conf; | 2484 | unsigned int def_conf; |
2287 | nid = cfg->input_pins[AUTO_PIN_MIC]; | 2485 | unsigned int mic_pin = AUTO_PIN_MIC; |
2486 | again: | ||
2487 | nid = cfg->input_pins[mic_pin]; | ||
2288 | def_conf = snd_hda_codec_read(codec, nid, 0, | 2488 | def_conf = snd_hda_codec_read(codec, nid, 0, |
2289 | AC_VERB_GET_CONFIG_DEFAULT, 0); | 2489 | AC_VERB_GET_CONFIG_DEFAULT, 0); |
2290 | |||
2291 | /* some laptops have an internal analog microphone | 2490 | /* some laptops have an internal analog microphone |
2292 | * which can't be used as a output */ | 2491 | * which can't be used as a output */ |
2293 | if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) { | 2492 | if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) { |
@@ -2297,38 +2496,22 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
2297 | err = stac92xx_add_control(spec, | 2496 | err = stac92xx_add_control(spec, |
2298 | STAC_CTL_WIDGET_IO_SWITCH, | 2497 | STAC_CTL_WIDGET_IO_SWITCH, |
2299 | "Mic as Output Switch", (nid << 8) | 1); | 2498 | "Mic as Output Switch", (nid << 8) | 1); |
2499 | nid = snd_hda_codec_read(codec, nid, 0, | ||
2500 | AC_VERB_GET_CONNECT_LIST, 0) & 0xff; | ||
2501 | if (!check_in_dac_nids(spec, nid)) | ||
2502 | add_spec_dacs(spec, nid); | ||
2300 | if (err < 0) | 2503 | if (err < 0) |
2301 | return err; | 2504 | return err; |
2302 | } | 2505 | } |
2506 | } else if (mic_pin == AUTO_PIN_MIC) { | ||
2507 | mic_pin = AUTO_PIN_FRONT_MIC; | ||
2508 | goto again; | ||
2303 | } | 2509 | } |
2304 | } | 2510 | } |
2305 | 2511 | ||
2306 | return 0; | 2512 | return 0; |
2307 | } | 2513 | } |
2308 | 2514 | ||
2309 | static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) | ||
2310 | { | ||
2311 | if (is_in_dac_nids(spec, nid)) | ||
2312 | return 1; | ||
2313 | if (spec->multiout.hp_nid == nid) | ||
2314 | return 1; | ||
2315 | return 0; | ||
2316 | } | ||
2317 | |||
2318 | static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid) | ||
2319 | { | ||
2320 | if (!spec->multiout.hp_nid) | ||
2321 | spec->multiout.hp_nid = nid; | ||
2322 | else if (spec->multiout.num_dacs > 4) { | ||
2323 | printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid); | ||
2324 | return 1; | ||
2325 | } else { | ||
2326 | spec->multiout.dac_nids[spec->multiout.num_dacs] = nid; | ||
2327 | spec->multiout.num_dacs++; | ||
2328 | } | ||
2329 | return 0; | ||
2330 | } | ||
2331 | |||
2332 | /* add playback controls for Speaker and HP outputs */ | 2515 | /* add playback controls for Speaker and HP outputs */ |
2333 | static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, | 2516 | static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, |
2334 | struct auto_pin_cfg *cfg) | 2517 | struct auto_pin_cfg *cfg) |
@@ -2378,12 +2561,8 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, | |||
2378 | return err; | 2561 | return err; |
2379 | } | 2562 | } |
2380 | if (spec->multiout.hp_nid) { | 2563 | if (spec->multiout.hp_nid) { |
2381 | const char *pfx; | 2564 | err = create_controls(spec, "Headphone", |
2382 | if (old_num_dacs == spec->multiout.num_dacs) | 2565 | spec->multiout.hp_nid, 3); |
2383 | pfx = "Master"; | ||
2384 | else | ||
2385 | pfx = "Headphone"; | ||
2386 | err = create_controls(spec, pfx, spec->multiout.hp_nid, 3); | ||
2387 | if (err < 0) | 2566 | if (err < 0) |
2388 | return err; | 2567 | return err; |
2389 | } | 2568 | } |
@@ -2745,7 +2924,7 @@ static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec, | |||
2745 | */ | 2924 | */ |
2746 | for (i = 0; i < spec->autocfg.speaker_outs && lfe_pin == 0x0; i++) { | 2925 | for (i = 0; i < spec->autocfg.speaker_outs && lfe_pin == 0x0; i++) { |
2747 | hda_nid_t pin = spec->autocfg.speaker_pins[i]; | 2926 | hda_nid_t pin = spec->autocfg.speaker_pins[i]; |
2748 | unsigned long wcaps = get_wcaps(codec, pin); | 2927 | unsigned int wcaps = get_wcaps(codec, pin); |
2749 | wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP); | 2928 | wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP); |
2750 | if (wcaps == AC_WCAP_OUT_AMP) | 2929 | if (wcaps == AC_WCAP_OUT_AMP) |
2751 | /* found a mono speaker with an amp, must be lfe */ | 2930 | /* found a mono speaker with an amp, must be lfe */ |
@@ -2756,12 +2935,12 @@ static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec, | |||
2756 | if (lfe_pin == 0 && spec->autocfg.speaker_outs == 0) { | 2935 | if (lfe_pin == 0 && spec->autocfg.speaker_outs == 0) { |
2757 | for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) { | 2936 | for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) { |
2758 | hda_nid_t pin = spec->autocfg.line_out_pins[i]; | 2937 | hda_nid_t pin = spec->autocfg.line_out_pins[i]; |
2759 | unsigned long cfg; | 2938 | unsigned int defcfg; |
2760 | cfg = snd_hda_codec_read(codec, pin, 0, | 2939 | defcfg = snd_hda_codec_read(codec, pin, 0, |
2761 | AC_VERB_GET_CONFIG_DEFAULT, | 2940 | AC_VERB_GET_CONFIG_DEFAULT, |
2762 | 0x00); | 2941 | 0x00); |
2763 | if (get_defcfg_device(cfg) == AC_JACK_SPEAKER) { | 2942 | if (get_defcfg_device(defcfg) == AC_JACK_SPEAKER) { |
2764 | unsigned long wcaps = get_wcaps(codec, pin); | 2943 | unsigned int wcaps = get_wcaps(codec, pin); |
2765 | wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP); | 2944 | wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP); |
2766 | if (wcaps == AC_WCAP_OUT_AMP) | 2945 | if (wcaps == AC_WCAP_OUT_AMP) |
2767 | /* found a mono speaker with an amp, | 2946 | /* found a mono speaker with an amp, |
@@ -2866,6 +3045,19 @@ static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid) | |||
2866 | return 0; /* nid is not a HP-Out */ | 3045 | return 0; /* nid is not a HP-Out */ |
2867 | }; | 3046 | }; |
2868 | 3047 | ||
3048 | static void stac92xx_power_down(struct hda_codec *codec) | ||
3049 | { | ||
3050 | struct sigmatel_spec *spec = codec->spec; | ||
3051 | |||
3052 | /* power down inactive DACs */ | ||
3053 | hda_nid_t *dac; | ||
3054 | for (dac = spec->dac_list; *dac; dac++) | ||
3055 | if (!is_in_dac_nids(spec, *dac) && | ||
3056 | spec->multiout.hp_nid != *dac) | ||
3057 | snd_hda_codec_write_cache(codec, *dac, 0, | ||
3058 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
3059 | } | ||
3060 | |||
2869 | static int stac92xx_init(struct hda_codec *codec) | 3061 | static int stac92xx_init(struct hda_codec *codec) |
2870 | { | 3062 | { |
2871 | struct sigmatel_spec *spec = codec->spec; | 3063 | struct sigmatel_spec *spec = codec->spec; |
@@ -2909,16 +3101,21 @@ static int stac92xx_init(struct hda_codec *codec) | |||
2909 | ? STAC_HP_EVENT : STAC_PWR_EVENT; | 3101 | ? STAC_HP_EVENT : STAC_PWR_EVENT; |
2910 | int pinctl = snd_hda_codec_read(codec, spec->pwr_nids[i], | 3102 | int pinctl = snd_hda_codec_read(codec, spec->pwr_nids[i], |
2911 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | 3103 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); |
3104 | int def_conf = snd_hda_codec_read(codec, spec->pwr_nids[i], | ||
3105 | 0, AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
2912 | /* outputs are only ports capable of power management | 3106 | /* outputs are only ports capable of power management |
2913 | * any attempts on powering down a input port cause the | 3107 | * any attempts on powering down a input port cause the |
2914 | * referenced VREF to act quirky. | 3108 | * referenced VREF to act quirky. |
2915 | */ | 3109 | */ |
2916 | if (pinctl & AC_PINCTL_IN_EN) | 3110 | if (pinctl & AC_PINCTL_IN_EN) |
2917 | continue; | 3111 | continue; |
3112 | if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) | ||
3113 | continue; | ||
2918 | enable_pin_detect(codec, spec->pwr_nids[i], event | i); | 3114 | enable_pin_detect(codec, spec->pwr_nids[i], event | i); |
2919 | codec->patch_ops.unsol_event(codec, (event | i) << 26); | 3115 | codec->patch_ops.unsol_event(codec, (event | i) << 26); |
2920 | } | 3116 | } |
2921 | 3117 | if (spec->dac_list) | |
3118 | stac92xx_power_down(codec); | ||
2922 | if (cfg->dig_out_pin) | 3119 | if (cfg->dig_out_pin) |
2923 | stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin, | 3120 | stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin, |
2924 | AC_PINCTL_OUT_EN); | 3121 | AC_PINCTL_OUT_EN); |
@@ -3014,6 +3211,7 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res) | |||
3014 | { | 3211 | { |
3015 | struct sigmatel_spec *spec = codec->spec; | 3212 | struct sigmatel_spec *spec = codec->spec; |
3016 | struct auto_pin_cfg *cfg = &spec->autocfg; | 3213 | struct auto_pin_cfg *cfg = &spec->autocfg; |
3214 | int nid = cfg->hp_pins[cfg->hp_outs - 1]; | ||
3017 | int i, presence; | 3215 | int i, presence; |
3018 | 3216 | ||
3019 | presence = 0; | 3217 | presence = 0; |
@@ -3024,26 +3222,42 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res) | |||
3024 | for (i = 0; i < cfg->hp_outs; i++) { | 3222 | for (i = 0; i < cfg->hp_outs; i++) { |
3025 | if (presence) | 3223 | if (presence) |
3026 | break; | 3224 | break; |
3225 | if (spec->hp_switch && cfg->hp_pins[i] == nid) | ||
3226 | break; | ||
3027 | presence = get_hp_pin_presence(codec, cfg->hp_pins[i]); | 3227 | presence = get_hp_pin_presence(codec, cfg->hp_pins[i]); |
3028 | } | 3228 | } |
3029 | 3229 | ||
3030 | if (presence) { | 3230 | if (presence) { |
3031 | /* disable lineouts, enable hp */ | 3231 | /* disable lineouts, enable hp */ |
3232 | if (spec->hp_switch) | ||
3233 | stac92xx_reset_pinctl(codec, nid, AC_PINCTL_OUT_EN); | ||
3032 | for (i = 0; i < cfg->line_outs; i++) | 3234 | for (i = 0; i < cfg->line_outs; i++) |
3033 | stac92xx_reset_pinctl(codec, cfg->line_out_pins[i], | 3235 | stac92xx_reset_pinctl(codec, cfg->line_out_pins[i], |
3034 | AC_PINCTL_OUT_EN); | 3236 | AC_PINCTL_OUT_EN); |
3035 | for (i = 0; i < cfg->speaker_outs; i++) | 3237 | for (i = 0; i < cfg->speaker_outs; i++) |
3036 | stac92xx_reset_pinctl(codec, cfg->speaker_pins[i], | 3238 | stac92xx_reset_pinctl(codec, cfg->speaker_pins[i], |
3037 | AC_PINCTL_OUT_EN); | 3239 | AC_PINCTL_OUT_EN); |
3240 | if (spec->eapd_mask) | ||
3241 | stac_gpio_set(codec, spec->gpio_mask, | ||
3242 | spec->gpio_dir, spec->gpio_data & | ||
3243 | ~spec->eapd_mask); | ||
3038 | } else { | 3244 | } else { |
3039 | /* enable lineouts, disable hp */ | 3245 | /* enable lineouts, disable hp */ |
3246 | if (spec->hp_switch) | ||
3247 | stac92xx_set_pinctl(codec, nid, AC_PINCTL_OUT_EN); | ||
3040 | for (i = 0; i < cfg->line_outs; i++) | 3248 | for (i = 0; i < cfg->line_outs; i++) |
3041 | stac92xx_set_pinctl(codec, cfg->line_out_pins[i], | 3249 | stac92xx_set_pinctl(codec, cfg->line_out_pins[i], |
3042 | AC_PINCTL_OUT_EN); | 3250 | AC_PINCTL_OUT_EN); |
3043 | for (i = 0; i < cfg->speaker_outs; i++) | 3251 | for (i = 0; i < cfg->speaker_outs; i++) |
3044 | stac92xx_set_pinctl(codec, cfg->speaker_pins[i], | 3252 | stac92xx_set_pinctl(codec, cfg->speaker_pins[i], |
3045 | AC_PINCTL_OUT_EN); | 3253 | AC_PINCTL_OUT_EN); |
3254 | if (spec->eapd_mask) | ||
3255 | stac_gpio_set(codec, spec->gpio_mask, | ||
3256 | spec->gpio_dir, spec->gpio_data | | ||
3257 | spec->eapd_mask); | ||
3046 | } | 3258 | } |
3259 | if (!spec->hp_switch && cfg->hp_outs > 1 && presence) | ||
3260 | stac92xx_set_pinctl(codec, nid, AC_PINCTL_OUT_EN); | ||
3047 | } | 3261 | } |
3048 | 3262 | ||
3049 | static void stac92xx_pin_sense(struct hda_codec *codec, int idx) | 3263 | static void stac92xx_pin_sense(struct hda_codec *codec, int idx) |
@@ -3091,6 +3305,9 @@ static int stac92xx_resume(struct hda_codec *codec) | |||
3091 | spec->gpio_dir, spec->gpio_data); | 3305 | spec->gpio_dir, spec->gpio_data); |
3092 | snd_hda_codec_resume_amp(codec); | 3306 | snd_hda_codec_resume_amp(codec); |
3093 | snd_hda_codec_resume_cache(codec); | 3307 | snd_hda_codec_resume_cache(codec); |
3308 | /* power down inactive DACs */ | ||
3309 | if (spec->dac_list) | ||
3310 | stac92xx_power_down(codec); | ||
3094 | /* invoke unsolicited event to reset the HP state */ | 3311 | /* invoke unsolicited event to reset the HP state */ |
3095 | if (spec->hp_detect) | 3312 | if (spec->hp_detect) |
3096 | codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); | 3313 | codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); |
@@ -3147,12 +3364,18 @@ static int patch_stac9200(struct hda_codec *codec) | |||
3147 | spec->num_adcs = 1; | 3364 | spec->num_adcs = 1; |
3148 | spec->num_pwrs = 0; | 3365 | spec->num_pwrs = 0; |
3149 | 3366 | ||
3150 | if (spec->board_config == STAC_9200_GATEWAY) | 3367 | if (spec->board_config == STAC_9200_GATEWAY || |
3368 | spec->board_config == STAC_9200_OQO) | ||
3151 | spec->init = stac9200_eapd_init; | 3369 | spec->init = stac9200_eapd_init; |
3152 | else | 3370 | else |
3153 | spec->init = stac9200_core_init; | 3371 | spec->init = stac9200_core_init; |
3154 | spec->mixer = stac9200_mixer; | 3372 | spec->mixer = stac9200_mixer; |
3155 | 3373 | ||
3374 | if (spec->board_config == STAC_9200_PANASONIC) { | ||
3375 | spec->gpio_mask = spec->gpio_dir = 0x09; | ||
3376 | spec->gpio_data = 0x00; | ||
3377 | } | ||
3378 | |||
3156 | err = stac9200_parse_auto_config(codec); | 3379 | err = stac9200_parse_auto_config(codec); |
3157 | if (err < 0) { | 3380 | if (err < 0) { |
3158 | stac92xx_free(codec); | 3381 | stac92xx_free(codec); |
@@ -3293,6 +3516,7 @@ again: | |||
3293 | 3516 | ||
3294 | switch (spec->multiout.num_dacs) { | 3517 | switch (spec->multiout.num_dacs) { |
3295 | case 0x3: /* 6 Channel */ | 3518 | case 0x3: /* 6 Channel */ |
3519 | spec->multiout.hp_nid = 0x17; | ||
3296 | spec->mixer = stac92hd73xx_6ch_mixer; | 3520 | spec->mixer = stac92hd73xx_6ch_mixer; |
3297 | spec->init = stac92hd73xx_6ch_core_init; | 3521 | spec->init = stac92hd73xx_6ch_core_init; |
3298 | break; | 3522 | break; |
@@ -3318,13 +3542,42 @@ again: | |||
3318 | 3542 | ||
3319 | spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids); | 3543 | spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids); |
3320 | spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids); | 3544 | spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids); |
3321 | spec->num_dmics = STAC92HD73XX_NUM_DMICS; | ||
3322 | spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids); | 3545 | spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids); |
3323 | spec->dinput_mux = &stac92hd73xx_dmux; | 3546 | spec->dinput_mux = &stac92hd73xx_dmux; |
3324 | /* GPIO0 High = Enable EAPD */ | 3547 | /* GPIO0 High = Enable EAPD */ |
3325 | spec->gpio_mask = spec->gpio_dir = 0x1; | 3548 | spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; |
3326 | spec->gpio_data = 0x01; | 3549 | spec->gpio_data = 0x01; |
3327 | 3550 | ||
3551 | switch (spec->board_config) { | ||
3552 | case STAC_DELL_M6: | ||
3553 | spec->init = dell_eq_core_init; | ||
3554 | switch (codec->subsystem_id) { | ||
3555 | case 0x1028025e: /* Analog Mics */ | ||
3556 | case 0x1028025f: | ||
3557 | stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); | ||
3558 | spec->num_dmics = 0; | ||
3559 | break; | ||
3560 | case 0x10280271: /* Digital Mics */ | ||
3561 | case 0x10280272: | ||
3562 | spec->init = dell_m6_core_init; | ||
3563 | /* fall-through */ | ||
3564 | case 0x10280254: | ||
3565 | case 0x10280255: | ||
3566 | stac92xx_set_config_reg(codec, 0x13, 0x90A60160); | ||
3567 | spec->num_dmics = 1; | ||
3568 | break; | ||
3569 | case 0x10280256: /* Both */ | ||
3570 | case 0x10280057: | ||
3571 | stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); | ||
3572 | stac92xx_set_config_reg(codec, 0x13, 0x90A60160); | ||
3573 | spec->num_dmics = 1; | ||
3574 | break; | ||
3575 | } | ||
3576 | break; | ||
3577 | default: | ||
3578 | spec->num_dmics = STAC92HD73XX_NUM_DMICS; | ||
3579 | } | ||
3580 | |||
3328 | spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids); | 3581 | spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids); |
3329 | spec->pwr_nids = stac92hd73xx_pwr_nids; | 3582 | spec->pwr_nids = stac92hd73xx_pwr_nids; |
3330 | 3583 | ||
@@ -3398,7 +3651,10 @@ again: | |||
3398 | spec->aloopback_shift = 0; | 3651 | spec->aloopback_shift = 0; |
3399 | 3652 | ||
3400 | /* GPIO0 High = EAPD */ | 3653 | /* GPIO0 High = EAPD */ |
3401 | spec->gpio_mask = spec->gpio_dir = spec->gpio_data = 0x1; | 3654 | spec->gpio_mask = 0x01; |
3655 | spec->gpio_dir = 0x01; | ||
3656 | spec->gpio_mask = 0x01; | ||
3657 | spec->gpio_data = 0x01; | ||
3402 | 3658 | ||
3403 | spec->mux_nids = stac92hd71bxx_mux_nids; | 3659 | spec->mux_nids = stac92hd71bxx_mux_nids; |
3404 | spec->adc_nids = stac92hd71bxx_adc_nids; | 3660 | spec->adc_nids = stac92hd71bxx_adc_nids; |
@@ -3413,7 +3669,7 @@ again: | |||
3413 | spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); | 3669 | spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); |
3414 | spec->pwr_nids = stac92hd71bxx_pwr_nids; | 3670 | spec->pwr_nids = stac92hd71bxx_pwr_nids; |
3415 | 3671 | ||
3416 | spec->multiout.num_dacs = 2; | 3672 | spec->multiout.num_dacs = 1; |
3417 | spec->multiout.hp_nid = 0x11; | 3673 | spec->multiout.hp_nid = 0x11; |
3418 | spec->multiout.dac_nids = stac92hd71bxx_dac_nids; | 3674 | spec->multiout.dac_nids = stac92hd71bxx_dac_nids; |
3419 | 3675 | ||
@@ -3577,13 +3833,14 @@ static int patch_stac927x(struct hda_codec *codec) | |||
3577 | spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids); | 3833 | spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids); |
3578 | spec->mux_nids = stac927x_mux_nids; | 3834 | spec->mux_nids = stac927x_mux_nids; |
3579 | spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); | 3835 | spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); |
3836 | spec->dac_list = stac927x_dac_nids; | ||
3580 | spec->multiout.dac_nids = spec->dac_nids; | 3837 | spec->multiout.dac_nids = spec->dac_nids; |
3581 | 3838 | ||
3582 | switch (spec->board_config) { | 3839 | switch (spec->board_config) { |
3583 | case STAC_D965_3ST: | 3840 | case STAC_D965_3ST: |
3584 | case STAC_D965_5ST: | 3841 | case STAC_D965_5ST: |
3585 | /* GPIO0 High = Enable EAPD */ | 3842 | /* GPIO0 High = Enable EAPD */ |
3586 | spec->gpio_mask = spec->gpio_dir = 0x01; | 3843 | spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x01; |
3587 | spec->gpio_data = 0x01; | 3844 | spec->gpio_data = 0x01; |
3588 | spec->num_dmics = 0; | 3845 | spec->num_dmics = 0; |
3589 | 3846 | ||
@@ -3591,14 +3848,23 @@ static int patch_stac927x(struct hda_codec *codec) | |||
3591 | spec->mixer = stac927x_mixer; | 3848 | spec->mixer = stac927x_mixer; |
3592 | break; | 3849 | break; |
3593 | case STAC_DELL_BIOS: | 3850 | case STAC_DELL_BIOS: |
3851 | switch (codec->subsystem_id) { | ||
3852 | case 0x10280209: | ||
3853 | case 0x1028022e: | ||
3854 | /* correct the device field to SPDIF out */ | ||
3855 | stac92xx_set_config_reg(codec, 0x21, 0x01442070); | ||
3856 | break; | ||
3857 | }; | ||
3858 | /* configure the analog microphone on some laptops */ | ||
3859 | stac92xx_set_config_reg(codec, 0x0c, 0x90a79130); | ||
3594 | /* correct the front output jack as a hp out */ | 3860 | /* correct the front output jack as a hp out */ |
3595 | stac92xx_set_config_reg(codec, 0x0f, 0x02270110); | 3861 | stac92xx_set_config_reg(codec, 0x0f, 0x0227011f); |
3596 | /* correct the front input jack as a mic */ | 3862 | /* correct the front input jack as a mic */ |
3597 | stac92xx_set_config_reg(codec, 0x0e, 0x02a79130); | 3863 | stac92xx_set_config_reg(codec, 0x0e, 0x02a79130); |
3598 | /* fallthru */ | 3864 | /* fallthru */ |
3599 | case STAC_DELL_3ST: | 3865 | case STAC_DELL_3ST: |
3600 | /* GPIO2 High = Enable EAPD */ | 3866 | /* GPIO2 High = Enable EAPD */ |
3601 | spec->gpio_mask = spec->gpio_dir = 0x04; | 3867 | spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x04; |
3602 | spec->gpio_data = 0x04; | 3868 | spec->gpio_data = 0x04; |
3603 | spec->dmic_nids = stac927x_dmic_nids; | 3869 | spec->dmic_nids = stac927x_dmic_nids; |
3604 | spec->num_dmics = STAC927X_NUM_DMICS; | 3870 | spec->num_dmics = STAC927X_NUM_DMICS; |
@@ -3610,7 +3876,7 @@ static int patch_stac927x(struct hda_codec *codec) | |||
3610 | break; | 3876 | break; |
3611 | default: | 3877 | default: |
3612 | /* GPIO0 High = Enable EAPD */ | 3878 | /* GPIO0 High = Enable EAPD */ |
3613 | spec->gpio_mask = spec->gpio_dir = 0x1; | 3879 | spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; |
3614 | spec->gpio_data = 0x01; | 3880 | spec->gpio_data = 0x01; |
3615 | spec->num_dmics = 0; | 3881 | spec->num_dmics = 0; |
3616 | 3882 | ||
@@ -3714,6 +3980,7 @@ static int patch_stac9205(struct hda_codec *codec) | |||
3714 | (AC_USRSP_EN | STAC_HP_EVENT)); | 3980 | (AC_USRSP_EN | STAC_HP_EVENT)); |
3715 | 3981 | ||
3716 | spec->gpio_dir = 0x0b; | 3982 | spec->gpio_dir = 0x0b; |
3983 | spec->eapd_mask = 0x01; | ||
3717 | spec->gpio_mask = 0x1b; | 3984 | spec->gpio_mask = 0x1b; |
3718 | spec->gpio_mute = 0x10; | 3985 | spec->gpio_mute = 0x10; |
3719 | /* GPIO0 High = EAPD, GPIO1 Low = Headphone Mute, | 3986 | /* GPIO0 High = EAPD, GPIO1 Low = Headphone Mute, |
@@ -3723,7 +3990,7 @@ static int patch_stac9205(struct hda_codec *codec) | |||
3723 | break; | 3990 | break; |
3724 | default: | 3991 | default: |
3725 | /* GPIO0 High = EAPD */ | 3992 | /* GPIO0 High = EAPD */ |
3726 | spec->gpio_mask = spec->gpio_dir = 0x1; | 3993 | spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; |
3727 | spec->gpio_data = 0x01; | 3994 | spec->gpio_data = 0x01; |
3728 | break; | 3995 | break; |
3729 | } | 3996 | } |