diff options
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 973 |
1 files changed, 438 insertions, 535 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 3bc427645da8..13056429aa64 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -43,6 +43,7 @@ enum { | |||
43 | }; | 43 | }; |
44 | 44 | ||
45 | enum { | 45 | enum { |
46 | STAC_AUTO, | ||
46 | STAC_REF, | 47 | STAC_REF, |
47 | STAC_9200_OQO, | 48 | STAC_9200_OQO, |
48 | STAC_9200_DELL_D21, | 49 | STAC_9200_DELL_D21, |
@@ -62,14 +63,17 @@ enum { | |||
62 | }; | 63 | }; |
63 | 64 | ||
64 | enum { | 65 | enum { |
66 | STAC_9205_AUTO, | ||
65 | STAC_9205_REF, | 67 | STAC_9205_REF, |
66 | STAC_9205_DELL_M42, | 68 | STAC_9205_DELL_M42, |
67 | STAC_9205_DELL_M43, | 69 | STAC_9205_DELL_M43, |
68 | STAC_9205_DELL_M44, | 70 | STAC_9205_DELL_M44, |
71 | STAC_9205_EAPD, | ||
69 | STAC_9205_MODELS | 72 | STAC_9205_MODELS |
70 | }; | 73 | }; |
71 | 74 | ||
72 | enum { | 75 | enum { |
76 | STAC_92HD73XX_AUTO, | ||
73 | STAC_92HD73XX_NO_JD, /* no jack-detection */ | 77 | STAC_92HD73XX_NO_JD, /* no jack-detection */ |
74 | STAC_92HD73XX_REF, | 78 | STAC_92HD73XX_REF, |
75 | STAC_DELL_M6_AMIC, | 79 | STAC_DELL_M6_AMIC, |
@@ -80,12 +84,15 @@ enum { | |||
80 | }; | 84 | }; |
81 | 85 | ||
82 | enum { | 86 | enum { |
87 | STAC_92HD83XXX_AUTO, | ||
83 | STAC_92HD83XXX_REF, | 88 | STAC_92HD83XXX_REF, |
84 | STAC_92HD83XXX_PWR_REF, | 89 | STAC_92HD83XXX_PWR_REF, |
90 | STAC_DELL_S14, | ||
85 | STAC_92HD83XXX_MODELS | 91 | STAC_92HD83XXX_MODELS |
86 | }; | 92 | }; |
87 | 93 | ||
88 | enum { | 94 | enum { |
95 | STAC_92HD71BXX_AUTO, | ||
89 | STAC_92HD71BXX_REF, | 96 | STAC_92HD71BXX_REF, |
90 | STAC_DELL_M4_1, | 97 | STAC_DELL_M4_1, |
91 | STAC_DELL_M4_2, | 98 | STAC_DELL_M4_2, |
@@ -96,6 +103,7 @@ enum { | |||
96 | }; | 103 | }; |
97 | 104 | ||
98 | enum { | 105 | enum { |
106 | STAC_925x_AUTO, | ||
99 | STAC_925x_REF, | 107 | STAC_925x_REF, |
100 | STAC_M1, | 108 | STAC_M1, |
101 | STAC_M1_2, | 109 | STAC_M1_2, |
@@ -108,6 +116,7 @@ enum { | |||
108 | }; | 116 | }; |
109 | 117 | ||
110 | enum { | 118 | enum { |
119 | STAC_922X_AUTO, | ||
111 | STAC_D945_REF, | 120 | STAC_D945_REF, |
112 | STAC_D945GTP3, | 121 | STAC_D945GTP3, |
113 | STAC_D945GTP5, | 122 | STAC_D945GTP5, |
@@ -135,6 +144,7 @@ enum { | |||
135 | }; | 144 | }; |
136 | 145 | ||
137 | enum { | 146 | enum { |
147 | STAC_927X_AUTO, | ||
138 | STAC_D965_REF_NO_JD, /* no jack-detection */ | 148 | STAC_D965_REF_NO_JD, /* no jack-detection */ |
139 | STAC_D965_REF, | 149 | STAC_D965_REF, |
140 | STAC_D965_3ST, | 150 | STAC_D965_3ST, |
@@ -167,6 +177,7 @@ struct sigmatel_spec { | |||
167 | unsigned int alt_switch: 1; | 177 | unsigned int alt_switch: 1; |
168 | unsigned int hp_detect: 1; | 178 | unsigned int hp_detect: 1; |
169 | unsigned int spdif_mute: 1; | 179 | unsigned int spdif_mute: 1; |
180 | unsigned int check_volume_offset:1; | ||
170 | 181 | ||
171 | /* gpio lines */ | 182 | /* gpio lines */ |
172 | unsigned int eapd_mask; | 183 | unsigned int eapd_mask; |
@@ -203,6 +214,8 @@ struct sigmatel_spec { | |||
203 | hda_nid_t hp_dacs[5]; | 214 | hda_nid_t hp_dacs[5]; |
204 | hda_nid_t speaker_dacs[5]; | 215 | hda_nid_t speaker_dacs[5]; |
205 | 216 | ||
217 | int volume_offset; | ||
218 | |||
206 | /* capture */ | 219 | /* capture */ |
207 | hda_nid_t *adc_nids; | 220 | hda_nid_t *adc_nids; |
208 | unsigned int num_adcs; | 221 | unsigned int num_adcs; |
@@ -224,7 +237,6 @@ struct sigmatel_spec { | |||
224 | /* pin widgets */ | 237 | /* pin widgets */ |
225 | hda_nid_t *pin_nids; | 238 | hda_nid_t *pin_nids; |
226 | unsigned int num_pins; | 239 | unsigned int num_pins; |
227 | unsigned int *pin_configs; | ||
228 | 240 | ||
229 | /* codec specific stuff */ | 241 | /* codec specific stuff */ |
230 | struct hda_verb *init; | 242 | struct hda_verb *init; |
@@ -400,6 +412,10 @@ static hda_nid_t stac922x_mux_nids[2] = { | |||
400 | 0x12, 0x13, | 412 | 0x12, 0x13, |
401 | }; | 413 | }; |
402 | 414 | ||
415 | static hda_nid_t stac927x_slave_dig_outs[2] = { | ||
416 | 0x1f, 0, | ||
417 | }; | ||
418 | |||
403 | static hda_nid_t stac927x_adc_nids[3] = { | 419 | static hda_nid_t stac927x_adc_nids[3] = { |
404 | 0x07, 0x08, 0x09 | 420 | 0x07, 0x08, 0x09 |
405 | }; | 421 | }; |
@@ -472,15 +488,21 @@ static hda_nid_t stac92hd73xx_pin_nids[13] = { | |||
472 | 0x14, 0x22, 0x23 | 488 | 0x14, 0x22, 0x23 |
473 | }; | 489 | }; |
474 | 490 | ||
475 | static hda_nid_t stac92hd83xxx_pin_nids[14] = { | 491 | static hda_nid_t stac92hd83xxx_pin_nids[10] = { |
476 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | 492 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, |
477 | 0x0f, 0x10, 0x11, 0x12, 0x13, | 493 | 0x0f, 0x10, 0x11, 0x1f, 0x20, |
478 | 0x1d, 0x1e, 0x1f, 0x20 | 494 | }; |
495 | |||
496 | #define STAC92HD71BXX_NUM_PINS 13 | ||
497 | static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { | ||
498 | 0x0a, 0x0b, 0x0c, 0x0d, 0x00, | ||
499 | 0x00, 0x14, 0x18, 0x19, 0x1e, | ||
500 | 0x1f, 0x20, 0x27 | ||
479 | }; | 501 | }; |
480 | static hda_nid_t stac92hd71bxx_pin_nids[11] = { | 502 | static hda_nid_t stac92hd71bxx_pin_nids_6port[STAC92HD71BXX_NUM_PINS] = { |
481 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | 503 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, |
482 | 0x0f, 0x14, 0x18, 0x19, 0x1e, | 504 | 0x0f, 0x14, 0x18, 0x19, 0x1e, |
483 | 0x1f, | 505 | 0x1f, 0x20, 0x27 |
484 | }; | 506 | }; |
485 | 507 | ||
486 | static hda_nid_t stac927x_pin_nids[14] = { | 508 | static hda_nid_t stac927x_pin_nids[14] = { |
@@ -842,9 +864,9 @@ static struct hda_verb stac92hd73xx_10ch_core_init[] = { | |||
842 | }; | 864 | }; |
843 | 865 | ||
844 | static struct hda_verb stac92hd83xxx_core_init[] = { | 866 | static struct hda_verb stac92hd83xxx_core_init[] = { |
845 | { 0xa, AC_VERB_SET_CONNECT_SEL, 0x0}, | 867 | { 0xa, AC_VERB_SET_CONNECT_SEL, 0x1}, |
846 | { 0xb, AC_VERB_SET_CONNECT_SEL, 0x0}, | 868 | { 0xb, AC_VERB_SET_CONNECT_SEL, 0x1}, |
847 | { 0xd, AC_VERB_SET_CONNECT_SEL, 0x1}, | 869 | { 0xd, AC_VERB_SET_CONNECT_SEL, 0x0}, |
848 | 870 | ||
849 | /* power state controls amps */ | 871 | /* power state controls amps */ |
850 | { 0x01, AC_VERB_SET_EAPD, 1 << 2}, | 872 | { 0x01, AC_VERB_SET_EAPD, 1 << 2}, |
@@ -854,26 +876,25 @@ static struct hda_verb stac92hd83xxx_core_init[] = { | |||
854 | static struct hda_verb stac92hd71bxx_core_init[] = { | 876 | static struct hda_verb stac92hd71bxx_core_init[] = { |
855 | /* set master volume and direct control */ | 877 | /* set master volume and direct control */ |
856 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 878 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
857 | /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */ | ||
858 | { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
859 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
860 | { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
861 | {} | 879 | {} |
862 | }; | 880 | }; |
863 | 881 | ||
864 | #define HD_DISABLE_PORTF 2 | 882 | #define HD_DISABLE_PORTF 1 |
865 | static struct hda_verb stac92hd71bxx_analog_core_init[] = { | 883 | static struct hda_verb stac92hd71bxx_analog_core_init[] = { |
866 | /* start of config #1 */ | 884 | /* start of config #1 */ |
867 | 885 | ||
868 | /* connect port 0f to audio mixer */ | 886 | /* connect port 0f to audio mixer */ |
869 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, | 887 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, |
870 | /* unmute right and left channels for node 0x0f */ | ||
871 | { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
872 | /* start of config #2 */ | 888 | /* start of config #2 */ |
873 | 889 | ||
874 | /* set master volume and direct control */ | 890 | /* set master volume and direct control */ |
875 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 891 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
876 | /* unmute right and left channels for nodes 0x0a, 0xd */ | 892 | {} |
893 | }; | ||
894 | |||
895 | static struct hda_verb stac92hd71bxx_unmute_core_init[] = { | ||
896 | /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */ | ||
897 | { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
877 | { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 898 | { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
878 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 899 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
879 | {} | 900 | {} |
@@ -954,16 +975,6 @@ static struct hda_verb stac9205_core_init[] = { | |||
954 | .private_value = HDA_COMPOSE_AMP_VAL(nid, chs, idx, dir) \ | 975 | .private_value = HDA_COMPOSE_AMP_VAL(nid, chs, idx, dir) \ |
955 | } | 976 | } |
956 | 977 | ||
957 | #define STAC_INPUT_SOURCE(cnt) \ | ||
958 | { \ | ||
959 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
960 | .name = "Input Source", \ | ||
961 | .count = cnt, \ | ||
962 | .info = stac92xx_mux_enum_info, \ | ||
963 | .get = stac92xx_mux_enum_get, \ | ||
964 | .put = stac92xx_mux_enum_put, \ | ||
965 | } | ||
966 | |||
967 | #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \ | 978 | #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \ |
968 | { \ | 979 | { \ |
969 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 980 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
@@ -978,7 +989,6 @@ static struct hda_verb stac9205_core_init[] = { | |||
978 | static struct snd_kcontrol_new stac9200_mixer[] = { | 989 | static struct snd_kcontrol_new stac9200_mixer[] = { |
979 | HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), | 990 | HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), |
980 | HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), | 991 | HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), |
981 | STAC_INPUT_SOURCE(1), | ||
982 | HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), | 992 | HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), |
983 | HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), | 993 | HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), |
984 | { } /* end */ | 994 | { } /* end */ |
@@ -1094,7 +1104,6 @@ static struct snd_kcontrol_new stac92hd83xxx_mixer[] = { | |||
1094 | }; | 1104 | }; |
1095 | 1105 | ||
1096 | static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { | 1106 | static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { |
1097 | STAC_INPUT_SOURCE(2), | ||
1098 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2), | 1107 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2), |
1099 | 1108 | ||
1100 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), | 1109 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), |
@@ -1123,7 +1132,6 @@ static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { | |||
1123 | }; | 1132 | }; |
1124 | 1133 | ||
1125 | static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { | 1134 | static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { |
1126 | STAC_INPUT_SOURCE(2), | ||
1127 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2), | 1135 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2), |
1128 | 1136 | ||
1129 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), | 1137 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), |
@@ -1137,14 +1145,12 @@ static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { | |||
1137 | static struct snd_kcontrol_new stac925x_mixer[] = { | 1145 | static struct snd_kcontrol_new stac925x_mixer[] = { |
1138 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT), | 1146 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT), |
1139 | HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), | 1147 | HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), |
1140 | STAC_INPUT_SOURCE(1), | ||
1141 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), | 1148 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), |
1142 | HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT), | 1149 | HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT), |
1143 | { } /* end */ | 1150 | { } /* end */ |
1144 | }; | 1151 | }; |
1145 | 1152 | ||
1146 | static struct snd_kcontrol_new stac9205_mixer[] = { | 1153 | static struct snd_kcontrol_new stac9205_mixer[] = { |
1147 | STAC_INPUT_SOURCE(2), | ||
1148 | STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1), | 1154 | STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1), |
1149 | 1155 | ||
1150 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT), | 1156 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT), |
@@ -1157,7 +1163,6 @@ static struct snd_kcontrol_new stac9205_mixer[] = { | |||
1157 | 1163 | ||
1158 | /* This needs to be generated dynamically based on sequence */ | 1164 | /* This needs to be generated dynamically based on sequence */ |
1159 | static struct snd_kcontrol_new stac922x_mixer[] = { | 1165 | static struct snd_kcontrol_new stac922x_mixer[] = { |
1160 | STAC_INPUT_SOURCE(2), | ||
1161 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT), | 1166 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT), |
1162 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT), | 1167 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT), |
1163 | 1168 | ||
@@ -1168,7 +1173,6 @@ static struct snd_kcontrol_new stac922x_mixer[] = { | |||
1168 | 1173 | ||
1169 | 1174 | ||
1170 | static struct snd_kcontrol_new stac927x_mixer[] = { | 1175 | static struct snd_kcontrol_new stac927x_mixer[] = { |
1171 | STAC_INPUT_SOURCE(3), | ||
1172 | STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1), | 1176 | STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1), |
1173 | 1177 | ||
1174 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT), | 1178 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT), |
@@ -1294,6 +1298,8 @@ static int stac92xx_build_controls(struct hda_codec *codec) | |||
1294 | unsigned int vmaster_tlv[4]; | 1298 | unsigned int vmaster_tlv[4]; |
1295 | snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], | 1299 | snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], |
1296 | HDA_OUTPUT, vmaster_tlv); | 1300 | HDA_OUTPUT, vmaster_tlv); |
1301 | /* correct volume offset */ | ||
1302 | vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset; | ||
1297 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", | 1303 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", |
1298 | vmaster_tlv, slave_vols); | 1304 | vmaster_tlv, slave_vols); |
1299 | if (err < 0) | 1305 | if (err < 0) |
@@ -1490,6 +1496,7 @@ static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = { | |||
1490 | }; | 1496 | }; |
1491 | 1497 | ||
1492 | static const char *stac9200_models[STAC_9200_MODELS] = { | 1498 | static const char *stac9200_models[STAC_9200_MODELS] = { |
1499 | [STAC_AUTO] = "auto", | ||
1493 | [STAC_REF] = "ref", | 1500 | [STAC_REF] = "ref", |
1494 | [STAC_9200_OQO] = "oqo", | 1501 | [STAC_9200_OQO] = "oqo", |
1495 | [STAC_9200_DELL_D21] = "dell-d21", | 1502 | [STAC_9200_DELL_D21] = "dell-d21", |
@@ -1511,6 +1518,8 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = { | |||
1511 | /* SigmaTel reference board */ | 1518 | /* SigmaTel reference board */ |
1512 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1519 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1513 | "DFI LanParty", STAC_REF), | 1520 | "DFI LanParty", STAC_REF), |
1521 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, | ||
1522 | "DFI LanParty", STAC_REF), | ||
1514 | /* Dell laptops have BIOS problem */ | 1523 | /* Dell laptops have BIOS problem */ |
1515 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8, | 1524 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8, |
1516 | "unknown Dell", STAC_9200_DELL_D21), | 1525 | "unknown Dell", STAC_9200_DELL_D21), |
@@ -1633,6 +1642,7 @@ static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = { | |||
1633 | }; | 1642 | }; |
1634 | 1643 | ||
1635 | static const char *stac925x_models[STAC_925x_MODELS] = { | 1644 | static const char *stac925x_models[STAC_925x_MODELS] = { |
1645 | [STAC_925x_AUTO] = "auto", | ||
1636 | [STAC_REF] = "ref", | 1646 | [STAC_REF] = "ref", |
1637 | [STAC_M1] = "m1", | 1647 | [STAC_M1] = "m1", |
1638 | [STAC_M1_2] = "m1-2", | 1648 | [STAC_M1_2] = "m1-2", |
@@ -1660,6 +1670,7 @@ static struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = { | |||
1660 | static struct snd_pci_quirk stac925x_cfg_tbl[] = { | 1670 | static struct snd_pci_quirk stac925x_cfg_tbl[] = { |
1661 | /* SigmaTel reference board */ | 1671 | /* SigmaTel reference board */ |
1662 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), | 1672 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), |
1673 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF), | ||
1663 | SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF), | 1674 | SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF), |
1664 | 1675 | ||
1665 | /* Default table for unknown ID */ | 1676 | /* Default table for unknown ID */ |
@@ -1691,6 +1702,7 @@ static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { | |||
1691 | }; | 1702 | }; |
1692 | 1703 | ||
1693 | static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { | 1704 | static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { |
1705 | [STAC_92HD73XX_AUTO] = "auto", | ||
1694 | [STAC_92HD73XX_NO_JD] = "no-jd", | 1706 | [STAC_92HD73XX_NO_JD] = "no-jd", |
1695 | [STAC_92HD73XX_REF] = "ref", | 1707 | [STAC_92HD73XX_REF] = "ref", |
1696 | [STAC_DELL_M6_AMIC] = "dell-m6-amic", | 1708 | [STAC_DELL_M6_AMIC] = "dell-m6-amic", |
@@ -1703,6 +1715,8 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { | |||
1703 | /* SigmaTel reference board */ | 1715 | /* SigmaTel reference board */ |
1704 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1716 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1705 | "DFI LanParty", STAC_92HD73XX_REF), | 1717 | "DFI LanParty", STAC_92HD73XX_REF), |
1718 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, | ||
1719 | "DFI LanParty", STAC_92HD73XX_REF), | ||
1706 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254, | 1720 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254, |
1707 | "Dell Studio 1535", STAC_DELL_M6_DMIC), | 1721 | "Dell Studio 1535", STAC_DELL_M6_DMIC), |
1708 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255, | 1722 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255, |
@@ -1726,52 +1740,68 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { | |||
1726 | {} /* terminator */ | 1740 | {} /* terminator */ |
1727 | }; | 1741 | }; |
1728 | 1742 | ||
1729 | static unsigned int ref92hd83xxx_pin_configs[14] = { | 1743 | static unsigned int ref92hd83xxx_pin_configs[10] = { |
1730 | 0x02214030, 0x02211010, 0x02a19020, 0x02170130, | 1744 | 0x02214030, 0x02211010, 0x02a19020, 0x02170130, |
1731 | 0x01014050, 0x01819040, 0x01014020, 0x90a3014e, | 1745 | 0x01014050, 0x01819040, 0x01014020, 0x90a3014e, |
1732 | 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x40f000f0, | ||
1733 | 0x01451160, 0x98560170, | 1746 | 0x01451160, 0x98560170, |
1734 | }; | 1747 | }; |
1735 | 1748 | ||
1749 | static unsigned int dell_s14_pin_configs[10] = { | ||
1750 | 0x02214030, 0x02211010, 0x02a19020, 0x01014050, | ||
1751 | 0x40f000f0, 0x01819040, 0x40f000f0, 0x90a60160, | ||
1752 | 0x40f000f0, 0x40f000f0, | ||
1753 | }; | ||
1754 | |||
1736 | static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { | 1755 | static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { |
1737 | [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, | 1756 | [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, |
1738 | [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, | 1757 | [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, |
1758 | [STAC_DELL_S14] = dell_s14_pin_configs, | ||
1739 | }; | 1759 | }; |
1740 | 1760 | ||
1741 | static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { | 1761 | static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { |
1762 | [STAC_92HD83XXX_AUTO] = "auto", | ||
1742 | [STAC_92HD83XXX_REF] = "ref", | 1763 | [STAC_92HD83XXX_REF] = "ref", |
1743 | [STAC_92HD83XXX_PWR_REF] = "mic-ref", | 1764 | [STAC_92HD83XXX_PWR_REF] = "mic-ref", |
1765 | [STAC_DELL_S14] = "dell-s14", | ||
1744 | }; | 1766 | }; |
1745 | 1767 | ||
1746 | static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { | 1768 | static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { |
1747 | /* SigmaTel reference board */ | 1769 | /* SigmaTel reference board */ |
1748 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1770 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1749 | "DFI LanParty", STAC_92HD83XXX_REF), | 1771 | "DFI LanParty", STAC_92HD83XXX_REF), |
1772 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, | ||
1773 | "DFI LanParty", STAC_92HD83XXX_REF), | ||
1774 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba, | ||
1775 | "unknown Dell", STAC_DELL_S14), | ||
1750 | {} /* terminator */ | 1776 | {} /* terminator */ |
1751 | }; | 1777 | }; |
1752 | 1778 | ||
1753 | static unsigned int ref92hd71bxx_pin_configs[11] = { | 1779 | static unsigned int ref92hd71bxx_pin_configs[STAC92HD71BXX_NUM_PINS] = { |
1754 | 0x02214030, 0x02a19040, 0x01a19020, 0x01014010, | 1780 | 0x02214030, 0x02a19040, 0x01a19020, 0x01014010, |
1755 | 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0, | 1781 | 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0, |
1756 | 0x90a000f0, 0x01452050, 0x01452050, | 1782 | 0x90a000f0, 0x01452050, 0x01452050, 0x00000000, |
1783 | 0x00000000 | ||
1757 | }; | 1784 | }; |
1758 | 1785 | ||
1759 | static unsigned int dell_m4_1_pin_configs[11] = { | 1786 | static unsigned int dell_m4_1_pin_configs[STAC92HD71BXX_NUM_PINS] = { |
1760 | 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, | 1787 | 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, |
1761 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, | 1788 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, |
1762 | 0x40f000f0, 0x4f0000f0, 0x4f0000f0, | 1789 | 0x40f000f0, 0x4f0000f0, 0x4f0000f0, 0x00000000, |
1790 | 0x00000000 | ||
1763 | }; | 1791 | }; |
1764 | 1792 | ||
1765 | static unsigned int dell_m4_2_pin_configs[11] = { | 1793 | static unsigned int dell_m4_2_pin_configs[STAC92HD71BXX_NUM_PINS] = { |
1766 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, | 1794 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, |
1767 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, | 1795 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, |
1768 | 0x40f000f0, 0x044413b0, 0x044413b0, | 1796 | 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000, |
1797 | 0x00000000 | ||
1769 | }; | 1798 | }; |
1770 | 1799 | ||
1771 | static unsigned int dell_m4_3_pin_configs[11] = { | 1800 | static unsigned int dell_m4_3_pin_configs[STAC92HD71BXX_NUM_PINS] = { |
1772 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, | 1801 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, |
1773 | 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a000f0, | 1802 | 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a000f0, |
1774 | 0x40f000f0, 0x044413b0, 0x044413b0, | 1803 | 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000, |
1804 | 0x00000000 | ||
1775 | }; | 1805 | }; |
1776 | 1806 | ||
1777 | static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { | 1807 | static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { |
@@ -1784,6 +1814,7 @@ static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { | |||
1784 | }; | 1814 | }; |
1785 | 1815 | ||
1786 | static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { | 1816 | static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { |
1817 | [STAC_92HD71BXX_AUTO] = "auto", | ||
1787 | [STAC_92HD71BXX_REF] = "ref", | 1818 | [STAC_92HD71BXX_REF] = "ref", |
1788 | [STAC_DELL_M4_1] = "dell-m4-1", | 1819 | [STAC_DELL_M4_1] = "dell-m4-1", |
1789 | [STAC_DELL_M4_2] = "dell-m4-2", | 1820 | [STAC_DELL_M4_2] = "dell-m4-2", |
@@ -1796,20 +1827,14 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { | |||
1796 | /* SigmaTel reference board */ | 1827 | /* SigmaTel reference board */ |
1797 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1828 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1798 | "DFI LanParty", STAC_92HD71BXX_REF), | 1829 | "DFI LanParty", STAC_92HD71BXX_REF), |
1799 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f2, | 1830 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, |
1800 | "HP dv5", STAC_HP_M4), | 1831 | "DFI LanParty", STAC_92HD71BXX_REF), |
1801 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4, | 1832 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0, |
1802 | "HP dv7", STAC_HP_DV5), | 1833 | "HP dv4-7", STAC_HP_DV5), |
1803 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f7, | 1834 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600, |
1804 | "HP dv4", STAC_HP_DV5), | 1835 | "HP dv4-7", STAC_HP_DV5), |
1805 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fc, | ||
1806 | "HP dv7", STAC_HP_M4), | ||
1807 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3600, | ||
1808 | "HP dv5", STAC_HP_DV5), | ||
1809 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3603, | ||
1810 | "HP dv5", STAC_HP_DV5), | ||
1811 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, | 1836 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, |
1812 | "unknown HP", STAC_HP_M4), | 1837 | "HP mini 1000", STAC_HP_M4), |
1813 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, | 1838 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, |
1814 | "unknown Dell", STAC_DELL_M4_1), | 1839 | "unknown Dell", STAC_DELL_M4_1), |
1815 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234, | 1840 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234, |
@@ -1961,6 +1986,7 @@ static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { | |||
1961 | }; | 1986 | }; |
1962 | 1987 | ||
1963 | static const char *stac922x_models[STAC_922X_MODELS] = { | 1988 | static const char *stac922x_models[STAC_922X_MODELS] = { |
1989 | [STAC_922X_AUTO] = "auto", | ||
1964 | [STAC_D945_REF] = "ref", | 1990 | [STAC_D945_REF] = "ref", |
1965 | [STAC_D945GTP5] = "5stack", | 1991 | [STAC_D945GTP5] = "5stack", |
1966 | [STAC_D945GTP3] = "3stack", | 1992 | [STAC_D945GTP3] = "3stack", |
@@ -1988,6 +2014,8 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = { | |||
1988 | /* SigmaTel reference board */ | 2014 | /* SigmaTel reference board */ |
1989 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 2015 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1990 | "DFI LanParty", STAC_D945_REF), | 2016 | "DFI LanParty", STAC_D945_REF), |
2017 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, | ||
2018 | "DFI LanParty", STAC_D945_REF), | ||
1991 | /* Intel 945G based systems */ | 2019 | /* Intel 945G based systems */ |
1992 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101, | 2020 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101, |
1993 | "Intel D945G", STAC_D945GTP3), | 2021 | "Intel D945G", STAC_D945GTP3), |
@@ -2041,6 +2069,9 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = { | |||
2041 | "Intel D945P", STAC_D945GTP3), | 2069 | "Intel D945P", STAC_D945GTP3), |
2042 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707, | 2070 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707, |
2043 | "Intel D945P", STAC_D945GTP5), | 2071 | "Intel D945P", STAC_D945GTP5), |
2072 | /* other intel */ | ||
2073 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0204, | ||
2074 | "Intel D945", STAC_D945_REF), | ||
2044 | /* other systems */ | 2075 | /* other systems */ |
2045 | /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */ | 2076 | /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */ |
2046 | SND_PCI_QUIRK(0x8384, 0x7680, | 2077 | SND_PCI_QUIRK(0x8384, 0x7680, |
@@ -2065,31 +2096,7 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = { | |||
2065 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7, | 2096 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7, |
2066 | "Dell XPS M1210", STAC_922X_DELL_M82), | 2097 | "Dell XPS M1210", STAC_922X_DELL_M82), |
2067 | /* ECS/PC Chips boards */ | 2098 | /* ECS/PC Chips boards */ |
2068 | SND_PCI_QUIRK(0x1019, 0x2144, | 2099 | SND_PCI_QUIRK_MASK(0x1019, 0xf000, 0x2000, |
2069 | "ECS/PC chips", STAC_ECS_202), | ||
2070 | SND_PCI_QUIRK(0x1019, 0x2608, | ||
2071 | "ECS/PC chips", STAC_ECS_202), | ||
2072 | SND_PCI_QUIRK(0x1019, 0x2633, | ||
2073 | "ECS/PC chips P17G/1333", STAC_ECS_202), | ||
2074 | SND_PCI_QUIRK(0x1019, 0x2811, | ||
2075 | "ECS/PC chips", STAC_ECS_202), | ||
2076 | SND_PCI_QUIRK(0x1019, 0x2812, | ||
2077 | "ECS/PC chips", STAC_ECS_202), | ||
2078 | SND_PCI_QUIRK(0x1019, 0x2813, | ||
2079 | "ECS/PC chips", STAC_ECS_202), | ||
2080 | SND_PCI_QUIRK(0x1019, 0x2814, | ||
2081 | "ECS/PC chips", STAC_ECS_202), | ||
2082 | SND_PCI_QUIRK(0x1019, 0x2815, | ||
2083 | "ECS/PC chips", STAC_ECS_202), | ||
2084 | SND_PCI_QUIRK(0x1019, 0x2816, | ||
2085 | "ECS/PC chips", STAC_ECS_202), | ||
2086 | SND_PCI_QUIRK(0x1019, 0x2817, | ||
2087 | "ECS/PC chips", STAC_ECS_202), | ||
2088 | SND_PCI_QUIRK(0x1019, 0x2818, | ||
2089 | "ECS/PC chips", STAC_ECS_202), | ||
2090 | SND_PCI_QUIRK(0x1019, 0x2819, | ||
2091 | "ECS/PC chips", STAC_ECS_202), | ||
2092 | SND_PCI_QUIRK(0x1019, 0x2820, | ||
2093 | "ECS/PC chips", STAC_ECS_202), | 2100 | "ECS/PC chips", STAC_ECS_202), |
2094 | {} /* terminator */ | 2101 | {} /* terminator */ |
2095 | }; | 2102 | }; |
@@ -2132,6 +2139,7 @@ static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { | |||
2132 | }; | 2139 | }; |
2133 | 2140 | ||
2134 | static const char *stac927x_models[STAC_927X_MODELS] = { | 2141 | static const char *stac927x_models[STAC_927X_MODELS] = { |
2142 | [STAC_927X_AUTO] = "auto", | ||
2135 | [STAC_D965_REF_NO_JD] = "ref-no-jd", | 2143 | [STAC_D965_REF_NO_JD] = "ref-no-jd", |
2136 | [STAC_D965_REF] = "ref", | 2144 | [STAC_D965_REF] = "ref", |
2137 | [STAC_D965_3ST] = "3stack", | 2145 | [STAC_D965_3ST] = "3stack", |
@@ -2144,26 +2152,16 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = { | |||
2144 | /* SigmaTel reference board */ | 2152 | /* SigmaTel reference board */ |
2145 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 2153 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
2146 | "DFI LanParty", STAC_D965_REF), | 2154 | "DFI LanParty", STAC_D965_REF), |
2155 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, | ||
2156 | "DFI LanParty", STAC_D965_REF), | ||
2147 | /* Intel 946 based systems */ | 2157 | /* Intel 946 based systems */ |
2148 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST), | 2158 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST), |
2149 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST), | 2159 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST), |
2150 | /* 965 based 3 stack systems */ | 2160 | /* 965 based 3 stack systems */ |
2151 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2116, "Intel D965", STAC_D965_3ST), | 2161 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2100, |
2152 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2115, "Intel D965", STAC_D965_3ST), | 2162 | "Intel D965", STAC_D965_3ST), |
2153 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2114, "Intel D965", STAC_D965_3ST), | 2163 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2000, |
2154 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2113, "Intel D965", STAC_D965_3ST), | 2164 | "Intel D965", STAC_D965_3ST), |
2155 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2112, "Intel D965", STAC_D965_3ST), | ||
2156 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2111, "Intel D965", STAC_D965_3ST), | ||
2157 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2110, "Intel D965", STAC_D965_3ST), | ||
2158 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2009, "Intel D965", STAC_D965_3ST), | ||
2159 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2008, "Intel D965", STAC_D965_3ST), | ||
2160 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2007, "Intel D965", STAC_D965_3ST), | ||
2161 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2006, "Intel D965", STAC_D965_3ST), | ||
2162 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2005, "Intel D965", STAC_D965_3ST), | ||
2163 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2004, "Intel D965", STAC_D965_3ST), | ||
2164 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2003, "Intel D965", STAC_D965_3ST), | ||
2165 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2002, "Intel D965", STAC_D965_3ST), | ||
2166 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2001, "Intel D965", STAC_D965_3ST), | ||
2167 | /* Dell 3 stack systems */ | 2165 | /* Dell 3 stack systems */ |
2168 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_3ST), | 2166 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_3ST), |
2169 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST), | 2167 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST), |
@@ -2179,15 +2177,10 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = { | |||
2179 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS), | 2177 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS), |
2180 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_DELL_BIOS), | 2178 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_DELL_BIOS), |
2181 | /* 965 based 5 stack systems */ | 2179 | /* 965 based 5 stack systems */ |
2182 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2301, "Intel D965", STAC_D965_5ST), | 2180 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2300, |
2183 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2302, "Intel D965", STAC_D965_5ST), | 2181 | "Intel D965", STAC_D965_5ST), |
2184 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2303, "Intel D965", STAC_D965_5ST), | 2182 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2500, |
2185 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2304, "Intel D965", STAC_D965_5ST), | 2183 | "Intel D965", STAC_D965_5ST), |
2186 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2305, "Intel D965", STAC_D965_5ST), | ||
2187 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2501, "Intel D965", STAC_D965_5ST), | ||
2188 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2502, "Intel D965", STAC_D965_5ST), | ||
2189 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2503, "Intel D965", STAC_D965_5ST), | ||
2190 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2504, "Intel D965", STAC_D965_5ST), | ||
2191 | {} /* terminator */ | 2184 | {} /* terminator */ |
2192 | }; | 2185 | }; |
2193 | 2186 | ||
@@ -2240,19 +2233,25 @@ static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { | |||
2240 | [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs, | 2233 | [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs, |
2241 | [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs, | 2234 | [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs, |
2242 | [STAC_9205_DELL_M44] = dell_9205_m44_pin_configs, | 2235 | [STAC_9205_DELL_M44] = dell_9205_m44_pin_configs, |
2236 | [STAC_9205_EAPD] = NULL, | ||
2243 | }; | 2237 | }; |
2244 | 2238 | ||
2245 | static const char *stac9205_models[STAC_9205_MODELS] = { | 2239 | static const char *stac9205_models[STAC_9205_MODELS] = { |
2240 | [STAC_9205_AUTO] = "auto", | ||
2246 | [STAC_9205_REF] = "ref", | 2241 | [STAC_9205_REF] = "ref", |
2247 | [STAC_9205_DELL_M42] = "dell-m42", | 2242 | [STAC_9205_DELL_M42] = "dell-m42", |
2248 | [STAC_9205_DELL_M43] = "dell-m43", | 2243 | [STAC_9205_DELL_M43] = "dell-m43", |
2249 | [STAC_9205_DELL_M44] = "dell-m44", | 2244 | [STAC_9205_DELL_M44] = "dell-m44", |
2245 | [STAC_9205_EAPD] = "eapd", | ||
2250 | }; | 2246 | }; |
2251 | 2247 | ||
2252 | static struct snd_pci_quirk stac9205_cfg_tbl[] = { | 2248 | static struct snd_pci_quirk stac9205_cfg_tbl[] = { |
2253 | /* SigmaTel reference board */ | 2249 | /* SigmaTel reference board */ |
2254 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 2250 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
2255 | "DFI LanParty", STAC_9205_REF), | 2251 | "DFI LanParty", STAC_9205_REF), |
2252 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, | ||
2253 | "DFI LanParty", STAC_9205_REF), | ||
2254 | /* Dell */ | ||
2256 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1, | 2255 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1, |
2257 | "unknown Dell", STAC_9205_DELL_M42), | 2256 | "unknown Dell", STAC_9205_DELL_M42), |
2258 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2, | 2257 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2, |
@@ -2283,101 +2282,24 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { | |||
2283 | "Dell Inspiron", STAC_9205_DELL_M44), | 2282 | "Dell Inspiron", STAC_9205_DELL_M44), |
2284 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228, | 2283 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228, |
2285 | "Dell Vostro 1500", STAC_9205_DELL_M42), | 2284 | "Dell Vostro 1500", STAC_9205_DELL_M42), |
2285 | /* Gateway */ | ||
2286 | SND_PCI_QUIRK(0x107b, 0x0565, "Gateway T1616", STAC_9205_EAPD), | ||
2286 | {} /* terminator */ | 2287 | {} /* terminator */ |
2287 | }; | 2288 | }; |
2288 | 2289 | ||
2289 | static int stac92xx_save_bios_config_regs(struct hda_codec *codec) | 2290 | static void stac92xx_set_config_regs(struct hda_codec *codec, |
2290 | { | 2291 | unsigned int *pincfgs) |
2291 | int i; | ||
2292 | struct sigmatel_spec *spec = codec->spec; | ||
2293 | |||
2294 | kfree(spec->pin_configs); | ||
2295 | spec->pin_configs = kcalloc(spec->num_pins, sizeof(*spec->pin_configs), | ||
2296 | GFP_KERNEL); | ||
2297 | if (!spec->pin_configs) | ||
2298 | return -ENOMEM; | ||
2299 | |||
2300 | for (i = 0; i < spec->num_pins; i++) { | ||
2301 | hda_nid_t nid = spec->pin_nids[i]; | ||
2302 | unsigned int pin_cfg; | ||
2303 | |||
2304 | pin_cfg = snd_hda_codec_read(codec, nid, 0, | ||
2305 | AC_VERB_GET_CONFIG_DEFAULT, 0x00); | ||
2306 | snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x bios pin config %8.8x\n", | ||
2307 | nid, pin_cfg); | ||
2308 | spec->pin_configs[i] = pin_cfg; | ||
2309 | } | ||
2310 | |||
2311 | return 0; | ||
2312 | } | ||
2313 | |||
2314 | static void stac92xx_set_config_reg(struct hda_codec *codec, | ||
2315 | hda_nid_t pin_nid, unsigned int pin_config) | ||
2316 | { | ||
2317 | int i; | ||
2318 | snd_hda_codec_write(codec, pin_nid, 0, | ||
2319 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, | ||
2320 | pin_config & 0x000000ff); | ||
2321 | snd_hda_codec_write(codec, pin_nid, 0, | ||
2322 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, | ||
2323 | (pin_config & 0x0000ff00) >> 8); | ||
2324 | snd_hda_codec_write(codec, pin_nid, 0, | ||
2325 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, | ||
2326 | (pin_config & 0x00ff0000) >> 16); | ||
2327 | snd_hda_codec_write(codec, pin_nid, 0, | ||
2328 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, | ||
2329 | pin_config >> 24); | ||
2330 | i = snd_hda_codec_read(codec, pin_nid, 0, | ||
2331 | AC_VERB_GET_CONFIG_DEFAULT, | ||
2332 | 0x00); | ||
2333 | snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n", | ||
2334 | pin_nid, i); | ||
2335 | } | ||
2336 | |||
2337 | static void stac92xx_set_config_regs(struct hda_codec *codec) | ||
2338 | { | 2292 | { |
2339 | int i; | 2293 | int i; |
2340 | struct sigmatel_spec *spec = codec->spec; | 2294 | struct sigmatel_spec *spec = codec->spec; |
2341 | 2295 | ||
2342 | if (!spec->pin_configs) | 2296 | if (!pincfgs) |
2343 | return; | 2297 | return; |
2344 | 2298 | ||
2345 | for (i = 0; i < spec->num_pins; i++) | 2299 | for (i = 0; i < spec->num_pins; i++) |
2346 | stac92xx_set_config_reg(codec, spec->pin_nids[i], | 2300 | if (spec->pin_nids[i] && pincfgs[i]) |
2347 | spec->pin_configs[i]); | 2301 | snd_hda_codec_set_pincfg(codec, spec->pin_nids[i], |
2348 | } | 2302 | pincfgs[i]); |
2349 | |||
2350 | static int stac_save_pin_cfgs(struct hda_codec *codec, unsigned int *pins) | ||
2351 | { | ||
2352 | struct sigmatel_spec *spec = codec->spec; | ||
2353 | |||
2354 | if (!pins) | ||
2355 | return stac92xx_save_bios_config_regs(codec); | ||
2356 | |||
2357 | kfree(spec->pin_configs); | ||
2358 | spec->pin_configs = kmemdup(pins, | ||
2359 | spec->num_pins * sizeof(*pins), | ||
2360 | GFP_KERNEL); | ||
2361 | if (!spec->pin_configs) | ||
2362 | return -ENOMEM; | ||
2363 | |||
2364 | stac92xx_set_config_regs(codec); | ||
2365 | return 0; | ||
2366 | } | ||
2367 | |||
2368 | static void stac_change_pin_config(struct hda_codec *codec, hda_nid_t nid, | ||
2369 | unsigned int cfg) | ||
2370 | { | ||
2371 | struct sigmatel_spec *spec = codec->spec; | ||
2372 | int i; | ||
2373 | |||
2374 | for (i = 0; i < spec->num_pins; i++) { | ||
2375 | if (spec->pin_nids[i] == nid) { | ||
2376 | spec->pin_configs[i] = cfg; | ||
2377 | stac92xx_set_config_reg(codec, nid, cfg); | ||
2378 | break; | ||
2379 | } | ||
2380 | } | ||
2381 | } | 2303 | } |
2382 | 2304 | ||
2383 | /* | 2305 | /* |
@@ -2567,7 +2489,7 @@ static int stac92xx_build_pcms(struct hda_codec *codec) | |||
2567 | codec->num_pcms++; | 2489 | codec->num_pcms++; |
2568 | info++; | 2490 | info++; |
2569 | info->name = "STAC92xx Digital"; | 2491 | info->name = "STAC92xx Digital"; |
2570 | info->pcm_type = HDA_PCM_TYPE_SPDIF; | 2492 | info->pcm_type = spec->autocfg.dig_out_type[0]; |
2571 | if (spec->multiout.dig_out_nid) { | 2493 | if (spec->multiout.dig_out_nid) { |
2572 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback; | 2494 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback; |
2573 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; | 2495 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; |
@@ -2759,22 +2681,37 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = { | |||
2759 | }; | 2681 | }; |
2760 | 2682 | ||
2761 | /* add dynamic controls */ | 2683 | /* add dynamic controls */ |
2762 | static int stac92xx_add_control_temp(struct sigmatel_spec *spec, | 2684 | static struct snd_kcontrol_new * |
2763 | struct snd_kcontrol_new *ktemp, | 2685 | stac_control_new(struct sigmatel_spec *spec, |
2764 | int idx, const char *name, | 2686 | struct snd_kcontrol_new *ktemp, |
2765 | unsigned long val) | 2687 | const char *name) |
2766 | { | 2688 | { |
2767 | struct snd_kcontrol_new *knew; | 2689 | struct snd_kcontrol_new *knew; |
2768 | 2690 | ||
2769 | snd_array_init(&spec->kctls, sizeof(*knew), 32); | 2691 | snd_array_init(&spec->kctls, sizeof(*knew), 32); |
2770 | knew = snd_array_new(&spec->kctls); | 2692 | knew = snd_array_new(&spec->kctls); |
2771 | if (!knew) | 2693 | if (!knew) |
2772 | return -ENOMEM; | 2694 | return NULL; |
2773 | *knew = *ktemp; | 2695 | *knew = *ktemp; |
2774 | knew->index = idx; | ||
2775 | knew->name = kstrdup(name, GFP_KERNEL); | 2696 | knew->name = kstrdup(name, GFP_KERNEL); |
2776 | if (!knew->name) | 2697 | if (!knew->name) { |
2698 | /* roolback */ | ||
2699 | memset(knew, 0, sizeof(*knew)); | ||
2700 | spec->kctls.alloced--; | ||
2701 | return NULL; | ||
2702 | } | ||
2703 | return knew; | ||
2704 | } | ||
2705 | |||
2706 | static int stac92xx_add_control_temp(struct sigmatel_spec *spec, | ||
2707 | struct snd_kcontrol_new *ktemp, | ||
2708 | int idx, const char *name, | ||
2709 | unsigned long val) | ||
2710 | { | ||
2711 | struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name); | ||
2712 | if (!knew) | ||
2777 | return -ENOMEM; | 2713 | return -ENOMEM; |
2714 | knew->index = idx; | ||
2778 | knew->private_value = val; | 2715 | knew->private_value = val; |
2779 | return 0; | 2716 | return 0; |
2780 | } | 2717 | } |
@@ -2796,6 +2733,29 @@ static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type, | |||
2796 | return stac92xx_add_control_idx(spec, type, 0, name, val); | 2733 | return stac92xx_add_control_idx(spec, type, 0, name, val); |
2797 | } | 2734 | } |
2798 | 2735 | ||
2736 | static struct snd_kcontrol_new stac_input_src_temp = { | ||
2737 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2738 | .name = "Input Source", | ||
2739 | .info = stac92xx_mux_enum_info, | ||
2740 | .get = stac92xx_mux_enum_get, | ||
2741 | .put = stac92xx_mux_enum_put, | ||
2742 | }; | ||
2743 | |||
2744 | static int stac92xx_add_input_source(struct sigmatel_spec *spec) | ||
2745 | { | ||
2746 | struct snd_kcontrol_new *knew; | ||
2747 | struct hda_input_mux *imux = &spec->private_imux; | ||
2748 | |||
2749 | if (!spec->num_adcs || imux->num_items <= 1) | ||
2750 | return 0; /* no need for input source control */ | ||
2751 | knew = stac_control_new(spec, &stac_input_src_temp, | ||
2752 | stac_input_src_temp.name); | ||
2753 | if (!knew) | ||
2754 | return -ENOMEM; | ||
2755 | knew->count = spec->num_adcs; | ||
2756 | return 0; | ||
2757 | } | ||
2758 | |||
2799 | /* check whether the line-input can be used as line-out */ | 2759 | /* check whether the line-input can be used as line-out */ |
2800 | static hda_nid_t check_line_out_switch(struct hda_codec *codec) | 2760 | static hda_nid_t check_line_out_switch(struct hda_codec *codec) |
2801 | { | 2761 | { |
@@ -2826,8 +2786,7 @@ static hda_nid_t check_mic_out_switch(struct hda_codec *codec) | |||
2826 | mic_pin = AUTO_PIN_MIC; | 2786 | mic_pin = AUTO_PIN_MIC; |
2827 | for (;;) { | 2787 | for (;;) { |
2828 | hda_nid_t nid = cfg->input_pins[mic_pin]; | 2788 | hda_nid_t nid = cfg->input_pins[mic_pin]; |
2829 | def_conf = snd_hda_codec_read(codec, nid, 0, | 2789 | def_conf = snd_hda_codec_get_pincfg(codec, nid); |
2830 | AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
2831 | /* some laptops have an internal analog microphone | 2790 | /* some laptops have an internal analog microphone |
2832 | * which can't be used as a output */ | 2791 | * which can't be used as a output */ |
2833 | if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) { | 2792 | if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) { |
@@ -2994,14 +2953,34 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec) | |||
2994 | } | 2953 | } |
2995 | 2954 | ||
2996 | /* create volume control/switch for the given prefx type */ | 2955 | /* create volume control/switch for the given prefx type */ |
2997 | static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_t nid, int chs) | 2956 | static int create_controls(struct hda_codec *codec, const char *pfx, |
2957 | hda_nid_t nid, int chs) | ||
2998 | { | 2958 | { |
2959 | struct sigmatel_spec *spec = codec->spec; | ||
2999 | char name[32]; | 2960 | char name[32]; |
3000 | int err; | 2961 | int err; |
3001 | 2962 | ||
2963 | if (!spec->check_volume_offset) { | ||
2964 | unsigned int caps, step, nums, db_scale; | ||
2965 | caps = query_amp_caps(codec, nid, HDA_OUTPUT); | ||
2966 | step = (caps & AC_AMPCAP_STEP_SIZE) >> | ||
2967 | AC_AMPCAP_STEP_SIZE_SHIFT; | ||
2968 | step = (step + 1) * 25; /* in .01dB unit */ | ||
2969 | nums = (caps & AC_AMPCAP_NUM_STEPS) >> | ||
2970 | AC_AMPCAP_NUM_STEPS_SHIFT; | ||
2971 | db_scale = nums * step; | ||
2972 | /* if dB scale is over -64dB, and finer enough, | ||
2973 | * let's reduce it to half | ||
2974 | */ | ||
2975 | if (db_scale > 6400 && nums >= 0x1f) | ||
2976 | spec->volume_offset = nums / 2; | ||
2977 | spec->check_volume_offset = 1; | ||
2978 | } | ||
2979 | |||
3002 | sprintf(name, "%s Playback Volume", pfx); | 2980 | sprintf(name, "%s Playback Volume", pfx); |
3003 | err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name, | 2981 | err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name, |
3004 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); | 2982 | HDA_COMPOSE_AMP_VAL_OFS(nid, chs, 0, HDA_OUTPUT, |
2983 | spec->volume_offset)); | ||
3005 | if (err < 0) | 2984 | if (err < 0) |
3006 | return err; | 2985 | return err; |
3007 | sprintf(name, "%s Playback Switch", pfx); | 2986 | sprintf(name, "%s Playback Switch", pfx); |
@@ -3067,10 +3046,10 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
3067 | nid = spec->multiout.dac_nids[i]; | 3046 | nid = spec->multiout.dac_nids[i]; |
3068 | if (i == 2) { | 3047 | if (i == 2) { |
3069 | /* Center/LFE */ | 3048 | /* Center/LFE */ |
3070 | err = create_controls(spec, "Center", nid, 1); | 3049 | err = create_controls(codec, "Center", nid, 1); |
3071 | if (err < 0) | 3050 | if (err < 0) |
3072 | return err; | 3051 | return err; |
3073 | err = create_controls(spec, "LFE", nid, 2); | 3052 | err = create_controls(codec, "LFE", nid, 2); |
3074 | if (err < 0) | 3053 | if (err < 0) |
3075 | return err; | 3054 | return err; |
3076 | 3055 | ||
@@ -3098,7 +3077,7 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
3098 | break; | 3077 | break; |
3099 | } | 3078 | } |
3100 | } | 3079 | } |
3101 | err = create_controls(spec, name, nid, 3); | 3080 | err = create_controls(codec, name, nid, 3); |
3102 | if (err < 0) | 3081 | if (err < 0) |
3103 | return err; | 3082 | return err; |
3104 | } | 3083 | } |
@@ -3153,7 +3132,7 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, | |||
3153 | nid = spec->hp_dacs[i]; | 3132 | nid = spec->hp_dacs[i]; |
3154 | if (!nid) | 3133 | if (!nid) |
3155 | continue; | 3134 | continue; |
3156 | err = create_controls(spec, pfxs[nums++], nid, 3); | 3135 | err = create_controls(codec, pfxs[nums++], nid, 3); |
3157 | if (err < 0) | 3136 | if (err < 0) |
3158 | return err; | 3137 | return err; |
3159 | } | 3138 | } |
@@ -3167,7 +3146,7 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, | |||
3167 | nid = spec->speaker_dacs[i]; | 3146 | nid = spec->speaker_dacs[i]; |
3168 | if (!nid) | 3147 | if (!nid) |
3169 | continue; | 3148 | continue; |
3170 | err = create_controls(spec, pfxs[nums++], nid, 3); | 3149 | err = create_controls(codec, pfxs[nums++], nid, 3); |
3171 | if (err < 0) | 3150 | if (err < 0) |
3172 | return err; | 3151 | return err; |
3173 | } | 3152 | } |
@@ -3379,11 +3358,7 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | |||
3379 | unsigned int wcaps; | 3358 | unsigned int wcaps; |
3380 | unsigned int def_conf; | 3359 | unsigned int def_conf; |
3381 | 3360 | ||
3382 | def_conf = snd_hda_codec_read(codec, | 3361 | def_conf = snd_hda_codec_get_pincfg(codec, spec->dmic_nids[i]); |
3383 | spec->dmic_nids[i], | ||
3384 | 0, | ||
3385 | AC_VERB_GET_CONFIG_DEFAULT, | ||
3386 | 0); | ||
3387 | if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) | 3362 | if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) |
3388 | continue; | 3363 | continue; |
3389 | 3364 | ||
@@ -3661,11 +3636,15 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
3661 | return err; | 3636 | return err; |
3662 | } | 3637 | } |
3663 | 3638 | ||
3639 | err = stac92xx_add_input_source(spec); | ||
3640 | if (err < 0) | ||
3641 | return err; | ||
3642 | |||
3664 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 3643 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
3665 | if (spec->multiout.max_channels > 2) | 3644 | if (spec->multiout.max_channels > 2) |
3666 | spec->surr_switch = 1; | 3645 | spec->surr_switch = 1; |
3667 | 3646 | ||
3668 | if (spec->autocfg.dig_out_pin) | 3647 | if (spec->autocfg.dig_outs) |
3669 | spec->multiout.dig_out_nid = dig_out; | 3648 | spec->multiout.dig_out_nid = dig_out; |
3670 | if (dig_in && spec->autocfg.dig_in_pin) | 3649 | if (dig_in && spec->autocfg.dig_in_pin) |
3671 | spec->dig_in_nid = dig_in; | 3650 | spec->dig_in_nid = dig_in; |
@@ -3728,9 +3707,7 @@ static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec, | |||
3728 | for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) { | 3707 | for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) { |
3729 | hda_nid_t pin = spec->autocfg.line_out_pins[i]; | 3708 | hda_nid_t pin = spec->autocfg.line_out_pins[i]; |
3730 | unsigned int defcfg; | 3709 | unsigned int defcfg; |
3731 | defcfg = snd_hda_codec_read(codec, pin, 0, | 3710 | defcfg = snd_hda_codec_get_pincfg(codec, pin); |
3732 | AC_VERB_GET_CONFIG_DEFAULT, | ||
3733 | 0x00); | ||
3734 | if (get_defcfg_device(defcfg) == AC_JACK_SPEAKER) { | 3711 | if (get_defcfg_device(defcfg) == AC_JACK_SPEAKER) { |
3735 | unsigned int wcaps = get_wcaps(codec, pin); | 3712 | unsigned int wcaps = get_wcaps(codec, pin); |
3736 | wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP); | 3713 | wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP); |
@@ -3743,7 +3720,7 @@ static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec, | |||
3743 | } | 3720 | } |
3744 | 3721 | ||
3745 | if (lfe_pin) { | 3722 | if (lfe_pin) { |
3746 | err = create_controls(spec, "LFE", lfe_pin, 1); | 3723 | err = create_controls(codec, "LFE", lfe_pin, 1); |
3747 | if (err < 0) | 3724 | if (err < 0) |
3748 | return err; | 3725 | return err; |
3749 | } | 3726 | } |
@@ -3774,7 +3751,11 @@ static int stac9200_parse_auto_config(struct hda_codec *codec) | |||
3774 | return err; | 3751 | return err; |
3775 | } | 3752 | } |
3776 | 3753 | ||
3777 | if (spec->autocfg.dig_out_pin) | 3754 | err = stac92xx_add_input_source(spec); |
3755 | if (err < 0) | ||
3756 | return err; | ||
3757 | |||
3758 | if (spec->autocfg.dig_outs) | ||
3778 | spec->multiout.dig_out_nid = 0x05; | 3759 | spec->multiout.dig_out_nid = 0x05; |
3779 | if (spec->autocfg.dig_in_pin) | 3760 | if (spec->autocfg.dig_in_pin) |
3780 | spec->dig_in_nid = 0x04; | 3761 | spec->dig_in_nid = 0x04; |
@@ -3830,8 +3811,7 @@ static int stac92xx_add_jack(struct hda_codec *codec, | |||
3830 | #ifdef CONFIG_SND_JACK | 3811 | #ifdef CONFIG_SND_JACK |
3831 | struct sigmatel_spec *spec = codec->spec; | 3812 | struct sigmatel_spec *spec = codec->spec; |
3832 | struct sigmatel_jack *jack; | 3813 | struct sigmatel_jack *jack; |
3833 | int def_conf = snd_hda_codec_read(codec, nid, | 3814 | int def_conf = snd_hda_codec_get_pincfg(codec, nid); |
3834 | 0, AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
3835 | int connectivity = get_defcfg_connect(def_conf); | 3815 | int connectivity = get_defcfg_connect(def_conf); |
3836 | char name[32]; | 3816 | char name[32]; |
3837 | 3817 | ||
@@ -4011,8 +3991,7 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4011 | pinctl); | 3991 | pinctl); |
4012 | } | 3992 | } |
4013 | } | 3993 | } |
4014 | conf = snd_hda_codec_read(codec, nid, 0, | 3994 | conf = snd_hda_codec_get_pincfg(codec, nid); |
4015 | AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
4016 | if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) { | 3995 | if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) { |
4017 | enable_pin_detect(codec, nid, | 3996 | enable_pin_detect(codec, nid, |
4018 | STAC_INSERT_EVENT); | 3997 | STAC_INSERT_EVENT); |
@@ -4024,8 +4003,8 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4024 | for (i = 0; i < spec->num_dmics; i++) | 4003 | for (i = 0; i < spec->num_dmics; i++) |
4025 | stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i], | 4004 | stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i], |
4026 | AC_PINCTL_IN_EN); | 4005 | AC_PINCTL_IN_EN); |
4027 | if (cfg->dig_out_pin) | 4006 | if (cfg->dig_out_pins[0]) |
4028 | stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin, | 4007 | stac92xx_auto_set_pinctl(codec, cfg->dig_out_pins[0], |
4029 | AC_PINCTL_OUT_EN); | 4008 | AC_PINCTL_OUT_EN); |
4030 | if (cfg->dig_in_pin) | 4009 | if (cfg->dig_in_pin) |
4031 | stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin, | 4010 | stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin, |
@@ -4053,8 +4032,7 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4053 | stac_toggle_power_map(codec, nid, 1); | 4032 | stac_toggle_power_map(codec, nid, 1); |
4054 | continue; | 4033 | continue; |
4055 | } | 4034 | } |
4056 | def_conf = snd_hda_codec_read(codec, nid, 0, | 4035 | def_conf = snd_hda_codec_get_pincfg(codec, nid); |
4057 | AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
4058 | def_conf = get_defcfg_connect(def_conf); | 4036 | def_conf = get_defcfg_connect(def_conf); |
4059 | /* skip any ports that don't have jacks since presence | 4037 | /* skip any ports that don't have jacks since presence |
4060 | * detection is useless */ | 4038 | * detection is useless */ |
@@ -4108,7 +4086,6 @@ static void stac92xx_free(struct hda_codec *codec) | |||
4108 | if (! spec) | 4086 | if (! spec) |
4109 | return; | 4087 | return; |
4110 | 4088 | ||
4111 | kfree(spec->pin_configs); | ||
4112 | stac92xx_free_jacks(codec); | 4089 | stac92xx_free_jacks(codec); |
4113 | snd_array_free(&spec->events); | 4090 | snd_array_free(&spec->events); |
4114 | 4091 | ||
@@ -4119,7 +4096,9 @@ static void stac92xx_free(struct hda_codec *codec) | |||
4119 | static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, | 4096 | static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, |
4120 | unsigned int flag) | 4097 | unsigned int flag) |
4121 | { | 4098 | { |
4122 | unsigned int pin_ctl = snd_hda_codec_read(codec, nid, | 4099 | unsigned int old_ctl, pin_ctl; |
4100 | |||
4101 | pin_ctl = snd_hda_codec_read(codec, nid, | ||
4123 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); | 4102 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); |
4124 | 4103 | ||
4125 | if (pin_ctl & AC_PINCTL_IN_EN) { | 4104 | if (pin_ctl & AC_PINCTL_IN_EN) { |
@@ -4133,14 +4112,17 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, | |||
4133 | return; | 4112 | return; |
4134 | } | 4113 | } |
4135 | 4114 | ||
4115 | old_ctl = pin_ctl; | ||
4136 | /* if setting pin direction bits, clear the current | 4116 | /* if setting pin direction bits, clear the current |
4137 | direction bits first */ | 4117 | direction bits first */ |
4138 | if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)) | 4118 | if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)) |
4139 | pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); | 4119 | pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); |
4140 | 4120 | ||
4141 | snd_hda_codec_write_cache(codec, nid, 0, | 4121 | pin_ctl |= flag; |
4142 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 4122 | if (old_ctl != pin_ctl) |
4143 | pin_ctl | flag); | 4123 | snd_hda_codec_write_cache(codec, nid, 0, |
4124 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
4125 | pin_ctl); | ||
4144 | } | 4126 | } |
4145 | 4127 | ||
4146 | static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid, | 4128 | static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid, |
@@ -4148,9 +4130,10 @@ static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid, | |||
4148 | { | 4130 | { |
4149 | unsigned int pin_ctl = snd_hda_codec_read(codec, nid, | 4131 | unsigned int pin_ctl = snd_hda_codec_read(codec, nid, |
4150 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); | 4132 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); |
4151 | snd_hda_codec_write_cache(codec, nid, 0, | 4133 | if (pin_ctl & flag) |
4152 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 4134 | snd_hda_codec_write_cache(codec, nid, 0, |
4153 | pin_ctl & ~flag); | 4135 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
4136 | pin_ctl & ~flag); | ||
4154 | } | 4137 | } |
4155 | 4138 | ||
4156 | static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid) | 4139 | static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid) |
@@ -4413,7 +4396,6 @@ static int stac92xx_resume(struct hda_codec *codec) | |||
4413 | { | 4396 | { |
4414 | struct sigmatel_spec *spec = codec->spec; | 4397 | struct sigmatel_spec *spec = codec->spec; |
4415 | 4398 | ||
4416 | stac92xx_set_config_regs(codec); | ||
4417 | stac92xx_init(codec); | 4399 | stac92xx_init(codec); |
4418 | snd_hda_codec_resume_amp(codec); | 4400 | snd_hda_codec_resume_amp(codec); |
4419 | snd_hda_codec_resume_cache(codec); | 4401 | snd_hda_codec_resume_cache(codec); |
@@ -4462,16 +4444,11 @@ static int patch_stac9200(struct hda_codec *codec) | |||
4462 | spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS, | 4444 | spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS, |
4463 | stac9200_models, | 4445 | stac9200_models, |
4464 | stac9200_cfg_tbl); | 4446 | stac9200_cfg_tbl); |
4465 | if (spec->board_config < 0) { | 4447 | if (spec->board_config < 0) |
4466 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n"); | 4448 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n"); |
4467 | err = stac92xx_save_bios_config_regs(codec); | 4449 | else |
4468 | } else | 4450 | stac92xx_set_config_regs(codec, |
4469 | err = stac_save_pin_cfgs(codec, | ||
4470 | stac9200_brd_tbl[spec->board_config]); | 4451 | stac9200_brd_tbl[spec->board_config]); |
4471 | if (err < 0) { | ||
4472 | stac92xx_free(codec); | ||
4473 | return err; | ||
4474 | } | ||
4475 | 4452 | ||
4476 | spec->multiout.max_channels = 2; | 4453 | spec->multiout.max_channels = 2; |
4477 | spec->multiout.num_dacs = 1; | 4454 | spec->multiout.num_dacs = 1; |
@@ -4539,17 +4516,12 @@ static int patch_stac925x(struct hda_codec *codec) | |||
4539 | stac925x_models, | 4516 | stac925x_models, |
4540 | stac925x_cfg_tbl); | 4517 | stac925x_cfg_tbl); |
4541 | again: | 4518 | again: |
4542 | if (spec->board_config < 0) { | 4519 | if (spec->board_config < 0) |
4543 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x," | 4520 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x," |
4544 | "using BIOS defaults\n"); | 4521 | "using BIOS defaults\n"); |
4545 | err = stac92xx_save_bios_config_regs(codec); | 4522 | else |
4546 | } else | 4523 | stac92xx_set_config_regs(codec, |
4547 | err = stac_save_pin_cfgs(codec, | ||
4548 | stac925x_brd_tbl[spec->board_config]); | 4524 | stac925x_brd_tbl[spec->board_config]); |
4549 | if (err < 0) { | ||
4550 | stac92xx_free(codec); | ||
4551 | return err; | ||
4552 | } | ||
4553 | 4525 | ||
4554 | spec->multiout.max_channels = 2; | 4526 | spec->multiout.max_channels = 2; |
4555 | spec->multiout.num_dacs = 1; | 4527 | spec->multiout.num_dacs = 1; |
@@ -4627,17 +4599,12 @@ static int patch_stac92hd73xx(struct hda_codec *codec) | |||
4627 | stac92hd73xx_models, | 4599 | stac92hd73xx_models, |
4628 | stac92hd73xx_cfg_tbl); | 4600 | stac92hd73xx_cfg_tbl); |
4629 | again: | 4601 | again: |
4630 | if (spec->board_config < 0) { | 4602 | if (spec->board_config < 0) |
4631 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" | 4603 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" |
4632 | " STAC92HD73XX, using BIOS defaults\n"); | 4604 | " STAC92HD73XX, using BIOS defaults\n"); |
4633 | err = stac92xx_save_bios_config_regs(codec); | 4605 | else |
4634 | } else | 4606 | stac92xx_set_config_regs(codec, |
4635 | err = stac_save_pin_cfgs(codec, | ||
4636 | stac92hd73xx_brd_tbl[spec->board_config]); | 4607 | stac92hd73xx_brd_tbl[spec->board_config]); |
4637 | if (err < 0) { | ||
4638 | stac92xx_free(codec); | ||
4639 | return err; | ||
4640 | } | ||
4641 | 4608 | ||
4642 | num_dacs = snd_hda_get_connections(codec, 0x0a, | 4609 | num_dacs = snd_hda_get_connections(codec, 0x0a, |
4643 | conn, STAC92HD73_DAC_COUNT + 2) - 1; | 4610 | conn, STAC92HD73_DAC_COUNT + 2) - 1; |
@@ -4697,18 +4664,18 @@ again: | |||
4697 | spec->init = dell_m6_core_init; | 4664 | spec->init = dell_m6_core_init; |
4698 | switch (spec->board_config) { | 4665 | switch (spec->board_config) { |
4699 | case STAC_DELL_M6_AMIC: /* Analog Mics */ | 4666 | case STAC_DELL_M6_AMIC: /* Analog Mics */ |
4700 | stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); | 4667 | snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170); |
4701 | spec->num_dmics = 0; | 4668 | spec->num_dmics = 0; |
4702 | spec->private_dimux.num_items = 1; | 4669 | spec->private_dimux.num_items = 1; |
4703 | break; | 4670 | break; |
4704 | case STAC_DELL_M6_DMIC: /* Digital Mics */ | 4671 | case STAC_DELL_M6_DMIC: /* Digital Mics */ |
4705 | stac92xx_set_config_reg(codec, 0x13, 0x90A60160); | 4672 | snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160); |
4706 | spec->num_dmics = 1; | 4673 | spec->num_dmics = 1; |
4707 | spec->private_dimux.num_items = 2; | 4674 | spec->private_dimux.num_items = 2; |
4708 | break; | 4675 | break; |
4709 | case STAC_DELL_M6_BOTH: /* Both */ | 4676 | case STAC_DELL_M6_BOTH: /* Both */ |
4710 | stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); | 4677 | snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170); |
4711 | stac92xx_set_config_reg(codec, 0x13, 0x90A60160); | 4678 | snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160); |
4712 | spec->num_dmics = 1; | 4679 | spec->num_dmics = 1; |
4713 | spec->private_dimux.num_items = 2; | 4680 | spec->private_dimux.num_items = 2; |
4714 | break; | 4681 | break; |
@@ -4771,6 +4738,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
4771 | hda_nid_t conn[STAC92HD83_DAC_COUNT + 1]; | 4738 | hda_nid_t conn[STAC92HD83_DAC_COUNT + 1]; |
4772 | int err; | 4739 | int err; |
4773 | int num_dacs; | 4740 | int num_dacs; |
4741 | hda_nid_t nid; | ||
4774 | 4742 | ||
4775 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 4743 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
4776 | if (spec == NULL) | 4744 | if (spec == NULL) |
@@ -4789,15 +4757,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
4789 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); | 4757 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); |
4790 | spec->multiout.dac_nids = spec->dac_nids; | 4758 | spec->multiout.dac_nids = spec->dac_nids; |
4791 | 4759 | ||
4792 | |||
4793 | /* set port 0xe to select the last DAC | ||
4794 | */ | ||
4795 | num_dacs = snd_hda_get_connections(codec, 0x0e, | ||
4796 | conn, STAC92HD83_DAC_COUNT + 1) - 1; | ||
4797 | |||
4798 | snd_hda_codec_write_cache(codec, 0xe, 0, | ||
4799 | AC_VERB_SET_CONNECT_SEL, num_dacs); | ||
4800 | |||
4801 | spec->init = stac92hd83xxx_core_init; | 4760 | spec->init = stac92hd83xxx_core_init; |
4802 | spec->mixer = stac92hd83xxx_mixer; | 4761 | spec->mixer = stac92hd83xxx_mixer; |
4803 | spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids); | 4762 | spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids); |
@@ -4812,17 +4771,12 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
4812 | stac92hd83xxx_models, | 4771 | stac92hd83xxx_models, |
4813 | stac92hd83xxx_cfg_tbl); | 4772 | stac92hd83xxx_cfg_tbl); |
4814 | again: | 4773 | again: |
4815 | if (spec->board_config < 0) { | 4774 | if (spec->board_config < 0) |
4816 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" | 4775 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" |
4817 | " STAC92HD83XXX, using BIOS defaults\n"); | 4776 | " STAC92HD83XXX, using BIOS defaults\n"); |
4818 | err = stac92xx_save_bios_config_regs(codec); | 4777 | else |
4819 | } else | 4778 | stac92xx_set_config_regs(codec, |
4820 | err = stac_save_pin_cfgs(codec, | ||
4821 | stac92hd83xxx_brd_tbl[spec->board_config]); | 4779 | stac92hd83xxx_brd_tbl[spec->board_config]); |
4822 | if (err < 0) { | ||
4823 | stac92xx_free(codec); | ||
4824 | return err; | ||
4825 | } | ||
4826 | 4780 | ||
4827 | switch (codec->vendor_id) { | 4781 | switch (codec->vendor_id) { |
4828 | case 0x111d7604: | 4782 | case 0x111d7604: |
@@ -4849,6 +4803,23 @@ again: | |||
4849 | return err; | 4803 | return err; |
4850 | } | 4804 | } |
4851 | 4805 | ||
4806 | switch (spec->board_config) { | ||
4807 | case STAC_DELL_S14: | ||
4808 | nid = 0xf; | ||
4809 | break; | ||
4810 | default: | ||
4811 | nid = 0xe; | ||
4812 | break; | ||
4813 | } | ||
4814 | |||
4815 | num_dacs = snd_hda_get_connections(codec, nid, | ||
4816 | conn, STAC92HD83_DAC_COUNT + 1) - 1; | ||
4817 | |||
4818 | /* set port X to select the last DAC | ||
4819 | */ | ||
4820 | snd_hda_codec_write_cache(codec, nid, 0, | ||
4821 | AC_VERB_SET_CONNECT_SEL, num_dacs); | ||
4822 | |||
4852 | codec->patch_ops = stac92xx_patch_ops; | 4823 | codec->patch_ops = stac92xx_patch_ops; |
4853 | 4824 | ||
4854 | codec->proc_widget_hook = stac92hd_proc_hook; | 4825 | codec->proc_widget_hook = stac92hd_proc_hook; |
@@ -4856,7 +4827,16 @@ again: | |||
4856 | return 0; | 4827 | return 0; |
4857 | } | 4828 | } |
4858 | 4829 | ||
4859 | static struct hda_input_mux stac92hd71bxx_dmux = { | 4830 | static struct hda_input_mux stac92hd71bxx_dmux_nomixer = { |
4831 | .num_items = 3, | ||
4832 | .items = { | ||
4833 | { "Analog Inputs", 0x00 }, | ||
4834 | { "Digital Mic 1", 0x02 }, | ||
4835 | { "Digital Mic 2", 0x03 }, | ||
4836 | } | ||
4837 | }; | ||
4838 | |||
4839 | static struct hda_input_mux stac92hd71bxx_dmux_amixer = { | ||
4860 | .num_items = 4, | 4840 | .num_items = 4, |
4861 | .items = { | 4841 | .items = { |
4862 | { "Analog Inputs", 0x00 }, | 4842 | { "Analog Inputs", 0x00 }, |
@@ -4866,10 +4846,67 @@ static struct hda_input_mux stac92hd71bxx_dmux = { | |||
4866 | } | 4846 | } |
4867 | }; | 4847 | }; |
4868 | 4848 | ||
4849 | /* get the pin connection (fixed, none, etc) */ | ||
4850 | static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx) | ||
4851 | { | ||
4852 | struct sigmatel_spec *spec = codec->spec; | ||
4853 | unsigned int cfg; | ||
4854 | |||
4855 | cfg = snd_hda_codec_get_pincfg(codec, spec->pin_nids[idx]); | ||
4856 | return get_defcfg_connect(cfg); | ||
4857 | } | ||
4858 | |||
4859 | static int stac92hd71bxx_connected_ports(struct hda_codec *codec, | ||
4860 | hda_nid_t *nids, int num_nids) | ||
4861 | { | ||
4862 | struct sigmatel_spec *spec = codec->spec; | ||
4863 | int idx, num; | ||
4864 | unsigned int def_conf; | ||
4865 | |||
4866 | for (num = 0; num < num_nids; num++) { | ||
4867 | for (idx = 0; idx < spec->num_pins; idx++) | ||
4868 | if (spec->pin_nids[idx] == nids[num]) | ||
4869 | break; | ||
4870 | if (idx >= spec->num_pins) | ||
4871 | break; | ||
4872 | def_conf = stac_get_defcfg_connect(codec, idx); | ||
4873 | if (def_conf == AC_JACK_PORT_NONE) | ||
4874 | break; | ||
4875 | } | ||
4876 | return num; | ||
4877 | } | ||
4878 | |||
4879 | static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec, | ||
4880 | hda_nid_t dig0pin) | ||
4881 | { | ||
4882 | struct sigmatel_spec *spec = codec->spec; | ||
4883 | int idx; | ||
4884 | |||
4885 | for (idx = 0; idx < spec->num_pins; idx++) | ||
4886 | if (spec->pin_nids[idx] == dig0pin) | ||
4887 | break; | ||
4888 | if ((idx + 2) >= spec->num_pins) | ||
4889 | return 0; | ||
4890 | |||
4891 | /* dig1pin case */ | ||
4892 | if (stac_get_defcfg_connect(codec, idx + 1) != AC_JACK_PORT_NONE) | ||
4893 | return 2; | ||
4894 | |||
4895 | /* dig0pin + dig2pin case */ | ||
4896 | if (stac_get_defcfg_connect(codec, idx + 2) != AC_JACK_PORT_NONE) | ||
4897 | return 2; | ||
4898 | if (stac_get_defcfg_connect(codec, idx) != AC_JACK_PORT_NONE) | ||
4899 | return 1; | ||
4900 | else | ||
4901 | return 0; | ||
4902 | } | ||
4903 | |||
4869 | static int patch_stac92hd71bxx(struct hda_codec *codec) | 4904 | static int patch_stac92hd71bxx(struct hda_codec *codec) |
4870 | { | 4905 | { |
4871 | struct sigmatel_spec *spec; | 4906 | struct sigmatel_spec *spec; |
4907 | struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init; | ||
4872 | int err = 0; | 4908 | int err = 0; |
4909 | unsigned int ndmic_nids = 0; | ||
4873 | 4910 | ||
4874 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 4911 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
4875 | if (spec == NULL) | 4912 | if (spec == NULL) |
@@ -4877,27 +4914,32 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) | |||
4877 | 4914 | ||
4878 | codec->spec = spec; | 4915 | codec->spec = spec; |
4879 | codec->patch_ops = stac92xx_patch_ops; | 4916 | codec->patch_ops = stac92xx_patch_ops; |
4880 | spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids); | 4917 | spec->num_pins = STAC92HD71BXX_NUM_PINS; |
4918 | switch (codec->vendor_id) { | ||
4919 | case 0x111d76b6: | ||
4920 | case 0x111d76b7: | ||
4921 | spec->pin_nids = stac92hd71bxx_pin_nids_4port; | ||
4922 | break; | ||
4923 | case 0x111d7603: | ||
4924 | case 0x111d7608: | ||
4925 | /* On 92HD75Bx 0x27 isn't a pin nid */ | ||
4926 | spec->num_pins--; | ||
4927 | /* fallthrough */ | ||
4928 | default: | ||
4929 | spec->pin_nids = stac92hd71bxx_pin_nids_6port; | ||
4930 | } | ||
4881 | spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); | 4931 | spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); |
4882 | spec->pin_nids = stac92hd71bxx_pin_nids; | ||
4883 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux, | ||
4884 | sizeof(stac92hd71bxx_dmux)); | ||
4885 | spec->board_config = snd_hda_check_board_config(codec, | 4932 | spec->board_config = snd_hda_check_board_config(codec, |
4886 | STAC_92HD71BXX_MODELS, | 4933 | STAC_92HD71BXX_MODELS, |
4887 | stac92hd71bxx_models, | 4934 | stac92hd71bxx_models, |
4888 | stac92hd71bxx_cfg_tbl); | 4935 | stac92hd71bxx_cfg_tbl); |
4889 | again: | 4936 | again: |
4890 | if (spec->board_config < 0) { | 4937 | if (spec->board_config < 0) |
4891 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" | 4938 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" |
4892 | " STAC92HD71BXX, using BIOS defaults\n"); | 4939 | " STAC92HD71BXX, using BIOS defaults\n"); |
4893 | err = stac92xx_save_bios_config_regs(codec); | 4940 | else |
4894 | } else | 4941 | stac92xx_set_config_regs(codec, |
4895 | err = stac_save_pin_cfgs(codec, | ||
4896 | stac92hd71bxx_brd_tbl[spec->board_config]); | 4942 | stac92hd71bxx_brd_tbl[spec->board_config]); |
4897 | if (err < 0) { | ||
4898 | stac92xx_free(codec); | ||
4899 | return err; | ||
4900 | } | ||
4901 | 4943 | ||
4902 | if (spec->board_config > STAC_92HD71BXX_REF) { | 4944 | if (spec->board_config > STAC_92HD71BXX_REF) { |
4903 | /* GPIO0 = EAPD */ | 4945 | /* GPIO0 = EAPD */ |
@@ -4906,16 +4948,34 @@ again: | |||
4906 | spec->gpio_data = 0x01; | 4948 | spec->gpio_data = 0x01; |
4907 | } | 4949 | } |
4908 | 4950 | ||
4951 | spec->dmic_nids = stac92hd71bxx_dmic_nids; | ||
4952 | spec->dmux_nids = stac92hd71bxx_dmux_nids; | ||
4953 | |||
4909 | switch (codec->vendor_id) { | 4954 | switch (codec->vendor_id) { |
4910 | case 0x111d76b6: /* 4 Port without Analog Mixer */ | 4955 | case 0x111d76b6: /* 4 Port without Analog Mixer */ |
4911 | case 0x111d76b7: | 4956 | case 0x111d76b7: |
4957 | unmute_init++; | ||
4958 | /* fallthru */ | ||
4912 | case 0x111d76b4: /* 6 Port without Analog Mixer */ | 4959 | case 0x111d76b4: /* 6 Port without Analog Mixer */ |
4913 | case 0x111d76b5: | 4960 | case 0x111d76b5: |
4961 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_nomixer, | ||
4962 | sizeof(stac92hd71bxx_dmux_nomixer)); | ||
4914 | spec->mixer = stac92hd71bxx_mixer; | 4963 | spec->mixer = stac92hd71bxx_mixer; |
4915 | spec->init = stac92hd71bxx_core_init; | 4964 | spec->init = stac92hd71bxx_core_init; |
4916 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; | 4965 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; |
4966 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, | ||
4967 | stac92hd71bxx_dmic_nids, | ||
4968 | STAC92HD71BXX_NUM_DMICS); | ||
4969 | if (spec->num_dmics) { | ||
4970 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | ||
4971 | spec->dinput_mux = &spec->private_dimux; | ||
4972 | ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1; | ||
4973 | } | ||
4917 | break; | 4974 | break; |
4918 | case 0x111d7608: /* 5 Port with Analog Mixer */ | 4975 | case 0x111d7608: /* 5 Port with Analog Mixer */ |
4976 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_amixer, | ||
4977 | sizeof(stac92hd71bxx_dmux_amixer)); | ||
4978 | spec->private_dimux.num_items--; | ||
4919 | switch (spec->board_config) { | 4979 | switch (spec->board_config) { |
4920 | case STAC_HP_M4: | 4980 | case STAC_HP_M4: |
4921 | /* Enable VREF power saving on GPIO1 detect */ | 4981 | /* Enable VREF power saving on GPIO1 detect */ |
@@ -4942,7 +5002,15 @@ again: | |||
4942 | 5002 | ||
4943 | /* disable VSW */ | 5003 | /* disable VSW */ |
4944 | spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF]; | 5004 | spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF]; |
4945 | stac_change_pin_config(codec, 0xf, 0x40f000f0); | 5005 | unmute_init++; |
5006 | snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); | ||
5007 | snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); | ||
5008 | stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS - 1] = 0; | ||
5009 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, | ||
5010 | stac92hd71bxx_dmic_nids, | ||
5011 | STAC92HD71BXX_NUM_DMICS - 1); | ||
5012 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | ||
5013 | ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 2; | ||
4946 | break; | 5014 | break; |
4947 | case 0x111d7603: /* 6 Port with Analog Mixer */ | 5015 | case 0x111d7603: /* 6 Port with Analog Mixer */ |
4948 | if ((codec->revision_id & 0xf) == 1) | 5016 | if ((codec->revision_id & 0xf) == 1) |
@@ -4952,12 +5020,22 @@ again: | |||
4952 | spec->num_pwrs = 0; | 5020 | spec->num_pwrs = 0; |
4953 | /* fallthru */ | 5021 | /* fallthru */ |
4954 | default: | 5022 | default: |
5023 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_amixer, | ||
5024 | sizeof(stac92hd71bxx_dmux_amixer)); | ||
4955 | spec->dinput_mux = &spec->private_dimux; | 5025 | spec->dinput_mux = &spec->private_dimux; |
4956 | spec->mixer = stac92hd71bxx_analog_mixer; | 5026 | spec->mixer = stac92hd71bxx_analog_mixer; |
4957 | spec->init = stac92hd71bxx_analog_core_init; | 5027 | spec->init = stac92hd71bxx_analog_core_init; |
4958 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; | 5028 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; |
5029 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, | ||
5030 | stac92hd71bxx_dmic_nids, | ||
5031 | STAC92HD71BXX_NUM_DMICS); | ||
5032 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | ||
5033 | ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1; | ||
4959 | } | 5034 | } |
4960 | 5035 | ||
5036 | if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) | ||
5037 | snd_hda_sequence_write_cache(codec, unmute_init); | ||
5038 | |||
4961 | spec->aloopback_mask = 0x50; | 5039 | spec->aloopback_mask = 0x50; |
4962 | spec->aloopback_shift = 0; | 5040 | spec->aloopback_shift = 0; |
4963 | 5041 | ||
@@ -4965,18 +5043,17 @@ again: | |||
4965 | spec->digbeep_nid = 0x26; | 5043 | spec->digbeep_nid = 0x26; |
4966 | spec->mux_nids = stac92hd71bxx_mux_nids; | 5044 | spec->mux_nids = stac92hd71bxx_mux_nids; |
4967 | spec->adc_nids = stac92hd71bxx_adc_nids; | 5045 | spec->adc_nids = stac92hd71bxx_adc_nids; |
4968 | spec->dmic_nids = stac92hd71bxx_dmic_nids; | ||
4969 | spec->dmux_nids = stac92hd71bxx_dmux_nids; | ||
4970 | spec->smux_nids = stac92hd71bxx_smux_nids; | 5046 | spec->smux_nids = stac92hd71bxx_smux_nids; |
4971 | spec->pwr_nids = stac92hd71bxx_pwr_nids; | 5047 | spec->pwr_nids = stac92hd71bxx_pwr_nids; |
4972 | 5048 | ||
4973 | spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); | 5049 | spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); |
4974 | spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); | 5050 | spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); |
5051 | spec->num_smuxes = stac92hd71bxx_connected_smuxes(codec, 0x1e); | ||
4975 | 5052 | ||
4976 | switch (spec->board_config) { | 5053 | switch (spec->board_config) { |
4977 | case STAC_HP_M4: | 5054 | case STAC_HP_M4: |
4978 | /* enable internal microphone */ | 5055 | /* enable internal microphone */ |
4979 | stac_change_pin_config(codec, 0x0e, 0x01813040); | 5056 | snd_hda_codec_set_pincfg(codec, 0x0e, 0x01813040); |
4980 | stac92xx_auto_set_pinctl(codec, 0x0e, | 5057 | stac92xx_auto_set_pinctl(codec, 0x0e, |
4981 | AC_PINCTL_IN_EN | AC_PINCTL_VREF_80); | 5058 | AC_PINCTL_IN_EN | AC_PINCTL_VREF_80); |
4982 | /* fallthru */ | 5059 | /* fallthru */ |
@@ -4991,19 +5068,17 @@ again: | |||
4991 | spec->num_smuxes = 0; | 5068 | spec->num_smuxes = 0; |
4992 | spec->num_dmuxes = 1; | 5069 | spec->num_dmuxes = 1; |
4993 | break; | 5070 | break; |
4994 | default: | 5071 | case STAC_HP_DV5: |
4995 | spec->num_dmics = STAC92HD71BXX_NUM_DMICS; | 5072 | snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); |
4996 | spec->num_smuxes = ARRAY_SIZE(stac92hd71bxx_smux_nids); | 5073 | stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN); |
4997 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | 5074 | break; |
4998 | }; | 5075 | }; |
4999 | 5076 | ||
5000 | spec->multiout.dac_nids = spec->dac_nids; | 5077 | spec->multiout.dac_nids = spec->dac_nids; |
5001 | if (spec->dinput_mux) | 5078 | if (spec->dinput_mux) |
5002 | spec->private_dimux.num_items += | 5079 | spec->private_dimux.num_items += spec->num_dmics - ndmic_nids; |
5003 | spec->num_dmics - | ||
5004 | (ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1); | ||
5005 | 5080 | ||
5006 | err = stac92xx_parse_auto_config(codec, 0x21, 0x23); | 5081 | err = stac92xx_parse_auto_config(codec, 0x21, 0); |
5007 | if (!err) { | 5082 | if (!err) { |
5008 | if (spec->board_config < 0) { | 5083 | if (spec->board_config < 0) { |
5009 | printk(KERN_WARNING "hda_codec: No auto-config is " | 5084 | printk(KERN_WARNING "hda_codec: No auto-config is " |
@@ -5078,17 +5153,12 @@ static int patch_stac922x(struct hda_codec *codec) | |||
5078 | } | 5153 | } |
5079 | 5154 | ||
5080 | again: | 5155 | again: |
5081 | if (spec->board_config < 0) { | 5156 | if (spec->board_config < 0) |
5082 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, " | 5157 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, " |
5083 | "using BIOS defaults\n"); | 5158 | "using BIOS defaults\n"); |
5084 | err = stac92xx_save_bios_config_regs(codec); | 5159 | else |
5085 | } else | 5160 | stac92xx_set_config_regs(codec, |
5086 | err = stac_save_pin_cfgs(codec, | ||
5087 | stac922x_brd_tbl[spec->board_config]); | 5161 | stac922x_brd_tbl[spec->board_config]); |
5088 | if (err < 0) { | ||
5089 | stac92xx_free(codec); | ||
5090 | return err; | ||
5091 | } | ||
5092 | 5162 | ||
5093 | spec->adc_nids = stac922x_adc_nids; | 5163 | spec->adc_nids = stac922x_adc_nids; |
5094 | spec->mux_nids = stac922x_mux_nids; | 5164 | spec->mux_nids = stac922x_mux_nids; |
@@ -5139,24 +5209,19 @@ static int patch_stac927x(struct hda_codec *codec) | |||
5139 | return -ENOMEM; | 5209 | return -ENOMEM; |
5140 | 5210 | ||
5141 | codec->spec = spec; | 5211 | codec->spec = spec; |
5212 | codec->slave_dig_outs = stac927x_slave_dig_outs; | ||
5142 | spec->num_pins = ARRAY_SIZE(stac927x_pin_nids); | 5213 | spec->num_pins = ARRAY_SIZE(stac927x_pin_nids); |
5143 | spec->pin_nids = stac927x_pin_nids; | 5214 | spec->pin_nids = stac927x_pin_nids; |
5144 | spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS, | 5215 | spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS, |
5145 | stac927x_models, | 5216 | stac927x_models, |
5146 | stac927x_cfg_tbl); | 5217 | stac927x_cfg_tbl); |
5147 | again: | 5218 | again: |
5148 | if (spec->board_config < 0 || !stac927x_brd_tbl[spec->board_config]) { | 5219 | if (spec->board_config < 0) |
5149 | if (spec->board_config < 0) | 5220 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" |
5150 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" | 5221 | "STAC927x, using BIOS defaults\n"); |
5151 | "STAC927x, using BIOS defaults\n"); | 5222 | else |
5152 | err = stac92xx_save_bios_config_regs(codec); | 5223 | stac92xx_set_config_regs(codec, |
5153 | } else | ||
5154 | err = stac_save_pin_cfgs(codec, | ||
5155 | stac927x_brd_tbl[spec->board_config]); | 5224 | stac927x_brd_tbl[spec->board_config]); |
5156 | if (err < 0) { | ||
5157 | stac92xx_free(codec); | ||
5158 | return err; | ||
5159 | } | ||
5160 | 5225 | ||
5161 | spec->digbeep_nid = 0x23; | 5226 | spec->digbeep_nid = 0x23; |
5162 | spec->adc_nids = stac927x_adc_nids; | 5227 | spec->adc_nids = stac927x_adc_nids; |
@@ -5185,15 +5250,15 @@ static int patch_stac927x(struct hda_codec *codec) | |||
5185 | case 0x10280209: | 5250 | case 0x10280209: |
5186 | case 0x1028022e: | 5251 | case 0x1028022e: |
5187 | /* correct the device field to SPDIF out */ | 5252 | /* correct the device field to SPDIF out */ |
5188 | stac_change_pin_config(codec, 0x21, 0x01442070); | 5253 | snd_hda_codec_set_pincfg(codec, 0x21, 0x01442070); |
5189 | break; | 5254 | break; |
5190 | }; | 5255 | }; |
5191 | /* configure the analog microphone on some laptops */ | 5256 | /* configure the analog microphone on some laptops */ |
5192 | stac_change_pin_config(codec, 0x0c, 0x90a79130); | 5257 | snd_hda_codec_set_pincfg(codec, 0x0c, 0x90a79130); |
5193 | /* correct the front output jack as a hp out */ | 5258 | /* correct the front output jack as a hp out */ |
5194 | stac_change_pin_config(codec, 0x0f, 0x0227011f); | 5259 | snd_hda_codec_set_pincfg(codec, 0x0f, 0x0227011f); |
5195 | /* correct the front input jack as a mic */ | 5260 | /* correct the front input jack as a mic */ |
5196 | stac_change_pin_config(codec, 0x0e, 0x02a79130); | 5261 | snd_hda_codec_set_pincfg(codec, 0x0e, 0x02a79130); |
5197 | /* fallthru */ | 5262 | /* fallthru */ |
5198 | case STAC_DELL_3ST: | 5263 | case STAC_DELL_3ST: |
5199 | /* GPIO2 High = Enable EAPD */ | 5264 | /* GPIO2 High = Enable EAPD */ |
@@ -5278,16 +5343,11 @@ static int patch_stac9205(struct hda_codec *codec) | |||
5278 | stac9205_models, | 5343 | stac9205_models, |
5279 | stac9205_cfg_tbl); | 5344 | stac9205_cfg_tbl); |
5280 | again: | 5345 | again: |
5281 | if (spec->board_config < 0) { | 5346 | if (spec->board_config < 0) |
5282 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n"); | 5347 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n"); |
5283 | err = stac92xx_save_bios_config_regs(codec); | 5348 | else |
5284 | } else | 5349 | stac92xx_set_config_regs(codec, |
5285 | err = stac_save_pin_cfgs(codec, | ||
5286 | stac9205_brd_tbl[spec->board_config]); | 5350 | stac9205_brd_tbl[spec->board_config]); |
5287 | if (err < 0) { | ||
5288 | stac92xx_free(codec); | ||
5289 | return err; | ||
5290 | } | ||
5291 | 5351 | ||
5292 | spec->digbeep_nid = 0x23; | 5352 | spec->digbeep_nid = 0x23; |
5293 | spec->adc_nids = stac9205_adc_nids; | 5353 | spec->adc_nids = stac9205_adc_nids; |
@@ -5307,14 +5367,16 @@ static int patch_stac9205(struct hda_codec *codec) | |||
5307 | 5367 | ||
5308 | spec->aloopback_mask = 0x40; | 5368 | spec->aloopback_mask = 0x40; |
5309 | spec->aloopback_shift = 0; | 5369 | spec->aloopback_shift = 0; |
5310 | spec->eapd_switch = 1; | 5370 | /* Turn on/off EAPD per HP plugging */ |
5371 | if (spec->board_config != STAC_9205_EAPD) | ||
5372 | spec->eapd_switch = 1; | ||
5311 | spec->multiout.dac_nids = spec->dac_nids; | 5373 | spec->multiout.dac_nids = spec->dac_nids; |
5312 | 5374 | ||
5313 | switch (spec->board_config){ | 5375 | switch (spec->board_config){ |
5314 | case STAC_9205_DELL_M43: | 5376 | case STAC_9205_DELL_M43: |
5315 | /* Enable SPDIF in/out */ | 5377 | /* Enable SPDIF in/out */ |
5316 | stac_change_pin_config(codec, 0x1f, 0x01441030); | 5378 | snd_hda_codec_set_pincfg(codec, 0x1f, 0x01441030); |
5317 | stac_change_pin_config(codec, 0x20, 0x1c410030); | 5379 | snd_hda_codec_set_pincfg(codec, 0x20, 0x1c410030); |
5318 | 5380 | ||
5319 | /* Enable unsol response for GPIO4/Dock HP connection */ | 5381 | /* Enable unsol response for GPIO4/Dock HP connection */ |
5320 | err = stac_add_event(spec, codec->afg, STAC_VREF_EVENT, 0x01); | 5382 | err = stac_add_event(spec, codec->afg, STAC_VREF_EVENT, 0x01); |
@@ -5371,223 +5433,64 @@ static int patch_stac9205(struct hda_codec *codec) | |||
5371 | * STAC9872 hack | 5433 | * STAC9872 hack |
5372 | */ | 5434 | */ |
5373 | 5435 | ||
5374 | /* static config for Sony VAIO FE550G and Sony VAIO AR */ | 5436 | static struct hda_verb stac9872_core_init[] = { |
5375 | static hda_nid_t vaio_dacs[] = { 0x2 }; | ||
5376 | #define VAIO_HP_DAC 0x5 | ||
5377 | static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ }; | ||
5378 | static hda_nid_t vaio_mux_nids[] = { 0x15 }; | ||
5379 | |||
5380 | static struct hda_input_mux vaio_mux = { | ||
5381 | .num_items = 3, | ||
5382 | .items = { | ||
5383 | /* { "HP", 0x0 }, */ | ||
5384 | { "Mic Jack", 0x1 }, | ||
5385 | { "Internal Mic", 0x2 }, | ||
5386 | { "PCM", 0x3 }, | ||
5387 | } | ||
5388 | }; | ||
5389 | |||
5390 | static struct hda_verb vaio_init[] = { | ||
5391 | {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */ | ||
5392 | {0x0a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | STAC_HP_EVENT}, | ||
5393 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */ | ||
5394 | {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */ | ||
5395 | {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ | ||
5396 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ | ||
5397 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ | ||
5398 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ | ||
5399 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ | ||
5400 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */ | ||
5401 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */ | ||
5402 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ | ||
5403 | {} | ||
5404 | }; | ||
5405 | |||
5406 | static struct hda_verb vaio_ar_init[] = { | ||
5407 | {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */ | ||
5408 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */ | ||
5409 | {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */ | ||
5410 | {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ | ||
5411 | /* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */ | ||
5412 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ | ||
5413 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ | 5437 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ |
5414 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ | ||
5415 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ | ||
5416 | /* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */ | ||
5417 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */ | ||
5418 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */ | ||
5419 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ | 5438 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ |
5420 | {} | 5439 | {} |
5421 | }; | 5440 | }; |
5422 | 5441 | ||
5423 | static struct snd_kcontrol_new vaio_mixer[] = { | 5442 | static struct snd_kcontrol_new stac9872_mixer[] = { |
5424 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x02, 0, HDA_OUTPUT), | ||
5425 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x02, 0, HDA_OUTPUT), | ||
5426 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x05, 0, HDA_OUTPUT), | ||
5427 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x05, 0, HDA_OUTPUT), | ||
5428 | /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */ | ||
5429 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), | ||
5430 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), | ||
5431 | { | ||
5432 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
5433 | .name = "Capture Source", | ||
5434 | .count = 1, | ||
5435 | .info = stac92xx_mux_enum_info, | ||
5436 | .get = stac92xx_mux_enum_get, | ||
5437 | .put = stac92xx_mux_enum_put, | ||
5438 | }, | ||
5439 | {} | ||
5440 | }; | ||
5441 | |||
5442 | static struct snd_kcontrol_new vaio_ar_mixer[] = { | ||
5443 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x02, 0, HDA_OUTPUT), | ||
5444 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x02, 0, HDA_OUTPUT), | ||
5445 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x05, 0, HDA_OUTPUT), | ||
5446 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x05, 0, HDA_OUTPUT), | ||
5447 | /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */ | ||
5448 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), | 5443 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), |
5449 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), | 5444 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), |
5450 | /*HDA_CODEC_MUTE("Optical Out Switch", 0x10, 0, HDA_OUTPUT), | 5445 | { } /* end */ |
5451 | HDA_CODEC_VOLUME("Optical Out Volume", 0x10, 0, HDA_OUTPUT),*/ | ||
5452 | { | ||
5453 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
5454 | .name = "Capture Source", | ||
5455 | .count = 1, | ||
5456 | .info = stac92xx_mux_enum_info, | ||
5457 | .get = stac92xx_mux_enum_get, | ||
5458 | .put = stac92xx_mux_enum_put, | ||
5459 | }, | ||
5460 | {} | ||
5461 | }; | ||
5462 | |||
5463 | static struct hda_codec_ops stac9872_patch_ops = { | ||
5464 | .build_controls = stac92xx_build_controls, | ||
5465 | .build_pcms = stac92xx_build_pcms, | ||
5466 | .init = stac92xx_init, | ||
5467 | .free = stac92xx_free, | ||
5468 | #ifdef SND_HDA_NEEDS_RESUME | ||
5469 | .resume = stac92xx_resume, | ||
5470 | #endif | ||
5471 | }; | ||
5472 | |||
5473 | static int stac9872_vaio_init(struct hda_codec *codec) | ||
5474 | { | ||
5475 | int err; | ||
5476 | |||
5477 | err = stac92xx_init(codec); | ||
5478 | if (err < 0) | ||
5479 | return err; | ||
5480 | if (codec->patch_ops.unsol_event) | ||
5481 | codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); | ||
5482 | return 0; | ||
5483 | } | ||
5484 | |||
5485 | static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res) | ||
5486 | { | ||
5487 | if (get_pin_presence(codec, 0x0a)) { | ||
5488 | stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN); | ||
5489 | stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN); | ||
5490 | } else { | ||
5491 | stac92xx_reset_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN); | ||
5492 | stac92xx_set_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN); | ||
5493 | } | ||
5494 | } | ||
5495 | |||
5496 | static void stac9872_vaio_unsol_event(struct hda_codec *codec, unsigned int res) | ||
5497 | { | ||
5498 | switch (res >> 26) { | ||
5499 | case STAC_HP_EVENT: | ||
5500 | stac9872_vaio_hp_detect(codec, res); | ||
5501 | break; | ||
5502 | } | ||
5503 | } | ||
5504 | |||
5505 | static struct hda_codec_ops stac9872_vaio_patch_ops = { | ||
5506 | .build_controls = stac92xx_build_controls, | ||
5507 | .build_pcms = stac92xx_build_pcms, | ||
5508 | .init = stac9872_vaio_init, | ||
5509 | .free = stac92xx_free, | ||
5510 | .unsol_event = stac9872_vaio_unsol_event, | ||
5511 | #ifdef CONFIG_PM | ||
5512 | .resume = stac92xx_resume, | ||
5513 | #endif | ||
5514 | }; | 5446 | }; |
5515 | 5447 | ||
5516 | enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */ | 5448 | static hda_nid_t stac9872_pin_nids[] = { |
5517 | CXD9872RD_VAIO, | 5449 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
5518 | /* Unknown. id=0x83847662 and subsys=0x104D1200 or 104D1000. */ | 5450 | 0x11, 0x13, 0x14, |
5519 | STAC9872AK_VAIO, | ||
5520 | /* Unknown. id=0x83847661 and subsys=0x104D1200. */ | ||
5521 | STAC9872K_VAIO, | ||
5522 | /* AR Series. id=0x83847664 and subsys=104D1300 */ | ||
5523 | CXD9872AKD_VAIO, | ||
5524 | STAC_9872_MODELS, | ||
5525 | }; | 5451 | }; |
5526 | 5452 | ||
5527 | static const char *stac9872_models[STAC_9872_MODELS] = { | 5453 | static hda_nid_t stac9872_adc_nids[] = { |
5528 | [CXD9872RD_VAIO] = "vaio", | 5454 | 0x8 /*,0x6*/ |
5529 | [CXD9872AKD_VAIO] = "vaio-ar", | ||
5530 | }; | 5455 | }; |
5531 | 5456 | ||
5532 | static struct snd_pci_quirk stac9872_cfg_tbl[] = { | 5457 | static hda_nid_t stac9872_mux_nids[] = { |
5533 | SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO), | 5458 | 0x15 |
5534 | SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO), | ||
5535 | SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO), | ||
5536 | SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO), | ||
5537 | {} | ||
5538 | }; | 5459 | }; |
5539 | 5460 | ||
5540 | static int patch_stac9872(struct hda_codec *codec) | 5461 | static int patch_stac9872(struct hda_codec *codec) |
5541 | { | 5462 | { |
5542 | struct sigmatel_spec *spec; | 5463 | struct sigmatel_spec *spec; |
5543 | int board_config; | 5464 | int err; |
5544 | 5465 | ||
5545 | board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS, | ||
5546 | stac9872_models, | ||
5547 | stac9872_cfg_tbl); | ||
5548 | if (board_config < 0) | ||
5549 | /* unknown config, let generic-parser do its job... */ | ||
5550 | return snd_hda_parse_generic_codec(codec); | ||
5551 | |||
5552 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 5466 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
5553 | if (spec == NULL) | 5467 | if (spec == NULL) |
5554 | return -ENOMEM; | 5468 | return -ENOMEM; |
5555 | |||
5556 | codec->spec = spec; | 5469 | codec->spec = spec; |
5557 | switch (board_config) { | ||
5558 | case CXD9872RD_VAIO: | ||
5559 | case STAC9872AK_VAIO: | ||
5560 | case STAC9872K_VAIO: | ||
5561 | spec->mixer = vaio_mixer; | ||
5562 | spec->init = vaio_init; | ||
5563 | spec->multiout.max_channels = 2; | ||
5564 | spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs); | ||
5565 | spec->multiout.dac_nids = vaio_dacs; | ||
5566 | spec->multiout.hp_nid = VAIO_HP_DAC; | ||
5567 | spec->num_adcs = ARRAY_SIZE(vaio_adcs); | ||
5568 | spec->adc_nids = vaio_adcs; | ||
5569 | spec->num_pwrs = 0; | ||
5570 | spec->input_mux = &vaio_mux; | ||
5571 | spec->mux_nids = vaio_mux_nids; | ||
5572 | codec->patch_ops = stac9872_vaio_patch_ops; | ||
5573 | break; | ||
5574 | |||
5575 | case CXD9872AKD_VAIO: | ||
5576 | spec->mixer = vaio_ar_mixer; | ||
5577 | spec->init = vaio_ar_init; | ||
5578 | spec->multiout.max_channels = 2; | ||
5579 | spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs); | ||
5580 | spec->multiout.dac_nids = vaio_dacs; | ||
5581 | spec->multiout.hp_nid = VAIO_HP_DAC; | ||
5582 | spec->num_adcs = ARRAY_SIZE(vaio_adcs); | ||
5583 | spec->num_pwrs = 0; | ||
5584 | spec->adc_nids = vaio_adcs; | ||
5585 | spec->input_mux = &vaio_mux; | ||
5586 | spec->mux_nids = vaio_mux_nids; | ||
5587 | codec->patch_ops = stac9872_patch_ops; | ||
5588 | break; | ||
5589 | } | ||
5590 | 5470 | ||
5471 | #if 0 /* no model right now */ | ||
5472 | spec->board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS, | ||
5473 | stac9872_models, | ||
5474 | stac9872_cfg_tbl); | ||
5475 | #endif | ||
5476 | |||
5477 | spec->num_pins = ARRAY_SIZE(stac9872_pin_nids); | ||
5478 | spec->pin_nids = stac9872_pin_nids; | ||
5479 | spec->multiout.dac_nids = spec->dac_nids; | ||
5480 | spec->num_adcs = ARRAY_SIZE(stac9872_adc_nids); | ||
5481 | spec->adc_nids = stac9872_adc_nids; | ||
5482 | spec->num_muxes = ARRAY_SIZE(stac9872_mux_nids); | ||
5483 | spec->mux_nids = stac9872_mux_nids; | ||
5484 | spec->mixer = stac9872_mixer; | ||
5485 | spec->init = stac9872_core_init; | ||
5486 | |||
5487 | err = stac92xx_parse_auto_config(codec, 0x10, 0x12); | ||
5488 | if (err < 0) { | ||
5489 | stac92xx_free(codec); | ||
5490 | return -EINVAL; | ||
5491 | } | ||
5492 | spec->input_mux = &spec->private_imux; | ||
5493 | codec->patch_ops = stac92xx_patch_ops; | ||
5591 | return 0; | 5494 | return 0; |
5592 | } | 5495 | } |
5593 | 5496 | ||