diff options
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 1353 |
1 files changed, 712 insertions, 641 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 38428e22428f..b5e108aa8f63 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,22 +84,27 @@ 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, |
92 | STAC_DELL_M4_3, | 99 | STAC_DELL_M4_3, |
93 | STAC_HP_M4, | 100 | STAC_HP_M4, |
94 | STAC_HP_DV5, | 101 | STAC_HP_DV5, |
102 | STAC_HP_HDX, | ||
95 | STAC_92HD71BXX_MODELS | 103 | STAC_92HD71BXX_MODELS |
96 | }; | 104 | }; |
97 | 105 | ||
98 | enum { | 106 | enum { |
107 | STAC_925x_AUTO, | ||
99 | STAC_925x_REF, | 108 | STAC_925x_REF, |
100 | STAC_M1, | 109 | STAC_M1, |
101 | STAC_M1_2, | 110 | STAC_M1_2, |
@@ -108,6 +117,7 @@ enum { | |||
108 | }; | 117 | }; |
109 | 118 | ||
110 | enum { | 119 | enum { |
120 | STAC_922X_AUTO, | ||
111 | STAC_D945_REF, | 121 | STAC_D945_REF, |
112 | STAC_D945GTP3, | 122 | STAC_D945GTP3, |
113 | STAC_D945GTP5, | 123 | STAC_D945GTP5, |
@@ -135,6 +145,7 @@ enum { | |||
135 | }; | 145 | }; |
136 | 146 | ||
137 | enum { | 147 | enum { |
148 | STAC_927X_AUTO, | ||
138 | STAC_D965_REF_NO_JD, /* no jack-detection */ | 149 | STAC_D965_REF_NO_JD, /* no jack-detection */ |
139 | STAC_D965_REF, | 150 | STAC_D965_REF, |
140 | STAC_D965_3ST, | 151 | STAC_D965_3ST, |
@@ -144,6 +155,12 @@ enum { | |||
144 | STAC_927X_MODELS | 155 | STAC_927X_MODELS |
145 | }; | 156 | }; |
146 | 157 | ||
158 | enum { | ||
159 | STAC_9872_AUTO, | ||
160 | STAC_9872_VAIO, | ||
161 | STAC_9872_MODELS | ||
162 | }; | ||
163 | |||
147 | struct sigmatel_event { | 164 | struct sigmatel_event { |
148 | hda_nid_t nid; | 165 | hda_nid_t nid; |
149 | unsigned char type; | 166 | unsigned char type; |
@@ -167,6 +184,7 @@ struct sigmatel_spec { | |||
167 | unsigned int alt_switch: 1; | 184 | unsigned int alt_switch: 1; |
168 | unsigned int hp_detect: 1; | 185 | unsigned int hp_detect: 1; |
169 | unsigned int spdif_mute: 1; | 186 | unsigned int spdif_mute: 1; |
187 | unsigned int check_volume_offset:1; | ||
170 | 188 | ||
171 | /* gpio lines */ | 189 | /* gpio lines */ |
172 | unsigned int eapd_mask; | 190 | unsigned int eapd_mask; |
@@ -179,6 +197,7 @@ struct sigmatel_spec { | |||
179 | unsigned int stream_delay; | 197 | unsigned int stream_delay; |
180 | 198 | ||
181 | /* analog loopback */ | 199 | /* analog loopback */ |
200 | struct snd_kcontrol_new *aloopback_ctl; | ||
182 | unsigned char aloopback_mask; | 201 | unsigned char aloopback_mask; |
183 | unsigned char aloopback_shift; | 202 | unsigned char aloopback_shift; |
184 | 203 | ||
@@ -203,6 +222,8 @@ struct sigmatel_spec { | |||
203 | hda_nid_t hp_dacs[5]; | 222 | hda_nid_t hp_dacs[5]; |
204 | hda_nid_t speaker_dacs[5]; | 223 | hda_nid_t speaker_dacs[5]; |
205 | 224 | ||
225 | int volume_offset; | ||
226 | |||
206 | /* capture */ | 227 | /* capture */ |
207 | hda_nid_t *adc_nids; | 228 | hda_nid_t *adc_nids; |
208 | unsigned int num_adcs; | 229 | unsigned int num_adcs; |
@@ -224,7 +245,6 @@ struct sigmatel_spec { | |||
224 | /* pin widgets */ | 245 | /* pin widgets */ |
225 | hda_nid_t *pin_nids; | 246 | hda_nid_t *pin_nids; |
226 | unsigned int num_pins; | 247 | unsigned int num_pins; |
227 | unsigned int *pin_configs; | ||
228 | 248 | ||
229 | /* codec specific stuff */ | 249 | /* codec specific stuff */ |
230 | struct hda_verb *init; | 250 | struct hda_verb *init; |
@@ -400,6 +420,10 @@ static hda_nid_t stac922x_mux_nids[2] = { | |||
400 | 0x12, 0x13, | 420 | 0x12, 0x13, |
401 | }; | 421 | }; |
402 | 422 | ||
423 | static hda_nid_t stac927x_slave_dig_outs[2] = { | ||
424 | 0x1f, 0, | ||
425 | }; | ||
426 | |||
403 | static hda_nid_t stac927x_adc_nids[3] = { | 427 | static hda_nid_t stac927x_adc_nids[3] = { |
404 | 0x07, 0x08, 0x09 | 428 | 0x07, 0x08, 0x09 |
405 | }; | 429 | }; |
@@ -472,15 +496,21 @@ static hda_nid_t stac92hd73xx_pin_nids[13] = { | |||
472 | 0x14, 0x22, 0x23 | 496 | 0x14, 0x22, 0x23 |
473 | }; | 497 | }; |
474 | 498 | ||
475 | static hda_nid_t stac92hd83xxx_pin_nids[14] = { | 499 | static hda_nid_t stac92hd83xxx_pin_nids[10] = { |
476 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | 500 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, |
477 | 0x0f, 0x10, 0x11, 0x12, 0x13, | 501 | 0x0f, 0x10, 0x11, 0x1f, 0x20, |
478 | 0x1d, 0x1e, 0x1f, 0x20 | 502 | }; |
503 | |||
504 | #define STAC92HD71BXX_NUM_PINS 13 | ||
505 | static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { | ||
506 | 0x0a, 0x0b, 0x0c, 0x0d, 0x00, | ||
507 | 0x00, 0x14, 0x18, 0x19, 0x1e, | ||
508 | 0x1f, 0x20, 0x27 | ||
479 | }; | 509 | }; |
480 | static hda_nid_t stac92hd71bxx_pin_nids[11] = { | 510 | static hda_nid_t stac92hd71bxx_pin_nids_6port[STAC92HD71BXX_NUM_PINS] = { |
481 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | 511 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, |
482 | 0x0f, 0x14, 0x18, 0x19, 0x1e, | 512 | 0x0f, 0x14, 0x18, 0x19, 0x1e, |
483 | 0x1f, | 513 | 0x1f, 0x20, 0x27 |
484 | }; | 514 | }; |
485 | 515 | ||
486 | static hda_nid_t stac927x_pin_nids[14] = { | 516 | static hda_nid_t stac927x_pin_nids[14] = { |
@@ -842,9 +872,9 @@ static struct hda_verb stac92hd73xx_10ch_core_init[] = { | |||
842 | }; | 872 | }; |
843 | 873 | ||
844 | static struct hda_verb stac92hd83xxx_core_init[] = { | 874 | static struct hda_verb stac92hd83xxx_core_init[] = { |
845 | { 0xa, AC_VERB_SET_CONNECT_SEL, 0x0}, | 875 | { 0xa, AC_VERB_SET_CONNECT_SEL, 0x1}, |
846 | { 0xb, AC_VERB_SET_CONNECT_SEL, 0x0}, | 876 | { 0xb, AC_VERB_SET_CONNECT_SEL, 0x1}, |
847 | { 0xd, AC_VERB_SET_CONNECT_SEL, 0x1}, | 877 | { 0xd, AC_VERB_SET_CONNECT_SEL, 0x0}, |
848 | 878 | ||
849 | /* power state controls amps */ | 879 | /* power state controls amps */ |
850 | { 0x01, AC_VERB_SET_EAPD, 1 << 2}, | 880 | { 0x01, AC_VERB_SET_EAPD, 1 << 2}, |
@@ -854,26 +884,25 @@ static struct hda_verb stac92hd83xxx_core_init[] = { | |||
854 | static struct hda_verb stac92hd71bxx_core_init[] = { | 884 | static struct hda_verb stac92hd71bxx_core_init[] = { |
855 | /* set master volume and direct control */ | 885 | /* set master volume and direct control */ |
856 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 886 | { 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 | {} | 887 | {} |
862 | }; | 888 | }; |
863 | 889 | ||
864 | #define HD_DISABLE_PORTF 2 | 890 | #define HD_DISABLE_PORTF 1 |
865 | static struct hda_verb stac92hd71bxx_analog_core_init[] = { | 891 | static struct hda_verb stac92hd71bxx_analog_core_init[] = { |
866 | /* start of config #1 */ | 892 | /* start of config #1 */ |
867 | 893 | ||
868 | /* connect port 0f to audio mixer */ | 894 | /* connect port 0f to audio mixer */ |
869 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, | 895 | { 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 */ | 896 | /* start of config #2 */ |
873 | 897 | ||
874 | /* set master volume and direct control */ | 898 | /* set master volume and direct control */ |
875 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 899 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
876 | /* unmute right and left channels for nodes 0x0a, 0xd */ | 900 | {} |
901 | }; | ||
902 | |||
903 | static struct hda_verb stac92hd71bxx_unmute_core_init[] = { | ||
904 | /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */ | ||
905 | { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
877 | { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 906 | { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
878 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 907 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
879 | {} | 908 | {} |
@@ -954,16 +983,6 @@ static struct hda_verb stac9205_core_init[] = { | |||
954 | .private_value = HDA_COMPOSE_AMP_VAL(nid, chs, idx, dir) \ | 983 | .private_value = HDA_COMPOSE_AMP_VAL(nid, chs, idx, dir) \ |
955 | } | 984 | } |
956 | 985 | ||
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) \ | 986 | #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \ |
968 | { \ | 987 | { \ |
969 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 988 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
@@ -978,7 +997,6 @@ static struct hda_verb stac9205_core_init[] = { | |||
978 | static struct snd_kcontrol_new stac9200_mixer[] = { | 997 | static struct snd_kcontrol_new stac9200_mixer[] = { |
979 | HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), | 998 | HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), |
980 | HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), | 999 | 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), | 1000 | HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), |
983 | HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), | 1001 | HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), |
984 | { } /* end */ | 1002 | { } /* end */ |
@@ -1003,8 +1021,6 @@ static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = { | |||
1003 | HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT), | 1021 | HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT), |
1004 | HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT), | 1022 | HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT), |
1005 | 1023 | ||
1006 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3), | ||
1007 | |||
1008 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), | 1024 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), |
1009 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), | 1025 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), |
1010 | 1026 | ||
@@ -1014,9 +1030,22 @@ static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = { | |||
1014 | { } /* end */ | 1030 | { } /* end */ |
1015 | }; | 1031 | }; |
1016 | 1032 | ||
1017 | static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = { | 1033 | static struct snd_kcontrol_new stac92hd73xx_6ch_loopback[] = { |
1034 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3), | ||
1035 | {} | ||
1036 | }; | ||
1037 | |||
1038 | static struct snd_kcontrol_new stac92hd73xx_8ch_loopback[] = { | ||
1018 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4), | 1039 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4), |
1040 | {} | ||
1041 | }; | ||
1019 | 1042 | ||
1043 | static struct snd_kcontrol_new stac92hd73xx_10ch_loopback[] = { | ||
1044 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5), | ||
1045 | {} | ||
1046 | }; | ||
1047 | |||
1048 | static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = { | ||
1020 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), | 1049 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), |
1021 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), | 1050 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), |
1022 | 1051 | ||
@@ -1041,8 +1070,6 @@ static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = { | |||
1041 | }; | 1070 | }; |
1042 | 1071 | ||
1043 | static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = { | 1072 | static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = { |
1044 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5), | ||
1045 | |||
1046 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), | 1073 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), |
1047 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), | 1074 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), |
1048 | 1075 | ||
@@ -1094,9 +1121,6 @@ static struct snd_kcontrol_new stac92hd83xxx_mixer[] = { | |||
1094 | }; | 1121 | }; |
1095 | 1122 | ||
1096 | static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { | 1123 | static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { |
1097 | STAC_INPUT_SOURCE(2), | ||
1098 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2), | ||
1099 | |||
1100 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), | 1124 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), |
1101 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), | 1125 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), |
1102 | 1126 | ||
@@ -1122,10 +1146,11 @@ static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { | |||
1122 | { } /* end */ | 1146 | { } /* end */ |
1123 | }; | 1147 | }; |
1124 | 1148 | ||
1125 | static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { | 1149 | static struct snd_kcontrol_new stac92hd71bxx_loopback[] = { |
1126 | STAC_INPUT_SOURCE(2), | 1150 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2) |
1127 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2), | 1151 | }; |
1128 | 1152 | ||
1153 | static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { | ||
1129 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), | 1154 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), |
1130 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), | 1155 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), |
1131 | 1156 | ||
@@ -1137,16 +1162,12 @@ static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { | |||
1137 | static struct snd_kcontrol_new stac925x_mixer[] = { | 1162 | static struct snd_kcontrol_new stac925x_mixer[] = { |
1138 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT), | 1163 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT), |
1139 | HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), | 1164 | 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), | 1165 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), |
1142 | HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT), | 1166 | HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT), |
1143 | { } /* end */ | 1167 | { } /* end */ |
1144 | }; | 1168 | }; |
1145 | 1169 | ||
1146 | static struct snd_kcontrol_new stac9205_mixer[] = { | 1170 | static struct snd_kcontrol_new stac9205_mixer[] = { |
1147 | STAC_INPUT_SOURCE(2), | ||
1148 | STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1), | ||
1149 | |||
1150 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT), | 1171 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT), |
1151 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT), | 1172 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT), |
1152 | 1173 | ||
@@ -1155,9 +1176,13 @@ static struct snd_kcontrol_new stac9205_mixer[] = { | |||
1155 | { } /* end */ | 1176 | { } /* end */ |
1156 | }; | 1177 | }; |
1157 | 1178 | ||
1179 | static struct snd_kcontrol_new stac9205_loopback[] = { | ||
1180 | STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1), | ||
1181 | {} | ||
1182 | }; | ||
1183 | |||
1158 | /* This needs to be generated dynamically based on sequence */ | 1184 | /* This needs to be generated dynamically based on sequence */ |
1159 | static struct snd_kcontrol_new stac922x_mixer[] = { | 1185 | static struct snd_kcontrol_new stac922x_mixer[] = { |
1160 | STAC_INPUT_SOURCE(2), | ||
1161 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT), | 1186 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT), |
1162 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT), | 1187 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT), |
1163 | 1188 | ||
@@ -1168,9 +1193,6 @@ static struct snd_kcontrol_new stac922x_mixer[] = { | |||
1168 | 1193 | ||
1169 | 1194 | ||
1170 | static struct snd_kcontrol_new stac927x_mixer[] = { | 1195 | static struct snd_kcontrol_new stac927x_mixer[] = { |
1171 | STAC_INPUT_SOURCE(3), | ||
1172 | STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1), | ||
1173 | |||
1174 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT), | 1196 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT), |
1175 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT), | 1197 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT), |
1176 | 1198 | ||
@@ -1182,6 +1204,11 @@ static struct snd_kcontrol_new stac927x_mixer[] = { | |||
1182 | { } /* end */ | 1204 | { } /* end */ |
1183 | }; | 1205 | }; |
1184 | 1206 | ||
1207 | static struct snd_kcontrol_new stac927x_loopback[] = { | ||
1208 | STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1), | ||
1209 | {} | ||
1210 | }; | ||
1211 | |||
1185 | static struct snd_kcontrol_new stac_dmux_mixer = { | 1212 | static struct snd_kcontrol_new stac_dmux_mixer = { |
1186 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1213 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1187 | .name = "Digital Input Source", | 1214 | .name = "Digital Input Source", |
@@ -1207,10 +1234,7 @@ static const char *slave_vols[] = { | |||
1207 | "LFE Playback Volume", | 1234 | "LFE Playback Volume", |
1208 | "Side Playback Volume", | 1235 | "Side Playback Volume", |
1209 | "Headphone Playback Volume", | 1236 | "Headphone Playback Volume", |
1210 | "Headphone Playback Volume", | ||
1211 | "Speaker Playback Volume", | 1237 | "Speaker Playback Volume", |
1212 | "External Speaker Playback Volume", | ||
1213 | "Speaker2 Playback Volume", | ||
1214 | NULL | 1238 | NULL |
1215 | }; | 1239 | }; |
1216 | 1240 | ||
@@ -1221,10 +1245,7 @@ static const char *slave_sws[] = { | |||
1221 | "LFE Playback Switch", | 1245 | "LFE Playback Switch", |
1222 | "Side Playback Switch", | 1246 | "Side Playback Switch", |
1223 | "Headphone Playback Switch", | 1247 | "Headphone Playback Switch", |
1224 | "Headphone Playback Switch", | ||
1225 | "Speaker Playback Switch", | 1248 | "Speaker Playback Switch", |
1226 | "External Speaker Playback Switch", | ||
1227 | "Speaker2 Playback Switch", | ||
1228 | "IEC958 Playback Switch", | 1249 | "IEC958 Playback Switch", |
1229 | NULL | 1250 | NULL |
1230 | }; | 1251 | }; |
@@ -1294,6 +1315,8 @@ static int stac92xx_build_controls(struct hda_codec *codec) | |||
1294 | unsigned int vmaster_tlv[4]; | 1315 | unsigned int vmaster_tlv[4]; |
1295 | snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], | 1316 | snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], |
1296 | HDA_OUTPUT, vmaster_tlv); | 1317 | HDA_OUTPUT, vmaster_tlv); |
1318 | /* correct volume offset */ | ||
1319 | vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset; | ||
1297 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", | 1320 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", |
1298 | vmaster_tlv, slave_vols); | 1321 | vmaster_tlv, slave_vols); |
1299 | if (err < 0) | 1322 | if (err < 0) |
@@ -1306,6 +1329,13 @@ static int stac92xx_build_controls(struct hda_codec *codec) | |||
1306 | return err; | 1329 | return err; |
1307 | } | 1330 | } |
1308 | 1331 | ||
1332 | if (spec->aloopback_ctl && | ||
1333 | snd_hda_get_bool_hint(codec, "loopback") == 1) { | ||
1334 | err = snd_hda_add_new_ctls(codec, spec->aloopback_ctl); | ||
1335 | if (err < 0) | ||
1336 | return err; | ||
1337 | } | ||
1338 | |||
1309 | stac92xx_free_kctls(codec); /* no longer needed */ | 1339 | stac92xx_free_kctls(codec); /* no longer needed */ |
1310 | 1340 | ||
1311 | /* create jack input elements */ | 1341 | /* create jack input elements */ |
@@ -1490,6 +1520,7 @@ static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = { | |||
1490 | }; | 1520 | }; |
1491 | 1521 | ||
1492 | static const char *stac9200_models[STAC_9200_MODELS] = { | 1522 | static const char *stac9200_models[STAC_9200_MODELS] = { |
1523 | [STAC_AUTO] = "auto", | ||
1493 | [STAC_REF] = "ref", | 1524 | [STAC_REF] = "ref", |
1494 | [STAC_9200_OQO] = "oqo", | 1525 | [STAC_9200_OQO] = "oqo", |
1495 | [STAC_9200_DELL_D21] = "dell-d21", | 1526 | [STAC_9200_DELL_D21] = "dell-d21", |
@@ -1511,6 +1542,8 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = { | |||
1511 | /* SigmaTel reference board */ | 1542 | /* SigmaTel reference board */ |
1512 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1543 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1513 | "DFI LanParty", STAC_REF), | 1544 | "DFI LanParty", STAC_REF), |
1545 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, | ||
1546 | "DFI LanParty", STAC_REF), | ||
1514 | /* Dell laptops have BIOS problem */ | 1547 | /* Dell laptops have BIOS problem */ |
1515 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8, | 1548 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8, |
1516 | "unknown Dell", STAC_9200_DELL_D21), | 1549 | "unknown Dell", STAC_9200_DELL_D21), |
@@ -1633,6 +1666,7 @@ static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = { | |||
1633 | }; | 1666 | }; |
1634 | 1667 | ||
1635 | static const char *stac925x_models[STAC_925x_MODELS] = { | 1668 | static const char *stac925x_models[STAC_925x_MODELS] = { |
1669 | [STAC_925x_AUTO] = "auto", | ||
1636 | [STAC_REF] = "ref", | 1670 | [STAC_REF] = "ref", |
1637 | [STAC_M1] = "m1", | 1671 | [STAC_M1] = "m1", |
1638 | [STAC_M1_2] = "m1-2", | 1672 | [STAC_M1_2] = "m1-2", |
@@ -1660,6 +1694,7 @@ static struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = { | |||
1660 | static struct snd_pci_quirk stac925x_cfg_tbl[] = { | 1694 | static struct snd_pci_quirk stac925x_cfg_tbl[] = { |
1661 | /* SigmaTel reference board */ | 1695 | /* SigmaTel reference board */ |
1662 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), | 1696 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), |
1697 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF), | ||
1663 | SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF), | 1698 | SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF), |
1664 | 1699 | ||
1665 | /* Default table for unknown ID */ | 1700 | /* Default table for unknown ID */ |
@@ -1691,6 +1726,7 @@ static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { | |||
1691 | }; | 1726 | }; |
1692 | 1727 | ||
1693 | static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { | 1728 | static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { |
1729 | [STAC_92HD73XX_AUTO] = "auto", | ||
1694 | [STAC_92HD73XX_NO_JD] = "no-jd", | 1730 | [STAC_92HD73XX_NO_JD] = "no-jd", |
1695 | [STAC_92HD73XX_REF] = "ref", | 1731 | [STAC_92HD73XX_REF] = "ref", |
1696 | [STAC_DELL_M6_AMIC] = "dell-m6-amic", | 1732 | [STAC_DELL_M6_AMIC] = "dell-m6-amic", |
@@ -1703,6 +1739,8 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { | |||
1703 | /* SigmaTel reference board */ | 1739 | /* SigmaTel reference board */ |
1704 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1740 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1705 | "DFI LanParty", STAC_92HD73XX_REF), | 1741 | "DFI LanParty", STAC_92HD73XX_REF), |
1742 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, | ||
1743 | "DFI LanParty", STAC_92HD73XX_REF), | ||
1706 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254, | 1744 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254, |
1707 | "Dell Studio 1535", STAC_DELL_M6_DMIC), | 1745 | "Dell Studio 1535", STAC_DELL_M6_DMIC), |
1708 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255, | 1746 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255, |
@@ -1726,52 +1764,68 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { | |||
1726 | {} /* terminator */ | 1764 | {} /* terminator */ |
1727 | }; | 1765 | }; |
1728 | 1766 | ||
1729 | static unsigned int ref92hd83xxx_pin_configs[14] = { | 1767 | static unsigned int ref92hd83xxx_pin_configs[10] = { |
1730 | 0x02214030, 0x02211010, 0x02a19020, 0x02170130, | 1768 | 0x02214030, 0x02211010, 0x02a19020, 0x02170130, |
1731 | 0x01014050, 0x01819040, 0x01014020, 0x90a3014e, | 1769 | 0x01014050, 0x01819040, 0x01014020, 0x90a3014e, |
1732 | 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x40f000f0, | ||
1733 | 0x01451160, 0x98560170, | 1770 | 0x01451160, 0x98560170, |
1734 | }; | 1771 | }; |
1735 | 1772 | ||
1773 | static unsigned int dell_s14_pin_configs[10] = { | ||
1774 | 0x02214030, 0x02211010, 0x02a19020, 0x01014050, | ||
1775 | 0x40f000f0, 0x01819040, 0x40f000f0, 0x90a60160, | ||
1776 | 0x40f000f0, 0x40f000f0, | ||
1777 | }; | ||
1778 | |||
1736 | static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { | 1779 | static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { |
1737 | [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, | 1780 | [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, |
1738 | [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, | 1781 | [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, |
1782 | [STAC_DELL_S14] = dell_s14_pin_configs, | ||
1739 | }; | 1783 | }; |
1740 | 1784 | ||
1741 | static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { | 1785 | static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { |
1786 | [STAC_92HD83XXX_AUTO] = "auto", | ||
1742 | [STAC_92HD83XXX_REF] = "ref", | 1787 | [STAC_92HD83XXX_REF] = "ref", |
1743 | [STAC_92HD83XXX_PWR_REF] = "mic-ref", | 1788 | [STAC_92HD83XXX_PWR_REF] = "mic-ref", |
1789 | [STAC_DELL_S14] = "dell-s14", | ||
1744 | }; | 1790 | }; |
1745 | 1791 | ||
1746 | static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { | 1792 | static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { |
1747 | /* SigmaTel reference board */ | 1793 | /* SigmaTel reference board */ |
1748 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1794 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1749 | "DFI LanParty", STAC_92HD83XXX_REF), | 1795 | "DFI LanParty", STAC_92HD83XXX_REF), |
1796 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, | ||
1797 | "DFI LanParty", STAC_92HD83XXX_REF), | ||
1798 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ba, | ||
1799 | "unknown Dell", STAC_DELL_S14), | ||
1750 | {} /* terminator */ | 1800 | {} /* terminator */ |
1751 | }; | 1801 | }; |
1752 | 1802 | ||
1753 | static unsigned int ref92hd71bxx_pin_configs[11] = { | 1803 | static unsigned int ref92hd71bxx_pin_configs[STAC92HD71BXX_NUM_PINS] = { |
1754 | 0x02214030, 0x02a19040, 0x01a19020, 0x01014010, | 1804 | 0x02214030, 0x02a19040, 0x01a19020, 0x01014010, |
1755 | 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0, | 1805 | 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0, |
1756 | 0x90a000f0, 0x01452050, 0x01452050, | 1806 | 0x90a000f0, 0x01452050, 0x01452050, 0x00000000, |
1807 | 0x00000000 | ||
1757 | }; | 1808 | }; |
1758 | 1809 | ||
1759 | static unsigned int dell_m4_1_pin_configs[11] = { | 1810 | static unsigned int dell_m4_1_pin_configs[STAC92HD71BXX_NUM_PINS] = { |
1760 | 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, | 1811 | 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, |
1761 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, | 1812 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, |
1762 | 0x40f000f0, 0x4f0000f0, 0x4f0000f0, | 1813 | 0x40f000f0, 0x4f0000f0, 0x4f0000f0, 0x00000000, |
1814 | 0x00000000 | ||
1763 | }; | 1815 | }; |
1764 | 1816 | ||
1765 | static unsigned int dell_m4_2_pin_configs[11] = { | 1817 | static unsigned int dell_m4_2_pin_configs[STAC92HD71BXX_NUM_PINS] = { |
1766 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, | 1818 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, |
1767 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, | 1819 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, |
1768 | 0x40f000f0, 0x044413b0, 0x044413b0, | 1820 | 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000, |
1821 | 0x00000000 | ||
1769 | }; | 1822 | }; |
1770 | 1823 | ||
1771 | static unsigned int dell_m4_3_pin_configs[11] = { | 1824 | static unsigned int dell_m4_3_pin_configs[STAC92HD71BXX_NUM_PINS] = { |
1772 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, | 1825 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, |
1773 | 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a000f0, | 1826 | 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a000f0, |
1774 | 0x40f000f0, 0x044413b0, 0x044413b0, | 1827 | 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000, |
1828 | 0x00000000 | ||
1775 | }; | 1829 | }; |
1776 | 1830 | ||
1777 | static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { | 1831 | static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { |
@@ -1781,35 +1835,38 @@ static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { | |||
1781 | [STAC_DELL_M4_3] = dell_m4_3_pin_configs, | 1835 | [STAC_DELL_M4_3] = dell_m4_3_pin_configs, |
1782 | [STAC_HP_M4] = NULL, | 1836 | [STAC_HP_M4] = NULL, |
1783 | [STAC_HP_DV5] = NULL, | 1837 | [STAC_HP_DV5] = NULL, |
1838 | [STAC_HP_HDX] = NULL, | ||
1784 | }; | 1839 | }; |
1785 | 1840 | ||
1786 | static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { | 1841 | static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { |
1842 | [STAC_92HD71BXX_AUTO] = "auto", | ||
1787 | [STAC_92HD71BXX_REF] = "ref", | 1843 | [STAC_92HD71BXX_REF] = "ref", |
1788 | [STAC_DELL_M4_1] = "dell-m4-1", | 1844 | [STAC_DELL_M4_1] = "dell-m4-1", |
1789 | [STAC_DELL_M4_2] = "dell-m4-2", | 1845 | [STAC_DELL_M4_2] = "dell-m4-2", |
1790 | [STAC_DELL_M4_3] = "dell-m4-3", | 1846 | [STAC_DELL_M4_3] = "dell-m4-3", |
1791 | [STAC_HP_M4] = "hp-m4", | 1847 | [STAC_HP_M4] = "hp-m4", |
1792 | [STAC_HP_DV5] = "hp-dv5", | 1848 | [STAC_HP_DV5] = "hp-dv5", |
1849 | [STAC_HP_HDX] = "hp-hdx", | ||
1793 | }; | 1850 | }; |
1794 | 1851 | ||
1795 | static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { | 1852 | static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { |
1796 | /* SigmaTel reference board */ | 1853 | /* SigmaTel reference board */ |
1797 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1854 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1798 | "DFI LanParty", STAC_92HD71BXX_REF), | 1855 | "DFI LanParty", STAC_92HD71BXX_REF), |
1799 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f2, | 1856 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, |
1800 | "HP dv5", STAC_HP_M4), | 1857 | "DFI LanParty", STAC_92HD71BXX_REF), |
1801 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4, | 1858 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080, |
1802 | "HP dv7", STAC_HP_M4), | 1859 | "HP", STAC_HP_DV5), |
1803 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f7, | 1860 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0, |
1804 | "HP dv4", STAC_HP_DV5), | 1861 | "HP dv4-7", STAC_HP_DV5), |
1805 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fc, | 1862 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600, |
1806 | "HP dv7", STAC_HP_M4), | 1863 | "HP dv4-7", STAC_HP_DV5), |
1807 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3600, | 1864 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3610, |
1808 | "HP dv5", STAC_HP_DV5), | 1865 | "HP HDX", STAC_HP_HDX), /* HDX18 */ |
1809 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3603, | ||
1810 | "HP dv5", STAC_HP_DV5), | ||
1811 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, | 1866 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, |
1812 | "unknown HP", STAC_HP_M4), | 1867 | "HP mini 1000", STAC_HP_M4), |
1868 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361b, | ||
1869 | "HP HDX", STAC_HP_HDX), /* HDX16 */ | ||
1813 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, | 1870 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, |
1814 | "unknown Dell", STAC_DELL_M4_1), | 1871 | "unknown Dell", STAC_DELL_M4_1), |
1815 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234, | 1872 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234, |
@@ -1961,6 +2018,7 @@ static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { | |||
1961 | }; | 2018 | }; |
1962 | 2019 | ||
1963 | static const char *stac922x_models[STAC_922X_MODELS] = { | 2020 | static const char *stac922x_models[STAC_922X_MODELS] = { |
2021 | [STAC_922X_AUTO] = "auto", | ||
1964 | [STAC_D945_REF] = "ref", | 2022 | [STAC_D945_REF] = "ref", |
1965 | [STAC_D945GTP5] = "5stack", | 2023 | [STAC_D945GTP5] = "5stack", |
1966 | [STAC_D945GTP3] = "3stack", | 2024 | [STAC_D945GTP3] = "3stack", |
@@ -1988,6 +2046,8 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = { | |||
1988 | /* SigmaTel reference board */ | 2046 | /* SigmaTel reference board */ |
1989 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 2047 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1990 | "DFI LanParty", STAC_D945_REF), | 2048 | "DFI LanParty", STAC_D945_REF), |
2049 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, | ||
2050 | "DFI LanParty", STAC_D945_REF), | ||
1991 | /* Intel 945G based systems */ | 2051 | /* Intel 945G based systems */ |
1992 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101, | 2052 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101, |
1993 | "Intel D945G", STAC_D945GTP3), | 2053 | "Intel D945G", STAC_D945GTP3), |
@@ -2041,6 +2101,9 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = { | |||
2041 | "Intel D945P", STAC_D945GTP3), | 2101 | "Intel D945P", STAC_D945GTP3), |
2042 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707, | 2102 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707, |
2043 | "Intel D945P", STAC_D945GTP5), | 2103 | "Intel D945P", STAC_D945GTP5), |
2104 | /* other intel */ | ||
2105 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0204, | ||
2106 | "Intel D945", STAC_D945_REF), | ||
2044 | /* other systems */ | 2107 | /* other systems */ |
2045 | /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */ | 2108 | /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */ |
2046 | SND_PCI_QUIRK(0x8384, 0x7680, | 2109 | SND_PCI_QUIRK(0x8384, 0x7680, |
@@ -2065,31 +2128,7 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = { | |||
2065 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7, | 2128 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7, |
2066 | "Dell XPS M1210", STAC_922X_DELL_M82), | 2129 | "Dell XPS M1210", STAC_922X_DELL_M82), |
2067 | /* ECS/PC Chips boards */ | 2130 | /* ECS/PC Chips boards */ |
2068 | SND_PCI_QUIRK(0x1019, 0x2144, | 2131 | 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), | 2132 | "ECS/PC chips", STAC_ECS_202), |
2094 | {} /* terminator */ | 2133 | {} /* terminator */ |
2095 | }; | 2134 | }; |
@@ -2132,6 +2171,7 @@ static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { | |||
2132 | }; | 2171 | }; |
2133 | 2172 | ||
2134 | static const char *stac927x_models[STAC_927X_MODELS] = { | 2173 | static const char *stac927x_models[STAC_927X_MODELS] = { |
2174 | [STAC_927X_AUTO] = "auto", | ||
2135 | [STAC_D965_REF_NO_JD] = "ref-no-jd", | 2175 | [STAC_D965_REF_NO_JD] = "ref-no-jd", |
2136 | [STAC_D965_REF] = "ref", | 2176 | [STAC_D965_REF] = "ref", |
2137 | [STAC_D965_3ST] = "3stack", | 2177 | [STAC_D965_3ST] = "3stack", |
@@ -2144,26 +2184,16 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = { | |||
2144 | /* SigmaTel reference board */ | 2184 | /* SigmaTel reference board */ |
2145 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 2185 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
2146 | "DFI LanParty", STAC_D965_REF), | 2186 | "DFI LanParty", STAC_D965_REF), |
2187 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, | ||
2188 | "DFI LanParty", STAC_D965_REF), | ||
2147 | /* Intel 946 based systems */ | 2189 | /* Intel 946 based systems */ |
2148 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x3d01, "Intel D946", STAC_D965_3ST), | 2190 | 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), | 2191 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0xa301, "Intel D946", STAC_D965_3ST), |
2150 | /* 965 based 3 stack systems */ | 2192 | /* 965 based 3 stack systems */ |
2151 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2116, "Intel D965", STAC_D965_3ST), | 2193 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2100, |
2152 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2115, "Intel D965", STAC_D965_3ST), | 2194 | "Intel D965", STAC_D965_3ST), |
2153 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2114, "Intel D965", STAC_D965_3ST), | 2195 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2000, |
2154 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2113, "Intel D965", STAC_D965_3ST), | 2196 | "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 */ | 2197 | /* Dell 3 stack systems */ |
2168 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_3ST), | 2198 | 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), | 2199 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST), |
@@ -2179,15 +2209,10 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = { | |||
2179 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS), | 2209 | 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), | 2210 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_DELL_BIOS), |
2181 | /* 965 based 5 stack systems */ | 2211 | /* 965 based 5 stack systems */ |
2182 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2301, "Intel D965", STAC_D965_5ST), | 2212 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2300, |
2183 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2302, "Intel D965", STAC_D965_5ST), | 2213 | "Intel D965", STAC_D965_5ST), |
2184 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2303, "Intel D965", STAC_D965_5ST), | 2214 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2500, |
2185 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2304, "Intel D965", STAC_D965_5ST), | 2215 | "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 */ | 2216 | {} /* terminator */ |
2192 | }; | 2217 | }; |
2193 | 2218 | ||
@@ -2240,19 +2265,25 @@ static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { | |||
2240 | [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs, | 2265 | [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs, |
2241 | [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs, | 2266 | [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs, |
2242 | [STAC_9205_DELL_M44] = dell_9205_m44_pin_configs, | 2267 | [STAC_9205_DELL_M44] = dell_9205_m44_pin_configs, |
2268 | [STAC_9205_EAPD] = NULL, | ||
2243 | }; | 2269 | }; |
2244 | 2270 | ||
2245 | static const char *stac9205_models[STAC_9205_MODELS] = { | 2271 | static const char *stac9205_models[STAC_9205_MODELS] = { |
2272 | [STAC_9205_AUTO] = "auto", | ||
2246 | [STAC_9205_REF] = "ref", | 2273 | [STAC_9205_REF] = "ref", |
2247 | [STAC_9205_DELL_M42] = "dell-m42", | 2274 | [STAC_9205_DELL_M42] = "dell-m42", |
2248 | [STAC_9205_DELL_M43] = "dell-m43", | 2275 | [STAC_9205_DELL_M43] = "dell-m43", |
2249 | [STAC_9205_DELL_M44] = "dell-m44", | 2276 | [STAC_9205_DELL_M44] = "dell-m44", |
2277 | [STAC_9205_EAPD] = "eapd", | ||
2250 | }; | 2278 | }; |
2251 | 2279 | ||
2252 | static struct snd_pci_quirk stac9205_cfg_tbl[] = { | 2280 | static struct snd_pci_quirk stac9205_cfg_tbl[] = { |
2253 | /* SigmaTel reference board */ | 2281 | /* SigmaTel reference board */ |
2254 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 2282 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
2255 | "DFI LanParty", STAC_9205_REF), | 2283 | "DFI LanParty", STAC_9205_REF), |
2284 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, | ||
2285 | "DFI LanParty", STAC_9205_REF), | ||
2286 | /* Dell */ | ||
2256 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1, | 2287 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1, |
2257 | "unknown Dell", STAC_9205_DELL_M42), | 2288 | "unknown Dell", STAC_9205_DELL_M42), |
2258 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2, | 2289 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2, |
@@ -2283,101 +2314,24 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { | |||
2283 | "Dell Inspiron", STAC_9205_DELL_M44), | 2314 | "Dell Inspiron", STAC_9205_DELL_M44), |
2284 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228, | 2315 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228, |
2285 | "Dell Vostro 1500", STAC_9205_DELL_M42), | 2316 | "Dell Vostro 1500", STAC_9205_DELL_M42), |
2317 | /* Gateway */ | ||
2318 | SND_PCI_QUIRK(0x107b, 0x0565, "Gateway T1616", STAC_9205_EAPD), | ||
2286 | {} /* terminator */ | 2319 | {} /* terminator */ |
2287 | }; | 2320 | }; |
2288 | 2321 | ||
2289 | static int stac92xx_save_bios_config_regs(struct hda_codec *codec) | 2322 | static void stac92xx_set_config_regs(struct hda_codec *codec, |
2290 | { | 2323 | 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 | { | 2324 | { |
2339 | int i; | 2325 | int i; |
2340 | struct sigmatel_spec *spec = codec->spec; | 2326 | struct sigmatel_spec *spec = codec->spec; |
2341 | 2327 | ||
2342 | if (!spec->pin_configs) | 2328 | if (!pincfgs) |
2343 | return; | 2329 | return; |
2344 | 2330 | ||
2345 | for (i = 0; i < spec->num_pins; i++) | 2331 | for (i = 0; i < spec->num_pins; i++) |
2346 | stac92xx_set_config_reg(codec, spec->pin_nids[i], | 2332 | if (spec->pin_nids[i] && pincfgs[i]) |
2347 | spec->pin_configs[i]); | 2333 | snd_hda_codec_set_pincfg(codec, spec->pin_nids[i], |
2348 | } | 2334 | 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 | } | 2335 | } |
2382 | 2336 | ||
2383 | /* | 2337 | /* |
@@ -2442,6 +2396,14 @@ static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
2442 | stream_tag, format, substream); | 2396 | stream_tag, format, substream); |
2443 | } | 2397 | } |
2444 | 2398 | ||
2399 | static int stac92xx_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
2400 | struct hda_codec *codec, | ||
2401 | struct snd_pcm_substream *substream) | ||
2402 | { | ||
2403 | struct sigmatel_spec *spec = codec->spec; | ||
2404 | return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); | ||
2405 | } | ||
2406 | |||
2445 | 2407 | ||
2446 | /* | 2408 | /* |
2447 | * Analog capture callbacks | 2409 | * Analog capture callbacks |
@@ -2486,7 +2448,8 @@ static struct hda_pcm_stream stac92xx_pcm_digital_playback = { | |||
2486 | .ops = { | 2448 | .ops = { |
2487 | .open = stac92xx_dig_playback_pcm_open, | 2449 | .open = stac92xx_dig_playback_pcm_open, |
2488 | .close = stac92xx_dig_playback_pcm_close, | 2450 | .close = stac92xx_dig_playback_pcm_close, |
2489 | .prepare = stac92xx_dig_playback_pcm_prepare | 2451 | .prepare = stac92xx_dig_playback_pcm_prepare, |
2452 | .cleanup = stac92xx_dig_playback_pcm_cleanup | ||
2490 | }, | 2453 | }, |
2491 | }; | 2454 | }; |
2492 | 2455 | ||
@@ -2558,7 +2521,7 @@ static int stac92xx_build_pcms(struct hda_codec *codec) | |||
2558 | codec->num_pcms++; | 2521 | codec->num_pcms++; |
2559 | info++; | 2522 | info++; |
2560 | info->name = "STAC92xx Digital"; | 2523 | info->name = "STAC92xx Digital"; |
2561 | info->pcm_type = HDA_PCM_TYPE_SPDIF; | 2524 | info->pcm_type = spec->autocfg.dig_out_type[0]; |
2562 | if (spec->multiout.dig_out_nid) { | 2525 | if (spec->multiout.dig_out_nid) { |
2563 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback; | 2526 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback; |
2564 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; | 2527 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; |
@@ -2574,8 +2537,7 @@ static int stac92xx_build_pcms(struct hda_codec *codec) | |||
2574 | 2537 | ||
2575 | static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid) | 2538 | static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid) |
2576 | { | 2539 | { |
2577 | unsigned int pincap = snd_hda_param_read(codec, nid, | 2540 | unsigned int pincap = snd_hda_query_pin_caps(codec, nid); |
2578 | AC_PAR_PIN_CAP); | ||
2579 | pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; | 2541 | pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; |
2580 | if (pincap & AC_PINCAP_VREF_100) | 2542 | if (pincap & AC_PINCAP_VREF_100) |
2581 | return AC_PINCTL_VREF_100; | 2543 | return AC_PINCTL_VREF_100; |
@@ -2750,22 +2712,37 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = { | |||
2750 | }; | 2712 | }; |
2751 | 2713 | ||
2752 | /* add dynamic controls */ | 2714 | /* add dynamic controls */ |
2753 | static int stac92xx_add_control_temp(struct sigmatel_spec *spec, | 2715 | static struct snd_kcontrol_new * |
2754 | struct snd_kcontrol_new *ktemp, | 2716 | stac_control_new(struct sigmatel_spec *spec, |
2755 | int idx, const char *name, | 2717 | struct snd_kcontrol_new *ktemp, |
2756 | unsigned long val) | 2718 | const char *name) |
2757 | { | 2719 | { |
2758 | struct snd_kcontrol_new *knew; | 2720 | struct snd_kcontrol_new *knew; |
2759 | 2721 | ||
2760 | snd_array_init(&spec->kctls, sizeof(*knew), 32); | 2722 | snd_array_init(&spec->kctls, sizeof(*knew), 32); |
2761 | knew = snd_array_new(&spec->kctls); | 2723 | knew = snd_array_new(&spec->kctls); |
2762 | if (!knew) | 2724 | if (!knew) |
2763 | return -ENOMEM; | 2725 | return NULL; |
2764 | *knew = *ktemp; | 2726 | *knew = *ktemp; |
2765 | knew->index = idx; | ||
2766 | knew->name = kstrdup(name, GFP_KERNEL); | 2727 | knew->name = kstrdup(name, GFP_KERNEL); |
2767 | if (!knew->name) | 2728 | if (!knew->name) { |
2729 | /* roolback */ | ||
2730 | memset(knew, 0, sizeof(*knew)); | ||
2731 | spec->kctls.alloced--; | ||
2732 | return NULL; | ||
2733 | } | ||
2734 | return knew; | ||
2735 | } | ||
2736 | |||
2737 | static int stac92xx_add_control_temp(struct sigmatel_spec *spec, | ||
2738 | struct snd_kcontrol_new *ktemp, | ||
2739 | int idx, const char *name, | ||
2740 | unsigned long val) | ||
2741 | { | ||
2742 | struct snd_kcontrol_new *knew = stac_control_new(spec, ktemp, name); | ||
2743 | if (!knew) | ||
2768 | return -ENOMEM; | 2744 | return -ENOMEM; |
2745 | knew->index = idx; | ||
2769 | knew->private_value = val; | 2746 | knew->private_value = val; |
2770 | return 0; | 2747 | return 0; |
2771 | } | 2748 | } |
@@ -2787,6 +2764,29 @@ static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type, | |||
2787 | return stac92xx_add_control_idx(spec, type, 0, name, val); | 2764 | return stac92xx_add_control_idx(spec, type, 0, name, val); |
2788 | } | 2765 | } |
2789 | 2766 | ||
2767 | static struct snd_kcontrol_new stac_input_src_temp = { | ||
2768 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
2769 | .name = "Input Source", | ||
2770 | .info = stac92xx_mux_enum_info, | ||
2771 | .get = stac92xx_mux_enum_get, | ||
2772 | .put = stac92xx_mux_enum_put, | ||
2773 | }; | ||
2774 | |||
2775 | static int stac92xx_add_input_source(struct sigmatel_spec *spec) | ||
2776 | { | ||
2777 | struct snd_kcontrol_new *knew; | ||
2778 | struct hda_input_mux *imux = &spec->private_imux; | ||
2779 | |||
2780 | if (!spec->num_adcs || imux->num_items <= 1) | ||
2781 | return 0; /* no need for input source control */ | ||
2782 | knew = stac_control_new(spec, &stac_input_src_temp, | ||
2783 | stac_input_src_temp.name); | ||
2784 | if (!knew) | ||
2785 | return -ENOMEM; | ||
2786 | knew->count = spec->num_adcs; | ||
2787 | return 0; | ||
2788 | } | ||
2789 | |||
2790 | /* check whether the line-input can be used as line-out */ | 2790 | /* check whether the line-input can be used as line-out */ |
2791 | static hda_nid_t check_line_out_switch(struct hda_codec *codec) | 2791 | static hda_nid_t check_line_out_switch(struct hda_codec *codec) |
2792 | { | 2792 | { |
@@ -2798,7 +2798,7 @@ static hda_nid_t check_line_out_switch(struct hda_codec *codec) | |||
2798 | if (cfg->line_out_type != AUTO_PIN_LINE_OUT) | 2798 | if (cfg->line_out_type != AUTO_PIN_LINE_OUT) |
2799 | return 0; | 2799 | return 0; |
2800 | nid = cfg->input_pins[AUTO_PIN_LINE]; | 2800 | nid = cfg->input_pins[AUTO_PIN_LINE]; |
2801 | pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); | 2801 | pincap = snd_hda_query_pin_caps(codec, nid); |
2802 | if (pincap & AC_PINCAP_OUT) | 2802 | if (pincap & AC_PINCAP_OUT) |
2803 | return nid; | 2803 | return nid; |
2804 | return 0; | 2804 | return 0; |
@@ -2817,12 +2817,11 @@ static hda_nid_t check_mic_out_switch(struct hda_codec *codec) | |||
2817 | mic_pin = AUTO_PIN_MIC; | 2817 | mic_pin = AUTO_PIN_MIC; |
2818 | for (;;) { | 2818 | for (;;) { |
2819 | hda_nid_t nid = cfg->input_pins[mic_pin]; | 2819 | hda_nid_t nid = cfg->input_pins[mic_pin]; |
2820 | def_conf = snd_hda_codec_read(codec, nid, 0, | 2820 | def_conf = snd_hda_codec_get_pincfg(codec, nid); |
2821 | AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
2822 | /* some laptops have an internal analog microphone | 2821 | /* some laptops have an internal analog microphone |
2823 | * which can't be used as a output */ | 2822 | * which can't be used as a output */ |
2824 | if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) { | 2823 | if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) { |
2825 | pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); | 2824 | pincap = snd_hda_query_pin_caps(codec, nid); |
2826 | if (pincap & AC_PINCAP_OUT) | 2825 | if (pincap & AC_PINCAP_OUT) |
2827 | return nid; | 2826 | return nid; |
2828 | } | 2827 | } |
@@ -2870,8 +2869,7 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid) | |||
2870 | conn_len = snd_hda_get_connections(codec, nid, conn, | 2869 | conn_len = snd_hda_get_connections(codec, nid, conn, |
2871 | HDA_MAX_CONNECTIONS); | 2870 | HDA_MAX_CONNECTIONS); |
2872 | for (j = 0; j < conn_len; j++) { | 2871 | for (j = 0; j < conn_len; j++) { |
2873 | wcaps = snd_hda_param_read(codec, conn[j], | 2872 | wcaps = get_wcaps(codec, conn[j]); |
2874 | AC_PAR_AUDIO_WIDGET_CAP); | ||
2875 | wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | 2873 | wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; |
2876 | /* we check only analog outputs */ | 2874 | /* we check only analog outputs */ |
2877 | if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL)) | 2875 | if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL)) |
@@ -2886,6 +2884,16 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid) | |||
2886 | return conn[j]; | 2884 | return conn[j]; |
2887 | } | 2885 | } |
2888 | } | 2886 | } |
2887 | /* if all DACs are already assigned, connect to the primary DAC */ | ||
2888 | if (conn_len > 1) { | ||
2889 | for (j = 0; j < conn_len; j++) { | ||
2890 | if (conn[j] == spec->multiout.dac_nids[0]) { | ||
2891 | snd_hda_codec_write_cache(codec, nid, 0, | ||
2892 | AC_VERB_SET_CONNECT_SEL, j); | ||
2893 | break; | ||
2894 | } | ||
2895 | } | ||
2896 | } | ||
2889 | return 0; | 2897 | return 0; |
2890 | } | 2898 | } |
2891 | 2899 | ||
@@ -2926,6 +2934,26 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec) | |||
2926 | add_spec_dacs(spec, dac); | 2934 | add_spec_dacs(spec, dac); |
2927 | } | 2935 | } |
2928 | 2936 | ||
2937 | for (i = 0; i < cfg->hp_outs; i++) { | ||
2938 | nid = cfg->hp_pins[i]; | ||
2939 | dac = get_unassigned_dac(codec, nid); | ||
2940 | if (dac) { | ||
2941 | if (!spec->multiout.hp_nid) | ||
2942 | spec->multiout.hp_nid = dac; | ||
2943 | else | ||
2944 | add_spec_extra_dacs(spec, dac); | ||
2945 | } | ||
2946 | spec->hp_dacs[i] = dac; | ||
2947 | } | ||
2948 | |||
2949 | for (i = 0; i < cfg->speaker_outs; i++) { | ||
2950 | nid = cfg->speaker_pins[i]; | ||
2951 | dac = get_unassigned_dac(codec, nid); | ||
2952 | if (dac) | ||
2953 | add_spec_extra_dacs(spec, dac); | ||
2954 | spec->speaker_dacs[i] = dac; | ||
2955 | } | ||
2956 | |||
2929 | /* add line-in as output */ | 2957 | /* add line-in as output */ |
2930 | nid = check_line_out_switch(codec); | 2958 | nid = check_line_out_switch(codec); |
2931 | if (nid) { | 2959 | if (nid) { |
@@ -2953,26 +2981,6 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec) | |||
2953 | } | 2981 | } |
2954 | } | 2982 | } |
2955 | 2983 | ||
2956 | for (i = 0; i < cfg->hp_outs; i++) { | ||
2957 | nid = cfg->hp_pins[i]; | ||
2958 | dac = get_unassigned_dac(codec, nid); | ||
2959 | if (dac) { | ||
2960 | if (!spec->multiout.hp_nid) | ||
2961 | spec->multiout.hp_nid = dac; | ||
2962 | else | ||
2963 | add_spec_extra_dacs(spec, dac); | ||
2964 | } | ||
2965 | spec->hp_dacs[i] = dac; | ||
2966 | } | ||
2967 | |||
2968 | for (i = 0; i < cfg->speaker_outs; i++) { | ||
2969 | nid = cfg->speaker_pins[i]; | ||
2970 | dac = get_unassigned_dac(codec, nid); | ||
2971 | if (dac) | ||
2972 | add_spec_extra_dacs(spec, dac); | ||
2973 | spec->speaker_dacs[i] = dac; | ||
2974 | } | ||
2975 | |||
2976 | snd_printd("stac92xx: dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", | 2984 | snd_printd("stac92xx: dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", |
2977 | spec->multiout.num_dacs, | 2985 | spec->multiout.num_dacs, |
2978 | spec->multiout.dac_nids[0], | 2986 | spec->multiout.dac_nids[0], |
@@ -2985,24 +2993,47 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec) | |||
2985 | } | 2993 | } |
2986 | 2994 | ||
2987 | /* create volume control/switch for the given prefx type */ | 2995 | /* create volume control/switch for the given prefx type */ |
2988 | static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_t nid, int chs) | 2996 | static int create_controls_idx(struct hda_codec *codec, const char *pfx, |
2997 | int idx, hda_nid_t nid, int chs) | ||
2989 | { | 2998 | { |
2999 | struct sigmatel_spec *spec = codec->spec; | ||
2990 | char name[32]; | 3000 | char name[32]; |
2991 | int err; | 3001 | int err; |
2992 | 3002 | ||
3003 | if (!spec->check_volume_offset) { | ||
3004 | unsigned int caps, step, nums, db_scale; | ||
3005 | caps = query_amp_caps(codec, nid, HDA_OUTPUT); | ||
3006 | step = (caps & AC_AMPCAP_STEP_SIZE) >> | ||
3007 | AC_AMPCAP_STEP_SIZE_SHIFT; | ||
3008 | step = (step + 1) * 25; /* in .01dB unit */ | ||
3009 | nums = (caps & AC_AMPCAP_NUM_STEPS) >> | ||
3010 | AC_AMPCAP_NUM_STEPS_SHIFT; | ||
3011 | db_scale = nums * step; | ||
3012 | /* if dB scale is over -64dB, and finer enough, | ||
3013 | * let's reduce it to half | ||
3014 | */ | ||
3015 | if (db_scale > 6400 && nums >= 0x1f) | ||
3016 | spec->volume_offset = nums / 2; | ||
3017 | spec->check_volume_offset = 1; | ||
3018 | } | ||
3019 | |||
2993 | sprintf(name, "%s Playback Volume", pfx); | 3020 | sprintf(name, "%s Playback Volume", pfx); |
2994 | err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name, | 3021 | err = stac92xx_add_control_idx(spec, STAC_CTL_WIDGET_VOL, idx, name, |
2995 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); | 3022 | HDA_COMPOSE_AMP_VAL_OFS(nid, chs, 0, HDA_OUTPUT, |
3023 | spec->volume_offset)); | ||
2996 | if (err < 0) | 3024 | if (err < 0) |
2997 | return err; | 3025 | return err; |
2998 | sprintf(name, "%s Playback Switch", pfx); | 3026 | sprintf(name, "%s Playback Switch", pfx); |
2999 | err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, name, | 3027 | err = stac92xx_add_control_idx(spec, STAC_CTL_WIDGET_MUTE, idx, name, |
3000 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); | 3028 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); |
3001 | if (err < 0) | 3029 | if (err < 0) |
3002 | return err; | 3030 | return err; |
3003 | return 0; | 3031 | return 0; |
3004 | } | 3032 | } |
3005 | 3033 | ||
3034 | #define create_controls(codec, pfx, nid, chs) \ | ||
3035 | create_controls_idx(codec, pfx, 0, nid, chs) | ||
3036 | |||
3006 | static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid) | 3037 | static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid) |
3007 | { | 3038 | { |
3008 | if (spec->multiout.num_dacs > 4) { | 3039 | if (spec->multiout.num_dacs > 4) { |
@@ -3028,40 +3059,32 @@ static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid) | |||
3028 | return 1; | 3059 | return 1; |
3029 | } | 3060 | } |
3030 | 3061 | ||
3031 | static int is_unique_dac(struct sigmatel_spec *spec, hda_nid_t nid) | 3062 | /* Create output controls |
3032 | { | 3063 | * The mixer elements are named depending on the given type (AUTO_PIN_XXX_OUT) |
3033 | int i; | 3064 | */ |
3034 | 3065 | static int create_multi_out_ctls(struct hda_codec *codec, int num_outs, | |
3035 | if (spec->autocfg.line_outs != 1) | 3066 | const hda_nid_t *pins, |
3036 | return 0; | 3067 | const hda_nid_t *dac_nids, |
3037 | if (spec->multiout.hp_nid == nid) | 3068 | int type) |
3038 | return 0; | ||
3039 | for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++) | ||
3040 | if (spec->multiout.extra_out_nid[i] == nid) | ||
3041 | return 0; | ||
3042 | return 1; | ||
3043 | } | ||
3044 | |||
3045 | /* add playback controls from the parsed DAC table */ | ||
3046 | static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, | ||
3047 | const struct auto_pin_cfg *cfg) | ||
3048 | { | 3069 | { |
3049 | struct sigmatel_spec *spec = codec->spec; | 3070 | struct sigmatel_spec *spec = codec->spec; |
3050 | static const char *chname[4] = { | 3071 | static const char *chname[4] = { |
3051 | "Front", "Surround", NULL /*CLFE*/, "Side" | 3072 | "Front", "Surround", NULL /*CLFE*/, "Side" |
3052 | }; | 3073 | }; |
3053 | hda_nid_t nid = 0; | 3074 | hda_nid_t nid; |
3054 | int i, err; | 3075 | int i, err; |
3055 | unsigned int wid_caps; | 3076 | unsigned int wid_caps; |
3056 | 3077 | ||
3057 | for (i = 0; i < cfg->line_outs && spec->multiout.dac_nids[i]; i++) { | 3078 | for (i = 0; i < num_outs && i < ARRAY_SIZE(chname); i++) { |
3058 | nid = spec->multiout.dac_nids[i]; | 3079 | nid = dac_nids[i]; |
3059 | if (i == 2) { | 3080 | if (!nid) |
3081 | continue; | ||
3082 | if (type != AUTO_PIN_HP_OUT && i == 2) { | ||
3060 | /* Center/LFE */ | 3083 | /* Center/LFE */ |
3061 | err = create_controls(spec, "Center", nid, 1); | 3084 | err = create_controls(codec, "Center", nid, 1); |
3062 | if (err < 0) | 3085 | if (err < 0) |
3063 | return err; | 3086 | return err; |
3064 | err = create_controls(spec, "LFE", nid, 2); | 3087 | err = create_controls(codec, "LFE", nid, 2); |
3065 | if (err < 0) | 3088 | if (err < 0) |
3066 | return err; | 3089 | return err; |
3067 | 3090 | ||
@@ -3077,23 +3100,47 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
3077 | } | 3100 | } |
3078 | 3101 | ||
3079 | } else { | 3102 | } else { |
3080 | const char *name = chname[i]; | 3103 | const char *name; |
3081 | /* if it's a single DAC, assign a better name */ | 3104 | int idx; |
3082 | if (!i && is_unique_dac(spec, nid)) { | 3105 | switch (type) { |
3083 | switch (cfg->line_out_type) { | 3106 | case AUTO_PIN_HP_OUT: |
3084 | case AUTO_PIN_HP_OUT: | 3107 | name = "Headphone"; |
3085 | name = "Headphone"; | 3108 | idx = i; |
3086 | break; | 3109 | break; |
3087 | case AUTO_PIN_SPEAKER_OUT: | 3110 | case AUTO_PIN_SPEAKER_OUT: |
3088 | name = "Speaker"; | 3111 | name = "Speaker"; |
3089 | break; | 3112 | idx = i; |
3090 | } | 3113 | break; |
3114 | default: | ||
3115 | name = chname[i]; | ||
3116 | idx = 0; | ||
3117 | break; | ||
3091 | } | 3118 | } |
3092 | err = create_controls(spec, name, nid, 3); | 3119 | err = create_controls_idx(codec, name, idx, nid, 3); |
3093 | if (err < 0) | 3120 | if (err < 0) |
3094 | return err; | 3121 | return err; |
3122 | if (type == AUTO_PIN_HP_OUT && !spec->hp_detect) { | ||
3123 | wid_caps = get_wcaps(codec, pins[i]); | ||
3124 | if (wid_caps & AC_WCAP_UNSOL_CAP) | ||
3125 | spec->hp_detect = 1; | ||
3126 | } | ||
3095 | } | 3127 | } |
3096 | } | 3128 | } |
3129 | return 0; | ||
3130 | } | ||
3131 | |||
3132 | /* add playback controls from the parsed DAC table */ | ||
3133 | static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, | ||
3134 | const struct auto_pin_cfg *cfg) | ||
3135 | { | ||
3136 | struct sigmatel_spec *spec = codec->spec; | ||
3137 | int err; | ||
3138 | |||
3139 | err = create_multi_out_ctls(codec, cfg->line_outs, cfg->line_out_pins, | ||
3140 | spec->multiout.dac_nids, | ||
3141 | cfg->line_out_type); | ||
3142 | if (err < 0) | ||
3143 | return err; | ||
3097 | 3144 | ||
3098 | if (cfg->hp_outs > 1 && cfg->line_out_type == AUTO_PIN_LINE_OUT) { | 3145 | if (cfg->hp_outs > 1 && cfg->line_out_type == AUTO_PIN_LINE_OUT) { |
3099 | err = stac92xx_add_control(spec, | 3146 | err = stac92xx_add_control(spec, |
@@ -3128,40 +3175,18 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, | |||
3128 | struct auto_pin_cfg *cfg) | 3175 | struct auto_pin_cfg *cfg) |
3129 | { | 3176 | { |
3130 | struct sigmatel_spec *spec = codec->spec; | 3177 | struct sigmatel_spec *spec = codec->spec; |
3131 | hda_nid_t nid; | 3178 | int err; |
3132 | int i, err, nums; | 3179 | |
3180 | err = create_multi_out_ctls(codec, cfg->hp_outs, cfg->hp_pins, | ||
3181 | spec->hp_dacs, AUTO_PIN_HP_OUT); | ||
3182 | if (err < 0) | ||
3183 | return err; | ||
3184 | |||
3185 | err = create_multi_out_ctls(codec, cfg->speaker_outs, cfg->speaker_pins, | ||
3186 | spec->speaker_dacs, AUTO_PIN_SPEAKER_OUT); | ||
3187 | if (err < 0) | ||
3188 | return err; | ||
3133 | 3189 | ||
3134 | nums = 0; | ||
3135 | for (i = 0; i < cfg->hp_outs; i++) { | ||
3136 | static const char *pfxs[] = { | ||
3137 | "Headphone", "Headphone2", "Headphone3", | ||
3138 | }; | ||
3139 | unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]); | ||
3140 | if (wid_caps & AC_WCAP_UNSOL_CAP) | ||
3141 | spec->hp_detect = 1; | ||
3142 | if (nums >= ARRAY_SIZE(pfxs)) | ||
3143 | continue; | ||
3144 | nid = spec->hp_dacs[i]; | ||
3145 | if (!nid) | ||
3146 | continue; | ||
3147 | err = create_controls(spec, pfxs[nums++], nid, 3); | ||
3148 | if (err < 0) | ||
3149 | return err; | ||
3150 | } | ||
3151 | nums = 0; | ||
3152 | for (i = 0; i < cfg->speaker_outs; i++) { | ||
3153 | static const char *pfxs[] = { | ||
3154 | "Speaker", "External Speaker", "Speaker2", | ||
3155 | }; | ||
3156 | if (nums >= ARRAY_SIZE(pfxs)) | ||
3157 | continue; | ||
3158 | nid = spec->speaker_dacs[i]; | ||
3159 | if (!nid) | ||
3160 | continue; | ||
3161 | err = create_controls(spec, pfxs[nums++], nid, 3); | ||
3162 | if (err < 0) | ||
3163 | return err; | ||
3164 | } | ||
3165 | return 0; | 3190 | return 0; |
3166 | } | 3191 | } |
3167 | 3192 | ||
@@ -3370,11 +3395,7 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | |||
3370 | unsigned int wcaps; | 3395 | unsigned int wcaps; |
3371 | unsigned int def_conf; | 3396 | unsigned int def_conf; |
3372 | 3397 | ||
3373 | def_conf = snd_hda_codec_read(codec, | 3398 | def_conf = snd_hda_codec_get_pincfg(codec, spec->dmic_nids[i]); |
3374 | spec->dmic_nids[i], | ||
3375 | 0, | ||
3376 | AC_VERB_GET_CONFIG_DEFAULT, | ||
3377 | 0); | ||
3378 | if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) | 3399 | if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) |
3379 | continue; | 3400 | continue; |
3380 | 3401 | ||
@@ -3498,6 +3519,7 @@ static void stac92xx_auto_init_hp_out(struct hda_codec *codec) | |||
3498 | static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in) | 3519 | static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in) |
3499 | { | 3520 | { |
3500 | struct sigmatel_spec *spec = codec->spec; | 3521 | struct sigmatel_spec *spec = codec->spec; |
3522 | int hp_swap = 0; | ||
3501 | int err; | 3523 | int err; |
3502 | 3524 | ||
3503 | if ((err = snd_hda_parse_pin_def_config(codec, | 3525 | if ((err = snd_hda_parse_pin_def_config(codec, |
@@ -3525,6 +3547,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
3525 | spec->autocfg.line_outs = spec->autocfg.hp_outs; | 3547 | spec->autocfg.line_outs = spec->autocfg.hp_outs; |
3526 | spec->autocfg.line_out_type = AUTO_PIN_HP_OUT; | 3548 | spec->autocfg.line_out_type = AUTO_PIN_HP_OUT; |
3527 | spec->autocfg.hp_outs = 0; | 3549 | spec->autocfg.hp_outs = 0; |
3550 | hp_swap = 1; | ||
3528 | } | 3551 | } |
3529 | if (spec->autocfg.mono_out_pin) { | 3552 | if (spec->autocfg.mono_out_pin) { |
3530 | int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) & | 3553 | int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) & |
@@ -3618,12 +3641,19 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
3618 | #endif | 3641 | #endif |
3619 | 3642 | ||
3620 | err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg); | 3643 | err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg); |
3621 | |||
3622 | if (err < 0) | 3644 | if (err < 0) |
3623 | return err; | 3645 | return err; |
3624 | 3646 | ||
3625 | err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg); | 3647 | /* All output parsing done, now restore the swapped hp pins */ |
3648 | if (hp_swap) { | ||
3649 | memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins, | ||
3650 | sizeof(spec->autocfg.hp_pins)); | ||
3651 | spec->autocfg.hp_outs = spec->autocfg.line_outs; | ||
3652 | spec->autocfg.line_out_type = AUTO_PIN_HP_OUT; | ||
3653 | spec->autocfg.line_outs = 0; | ||
3654 | } | ||
3626 | 3655 | ||
3656 | err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg); | ||
3627 | if (err < 0) | 3657 | if (err < 0) |
3628 | return err; | 3658 | return err; |
3629 | 3659 | ||
@@ -3652,11 +3682,15 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
3652 | return err; | 3682 | return err; |
3653 | } | 3683 | } |
3654 | 3684 | ||
3685 | err = stac92xx_add_input_source(spec); | ||
3686 | if (err < 0) | ||
3687 | return err; | ||
3688 | |||
3655 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 3689 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
3656 | if (spec->multiout.max_channels > 2) | 3690 | if (spec->multiout.max_channels > 2) |
3657 | spec->surr_switch = 1; | 3691 | spec->surr_switch = 1; |
3658 | 3692 | ||
3659 | if (spec->autocfg.dig_out_pin) | 3693 | if (spec->autocfg.dig_outs) |
3660 | spec->multiout.dig_out_nid = dig_out; | 3694 | spec->multiout.dig_out_nid = dig_out; |
3661 | if (dig_in && spec->autocfg.dig_in_pin) | 3695 | if (dig_in && spec->autocfg.dig_in_pin) |
3662 | spec->dig_in_nid = dig_in; | 3696 | spec->dig_in_nid = dig_in; |
@@ -3719,9 +3753,7 @@ static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec, | |||
3719 | for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) { | 3753 | for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) { |
3720 | hda_nid_t pin = spec->autocfg.line_out_pins[i]; | 3754 | hda_nid_t pin = spec->autocfg.line_out_pins[i]; |
3721 | unsigned int defcfg; | 3755 | unsigned int defcfg; |
3722 | defcfg = snd_hda_codec_read(codec, pin, 0, | 3756 | defcfg = snd_hda_codec_get_pincfg(codec, pin); |
3723 | AC_VERB_GET_CONFIG_DEFAULT, | ||
3724 | 0x00); | ||
3725 | if (get_defcfg_device(defcfg) == AC_JACK_SPEAKER) { | 3757 | if (get_defcfg_device(defcfg) == AC_JACK_SPEAKER) { |
3726 | unsigned int wcaps = get_wcaps(codec, pin); | 3758 | unsigned int wcaps = get_wcaps(codec, pin); |
3727 | wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP); | 3759 | wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP); |
@@ -3734,7 +3766,7 @@ static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec, | |||
3734 | } | 3766 | } |
3735 | 3767 | ||
3736 | if (lfe_pin) { | 3768 | if (lfe_pin) { |
3737 | err = create_controls(spec, "LFE", lfe_pin, 1); | 3769 | err = create_controls(codec, "LFE", lfe_pin, 1); |
3738 | if (err < 0) | 3770 | if (err < 0) |
3739 | return err; | 3771 | return err; |
3740 | } | 3772 | } |
@@ -3765,7 +3797,11 @@ static int stac9200_parse_auto_config(struct hda_codec *codec) | |||
3765 | return err; | 3797 | return err; |
3766 | } | 3798 | } |
3767 | 3799 | ||
3768 | if (spec->autocfg.dig_out_pin) | 3800 | err = stac92xx_add_input_source(spec); |
3801 | if (err < 0) | ||
3802 | return err; | ||
3803 | |||
3804 | if (spec->autocfg.dig_outs) | ||
3769 | spec->multiout.dig_out_nid = 0x05; | 3805 | spec->multiout.dig_out_nid = 0x05; |
3770 | if (spec->autocfg.dig_in_pin) | 3806 | if (spec->autocfg.dig_in_pin) |
3771 | spec->dig_in_nid = 0x04; | 3807 | spec->dig_in_nid = 0x04; |
@@ -3821,8 +3857,7 @@ static int stac92xx_add_jack(struct hda_codec *codec, | |||
3821 | #ifdef CONFIG_SND_JACK | 3857 | #ifdef CONFIG_SND_JACK |
3822 | struct sigmatel_spec *spec = codec->spec; | 3858 | struct sigmatel_spec *spec = codec->spec; |
3823 | struct sigmatel_jack *jack; | 3859 | struct sigmatel_jack *jack; |
3824 | int def_conf = snd_hda_codec_read(codec, nid, | 3860 | int def_conf = snd_hda_codec_get_pincfg(codec, nid); |
3825 | 0, AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
3826 | int connectivity = get_defcfg_connect(def_conf); | 3861 | int connectivity = get_defcfg_connect(def_conf); |
3827 | char name[32]; | 3862 | char name[32]; |
3828 | 3863 | ||
@@ -3937,6 +3972,36 @@ static void stac92xx_power_down(struct hda_codec *codec) | |||
3937 | static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, | 3972 | static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, |
3938 | int enable); | 3973 | int enable); |
3939 | 3974 | ||
3975 | /* override some hints from the hwdep entry */ | ||
3976 | static void stac_store_hints(struct hda_codec *codec) | ||
3977 | { | ||
3978 | struct sigmatel_spec *spec = codec->spec; | ||
3979 | const char *p; | ||
3980 | int val; | ||
3981 | |||
3982 | val = snd_hda_get_bool_hint(codec, "hp_detect"); | ||
3983 | if (val >= 0) | ||
3984 | spec->hp_detect = val; | ||
3985 | p = snd_hda_get_hint(codec, "gpio_mask"); | ||
3986 | if (p) { | ||
3987 | spec->gpio_mask = simple_strtoul(p, NULL, 0); | ||
3988 | spec->eapd_mask = spec->gpio_dir = spec->gpio_data = | ||
3989 | spec->gpio_mask; | ||
3990 | } | ||
3991 | p = snd_hda_get_hint(codec, "gpio_dir"); | ||
3992 | if (p) | ||
3993 | spec->gpio_dir = simple_strtoul(p, NULL, 0) & spec->gpio_mask; | ||
3994 | p = snd_hda_get_hint(codec, "gpio_data"); | ||
3995 | if (p) | ||
3996 | spec->gpio_data = simple_strtoul(p, NULL, 0) & spec->gpio_mask; | ||
3997 | p = snd_hda_get_hint(codec, "eapd_mask"); | ||
3998 | if (p) | ||
3999 | spec->eapd_mask = simple_strtoul(p, NULL, 0) & spec->gpio_mask; | ||
4000 | val = snd_hda_get_bool_hint(codec, "eapd_switch"); | ||
4001 | if (val >= 0) | ||
4002 | spec->eapd_switch = val; | ||
4003 | } | ||
4004 | |||
3940 | static int stac92xx_init(struct hda_codec *codec) | 4005 | static int stac92xx_init(struct hda_codec *codec) |
3941 | { | 4006 | { |
3942 | struct sigmatel_spec *spec = codec->spec; | 4007 | struct sigmatel_spec *spec = codec->spec; |
@@ -3953,6 +4018,9 @@ static int stac92xx_init(struct hda_codec *codec) | |||
3953 | spec->adc_nids[i], 0, | 4018 | spec->adc_nids[i], 0, |
3954 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | 4019 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); |
3955 | 4020 | ||
4021 | /* override some hints */ | ||
4022 | stac_store_hints(codec); | ||
4023 | |||
3956 | /* set up GPIO */ | 4024 | /* set up GPIO */ |
3957 | gpio = spec->gpio_data; | 4025 | gpio = spec->gpio_data; |
3958 | /* turn on EAPD statically when spec->eapd_switch isn't set. | 4026 | /* turn on EAPD statically when spec->eapd_switch isn't set. |
@@ -4002,8 +4070,7 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4002 | pinctl); | 4070 | pinctl); |
4003 | } | 4071 | } |
4004 | } | 4072 | } |
4005 | conf = snd_hda_codec_read(codec, nid, 0, | 4073 | conf = snd_hda_codec_get_pincfg(codec, nid); |
4006 | AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
4007 | if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) { | 4074 | if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) { |
4008 | enable_pin_detect(codec, nid, | 4075 | enable_pin_detect(codec, nid, |
4009 | STAC_INSERT_EVENT); | 4076 | STAC_INSERT_EVENT); |
@@ -4015,8 +4082,8 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4015 | for (i = 0; i < spec->num_dmics; i++) | 4082 | for (i = 0; i < spec->num_dmics; i++) |
4016 | stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i], | 4083 | stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i], |
4017 | AC_PINCTL_IN_EN); | 4084 | AC_PINCTL_IN_EN); |
4018 | if (cfg->dig_out_pin) | 4085 | if (cfg->dig_out_pins[0]) |
4019 | stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin, | 4086 | stac92xx_auto_set_pinctl(codec, cfg->dig_out_pins[0], |
4020 | AC_PINCTL_OUT_EN); | 4087 | AC_PINCTL_OUT_EN); |
4021 | if (cfg->dig_in_pin) | 4088 | if (cfg->dig_in_pin) |
4022 | stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin, | 4089 | stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin, |
@@ -4044,8 +4111,7 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4044 | stac_toggle_power_map(codec, nid, 1); | 4111 | stac_toggle_power_map(codec, nid, 1); |
4045 | continue; | 4112 | continue; |
4046 | } | 4113 | } |
4047 | def_conf = snd_hda_codec_read(codec, nid, 0, | 4114 | def_conf = snd_hda_codec_get_pincfg(codec, nid); |
4048 | AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
4049 | def_conf = get_defcfg_connect(def_conf); | 4115 | def_conf = get_defcfg_connect(def_conf); |
4050 | /* skip any ports that don't have jacks since presence | 4116 | /* skip any ports that don't have jacks since presence |
4051 | * detection is useless */ | 4117 | * detection is useless */ |
@@ -4099,7 +4165,6 @@ static void stac92xx_free(struct hda_codec *codec) | |||
4099 | if (! spec) | 4165 | if (! spec) |
4100 | return; | 4166 | return; |
4101 | 4167 | ||
4102 | kfree(spec->pin_configs); | ||
4103 | stac92xx_free_jacks(codec); | 4168 | stac92xx_free_jacks(codec); |
4104 | snd_array_free(&spec->events); | 4169 | snd_array_free(&spec->events); |
4105 | 4170 | ||
@@ -4110,7 +4175,9 @@ static void stac92xx_free(struct hda_codec *codec) | |||
4110 | static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, | 4175 | static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, |
4111 | unsigned int flag) | 4176 | unsigned int flag) |
4112 | { | 4177 | { |
4113 | unsigned int pin_ctl = snd_hda_codec_read(codec, nid, | 4178 | unsigned int old_ctl, pin_ctl; |
4179 | |||
4180 | pin_ctl = snd_hda_codec_read(codec, nid, | ||
4114 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); | 4181 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); |
4115 | 4182 | ||
4116 | if (pin_ctl & AC_PINCTL_IN_EN) { | 4183 | if (pin_ctl & AC_PINCTL_IN_EN) { |
@@ -4124,14 +4191,17 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, | |||
4124 | return; | 4191 | return; |
4125 | } | 4192 | } |
4126 | 4193 | ||
4194 | old_ctl = pin_ctl; | ||
4127 | /* if setting pin direction bits, clear the current | 4195 | /* if setting pin direction bits, clear the current |
4128 | direction bits first */ | 4196 | direction bits first */ |
4129 | if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)) | 4197 | if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)) |
4130 | pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); | 4198 | pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); |
4131 | 4199 | ||
4132 | snd_hda_codec_write_cache(codec, nid, 0, | 4200 | pin_ctl |= flag; |
4133 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 4201 | if (old_ctl != pin_ctl) |
4134 | pin_ctl | flag); | 4202 | snd_hda_codec_write_cache(codec, nid, 0, |
4203 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
4204 | pin_ctl); | ||
4135 | } | 4205 | } |
4136 | 4206 | ||
4137 | static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid, | 4207 | static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid, |
@@ -4139,9 +4209,10 @@ static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid, | |||
4139 | { | 4209 | { |
4140 | unsigned int pin_ctl = snd_hda_codec_read(codec, nid, | 4210 | unsigned int pin_ctl = snd_hda_codec_read(codec, nid, |
4141 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); | 4211 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); |
4142 | snd_hda_codec_write_cache(codec, nid, 0, | 4212 | if (pin_ctl & flag) |
4143 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 4213 | snd_hda_codec_write_cache(codec, nid, 0, |
4144 | pin_ctl & ~flag); | 4214 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
4215 | pin_ctl & ~flag); | ||
4145 | } | 4216 | } |
4146 | 4217 | ||
4147 | static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid) | 4218 | static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid) |
@@ -4404,7 +4475,6 @@ static int stac92xx_resume(struct hda_codec *codec) | |||
4404 | { | 4475 | { |
4405 | struct sigmatel_spec *spec = codec->spec; | 4476 | struct sigmatel_spec *spec = codec->spec; |
4406 | 4477 | ||
4407 | stac92xx_set_config_regs(codec); | ||
4408 | stac92xx_init(codec); | 4478 | stac92xx_init(codec); |
4409 | snd_hda_codec_resume_amp(codec); | 4479 | snd_hda_codec_resume_amp(codec); |
4410 | snd_hda_codec_resume_cache(codec); | 4480 | snd_hda_codec_resume_cache(codec); |
@@ -4415,6 +4485,37 @@ static int stac92xx_resume(struct hda_codec *codec) | |||
4415 | return 0; | 4485 | return 0; |
4416 | } | 4486 | } |
4417 | 4487 | ||
4488 | |||
4489 | /* | ||
4490 | * using power check for controlling mute led of HP HDX notebooks | ||
4491 | * check for mute state only on Speakers (nid = 0x10) | ||
4492 | * | ||
4493 | * For this feature CONFIG_SND_HDA_POWER_SAVE is needed, otherwise | ||
4494 | * the LED is NOT working properly ! | ||
4495 | */ | ||
4496 | |||
4497 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
4498 | static int stac92xx_hp_hdx_check_power_status(struct hda_codec *codec, | ||
4499 | hda_nid_t nid) | ||
4500 | { | ||
4501 | struct sigmatel_spec *spec = codec->spec; | ||
4502 | |||
4503 | if (nid == 0x10) { | ||
4504 | if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & | ||
4505 | HDA_AMP_MUTE) | ||
4506 | spec->gpio_data &= ~0x08; /* orange */ | ||
4507 | else | ||
4508 | spec->gpio_data |= 0x08; /* white */ | ||
4509 | |||
4510 | stac_gpio_set(codec, spec->gpio_mask, | ||
4511 | spec->gpio_dir, | ||
4512 | spec->gpio_data); | ||
4513 | } | ||
4514 | |||
4515 | return 0; | ||
4516 | } | ||
4517 | #endif | ||
4518 | |||
4418 | static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) | 4519 | static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) |
4419 | { | 4520 | { |
4420 | struct sigmatel_spec *spec = codec->spec; | 4521 | struct sigmatel_spec *spec = codec->spec; |
@@ -4453,16 +4554,11 @@ static int patch_stac9200(struct hda_codec *codec) | |||
4453 | spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS, | 4554 | spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS, |
4454 | stac9200_models, | 4555 | stac9200_models, |
4455 | stac9200_cfg_tbl); | 4556 | stac9200_cfg_tbl); |
4456 | if (spec->board_config < 0) { | 4557 | if (spec->board_config < 0) |
4457 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n"); | 4558 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n"); |
4458 | err = stac92xx_save_bios_config_regs(codec); | 4559 | else |
4459 | } else | 4560 | stac92xx_set_config_regs(codec, |
4460 | err = stac_save_pin_cfgs(codec, | ||
4461 | stac9200_brd_tbl[spec->board_config]); | 4561 | stac9200_brd_tbl[spec->board_config]); |
4462 | if (err < 0) { | ||
4463 | stac92xx_free(codec); | ||
4464 | return err; | ||
4465 | } | ||
4466 | 4562 | ||
4467 | spec->multiout.max_channels = 2; | 4563 | spec->multiout.max_channels = 2; |
4468 | spec->multiout.num_dacs = 1; | 4564 | spec->multiout.num_dacs = 1; |
@@ -4530,17 +4626,12 @@ static int patch_stac925x(struct hda_codec *codec) | |||
4530 | stac925x_models, | 4626 | stac925x_models, |
4531 | stac925x_cfg_tbl); | 4627 | stac925x_cfg_tbl); |
4532 | again: | 4628 | again: |
4533 | if (spec->board_config < 0) { | 4629 | if (spec->board_config < 0) |
4534 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x," | 4630 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x," |
4535 | "using BIOS defaults\n"); | 4631 | "using BIOS defaults\n"); |
4536 | err = stac92xx_save_bios_config_regs(codec); | 4632 | else |
4537 | } else | 4633 | stac92xx_set_config_regs(codec, |
4538 | err = stac_save_pin_cfgs(codec, | ||
4539 | stac925x_brd_tbl[spec->board_config]); | 4634 | stac925x_brd_tbl[spec->board_config]); |
4540 | if (err < 0) { | ||
4541 | stac92xx_free(codec); | ||
4542 | return err; | ||
4543 | } | ||
4544 | 4635 | ||
4545 | spec->multiout.max_channels = 2; | 4636 | spec->multiout.max_channels = 2; |
4546 | spec->multiout.num_dacs = 1; | 4637 | spec->multiout.num_dacs = 1; |
@@ -4618,17 +4709,12 @@ static int patch_stac92hd73xx(struct hda_codec *codec) | |||
4618 | stac92hd73xx_models, | 4709 | stac92hd73xx_models, |
4619 | stac92hd73xx_cfg_tbl); | 4710 | stac92hd73xx_cfg_tbl); |
4620 | again: | 4711 | again: |
4621 | if (spec->board_config < 0) { | 4712 | if (spec->board_config < 0) |
4622 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" | 4713 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" |
4623 | " STAC92HD73XX, using BIOS defaults\n"); | 4714 | " STAC92HD73XX, using BIOS defaults\n"); |
4624 | err = stac92xx_save_bios_config_regs(codec); | 4715 | else |
4625 | } else | 4716 | stac92xx_set_config_regs(codec, |
4626 | err = stac_save_pin_cfgs(codec, | ||
4627 | stac92hd73xx_brd_tbl[spec->board_config]); | 4717 | stac92hd73xx_brd_tbl[spec->board_config]); |
4628 | if (err < 0) { | ||
4629 | stac92xx_free(codec); | ||
4630 | return err; | ||
4631 | } | ||
4632 | 4718 | ||
4633 | num_dacs = snd_hda_get_connections(codec, 0x0a, | 4719 | num_dacs = snd_hda_get_connections(codec, 0x0a, |
4634 | conn, STAC92HD73_DAC_COUNT + 2) - 1; | 4720 | conn, STAC92HD73_DAC_COUNT + 2) - 1; |
@@ -4642,14 +4728,18 @@ again: | |||
4642 | case 0x3: /* 6 Channel */ | 4728 | case 0x3: /* 6 Channel */ |
4643 | spec->mixer = stac92hd73xx_6ch_mixer; | 4729 | spec->mixer = stac92hd73xx_6ch_mixer; |
4644 | spec->init = stac92hd73xx_6ch_core_init; | 4730 | spec->init = stac92hd73xx_6ch_core_init; |
4731 | spec->aloopback_ctl = stac92hd73xx_6ch_loopback; | ||
4645 | break; | 4732 | break; |
4646 | case 0x4: /* 8 Channel */ | 4733 | case 0x4: /* 8 Channel */ |
4647 | spec->mixer = stac92hd73xx_8ch_mixer; | 4734 | spec->mixer = stac92hd73xx_8ch_mixer; |
4648 | spec->init = stac92hd73xx_8ch_core_init; | 4735 | spec->init = stac92hd73xx_8ch_core_init; |
4736 | spec->aloopback_ctl = stac92hd73xx_8ch_loopback; | ||
4649 | break; | 4737 | break; |
4650 | case 0x5: /* 10 Channel */ | 4738 | case 0x5: /* 10 Channel */ |
4651 | spec->mixer = stac92hd73xx_10ch_mixer; | 4739 | spec->mixer = stac92hd73xx_10ch_mixer; |
4652 | spec->init = stac92hd73xx_10ch_core_init; | 4740 | spec->init = stac92hd73xx_10ch_core_init; |
4741 | spec->aloopback_ctl = stac92hd73xx_10ch_loopback; | ||
4742 | break; | ||
4653 | } | 4743 | } |
4654 | spec->multiout.dac_nids = spec->dac_nids; | 4744 | spec->multiout.dac_nids = spec->dac_nids; |
4655 | 4745 | ||
@@ -4688,18 +4778,18 @@ again: | |||
4688 | spec->init = dell_m6_core_init; | 4778 | spec->init = dell_m6_core_init; |
4689 | switch (spec->board_config) { | 4779 | switch (spec->board_config) { |
4690 | case STAC_DELL_M6_AMIC: /* Analog Mics */ | 4780 | case STAC_DELL_M6_AMIC: /* Analog Mics */ |
4691 | stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); | 4781 | snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170); |
4692 | spec->num_dmics = 0; | 4782 | spec->num_dmics = 0; |
4693 | spec->private_dimux.num_items = 1; | 4783 | spec->private_dimux.num_items = 1; |
4694 | break; | 4784 | break; |
4695 | case STAC_DELL_M6_DMIC: /* Digital Mics */ | 4785 | case STAC_DELL_M6_DMIC: /* Digital Mics */ |
4696 | stac92xx_set_config_reg(codec, 0x13, 0x90A60160); | 4786 | snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160); |
4697 | spec->num_dmics = 1; | 4787 | spec->num_dmics = 1; |
4698 | spec->private_dimux.num_items = 2; | 4788 | spec->private_dimux.num_items = 2; |
4699 | break; | 4789 | break; |
4700 | case STAC_DELL_M6_BOTH: /* Both */ | 4790 | case STAC_DELL_M6_BOTH: /* Both */ |
4701 | stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); | 4791 | snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170); |
4702 | stac92xx_set_config_reg(codec, 0x13, 0x90A60160); | 4792 | snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160); |
4703 | spec->num_dmics = 1; | 4793 | spec->num_dmics = 1; |
4704 | spec->private_dimux.num_items = 2; | 4794 | spec->private_dimux.num_items = 2; |
4705 | break; | 4795 | break; |
@@ -4762,6 +4852,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
4762 | hda_nid_t conn[STAC92HD83_DAC_COUNT + 1]; | 4852 | hda_nid_t conn[STAC92HD83_DAC_COUNT + 1]; |
4763 | int err; | 4853 | int err; |
4764 | int num_dacs; | 4854 | int num_dacs; |
4855 | hda_nid_t nid; | ||
4765 | 4856 | ||
4766 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 4857 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
4767 | if (spec == NULL) | 4858 | if (spec == NULL) |
@@ -4780,15 +4871,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
4780 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); | 4871 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); |
4781 | spec->multiout.dac_nids = spec->dac_nids; | 4872 | spec->multiout.dac_nids = spec->dac_nids; |
4782 | 4873 | ||
4783 | |||
4784 | /* set port 0xe to select the last DAC | ||
4785 | */ | ||
4786 | num_dacs = snd_hda_get_connections(codec, 0x0e, | ||
4787 | conn, STAC92HD83_DAC_COUNT + 1) - 1; | ||
4788 | |||
4789 | snd_hda_codec_write_cache(codec, 0xe, 0, | ||
4790 | AC_VERB_SET_CONNECT_SEL, num_dacs); | ||
4791 | |||
4792 | spec->init = stac92hd83xxx_core_init; | 4874 | spec->init = stac92hd83xxx_core_init; |
4793 | spec->mixer = stac92hd83xxx_mixer; | 4875 | spec->mixer = stac92hd83xxx_mixer; |
4794 | spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids); | 4876 | spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids); |
@@ -4803,17 +4885,12 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
4803 | stac92hd83xxx_models, | 4885 | stac92hd83xxx_models, |
4804 | stac92hd83xxx_cfg_tbl); | 4886 | stac92hd83xxx_cfg_tbl); |
4805 | again: | 4887 | again: |
4806 | if (spec->board_config < 0) { | 4888 | if (spec->board_config < 0) |
4807 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" | 4889 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" |
4808 | " STAC92HD83XXX, using BIOS defaults\n"); | 4890 | " STAC92HD83XXX, using BIOS defaults\n"); |
4809 | err = stac92xx_save_bios_config_regs(codec); | 4891 | else |
4810 | } else | 4892 | stac92xx_set_config_regs(codec, |
4811 | err = stac_save_pin_cfgs(codec, | ||
4812 | stac92hd83xxx_brd_tbl[spec->board_config]); | 4893 | stac92hd83xxx_brd_tbl[spec->board_config]); |
4813 | if (err < 0) { | ||
4814 | stac92xx_free(codec); | ||
4815 | return err; | ||
4816 | } | ||
4817 | 4894 | ||
4818 | switch (codec->vendor_id) { | 4895 | switch (codec->vendor_id) { |
4819 | case 0x111d7604: | 4896 | case 0x111d7604: |
@@ -4840,6 +4917,23 @@ again: | |||
4840 | return err; | 4917 | return err; |
4841 | } | 4918 | } |
4842 | 4919 | ||
4920 | switch (spec->board_config) { | ||
4921 | case STAC_DELL_S14: | ||
4922 | nid = 0xf; | ||
4923 | break; | ||
4924 | default: | ||
4925 | nid = 0xe; | ||
4926 | break; | ||
4927 | } | ||
4928 | |||
4929 | num_dacs = snd_hda_get_connections(codec, nid, | ||
4930 | conn, STAC92HD83_DAC_COUNT + 1) - 1; | ||
4931 | |||
4932 | /* set port X to select the last DAC | ||
4933 | */ | ||
4934 | snd_hda_codec_write_cache(codec, nid, 0, | ||
4935 | AC_VERB_SET_CONNECT_SEL, num_dacs); | ||
4936 | |||
4843 | codec->patch_ops = stac92xx_patch_ops; | 4937 | codec->patch_ops = stac92xx_patch_ops; |
4844 | 4938 | ||
4845 | codec->proc_widget_hook = stac92hd_proc_hook; | 4939 | codec->proc_widget_hook = stac92hd_proc_hook; |
@@ -4847,7 +4941,16 @@ again: | |||
4847 | return 0; | 4941 | return 0; |
4848 | } | 4942 | } |
4849 | 4943 | ||
4850 | static struct hda_input_mux stac92hd71bxx_dmux = { | 4944 | static struct hda_input_mux stac92hd71bxx_dmux_nomixer = { |
4945 | .num_items = 3, | ||
4946 | .items = { | ||
4947 | { "Analog Inputs", 0x00 }, | ||
4948 | { "Digital Mic 1", 0x02 }, | ||
4949 | { "Digital Mic 2", 0x03 }, | ||
4950 | } | ||
4951 | }; | ||
4952 | |||
4953 | static struct hda_input_mux stac92hd71bxx_dmux_amixer = { | ||
4851 | .num_items = 4, | 4954 | .num_items = 4, |
4852 | .items = { | 4955 | .items = { |
4853 | { "Analog Inputs", 0x00 }, | 4956 | { "Analog Inputs", 0x00 }, |
@@ -4857,10 +4960,67 @@ static struct hda_input_mux stac92hd71bxx_dmux = { | |||
4857 | } | 4960 | } |
4858 | }; | 4961 | }; |
4859 | 4962 | ||
4963 | /* get the pin connection (fixed, none, etc) */ | ||
4964 | static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx) | ||
4965 | { | ||
4966 | struct sigmatel_spec *spec = codec->spec; | ||
4967 | unsigned int cfg; | ||
4968 | |||
4969 | cfg = snd_hda_codec_get_pincfg(codec, spec->pin_nids[idx]); | ||
4970 | return get_defcfg_connect(cfg); | ||
4971 | } | ||
4972 | |||
4973 | static int stac92hd71bxx_connected_ports(struct hda_codec *codec, | ||
4974 | hda_nid_t *nids, int num_nids) | ||
4975 | { | ||
4976 | struct sigmatel_spec *spec = codec->spec; | ||
4977 | int idx, num; | ||
4978 | unsigned int def_conf; | ||
4979 | |||
4980 | for (num = 0; num < num_nids; num++) { | ||
4981 | for (idx = 0; idx < spec->num_pins; idx++) | ||
4982 | if (spec->pin_nids[idx] == nids[num]) | ||
4983 | break; | ||
4984 | if (idx >= spec->num_pins) | ||
4985 | break; | ||
4986 | def_conf = stac_get_defcfg_connect(codec, idx); | ||
4987 | if (def_conf == AC_JACK_PORT_NONE) | ||
4988 | break; | ||
4989 | } | ||
4990 | return num; | ||
4991 | } | ||
4992 | |||
4993 | static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec, | ||
4994 | hda_nid_t dig0pin) | ||
4995 | { | ||
4996 | struct sigmatel_spec *spec = codec->spec; | ||
4997 | int idx; | ||
4998 | |||
4999 | for (idx = 0; idx < spec->num_pins; idx++) | ||
5000 | if (spec->pin_nids[idx] == dig0pin) | ||
5001 | break; | ||
5002 | if ((idx + 2) >= spec->num_pins) | ||
5003 | return 0; | ||
5004 | |||
5005 | /* dig1pin case */ | ||
5006 | if (stac_get_defcfg_connect(codec, idx + 1) != AC_JACK_PORT_NONE) | ||
5007 | return 2; | ||
5008 | |||
5009 | /* dig0pin + dig2pin case */ | ||
5010 | if (stac_get_defcfg_connect(codec, idx + 2) != AC_JACK_PORT_NONE) | ||
5011 | return 2; | ||
5012 | if (stac_get_defcfg_connect(codec, idx) != AC_JACK_PORT_NONE) | ||
5013 | return 1; | ||
5014 | else | ||
5015 | return 0; | ||
5016 | } | ||
5017 | |||
4860 | static int patch_stac92hd71bxx(struct hda_codec *codec) | 5018 | static int patch_stac92hd71bxx(struct hda_codec *codec) |
4861 | { | 5019 | { |
4862 | struct sigmatel_spec *spec; | 5020 | struct sigmatel_spec *spec; |
5021 | struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init; | ||
4863 | int err = 0; | 5022 | int err = 0; |
5023 | unsigned int ndmic_nids = 0; | ||
4864 | 5024 | ||
4865 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 5025 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
4866 | if (spec == NULL) | 5026 | if (spec == NULL) |
@@ -4868,27 +5028,32 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) | |||
4868 | 5028 | ||
4869 | codec->spec = spec; | 5029 | codec->spec = spec; |
4870 | codec->patch_ops = stac92xx_patch_ops; | 5030 | codec->patch_ops = stac92xx_patch_ops; |
4871 | spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids); | 5031 | spec->num_pins = STAC92HD71BXX_NUM_PINS; |
5032 | switch (codec->vendor_id) { | ||
5033 | case 0x111d76b6: | ||
5034 | case 0x111d76b7: | ||
5035 | spec->pin_nids = stac92hd71bxx_pin_nids_4port; | ||
5036 | break; | ||
5037 | case 0x111d7603: | ||
5038 | case 0x111d7608: | ||
5039 | /* On 92HD75Bx 0x27 isn't a pin nid */ | ||
5040 | spec->num_pins--; | ||
5041 | /* fallthrough */ | ||
5042 | default: | ||
5043 | spec->pin_nids = stac92hd71bxx_pin_nids_6port; | ||
5044 | } | ||
4872 | spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); | 5045 | spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); |
4873 | spec->pin_nids = stac92hd71bxx_pin_nids; | ||
4874 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux, | ||
4875 | sizeof(stac92hd71bxx_dmux)); | ||
4876 | spec->board_config = snd_hda_check_board_config(codec, | 5046 | spec->board_config = snd_hda_check_board_config(codec, |
4877 | STAC_92HD71BXX_MODELS, | 5047 | STAC_92HD71BXX_MODELS, |
4878 | stac92hd71bxx_models, | 5048 | stac92hd71bxx_models, |
4879 | stac92hd71bxx_cfg_tbl); | 5049 | stac92hd71bxx_cfg_tbl); |
4880 | again: | 5050 | again: |
4881 | if (spec->board_config < 0) { | 5051 | if (spec->board_config < 0) |
4882 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" | 5052 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" |
4883 | " STAC92HD71BXX, using BIOS defaults\n"); | 5053 | " STAC92HD71BXX, using BIOS defaults\n"); |
4884 | err = stac92xx_save_bios_config_regs(codec); | 5054 | else |
4885 | } else | 5055 | stac92xx_set_config_regs(codec, |
4886 | err = stac_save_pin_cfgs(codec, | ||
4887 | stac92hd71bxx_brd_tbl[spec->board_config]); | 5056 | stac92hd71bxx_brd_tbl[spec->board_config]); |
4888 | if (err < 0) { | ||
4889 | stac92xx_free(codec); | ||
4890 | return err; | ||
4891 | } | ||
4892 | 5057 | ||
4893 | if (spec->board_config > STAC_92HD71BXX_REF) { | 5058 | if (spec->board_config > STAC_92HD71BXX_REF) { |
4894 | /* GPIO0 = EAPD */ | 5059 | /* GPIO0 = EAPD */ |
@@ -4897,16 +5062,34 @@ again: | |||
4897 | spec->gpio_data = 0x01; | 5062 | spec->gpio_data = 0x01; |
4898 | } | 5063 | } |
4899 | 5064 | ||
5065 | spec->dmic_nids = stac92hd71bxx_dmic_nids; | ||
5066 | spec->dmux_nids = stac92hd71bxx_dmux_nids; | ||
5067 | |||
4900 | switch (codec->vendor_id) { | 5068 | switch (codec->vendor_id) { |
4901 | case 0x111d76b6: /* 4 Port without Analog Mixer */ | 5069 | case 0x111d76b6: /* 4 Port without Analog Mixer */ |
4902 | case 0x111d76b7: | 5070 | case 0x111d76b7: |
5071 | unmute_init++; | ||
5072 | /* fallthru */ | ||
4903 | case 0x111d76b4: /* 6 Port without Analog Mixer */ | 5073 | case 0x111d76b4: /* 6 Port without Analog Mixer */ |
4904 | case 0x111d76b5: | 5074 | case 0x111d76b5: |
5075 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_nomixer, | ||
5076 | sizeof(stac92hd71bxx_dmux_nomixer)); | ||
4905 | spec->mixer = stac92hd71bxx_mixer; | 5077 | spec->mixer = stac92hd71bxx_mixer; |
4906 | spec->init = stac92hd71bxx_core_init; | 5078 | spec->init = stac92hd71bxx_core_init; |
4907 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; | 5079 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; |
5080 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, | ||
5081 | stac92hd71bxx_dmic_nids, | ||
5082 | STAC92HD71BXX_NUM_DMICS); | ||
5083 | if (spec->num_dmics) { | ||
5084 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | ||
5085 | spec->dinput_mux = &spec->private_dimux; | ||
5086 | ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1; | ||
5087 | } | ||
4908 | break; | 5088 | break; |
4909 | case 0x111d7608: /* 5 Port with Analog Mixer */ | 5089 | case 0x111d7608: /* 5 Port with Analog Mixer */ |
5090 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_amixer, | ||
5091 | sizeof(stac92hd71bxx_dmux_amixer)); | ||
5092 | spec->private_dimux.num_items--; | ||
4910 | switch (spec->board_config) { | 5093 | switch (spec->board_config) { |
4911 | case STAC_HP_M4: | 5094 | case STAC_HP_M4: |
4912 | /* Enable VREF power saving on GPIO1 detect */ | 5095 | /* Enable VREF power saving on GPIO1 detect */ |
@@ -4933,7 +5116,15 @@ again: | |||
4933 | 5116 | ||
4934 | /* disable VSW */ | 5117 | /* disable VSW */ |
4935 | spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF]; | 5118 | spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF]; |
4936 | stac_change_pin_config(codec, 0xf, 0x40f000f0); | 5119 | unmute_init++; |
5120 | snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); | ||
5121 | snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); | ||
5122 | stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS - 1] = 0; | ||
5123 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, | ||
5124 | stac92hd71bxx_dmic_nids, | ||
5125 | STAC92HD71BXX_NUM_DMICS - 1); | ||
5126 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | ||
5127 | ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 2; | ||
4937 | break; | 5128 | break; |
4938 | case 0x111d7603: /* 6 Port with Analog Mixer */ | 5129 | case 0x111d7603: /* 6 Port with Analog Mixer */ |
4939 | if ((codec->revision_id & 0xf) == 1) | 5130 | if ((codec->revision_id & 0xf) == 1) |
@@ -4943,12 +5134,23 @@ again: | |||
4943 | spec->num_pwrs = 0; | 5134 | spec->num_pwrs = 0; |
4944 | /* fallthru */ | 5135 | /* fallthru */ |
4945 | default: | 5136 | default: |
5137 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_amixer, | ||
5138 | sizeof(stac92hd71bxx_dmux_amixer)); | ||
4946 | spec->dinput_mux = &spec->private_dimux; | 5139 | spec->dinput_mux = &spec->private_dimux; |
4947 | spec->mixer = stac92hd71bxx_analog_mixer; | 5140 | spec->mixer = stac92hd71bxx_analog_mixer; |
4948 | spec->init = stac92hd71bxx_analog_core_init; | 5141 | spec->init = stac92hd71bxx_analog_core_init; |
4949 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; | 5142 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; |
5143 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, | ||
5144 | stac92hd71bxx_dmic_nids, | ||
5145 | STAC92HD71BXX_NUM_DMICS); | ||
5146 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | ||
5147 | ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1; | ||
4950 | } | 5148 | } |
4951 | 5149 | ||
5150 | if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) | ||
5151 | snd_hda_sequence_write_cache(codec, unmute_init); | ||
5152 | |||
5153 | spec->aloopback_ctl = stac92hd71bxx_loopback; | ||
4952 | spec->aloopback_mask = 0x50; | 5154 | spec->aloopback_mask = 0x50; |
4953 | spec->aloopback_shift = 0; | 5155 | spec->aloopback_shift = 0; |
4954 | 5156 | ||
@@ -4956,18 +5158,17 @@ again: | |||
4956 | spec->digbeep_nid = 0x26; | 5158 | spec->digbeep_nid = 0x26; |
4957 | spec->mux_nids = stac92hd71bxx_mux_nids; | 5159 | spec->mux_nids = stac92hd71bxx_mux_nids; |
4958 | spec->adc_nids = stac92hd71bxx_adc_nids; | 5160 | spec->adc_nids = stac92hd71bxx_adc_nids; |
4959 | spec->dmic_nids = stac92hd71bxx_dmic_nids; | ||
4960 | spec->dmux_nids = stac92hd71bxx_dmux_nids; | ||
4961 | spec->smux_nids = stac92hd71bxx_smux_nids; | 5161 | spec->smux_nids = stac92hd71bxx_smux_nids; |
4962 | spec->pwr_nids = stac92hd71bxx_pwr_nids; | 5162 | spec->pwr_nids = stac92hd71bxx_pwr_nids; |
4963 | 5163 | ||
4964 | spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); | 5164 | spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); |
4965 | spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); | 5165 | spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); |
5166 | spec->num_smuxes = stac92hd71bxx_connected_smuxes(codec, 0x1e); | ||
4966 | 5167 | ||
4967 | switch (spec->board_config) { | 5168 | switch (spec->board_config) { |
4968 | case STAC_HP_M4: | 5169 | case STAC_HP_M4: |
4969 | /* enable internal microphone */ | 5170 | /* enable internal microphone */ |
4970 | stac_change_pin_config(codec, 0x0e, 0x01813040); | 5171 | snd_hda_codec_set_pincfg(codec, 0x0e, 0x01813040); |
4971 | stac92xx_auto_set_pinctl(codec, 0x0e, | 5172 | stac92xx_auto_set_pinctl(codec, 0x0e, |
4972 | AC_PINCTL_IN_EN | AC_PINCTL_VREF_80); | 5173 | AC_PINCTL_IN_EN | AC_PINCTL_VREF_80); |
4973 | /* fallthru */ | 5174 | /* fallthru */ |
@@ -4980,21 +5181,38 @@ again: | |||
4980 | case STAC_DELL_M4_3: | 5181 | case STAC_DELL_M4_3: |
4981 | spec->num_dmics = 1; | 5182 | spec->num_dmics = 1; |
4982 | spec->num_smuxes = 0; | 5183 | spec->num_smuxes = 0; |
4983 | spec->num_dmuxes = 0; | 5184 | spec->num_dmuxes = 1; |
5185 | break; | ||
5186 | case STAC_HP_DV5: | ||
5187 | snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); | ||
5188 | stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN); | ||
5189 | break; | ||
5190 | case STAC_HP_HDX: | ||
5191 | spec->num_dmics = 1; | ||
5192 | spec->num_dmuxes = 1; | ||
5193 | spec->num_smuxes = 1; | ||
5194 | /* | ||
5195 | * For controlling MUTE LED on HP HDX16/HDX18 notebooks, | ||
5196 | * the CONFIG_SND_HDA_POWER_SAVE is needed to be set. | ||
5197 | */ | ||
5198 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
5199 | /* orange/white mute led on GPIO3, orange=0, white=1 */ | ||
5200 | spec->gpio_mask |= 0x08; | ||
5201 | spec->gpio_dir |= 0x08; | ||
5202 | spec->gpio_data |= 0x08; /* set to white */ | ||
5203 | |||
5204 | /* register check_power_status callback. */ | ||
5205 | codec->patch_ops.check_power_status = | ||
5206 | stac92xx_hp_hdx_check_power_status; | ||
5207 | #endif | ||
4984 | break; | 5208 | break; |
4985 | default: | ||
4986 | spec->num_dmics = STAC92HD71BXX_NUM_DMICS; | ||
4987 | spec->num_smuxes = ARRAY_SIZE(stac92hd71bxx_smux_nids); | ||
4988 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | ||
4989 | }; | 5209 | }; |
4990 | 5210 | ||
4991 | spec->multiout.dac_nids = spec->dac_nids; | 5211 | spec->multiout.dac_nids = spec->dac_nids; |
4992 | if (spec->dinput_mux) | 5212 | if (spec->dinput_mux) |
4993 | spec->private_dimux.num_items += | 5213 | spec->private_dimux.num_items += spec->num_dmics - ndmic_nids; |
4994 | spec->num_dmics - | ||
4995 | (ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1); | ||
4996 | 5214 | ||
4997 | err = stac92xx_parse_auto_config(codec, 0x21, 0x23); | 5215 | err = stac92xx_parse_auto_config(codec, 0x21, 0); |
4998 | if (!err) { | 5216 | if (!err) { |
4999 | if (spec->board_config < 0) { | 5217 | if (spec->board_config < 0) { |
5000 | printk(KERN_WARNING "hda_codec: No auto-config is " | 5218 | printk(KERN_WARNING "hda_codec: No auto-config is " |
@@ -5069,17 +5287,12 @@ static int patch_stac922x(struct hda_codec *codec) | |||
5069 | } | 5287 | } |
5070 | 5288 | ||
5071 | again: | 5289 | again: |
5072 | if (spec->board_config < 0) { | 5290 | if (spec->board_config < 0) |
5073 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, " | 5291 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, " |
5074 | "using BIOS defaults\n"); | 5292 | "using BIOS defaults\n"); |
5075 | err = stac92xx_save_bios_config_regs(codec); | 5293 | else |
5076 | } else | 5294 | stac92xx_set_config_regs(codec, |
5077 | err = stac_save_pin_cfgs(codec, | ||
5078 | stac922x_brd_tbl[spec->board_config]); | 5295 | stac922x_brd_tbl[spec->board_config]); |
5079 | if (err < 0) { | ||
5080 | stac92xx_free(codec); | ||
5081 | return err; | ||
5082 | } | ||
5083 | 5296 | ||
5084 | spec->adc_nids = stac922x_adc_nids; | 5297 | spec->adc_nids = stac922x_adc_nids; |
5085 | spec->mux_nids = stac922x_mux_nids; | 5298 | spec->mux_nids = stac922x_mux_nids; |
@@ -5130,24 +5343,19 @@ static int patch_stac927x(struct hda_codec *codec) | |||
5130 | return -ENOMEM; | 5343 | return -ENOMEM; |
5131 | 5344 | ||
5132 | codec->spec = spec; | 5345 | codec->spec = spec; |
5346 | codec->slave_dig_outs = stac927x_slave_dig_outs; | ||
5133 | spec->num_pins = ARRAY_SIZE(stac927x_pin_nids); | 5347 | spec->num_pins = ARRAY_SIZE(stac927x_pin_nids); |
5134 | spec->pin_nids = stac927x_pin_nids; | 5348 | spec->pin_nids = stac927x_pin_nids; |
5135 | spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS, | 5349 | spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS, |
5136 | stac927x_models, | 5350 | stac927x_models, |
5137 | stac927x_cfg_tbl); | 5351 | stac927x_cfg_tbl); |
5138 | again: | 5352 | again: |
5139 | if (spec->board_config < 0 || !stac927x_brd_tbl[spec->board_config]) { | 5353 | if (spec->board_config < 0) |
5140 | if (spec->board_config < 0) | 5354 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" |
5141 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" | 5355 | "STAC927x, using BIOS defaults\n"); |
5142 | "STAC927x, using BIOS defaults\n"); | 5356 | else |
5143 | err = stac92xx_save_bios_config_regs(codec); | 5357 | stac92xx_set_config_regs(codec, |
5144 | } else | ||
5145 | err = stac_save_pin_cfgs(codec, | ||
5146 | stac927x_brd_tbl[spec->board_config]); | 5358 | stac927x_brd_tbl[spec->board_config]); |
5147 | if (err < 0) { | ||
5148 | stac92xx_free(codec); | ||
5149 | return err; | ||
5150 | } | ||
5151 | 5359 | ||
5152 | spec->digbeep_nid = 0x23; | 5360 | spec->digbeep_nid = 0x23; |
5153 | spec->adc_nids = stac927x_adc_nids; | 5361 | spec->adc_nids = stac927x_adc_nids; |
@@ -5176,15 +5384,15 @@ static int patch_stac927x(struct hda_codec *codec) | |||
5176 | case 0x10280209: | 5384 | case 0x10280209: |
5177 | case 0x1028022e: | 5385 | case 0x1028022e: |
5178 | /* correct the device field to SPDIF out */ | 5386 | /* correct the device field to SPDIF out */ |
5179 | stac_change_pin_config(codec, 0x21, 0x01442070); | 5387 | snd_hda_codec_set_pincfg(codec, 0x21, 0x01442070); |
5180 | break; | 5388 | break; |
5181 | }; | 5389 | }; |
5182 | /* configure the analog microphone on some laptops */ | 5390 | /* configure the analog microphone on some laptops */ |
5183 | stac_change_pin_config(codec, 0x0c, 0x90a79130); | 5391 | snd_hda_codec_set_pincfg(codec, 0x0c, 0x90a79130); |
5184 | /* correct the front output jack as a hp out */ | 5392 | /* correct the front output jack as a hp out */ |
5185 | stac_change_pin_config(codec, 0x0f, 0x0227011f); | 5393 | snd_hda_codec_set_pincfg(codec, 0x0f, 0x0227011f); |
5186 | /* correct the front input jack as a mic */ | 5394 | /* correct the front input jack as a mic */ |
5187 | stac_change_pin_config(codec, 0x0e, 0x02a79130); | 5395 | snd_hda_codec_set_pincfg(codec, 0x0e, 0x02a79130); |
5188 | /* fallthru */ | 5396 | /* fallthru */ |
5189 | case STAC_DELL_3ST: | 5397 | case STAC_DELL_3ST: |
5190 | /* GPIO2 High = Enable EAPD */ | 5398 | /* GPIO2 High = Enable EAPD */ |
@@ -5211,6 +5419,7 @@ static int patch_stac927x(struct hda_codec *codec) | |||
5211 | } | 5419 | } |
5212 | 5420 | ||
5213 | spec->num_pwrs = 0; | 5421 | spec->num_pwrs = 0; |
5422 | spec->aloopback_ctl = stac927x_loopback; | ||
5214 | spec->aloopback_mask = 0x40; | 5423 | spec->aloopback_mask = 0x40; |
5215 | spec->aloopback_shift = 0; | 5424 | spec->aloopback_shift = 0; |
5216 | spec->eapd_switch = 1; | 5425 | spec->eapd_switch = 1; |
@@ -5269,16 +5478,11 @@ static int patch_stac9205(struct hda_codec *codec) | |||
5269 | stac9205_models, | 5478 | stac9205_models, |
5270 | stac9205_cfg_tbl); | 5479 | stac9205_cfg_tbl); |
5271 | again: | 5480 | again: |
5272 | if (spec->board_config < 0) { | 5481 | if (spec->board_config < 0) |
5273 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n"); | 5482 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n"); |
5274 | err = stac92xx_save_bios_config_regs(codec); | 5483 | else |
5275 | } else | 5484 | stac92xx_set_config_regs(codec, |
5276 | err = stac_save_pin_cfgs(codec, | ||
5277 | stac9205_brd_tbl[spec->board_config]); | 5485 | stac9205_brd_tbl[spec->board_config]); |
5278 | if (err < 0) { | ||
5279 | stac92xx_free(codec); | ||
5280 | return err; | ||
5281 | } | ||
5282 | 5486 | ||
5283 | spec->digbeep_nid = 0x23; | 5487 | spec->digbeep_nid = 0x23; |
5284 | spec->adc_nids = stac9205_adc_nids; | 5488 | spec->adc_nids = stac9205_adc_nids; |
@@ -5295,17 +5499,20 @@ static int patch_stac9205(struct hda_codec *codec) | |||
5295 | 5499 | ||
5296 | spec->init = stac9205_core_init; | 5500 | spec->init = stac9205_core_init; |
5297 | spec->mixer = stac9205_mixer; | 5501 | spec->mixer = stac9205_mixer; |
5502 | spec->aloopback_ctl = stac9205_loopback; | ||
5298 | 5503 | ||
5299 | spec->aloopback_mask = 0x40; | 5504 | spec->aloopback_mask = 0x40; |
5300 | spec->aloopback_shift = 0; | 5505 | spec->aloopback_shift = 0; |
5301 | spec->eapd_switch = 1; | 5506 | /* Turn on/off EAPD per HP plugging */ |
5507 | if (spec->board_config != STAC_9205_EAPD) | ||
5508 | spec->eapd_switch = 1; | ||
5302 | spec->multiout.dac_nids = spec->dac_nids; | 5509 | spec->multiout.dac_nids = spec->dac_nids; |
5303 | 5510 | ||
5304 | switch (spec->board_config){ | 5511 | switch (spec->board_config){ |
5305 | case STAC_9205_DELL_M43: | 5512 | case STAC_9205_DELL_M43: |
5306 | /* Enable SPDIF in/out */ | 5513 | /* Enable SPDIF in/out */ |
5307 | stac_change_pin_config(codec, 0x1f, 0x01441030); | 5514 | snd_hda_codec_set_pincfg(codec, 0x1f, 0x01441030); |
5308 | stac_change_pin_config(codec, 0x20, 0x1c410030); | 5515 | snd_hda_codec_set_pincfg(codec, 0x20, 0x1c410030); |
5309 | 5516 | ||
5310 | /* Enable unsol response for GPIO4/Dock HP connection */ | 5517 | /* Enable unsol response for GPIO4/Dock HP connection */ |
5311 | err = stac_add_event(spec, codec->afg, STAC_VREF_EVENT, 0x01); | 5518 | err = stac_add_event(spec, codec->afg, STAC_VREF_EVENT, 0x01); |
@@ -5362,223 +5569,87 @@ static int patch_stac9205(struct hda_codec *codec) | |||
5362 | * STAC9872 hack | 5569 | * STAC9872 hack |
5363 | */ | 5570 | */ |
5364 | 5571 | ||
5365 | /* static config for Sony VAIO FE550G and Sony VAIO AR */ | 5572 | static struct hda_verb stac9872_core_init[] = { |
5366 | static hda_nid_t vaio_dacs[] = { 0x2 }; | ||
5367 | #define VAIO_HP_DAC 0x5 | ||
5368 | static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ }; | ||
5369 | static hda_nid_t vaio_mux_nids[] = { 0x15 }; | ||
5370 | |||
5371 | static struct hda_input_mux vaio_mux = { | ||
5372 | .num_items = 3, | ||
5373 | .items = { | ||
5374 | /* { "HP", 0x0 }, */ | ||
5375 | { "Mic Jack", 0x1 }, | ||
5376 | { "Internal Mic", 0x2 }, | ||
5377 | { "PCM", 0x3 }, | ||
5378 | } | ||
5379 | }; | ||
5380 | |||
5381 | static struct hda_verb vaio_init[] = { | ||
5382 | {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */ | ||
5383 | {0x0a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | STAC_HP_EVENT}, | ||
5384 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */ | ||
5385 | {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */ | ||
5386 | {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ | ||
5387 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ | ||
5388 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ | 5573 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ |
5389 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ | ||
5390 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ | ||
5391 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */ | ||
5392 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */ | ||
5393 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ | 5574 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ |
5394 | {} | 5575 | {} |
5395 | }; | 5576 | }; |
5396 | 5577 | ||
5397 | static struct hda_verb vaio_ar_init[] = { | 5578 | static struct snd_kcontrol_new stac9872_mixer[] = { |
5398 | {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */ | ||
5399 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */ | ||
5400 | {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */ | ||
5401 | {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ | ||
5402 | /* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */ | ||
5403 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ | ||
5404 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ | ||
5405 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ | ||
5406 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ | ||
5407 | /* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */ | ||
5408 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */ | ||
5409 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */ | ||
5410 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ | ||
5411 | {} | ||
5412 | }; | ||
5413 | |||
5414 | static struct snd_kcontrol_new vaio_mixer[] = { | ||
5415 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x02, 0, HDA_OUTPUT), | ||
5416 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x02, 0, HDA_OUTPUT), | ||
5417 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x05, 0, HDA_OUTPUT), | ||
5418 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x05, 0, HDA_OUTPUT), | ||
5419 | /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */ | ||
5420 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), | 5579 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), |
5421 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), | 5580 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), |
5422 | { | 5581 | { } /* end */ |
5423 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
5424 | .name = "Capture Source", | ||
5425 | .count = 1, | ||
5426 | .info = stac92xx_mux_enum_info, | ||
5427 | .get = stac92xx_mux_enum_get, | ||
5428 | .put = stac92xx_mux_enum_put, | ||
5429 | }, | ||
5430 | {} | ||
5431 | }; | 5582 | }; |
5432 | 5583 | ||
5433 | static struct snd_kcontrol_new vaio_ar_mixer[] = { | 5584 | static hda_nid_t stac9872_pin_nids[] = { |
5434 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x02, 0, HDA_OUTPUT), | 5585 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
5435 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x02, 0, HDA_OUTPUT), | 5586 | 0x11, 0x13, 0x14, |
5436 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x05, 0, HDA_OUTPUT), | ||
5437 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x05, 0, HDA_OUTPUT), | ||
5438 | /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */ | ||
5439 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), | ||
5440 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), | ||
5441 | /*HDA_CODEC_MUTE("Optical Out Switch", 0x10, 0, HDA_OUTPUT), | ||
5442 | HDA_CODEC_VOLUME("Optical Out Volume", 0x10, 0, HDA_OUTPUT),*/ | ||
5443 | { | ||
5444 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
5445 | .name = "Capture Source", | ||
5446 | .count = 1, | ||
5447 | .info = stac92xx_mux_enum_info, | ||
5448 | .get = stac92xx_mux_enum_get, | ||
5449 | .put = stac92xx_mux_enum_put, | ||
5450 | }, | ||
5451 | {} | ||
5452 | }; | 5587 | }; |
5453 | 5588 | ||
5454 | static struct hda_codec_ops stac9872_patch_ops = { | 5589 | static hda_nid_t stac9872_adc_nids[] = { |
5455 | .build_controls = stac92xx_build_controls, | 5590 | 0x8 /*,0x6*/ |
5456 | .build_pcms = stac92xx_build_pcms, | ||
5457 | .init = stac92xx_init, | ||
5458 | .free = stac92xx_free, | ||
5459 | #ifdef SND_HDA_NEEDS_RESUME | ||
5460 | .resume = stac92xx_resume, | ||
5461 | #endif | ||
5462 | }; | 5591 | }; |
5463 | 5592 | ||
5464 | static int stac9872_vaio_init(struct hda_codec *codec) | 5593 | static hda_nid_t stac9872_mux_nids[] = { |
5465 | { | 5594 | 0x15 |
5466 | int err; | ||
5467 | |||
5468 | err = stac92xx_init(codec); | ||
5469 | if (err < 0) | ||
5470 | return err; | ||
5471 | if (codec->patch_ops.unsol_event) | ||
5472 | codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); | ||
5473 | return 0; | ||
5474 | } | ||
5475 | |||
5476 | static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res) | ||
5477 | { | ||
5478 | if (get_pin_presence(codec, 0x0a)) { | ||
5479 | stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN); | ||
5480 | stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN); | ||
5481 | } else { | ||
5482 | stac92xx_reset_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN); | ||
5483 | stac92xx_set_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN); | ||
5484 | } | ||
5485 | } | ||
5486 | |||
5487 | static void stac9872_vaio_unsol_event(struct hda_codec *codec, unsigned int res) | ||
5488 | { | ||
5489 | switch (res >> 26) { | ||
5490 | case STAC_HP_EVENT: | ||
5491 | stac9872_vaio_hp_detect(codec, res); | ||
5492 | break; | ||
5493 | } | ||
5494 | } | ||
5495 | |||
5496 | static struct hda_codec_ops stac9872_vaio_patch_ops = { | ||
5497 | .build_controls = stac92xx_build_controls, | ||
5498 | .build_pcms = stac92xx_build_pcms, | ||
5499 | .init = stac9872_vaio_init, | ||
5500 | .free = stac92xx_free, | ||
5501 | .unsol_event = stac9872_vaio_unsol_event, | ||
5502 | #ifdef CONFIG_PM | ||
5503 | .resume = stac92xx_resume, | ||
5504 | #endif | ||
5505 | }; | 5595 | }; |
5506 | 5596 | ||
5507 | enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */ | 5597 | static unsigned int stac9872_vaio_pin_configs[9] = { |
5508 | CXD9872RD_VAIO, | 5598 | 0x03211020, 0x411111f0, 0x411111f0, 0x03a15030, |
5509 | /* Unknown. id=0x83847662 and subsys=0x104D1200 or 104D1000. */ | 5599 | 0x411111f0, 0x90170110, 0x411111f0, 0x411111f0, |
5510 | STAC9872AK_VAIO, | 5600 | 0x90a7013e |
5511 | /* Unknown. id=0x83847661 and subsys=0x104D1200. */ | ||
5512 | STAC9872K_VAIO, | ||
5513 | /* AR Series. id=0x83847664 and subsys=104D1300 */ | ||
5514 | CXD9872AKD_VAIO, | ||
5515 | STAC_9872_MODELS, | ||
5516 | }; | 5601 | }; |
5517 | 5602 | ||
5518 | static const char *stac9872_models[STAC_9872_MODELS] = { | 5603 | static const char *stac9872_models[STAC_9872_MODELS] = { |
5519 | [CXD9872RD_VAIO] = "vaio", | 5604 | [STAC_9872_AUTO] = "auto", |
5520 | [CXD9872AKD_VAIO] = "vaio-ar", | 5605 | [STAC_9872_VAIO] = "vaio", |
5606 | }; | ||
5607 | |||
5608 | static unsigned int *stac9872_brd_tbl[STAC_9872_MODELS] = { | ||
5609 | [STAC_9872_VAIO] = stac9872_vaio_pin_configs, | ||
5521 | }; | 5610 | }; |
5522 | 5611 | ||
5523 | static struct snd_pci_quirk stac9872_cfg_tbl[] = { | 5612 | static struct snd_pci_quirk stac9872_cfg_tbl[] = { |
5524 | SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO), | 5613 | {} /* terminator */ |
5525 | SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO), | ||
5526 | SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO), | ||
5527 | SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO), | ||
5528 | {} | ||
5529 | }; | 5614 | }; |
5530 | 5615 | ||
5531 | static int patch_stac9872(struct hda_codec *codec) | 5616 | static int patch_stac9872(struct hda_codec *codec) |
5532 | { | 5617 | { |
5533 | struct sigmatel_spec *spec; | 5618 | struct sigmatel_spec *spec; |
5534 | int board_config; | 5619 | int err; |
5535 | 5620 | ||
5536 | board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS, | ||
5537 | stac9872_models, | ||
5538 | stac9872_cfg_tbl); | ||
5539 | if (board_config < 0) | ||
5540 | /* unknown config, let generic-parser do its job... */ | ||
5541 | return snd_hda_parse_generic_codec(codec); | ||
5542 | |||
5543 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 5621 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
5544 | if (spec == NULL) | 5622 | if (spec == NULL) |
5545 | return -ENOMEM; | 5623 | return -ENOMEM; |
5546 | |||
5547 | codec->spec = spec; | 5624 | codec->spec = spec; |
5548 | switch (board_config) { | ||
5549 | case CXD9872RD_VAIO: | ||
5550 | case STAC9872AK_VAIO: | ||
5551 | case STAC9872K_VAIO: | ||
5552 | spec->mixer = vaio_mixer; | ||
5553 | spec->init = vaio_init; | ||
5554 | spec->multiout.max_channels = 2; | ||
5555 | spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs); | ||
5556 | spec->multiout.dac_nids = vaio_dacs; | ||
5557 | spec->multiout.hp_nid = VAIO_HP_DAC; | ||
5558 | spec->num_adcs = ARRAY_SIZE(vaio_adcs); | ||
5559 | spec->adc_nids = vaio_adcs; | ||
5560 | spec->num_pwrs = 0; | ||
5561 | spec->input_mux = &vaio_mux; | ||
5562 | spec->mux_nids = vaio_mux_nids; | ||
5563 | codec->patch_ops = stac9872_vaio_patch_ops; | ||
5564 | break; | ||
5565 | |||
5566 | case CXD9872AKD_VAIO: | ||
5567 | spec->mixer = vaio_ar_mixer; | ||
5568 | spec->init = vaio_ar_init; | ||
5569 | spec->multiout.max_channels = 2; | ||
5570 | spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs); | ||
5571 | spec->multiout.dac_nids = vaio_dacs; | ||
5572 | spec->multiout.hp_nid = VAIO_HP_DAC; | ||
5573 | spec->num_adcs = ARRAY_SIZE(vaio_adcs); | ||
5574 | spec->num_pwrs = 0; | ||
5575 | spec->adc_nids = vaio_adcs; | ||
5576 | spec->input_mux = &vaio_mux; | ||
5577 | spec->mux_nids = vaio_mux_nids; | ||
5578 | codec->patch_ops = stac9872_patch_ops; | ||
5579 | break; | ||
5580 | } | ||
5581 | 5625 | ||
5626 | spec->board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS, | ||
5627 | stac9872_models, | ||
5628 | stac9872_cfg_tbl); | ||
5629 | if (spec->board_config < 0) | ||
5630 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9872, " | ||
5631 | "using BIOS defaults\n"); | ||
5632 | else | ||
5633 | stac92xx_set_config_regs(codec, | ||
5634 | stac9872_brd_tbl[spec->board_config]); | ||
5635 | |||
5636 | spec->num_pins = ARRAY_SIZE(stac9872_pin_nids); | ||
5637 | spec->pin_nids = stac9872_pin_nids; | ||
5638 | spec->multiout.dac_nids = spec->dac_nids; | ||
5639 | spec->num_adcs = ARRAY_SIZE(stac9872_adc_nids); | ||
5640 | spec->adc_nids = stac9872_adc_nids; | ||
5641 | spec->num_muxes = ARRAY_SIZE(stac9872_mux_nids); | ||
5642 | spec->mux_nids = stac9872_mux_nids; | ||
5643 | spec->mixer = stac9872_mixer; | ||
5644 | spec->init = stac9872_core_init; | ||
5645 | |||
5646 | err = stac92xx_parse_auto_config(codec, 0x10, 0x12); | ||
5647 | if (err < 0) { | ||
5648 | stac92xx_free(codec); | ||
5649 | return -EINVAL; | ||
5650 | } | ||
5651 | spec->input_mux = &spec->private_imux; | ||
5652 | codec->patch_ops = stac92xx_patch_ops; | ||
5582 | return 0; | 5653 | return 0; |
5583 | } | 5654 | } |
5584 | 5655 | ||