diff options
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 1581 |
1 files changed, 902 insertions, 679 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 35b83dc6e19e..917bc5d3ac2c 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, |
@@ -55,20 +56,24 @@ enum { | |||
55 | STAC_9200_DELL_M25, | 56 | STAC_9200_DELL_M25, |
56 | STAC_9200_DELL_M26, | 57 | STAC_9200_DELL_M26, |
57 | STAC_9200_DELL_M27, | 58 | STAC_9200_DELL_M27, |
58 | STAC_9200_GATEWAY, | 59 | STAC_9200_M4, |
60 | STAC_9200_M4_2, | ||
59 | STAC_9200_PANASONIC, | 61 | STAC_9200_PANASONIC, |
60 | STAC_9200_MODELS | 62 | STAC_9200_MODELS |
61 | }; | 63 | }; |
62 | 64 | ||
63 | enum { | 65 | enum { |
66 | STAC_9205_AUTO, | ||
64 | STAC_9205_REF, | 67 | STAC_9205_REF, |
65 | STAC_9205_DELL_M42, | 68 | STAC_9205_DELL_M42, |
66 | STAC_9205_DELL_M43, | 69 | STAC_9205_DELL_M43, |
67 | STAC_9205_DELL_M44, | 70 | STAC_9205_DELL_M44, |
71 | STAC_9205_EAPD, | ||
68 | STAC_9205_MODELS | 72 | STAC_9205_MODELS |
69 | }; | 73 | }; |
70 | 74 | ||
71 | enum { | 75 | enum { |
76 | STAC_92HD73XX_AUTO, | ||
72 | STAC_92HD73XX_NO_JD, /* no jack-detection */ | 77 | STAC_92HD73XX_NO_JD, /* no jack-detection */ |
73 | STAC_92HD73XX_REF, | 78 | STAC_92HD73XX_REF, |
74 | STAC_DELL_M6_AMIC, | 79 | STAC_DELL_M6_AMIC, |
@@ -79,28 +84,40 @@ enum { | |||
79 | }; | 84 | }; |
80 | 85 | ||
81 | enum { | 86 | enum { |
87 | STAC_92HD83XXX_AUTO, | ||
82 | STAC_92HD83XXX_REF, | 88 | STAC_92HD83XXX_REF, |
89 | STAC_92HD83XXX_PWR_REF, | ||
90 | STAC_DELL_S14, | ||
83 | STAC_92HD83XXX_MODELS | 91 | STAC_92HD83XXX_MODELS |
84 | }; | 92 | }; |
85 | 93 | ||
86 | enum { | 94 | enum { |
95 | STAC_92HD71BXX_AUTO, | ||
87 | STAC_92HD71BXX_REF, | 96 | STAC_92HD71BXX_REF, |
88 | STAC_DELL_M4_1, | 97 | STAC_DELL_M4_1, |
89 | STAC_DELL_M4_2, | 98 | STAC_DELL_M4_2, |
90 | STAC_DELL_M4_3, | 99 | STAC_DELL_M4_3, |
91 | STAC_HP_M4, | 100 | STAC_HP_M4, |
101 | STAC_HP_DV5, | ||
102 | STAC_HP_HDX, | ||
92 | STAC_92HD71BXX_MODELS | 103 | STAC_92HD71BXX_MODELS |
93 | }; | 104 | }; |
94 | 105 | ||
95 | enum { | 106 | enum { |
107 | STAC_925x_AUTO, | ||
96 | STAC_925x_REF, | 108 | STAC_925x_REF, |
109 | STAC_M1, | ||
110 | STAC_M1_2, | ||
111 | STAC_M2, | ||
97 | STAC_M2_2, | 112 | STAC_M2_2, |
98 | STAC_MA6, | 113 | STAC_M3, |
99 | STAC_PA6, | 114 | STAC_M5, |
115 | STAC_M6, | ||
100 | STAC_925x_MODELS | 116 | STAC_925x_MODELS |
101 | }; | 117 | }; |
102 | 118 | ||
103 | enum { | 119 | enum { |
120 | STAC_922X_AUTO, | ||
104 | STAC_D945_REF, | 121 | STAC_D945_REF, |
105 | STAC_D945GTP3, | 122 | STAC_D945GTP3, |
106 | STAC_D945GTP5, | 123 | STAC_D945GTP5, |
@@ -128,6 +145,7 @@ enum { | |||
128 | }; | 145 | }; |
129 | 146 | ||
130 | enum { | 147 | enum { |
148 | STAC_927X_AUTO, | ||
131 | STAC_D965_REF_NO_JD, /* no jack-detection */ | 149 | STAC_D965_REF_NO_JD, /* no jack-detection */ |
132 | STAC_D965_REF, | 150 | STAC_D965_REF, |
133 | STAC_D965_3ST, | 151 | STAC_D965_3ST, |
@@ -137,6 +155,12 @@ enum { | |||
137 | STAC_927X_MODELS | 155 | STAC_927X_MODELS |
138 | }; | 156 | }; |
139 | 157 | ||
158 | enum { | ||
159 | STAC_9872_AUTO, | ||
160 | STAC_9872_VAIO, | ||
161 | STAC_9872_MODELS | ||
162 | }; | ||
163 | |||
140 | struct sigmatel_event { | 164 | struct sigmatel_event { |
141 | hda_nid_t nid; | 165 | hda_nid_t nid; |
142 | unsigned char type; | 166 | unsigned char type; |
@@ -160,6 +184,7 @@ struct sigmatel_spec { | |||
160 | unsigned int alt_switch: 1; | 184 | unsigned int alt_switch: 1; |
161 | unsigned int hp_detect: 1; | 185 | unsigned int hp_detect: 1; |
162 | unsigned int spdif_mute: 1; | 186 | unsigned int spdif_mute: 1; |
187 | unsigned int check_volume_offset:1; | ||
163 | 188 | ||
164 | /* gpio lines */ | 189 | /* gpio lines */ |
165 | unsigned int eapd_mask; | 190 | unsigned int eapd_mask; |
@@ -172,6 +197,7 @@ struct sigmatel_spec { | |||
172 | unsigned int stream_delay; | 197 | unsigned int stream_delay; |
173 | 198 | ||
174 | /* analog loopback */ | 199 | /* analog loopback */ |
200 | struct snd_kcontrol_new *aloopback_ctl; | ||
175 | unsigned char aloopback_mask; | 201 | unsigned char aloopback_mask; |
176 | unsigned char aloopback_shift; | 202 | unsigned char aloopback_shift; |
177 | 203 | ||
@@ -196,6 +222,8 @@ struct sigmatel_spec { | |||
196 | hda_nid_t hp_dacs[5]; | 222 | hda_nid_t hp_dacs[5]; |
197 | hda_nid_t speaker_dacs[5]; | 223 | hda_nid_t speaker_dacs[5]; |
198 | 224 | ||
225 | int volume_offset; | ||
226 | |||
199 | /* capture */ | 227 | /* capture */ |
200 | hda_nid_t *adc_nids; | 228 | hda_nid_t *adc_nids; |
201 | unsigned int num_adcs; | 229 | unsigned int num_adcs; |
@@ -217,7 +245,6 @@ struct sigmatel_spec { | |||
217 | /* pin widgets */ | 245 | /* pin widgets */ |
218 | hda_nid_t *pin_nids; | 246 | hda_nid_t *pin_nids; |
219 | unsigned int num_pins; | 247 | unsigned int num_pins; |
220 | unsigned int *pin_configs; | ||
221 | 248 | ||
222 | /* codec specific stuff */ | 249 | /* codec specific stuff */ |
223 | struct hda_verb *init; | 250 | struct hda_verb *init; |
@@ -328,7 +355,11 @@ static hda_nid_t stac92hd83xxx_slave_dig_outs[2] = { | |||
328 | }; | 355 | }; |
329 | 356 | ||
330 | static unsigned int stac92hd83xxx_pwr_mapping[4] = { | 357 | static unsigned int stac92hd83xxx_pwr_mapping[4] = { |
331 | 0x03, 0x0c, 0x10, 0x40, | 358 | 0x03, 0x0c, 0x20, 0x40, |
359 | }; | ||
360 | |||
361 | static hda_nid_t stac92hd83xxx_amp_nids[1] = { | ||
362 | 0xc, | ||
332 | }; | 363 | }; |
333 | 364 | ||
334 | static hda_nid_t stac92hd71bxx_pwr_nids[3] = { | 365 | static hda_nid_t stac92hd71bxx_pwr_nids[3] = { |
@@ -389,6 +420,10 @@ static hda_nid_t stac922x_mux_nids[2] = { | |||
389 | 0x12, 0x13, | 420 | 0x12, 0x13, |
390 | }; | 421 | }; |
391 | 422 | ||
423 | static hda_nid_t stac927x_slave_dig_outs[2] = { | ||
424 | 0x1f, 0, | ||
425 | }; | ||
426 | |||
392 | static hda_nid_t stac927x_adc_nids[3] = { | 427 | static hda_nid_t stac927x_adc_nids[3] = { |
393 | 0x07, 0x08, 0x09 | 428 | 0x07, 0x08, 0x09 |
394 | }; | 429 | }; |
@@ -461,15 +496,21 @@ static hda_nid_t stac92hd73xx_pin_nids[13] = { | |||
461 | 0x14, 0x22, 0x23 | 496 | 0x14, 0x22, 0x23 |
462 | }; | 497 | }; |
463 | 498 | ||
464 | static hda_nid_t stac92hd83xxx_pin_nids[14] = { | 499 | static hda_nid_t stac92hd83xxx_pin_nids[10] = { |
465 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | 500 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, |
466 | 0x0f, 0x10, 0x11, 0x12, 0x13, | 501 | 0x0f, 0x10, 0x11, 0x1f, 0x20, |
467 | 0x1d, 0x1e, 0x1f, 0x20 | ||
468 | }; | 502 | }; |
469 | static hda_nid_t stac92hd71bxx_pin_nids[11] = { | 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 | ||
509 | }; | ||
510 | static hda_nid_t stac92hd71bxx_pin_nids_6port[STAC92HD71BXX_NUM_PINS] = { | ||
470 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | 511 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, |
471 | 0x0f, 0x14, 0x18, 0x19, 0x1e, | 512 | 0x0f, 0x14, 0x18, 0x19, 0x1e, |
472 | 0x1f, | 513 | 0x1f, 0x20, 0x27 |
473 | }; | 514 | }; |
474 | 515 | ||
475 | static hda_nid_t stac927x_pin_nids[14] = { | 516 | static hda_nid_t stac927x_pin_nids[14] = { |
@@ -831,13 +872,9 @@ static struct hda_verb stac92hd73xx_10ch_core_init[] = { | |||
831 | }; | 872 | }; |
832 | 873 | ||
833 | static struct hda_verb stac92hd83xxx_core_init[] = { | 874 | static struct hda_verb stac92hd83xxx_core_init[] = { |
834 | /* start of config #1 */ | 875 | { 0xa, AC_VERB_SET_CONNECT_SEL, 0x1}, |
835 | { 0xe, AC_VERB_SET_CONNECT_SEL, 0x3}, | 876 | { 0xb, AC_VERB_SET_CONNECT_SEL, 0x1}, |
836 | 877 | { 0xd, AC_VERB_SET_CONNECT_SEL, 0x0}, | |
837 | /* start of config #2 */ | ||
838 | { 0xa, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
839 | { 0xb, AC_VERB_SET_CONNECT_SEL, 0x0}, | ||
840 | { 0xd, AC_VERB_SET_CONNECT_SEL, 0x1}, | ||
841 | 878 | ||
842 | /* power state controls amps */ | 879 | /* power state controls amps */ |
843 | { 0x01, AC_VERB_SET_EAPD, 1 << 2}, | 880 | { 0x01, AC_VERB_SET_EAPD, 1 << 2}, |
@@ -847,26 +884,25 @@ static struct hda_verb stac92hd83xxx_core_init[] = { | |||
847 | static struct hda_verb stac92hd71bxx_core_init[] = { | 884 | static struct hda_verb stac92hd71bxx_core_init[] = { |
848 | /* set master volume and direct control */ | 885 | /* set master volume and direct control */ |
849 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 886 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
850 | /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */ | ||
851 | { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
852 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
853 | { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
854 | {} | 887 | {} |
855 | }; | 888 | }; |
856 | 889 | ||
857 | #define HD_DISABLE_PORTF 2 | 890 | #define HD_DISABLE_PORTF 1 |
858 | static struct hda_verb stac92hd71bxx_analog_core_init[] = { | 891 | static struct hda_verb stac92hd71bxx_analog_core_init[] = { |
859 | /* start of config #1 */ | 892 | /* start of config #1 */ |
860 | 893 | ||
861 | /* connect port 0f to audio mixer */ | 894 | /* connect port 0f to audio mixer */ |
862 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, | 895 | { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, |
863 | /* unmute right and left channels for node 0x0f */ | ||
864 | { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
865 | /* start of config #2 */ | 896 | /* start of config #2 */ |
866 | 897 | ||
867 | /* set master volume and direct control */ | 898 | /* set master volume and direct control */ |
868 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 899 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
869 | /* 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)}, | ||
870 | { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 906 | { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
871 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 907 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
872 | {} | 908 | {} |
@@ -875,6 +911,8 @@ static struct hda_verb stac92hd71bxx_analog_core_init[] = { | |||
875 | static struct hda_verb stac925x_core_init[] = { | 911 | static struct hda_verb stac925x_core_init[] = { |
876 | /* set dac0mux for dac converter */ | 912 | /* set dac0mux for dac converter */ |
877 | { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00}, | 913 | { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00}, |
914 | /* mute the master volume */ | ||
915 | { 0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | ||
878 | {} | 916 | {} |
879 | }; | 917 | }; |
880 | 918 | ||
@@ -945,16 +983,6 @@ static struct hda_verb stac9205_core_init[] = { | |||
945 | .private_value = HDA_COMPOSE_AMP_VAL(nid, chs, idx, dir) \ | 983 | .private_value = HDA_COMPOSE_AMP_VAL(nid, chs, idx, dir) \ |
946 | } | 984 | } |
947 | 985 | ||
948 | #define STAC_INPUT_SOURCE(cnt) \ | ||
949 | { \ | ||
950 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
951 | .name = "Input Source", \ | ||
952 | .count = cnt, \ | ||
953 | .info = stac92xx_mux_enum_info, \ | ||
954 | .get = stac92xx_mux_enum_get, \ | ||
955 | .put = stac92xx_mux_enum_put, \ | ||
956 | } | ||
957 | |||
958 | #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \ | 986 | #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \ |
959 | { \ | 987 | { \ |
960 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | 988 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ |
@@ -969,7 +997,6 @@ static struct hda_verb stac9205_core_init[] = { | |||
969 | static struct snd_kcontrol_new stac9200_mixer[] = { | 997 | static struct snd_kcontrol_new stac9200_mixer[] = { |
970 | HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), | 998 | HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), |
971 | HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), | 999 | HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), |
972 | STAC_INPUT_SOURCE(1), | ||
973 | HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), | 1000 | HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), |
974 | HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), | 1001 | HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), |
975 | { } /* end */ | 1002 | { } /* end */ |
@@ -994,8 +1021,6 @@ static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = { | |||
994 | HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT), | 1021 | HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT), |
995 | HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT), | 1022 | HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT), |
996 | 1023 | ||
997 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3), | ||
998 | |||
999 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), | 1024 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), |
1000 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), | 1025 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), |
1001 | 1026 | ||
@@ -1005,9 +1030,22 @@ static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = { | |||
1005 | { } /* end */ | 1030 | { } /* end */ |
1006 | }; | 1031 | }; |
1007 | 1032 | ||
1008 | 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[] = { | ||
1009 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4), | 1039 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4), |
1040 | {} | ||
1041 | }; | ||
1042 | |||
1043 | static struct snd_kcontrol_new stac92hd73xx_10ch_loopback[] = { | ||
1044 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5), | ||
1045 | {} | ||
1046 | }; | ||
1010 | 1047 | ||
1048 | static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = { | ||
1011 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), | 1049 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), |
1012 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), | 1050 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), |
1013 | 1051 | ||
@@ -1032,8 +1070,6 @@ static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = { | |||
1032 | }; | 1070 | }; |
1033 | 1071 | ||
1034 | static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = { | 1072 | static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = { |
1035 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5), | ||
1036 | |||
1037 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), | 1073 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), |
1038 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), | 1074 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), |
1039 | 1075 | ||
@@ -1085,9 +1121,6 @@ static struct snd_kcontrol_new stac92hd83xxx_mixer[] = { | |||
1085 | }; | 1121 | }; |
1086 | 1122 | ||
1087 | static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { | 1123 | static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { |
1088 | STAC_INPUT_SOURCE(2), | ||
1089 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2), | ||
1090 | |||
1091 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), | 1124 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), |
1092 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), | 1125 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), |
1093 | 1126 | ||
@@ -1113,10 +1146,11 @@ static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { | |||
1113 | { } /* end */ | 1146 | { } /* end */ |
1114 | }; | 1147 | }; |
1115 | 1148 | ||
1116 | static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { | 1149 | static struct snd_kcontrol_new stac92hd71bxx_loopback[] = { |
1117 | STAC_INPUT_SOURCE(2), | 1150 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2) |
1118 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2), | 1151 | }; |
1119 | 1152 | ||
1153 | static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { | ||
1120 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), | 1154 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), |
1121 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), | 1155 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), |
1122 | 1156 | ||
@@ -1126,16 +1160,14 @@ static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { | |||
1126 | }; | 1160 | }; |
1127 | 1161 | ||
1128 | static struct snd_kcontrol_new stac925x_mixer[] = { | 1162 | static struct snd_kcontrol_new stac925x_mixer[] = { |
1129 | STAC_INPUT_SOURCE(1), | 1163 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT), |
1164 | HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), | ||
1130 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), | 1165 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), |
1131 | HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT), | 1166 | HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT), |
1132 | { } /* end */ | 1167 | { } /* end */ |
1133 | }; | 1168 | }; |
1134 | 1169 | ||
1135 | static struct snd_kcontrol_new stac9205_mixer[] = { | 1170 | static struct snd_kcontrol_new stac9205_mixer[] = { |
1136 | STAC_INPUT_SOURCE(2), | ||
1137 | STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1), | ||
1138 | |||
1139 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT), | 1171 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT), |
1140 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT), | 1172 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT), |
1141 | 1173 | ||
@@ -1144,9 +1176,13 @@ static struct snd_kcontrol_new stac9205_mixer[] = { | |||
1144 | { } /* end */ | 1176 | { } /* end */ |
1145 | }; | 1177 | }; |
1146 | 1178 | ||
1179 | static struct snd_kcontrol_new stac9205_loopback[] = { | ||
1180 | STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1), | ||
1181 | {} | ||
1182 | }; | ||
1183 | |||
1147 | /* This needs to be generated dynamically based on sequence */ | 1184 | /* This needs to be generated dynamically based on sequence */ |
1148 | static struct snd_kcontrol_new stac922x_mixer[] = { | 1185 | static struct snd_kcontrol_new stac922x_mixer[] = { |
1149 | STAC_INPUT_SOURCE(2), | ||
1150 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT), | 1186 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT), |
1151 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT), | 1187 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT), |
1152 | 1188 | ||
@@ -1157,9 +1193,6 @@ static struct snd_kcontrol_new stac922x_mixer[] = { | |||
1157 | 1193 | ||
1158 | 1194 | ||
1159 | static struct snd_kcontrol_new stac927x_mixer[] = { | 1195 | static struct snd_kcontrol_new stac927x_mixer[] = { |
1160 | STAC_INPUT_SOURCE(3), | ||
1161 | STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1), | ||
1162 | |||
1163 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT), | 1196 | HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT), |
1164 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT), | 1197 | HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT), |
1165 | 1198 | ||
@@ -1171,6 +1204,11 @@ static struct snd_kcontrol_new stac927x_mixer[] = { | |||
1171 | { } /* end */ | 1204 | { } /* end */ |
1172 | }; | 1205 | }; |
1173 | 1206 | ||
1207 | static struct snd_kcontrol_new stac927x_loopback[] = { | ||
1208 | STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1), | ||
1209 | {} | ||
1210 | }; | ||
1211 | |||
1174 | static struct snd_kcontrol_new stac_dmux_mixer = { | 1212 | static struct snd_kcontrol_new stac_dmux_mixer = { |
1175 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1213 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1176 | .name = "Digital Input Source", | 1214 | .name = "Digital Input Source", |
@@ -1196,10 +1234,7 @@ static const char *slave_vols[] = { | |||
1196 | "LFE Playback Volume", | 1234 | "LFE Playback Volume", |
1197 | "Side Playback Volume", | 1235 | "Side Playback Volume", |
1198 | "Headphone Playback Volume", | 1236 | "Headphone Playback Volume", |
1199 | "Headphone Playback Volume", | ||
1200 | "Speaker Playback Volume", | 1237 | "Speaker Playback Volume", |
1201 | "External Speaker Playback Volume", | ||
1202 | "Speaker2 Playback Volume", | ||
1203 | NULL | 1238 | NULL |
1204 | }; | 1239 | }; |
1205 | 1240 | ||
@@ -1210,10 +1245,7 @@ static const char *slave_sws[] = { | |||
1210 | "LFE Playback Switch", | 1245 | "LFE Playback Switch", |
1211 | "Side Playback Switch", | 1246 | "Side Playback Switch", |
1212 | "Headphone Playback Switch", | 1247 | "Headphone Playback Switch", |
1213 | "Headphone Playback Switch", | ||
1214 | "Speaker Playback Switch", | 1248 | "Speaker Playback Switch", |
1215 | "External Speaker Playback Switch", | ||
1216 | "Speaker2 Playback Switch", | ||
1217 | "IEC958 Playback Switch", | 1249 | "IEC958 Playback Switch", |
1218 | NULL | 1250 | NULL |
1219 | }; | 1251 | }; |
@@ -1283,6 +1315,8 @@ static int stac92xx_build_controls(struct hda_codec *codec) | |||
1283 | unsigned int vmaster_tlv[4]; | 1315 | unsigned int vmaster_tlv[4]; |
1284 | snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], | 1316 | snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0], |
1285 | HDA_OUTPUT, vmaster_tlv); | 1317 | HDA_OUTPUT, vmaster_tlv); |
1318 | /* correct volume offset */ | ||
1319 | vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset; | ||
1286 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", | 1320 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", |
1287 | vmaster_tlv, slave_vols); | 1321 | vmaster_tlv, slave_vols); |
1288 | if (err < 0) | 1322 | if (err < 0) |
@@ -1295,6 +1329,13 @@ static int stac92xx_build_controls(struct hda_codec *codec) | |||
1295 | return err; | 1329 | return err; |
1296 | } | 1330 | } |
1297 | 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 | |||
1298 | stac92xx_free_kctls(codec); /* no longer needed */ | 1339 | stac92xx_free_kctls(codec); /* no longer needed */ |
1299 | 1340 | ||
1300 | /* create jack input elements */ | 1341 | /* create jack input elements */ |
@@ -1334,7 +1375,16 @@ static unsigned int ref9200_pin_configs[8] = { | |||
1334 | 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, | 1375 | 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, |
1335 | }; | 1376 | }; |
1336 | 1377 | ||
1337 | /* | 1378 | static unsigned int gateway9200_m4_pin_configs[8] = { |
1379 | 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, | ||
1380 | 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, | ||
1381 | }; | ||
1382 | static unsigned int gateway9200_m4_2_pin_configs[8] = { | ||
1383 | 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, | ||
1384 | 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, | ||
1385 | }; | ||
1386 | |||
1387 | /* | ||
1338 | STAC 9200 pin configs for | 1388 | STAC 9200 pin configs for |
1339 | 102801A8 | 1389 | 102801A8 |
1340 | 102801DE | 1390 | 102801DE |
@@ -1464,10 +1514,13 @@ static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = { | |||
1464 | [STAC_9200_DELL_M25] = dell9200_m25_pin_configs, | 1514 | [STAC_9200_DELL_M25] = dell9200_m25_pin_configs, |
1465 | [STAC_9200_DELL_M26] = dell9200_m26_pin_configs, | 1515 | [STAC_9200_DELL_M26] = dell9200_m26_pin_configs, |
1466 | [STAC_9200_DELL_M27] = dell9200_m27_pin_configs, | 1516 | [STAC_9200_DELL_M27] = dell9200_m27_pin_configs, |
1517 | [STAC_9200_M4] = gateway9200_m4_pin_configs, | ||
1518 | [STAC_9200_M4_2] = gateway9200_m4_2_pin_configs, | ||
1467 | [STAC_9200_PANASONIC] = ref9200_pin_configs, | 1519 | [STAC_9200_PANASONIC] = ref9200_pin_configs, |
1468 | }; | 1520 | }; |
1469 | 1521 | ||
1470 | static const char *stac9200_models[STAC_9200_MODELS] = { | 1522 | static const char *stac9200_models[STAC_9200_MODELS] = { |
1523 | [STAC_AUTO] = "auto", | ||
1471 | [STAC_REF] = "ref", | 1524 | [STAC_REF] = "ref", |
1472 | [STAC_9200_OQO] = "oqo", | 1525 | [STAC_9200_OQO] = "oqo", |
1473 | [STAC_9200_DELL_D21] = "dell-d21", | 1526 | [STAC_9200_DELL_D21] = "dell-d21", |
@@ -1480,7 +1533,8 @@ static const char *stac9200_models[STAC_9200_MODELS] = { | |||
1480 | [STAC_9200_DELL_M25] = "dell-m25", | 1533 | [STAC_9200_DELL_M25] = "dell-m25", |
1481 | [STAC_9200_DELL_M26] = "dell-m26", | 1534 | [STAC_9200_DELL_M26] = "dell-m26", |
1482 | [STAC_9200_DELL_M27] = "dell-m27", | 1535 | [STAC_9200_DELL_M27] = "dell-m27", |
1483 | [STAC_9200_GATEWAY] = "gateway", | 1536 | [STAC_9200_M4] = "gateway-m4", |
1537 | [STAC_9200_M4_2] = "gateway-m4-2", | ||
1484 | [STAC_9200_PANASONIC] = "panasonic", | 1538 | [STAC_9200_PANASONIC] = "panasonic", |
1485 | }; | 1539 | }; |
1486 | 1540 | ||
@@ -1488,6 +1542,8 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = { | |||
1488 | /* SigmaTel reference board */ | 1542 | /* SigmaTel reference board */ |
1489 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1543 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1490 | "DFI LanParty", STAC_REF), | 1544 | "DFI LanParty", STAC_REF), |
1545 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, | ||
1546 | "DFI LanParty", STAC_REF), | ||
1491 | /* Dell laptops have BIOS problem */ | 1547 | /* Dell laptops have BIOS problem */ |
1492 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8, | 1548 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8, |
1493 | "unknown Dell", STAC_9200_DELL_D21), | 1549 | "unknown Dell", STAC_9200_DELL_D21), |
@@ -1550,11 +1606,9 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = { | |||
1550 | /* Panasonic */ | 1606 | /* Panasonic */ |
1551 | SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC), | 1607 | SND_PCI_QUIRK(0x10f7, 0x8338, "Panasonic CF-74", STAC_9200_PANASONIC), |
1552 | /* Gateway machines needs EAPD to be set on resume */ | 1608 | /* Gateway machines needs EAPD to be set on resume */ |
1553 | SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_GATEWAY), | 1609 | SND_PCI_QUIRK(0x107b, 0x0205, "Gateway S-7110M", STAC_9200_M4), |
1554 | SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", | 1610 | SND_PCI_QUIRK(0x107b, 0x0317, "Gateway MT3423, MX341*", STAC_9200_M4_2), |
1555 | STAC_9200_GATEWAY), | 1611 | SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", STAC_9200_M4_2), |
1556 | SND_PCI_QUIRK(0x107b, 0x0318, "Gateway ML3019, MT3707", | ||
1557 | STAC_9200_GATEWAY), | ||
1558 | /* OQO Mobile */ | 1612 | /* OQO Mobile */ |
1559 | SND_PCI_QUIRK(0x1106, 0x3288, "OQO Model 2", STAC_9200_OQO), | 1613 | SND_PCI_QUIRK(0x1106, 0x3288, "OQO Model 2", STAC_9200_OQO), |
1560 | {} /* terminator */ | 1614 | {} /* terminator */ |
@@ -1565,44 +1619,87 @@ static unsigned int ref925x_pin_configs[8] = { | |||
1565 | 0x90a70320, 0x02214210, 0x01019020, 0x9033032e, | 1619 | 0x90a70320, 0x02214210, 0x01019020, 0x9033032e, |
1566 | }; | 1620 | }; |
1567 | 1621 | ||
1568 | static unsigned int stac925x_MA6_pin_configs[8] = { | 1622 | static unsigned int stac925xM1_pin_configs[8] = { |
1569 | 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, | 1623 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, |
1570 | 0x90a70320, 0x90100211, 0x400003f1, 0x9033032e, | 1624 | 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, |
1571 | }; | 1625 | }; |
1572 | 1626 | ||
1573 | static unsigned int stac925x_PA6_pin_configs[8] = { | 1627 | static unsigned int stac925xM1_2_pin_configs[8] = { |
1574 | 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, | 1628 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, |
1575 | 0x50a103f0, 0x90100211, 0x400003f1, 0x9033032e, | 1629 | 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, |
1630 | }; | ||
1631 | |||
1632 | static unsigned int stac925xM2_pin_configs[8] = { | ||
1633 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, | ||
1634 | 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, | ||
1576 | }; | 1635 | }; |
1577 | 1636 | ||
1578 | static unsigned int stac925xM2_2_pin_configs[8] = { | 1637 | static unsigned int stac925xM2_2_pin_configs[8] = { |
1579 | 0x40c003f3, 0x424503f2, 0x04180011, 0x02a19020, | 1638 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, |
1580 | 0x50a103f0, 0x90100212, 0x400003f1, 0x9033032e, | 1639 | 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, |
1640 | }; | ||
1641 | |||
1642 | static unsigned int stac925xM3_pin_configs[8] = { | ||
1643 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, | ||
1644 | 0x40a000f0, 0x90100210, 0x400003f1, 0x503303f3, | ||
1645 | }; | ||
1646 | |||
1647 | static unsigned int stac925xM5_pin_configs[8] = { | ||
1648 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, | ||
1649 | 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, | ||
1650 | }; | ||
1651 | |||
1652 | static unsigned int stac925xM6_pin_configs[8] = { | ||
1653 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, | ||
1654 | 0x40a000f0, 0x90100210, 0x400003f1, 0x90330320, | ||
1581 | }; | 1655 | }; |
1582 | 1656 | ||
1583 | static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = { | 1657 | static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = { |
1584 | [STAC_REF] = ref925x_pin_configs, | 1658 | [STAC_REF] = ref925x_pin_configs, |
1659 | [STAC_M1] = stac925xM1_pin_configs, | ||
1660 | [STAC_M1_2] = stac925xM1_2_pin_configs, | ||
1661 | [STAC_M2] = stac925xM2_pin_configs, | ||
1585 | [STAC_M2_2] = stac925xM2_2_pin_configs, | 1662 | [STAC_M2_2] = stac925xM2_2_pin_configs, |
1586 | [STAC_MA6] = stac925x_MA6_pin_configs, | 1663 | [STAC_M3] = stac925xM3_pin_configs, |
1587 | [STAC_PA6] = stac925x_PA6_pin_configs, | 1664 | [STAC_M5] = stac925xM5_pin_configs, |
1665 | [STAC_M6] = stac925xM6_pin_configs, | ||
1588 | }; | 1666 | }; |
1589 | 1667 | ||
1590 | static const char *stac925x_models[STAC_925x_MODELS] = { | 1668 | static const char *stac925x_models[STAC_925x_MODELS] = { |
1669 | [STAC_925x_AUTO] = "auto", | ||
1591 | [STAC_REF] = "ref", | 1670 | [STAC_REF] = "ref", |
1671 | [STAC_M1] = "m1", | ||
1672 | [STAC_M1_2] = "m1-2", | ||
1673 | [STAC_M2] = "m2", | ||
1592 | [STAC_M2_2] = "m2-2", | 1674 | [STAC_M2_2] = "m2-2", |
1593 | [STAC_MA6] = "m6", | 1675 | [STAC_M3] = "m3", |
1594 | [STAC_PA6] = "pa6", | 1676 | [STAC_M5] = "m5", |
1677 | [STAC_M6] = "m6", | ||
1678 | }; | ||
1679 | |||
1680 | static struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = { | ||
1681 | SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2), | ||
1682 | SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5), | ||
1683 | SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1), | ||
1684 | SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_M2), | ||
1685 | SND_PCI_QUIRK(0x107b, 0x0367, "Gateway MX6453", STAC_M1_2), | ||
1686 | /* Not sure about the brand name for those */ | ||
1687 | SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M1), | ||
1688 | SND_PCI_QUIRK(0x107b, 0x0507, "Gateway mobile", STAC_M3), | ||
1689 | SND_PCI_QUIRK(0x107b, 0x0281, "Gateway mobile", STAC_M6), | ||
1690 | SND_PCI_QUIRK(0x107b, 0x0685, "Gateway mobile", STAC_M2_2), | ||
1691 | {} /* terminator */ | ||
1595 | }; | 1692 | }; |
1596 | 1693 | ||
1597 | static struct snd_pci_quirk stac925x_cfg_tbl[] = { | 1694 | static struct snd_pci_quirk stac925x_cfg_tbl[] = { |
1598 | /* SigmaTel reference board */ | 1695 | /* SigmaTel reference board */ |
1599 | 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), | ||
1600 | SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF), | 1698 | SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF), |
1601 | SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_REF), | 1699 | |
1602 | SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_REF), | 1700 | /* Default table for unknown ID */ |
1603 | SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_MA6), | 1701 | SND_PCI_QUIRK(0x1002, 0x437b, "Gateway mobile", STAC_M2_2), |
1604 | SND_PCI_QUIRK(0x107b, 0x0681, "Gateway NX860", STAC_PA6), | 1702 | |
1605 | SND_PCI_QUIRK(0x1002, 0x437b, "Gateway MX6453", STAC_M2_2), | ||
1606 | {} /* terminator */ | 1703 | {} /* terminator */ |
1607 | }; | 1704 | }; |
1608 | 1705 | ||
@@ -1629,6 +1726,7 @@ static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { | |||
1629 | }; | 1726 | }; |
1630 | 1727 | ||
1631 | static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { | 1728 | static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { |
1729 | [STAC_92HD73XX_AUTO] = "auto", | ||
1632 | [STAC_92HD73XX_NO_JD] = "no-jd", | 1730 | [STAC_92HD73XX_NO_JD] = "no-jd", |
1633 | [STAC_92HD73XX_REF] = "ref", | 1731 | [STAC_92HD73XX_REF] = "ref", |
1634 | [STAC_DELL_M6_AMIC] = "dell-m6-amic", | 1732 | [STAC_DELL_M6_AMIC] = "dell-m6-amic", |
@@ -1641,6 +1739,8 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { | |||
1641 | /* SigmaTel reference board */ | 1739 | /* SigmaTel reference board */ |
1642 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1740 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1643 | "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), | ||
1644 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254, | 1744 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254, |
1645 | "Dell Studio 1535", STAC_DELL_M6_DMIC), | 1745 | "Dell Studio 1535", STAC_DELL_M6_DMIC), |
1646 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255, | 1746 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255, |
@@ -1664,50 +1764,68 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { | |||
1664 | {} /* terminator */ | 1764 | {} /* terminator */ |
1665 | }; | 1765 | }; |
1666 | 1766 | ||
1667 | static unsigned int ref92hd83xxx_pin_configs[14] = { | 1767 | static unsigned int ref92hd83xxx_pin_configs[10] = { |
1668 | 0x02214030, 0x02211010, 0x02a19020, 0x02170130, | 1768 | 0x02214030, 0x02211010, 0x02a19020, 0x02170130, |
1669 | 0x01014050, 0x01819040, 0x01014020, 0x90a3014e, | 1769 | 0x01014050, 0x01819040, 0x01014020, 0x90a3014e, |
1670 | 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x40f000f0, | ||
1671 | 0x01451160, 0x98560170, | 1770 | 0x01451160, 0x98560170, |
1672 | }; | 1771 | }; |
1673 | 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 | |||
1674 | static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { | 1779 | static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { |
1675 | [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, | 1780 | [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, |
1781 | [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, | ||
1782 | [STAC_DELL_S14] = dell_s14_pin_configs, | ||
1676 | }; | 1783 | }; |
1677 | 1784 | ||
1678 | static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { | 1785 | static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { |
1786 | [STAC_92HD83XXX_AUTO] = "auto", | ||
1679 | [STAC_92HD83XXX_REF] = "ref", | 1787 | [STAC_92HD83XXX_REF] = "ref", |
1788 | [STAC_92HD83XXX_PWR_REF] = "mic-ref", | ||
1789 | [STAC_DELL_S14] = "dell-s14", | ||
1680 | }; | 1790 | }; |
1681 | 1791 | ||
1682 | static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { | 1792 | static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { |
1683 | /* SigmaTel reference board */ | 1793 | /* SigmaTel reference board */ |
1684 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1794 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1685 | "DFI LanParty", STAC_92HD71BXX_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), | ||
1686 | {} /* terminator */ | 1800 | {} /* terminator */ |
1687 | }; | 1801 | }; |
1688 | 1802 | ||
1689 | static unsigned int ref92hd71bxx_pin_configs[11] = { | 1803 | static unsigned int ref92hd71bxx_pin_configs[STAC92HD71BXX_NUM_PINS] = { |
1690 | 0x02214030, 0x02a19040, 0x01a19020, 0x01014010, | 1804 | 0x02214030, 0x02a19040, 0x01a19020, 0x01014010, |
1691 | 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0, | 1805 | 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0, |
1692 | 0x90a000f0, 0x01452050, 0x01452050, | 1806 | 0x90a000f0, 0x01452050, 0x01452050, 0x00000000, |
1807 | 0x00000000 | ||
1693 | }; | 1808 | }; |
1694 | 1809 | ||
1695 | static unsigned int dell_m4_1_pin_configs[11] = { | 1810 | static unsigned int dell_m4_1_pin_configs[STAC92HD71BXX_NUM_PINS] = { |
1696 | 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, | 1811 | 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, |
1697 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, | 1812 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, |
1698 | 0x40f000f0, 0x4f0000f0, 0x4f0000f0, | 1813 | 0x40f000f0, 0x4f0000f0, 0x4f0000f0, 0x00000000, |
1814 | 0x00000000 | ||
1699 | }; | 1815 | }; |
1700 | 1816 | ||
1701 | static unsigned int dell_m4_2_pin_configs[11] = { | 1817 | static unsigned int dell_m4_2_pin_configs[STAC92HD71BXX_NUM_PINS] = { |
1702 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, | 1818 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, |
1703 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, | 1819 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, |
1704 | 0x40f000f0, 0x044413b0, 0x044413b0, | 1820 | 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000, |
1821 | 0x00000000 | ||
1705 | }; | 1822 | }; |
1706 | 1823 | ||
1707 | static unsigned int dell_m4_3_pin_configs[11] = { | 1824 | static unsigned int dell_m4_3_pin_configs[STAC92HD71BXX_NUM_PINS] = { |
1708 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, | 1825 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, |
1709 | 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a000f0, | 1826 | 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a000f0, |
1710 | 0x40f000f0, 0x044413b0, 0x044413b0, | 1827 | 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000, |
1828 | 0x00000000 | ||
1711 | }; | 1829 | }; |
1712 | 1830 | ||
1713 | static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { | 1831 | static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { |
@@ -1716,28 +1834,39 @@ static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { | |||
1716 | [STAC_DELL_M4_2] = dell_m4_2_pin_configs, | 1834 | [STAC_DELL_M4_2] = dell_m4_2_pin_configs, |
1717 | [STAC_DELL_M4_3] = dell_m4_3_pin_configs, | 1835 | [STAC_DELL_M4_3] = dell_m4_3_pin_configs, |
1718 | [STAC_HP_M4] = NULL, | 1836 | [STAC_HP_M4] = NULL, |
1837 | [STAC_HP_DV5] = NULL, | ||
1838 | [STAC_HP_HDX] = NULL, | ||
1719 | }; | 1839 | }; |
1720 | 1840 | ||
1721 | static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { | 1841 | static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { |
1842 | [STAC_92HD71BXX_AUTO] = "auto", | ||
1722 | [STAC_92HD71BXX_REF] = "ref", | 1843 | [STAC_92HD71BXX_REF] = "ref", |
1723 | [STAC_DELL_M4_1] = "dell-m4-1", | 1844 | [STAC_DELL_M4_1] = "dell-m4-1", |
1724 | [STAC_DELL_M4_2] = "dell-m4-2", | 1845 | [STAC_DELL_M4_2] = "dell-m4-2", |
1725 | [STAC_DELL_M4_3] = "dell-m4-3", | 1846 | [STAC_DELL_M4_3] = "dell-m4-3", |
1726 | [STAC_HP_M4] = "hp-m4", | 1847 | [STAC_HP_M4] = "hp-m4", |
1848 | [STAC_HP_DV5] = "hp-dv5", | ||
1849 | [STAC_HP_HDX] = "hp-hdx", | ||
1727 | }; | 1850 | }; |
1728 | 1851 | ||
1729 | static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { | 1852 | static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { |
1730 | /* SigmaTel reference board */ | 1853 | /* SigmaTel reference board */ |
1731 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1854 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1732 | "DFI LanParty", STAC_92HD71BXX_REF), | 1855 | "DFI LanParty", STAC_92HD71BXX_REF), |
1733 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f2, | 1856 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, |
1734 | "HP dv5", STAC_HP_M4), | 1857 | "DFI LanParty", STAC_92HD71BXX_REF), |
1735 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4, | 1858 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080, |
1736 | "HP dv7", STAC_HP_M4), | 1859 | "HP", STAC_HP_DV5), |
1737 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fc, | 1860 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0, |
1738 | "HP dv7", STAC_HP_M4), | 1861 | "HP dv4-7", STAC_HP_DV5), |
1862 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600, | ||
1863 | "HP dv4-7", STAC_HP_DV5), | ||
1864 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3610, | ||
1865 | "HP HDX", STAC_HP_HDX), /* HDX18 */ | ||
1739 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, | 1866 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, |
1740 | "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 */ | ||
1741 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, | 1870 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, |
1742 | "unknown Dell", STAC_DELL_M4_1), | 1871 | "unknown Dell", STAC_DELL_M4_1), |
1743 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234, | 1872 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234, |
@@ -1889,6 +2018,7 @@ static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { | |||
1889 | }; | 2018 | }; |
1890 | 2019 | ||
1891 | static const char *stac922x_models[STAC_922X_MODELS] = { | 2020 | static const char *stac922x_models[STAC_922X_MODELS] = { |
2021 | [STAC_922X_AUTO] = "auto", | ||
1892 | [STAC_D945_REF] = "ref", | 2022 | [STAC_D945_REF] = "ref", |
1893 | [STAC_D945GTP5] = "5stack", | 2023 | [STAC_D945GTP5] = "5stack", |
1894 | [STAC_D945GTP3] = "3stack", | 2024 | [STAC_D945GTP3] = "3stack", |
@@ -1916,6 +2046,8 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = { | |||
1916 | /* SigmaTel reference board */ | 2046 | /* SigmaTel reference board */ |
1917 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 2047 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1918 | "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), | ||
1919 | /* Intel 945G based systems */ | 2051 | /* Intel 945G based systems */ |
1920 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101, | 2052 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101, |
1921 | "Intel D945G", STAC_D945GTP3), | 2053 | "Intel D945G", STAC_D945GTP3), |
@@ -1969,6 +2101,9 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = { | |||
1969 | "Intel D945P", STAC_D945GTP3), | 2101 | "Intel D945P", STAC_D945GTP3), |
1970 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707, | 2102 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0707, |
1971 | "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), | ||
1972 | /* other systems */ | 2107 | /* other systems */ |
1973 | /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */ | 2108 | /* Apple Intel Mac (Mac Mini, MacBook, MacBook Pro...) */ |
1974 | SND_PCI_QUIRK(0x8384, 0x7680, | 2109 | SND_PCI_QUIRK(0x8384, 0x7680, |
@@ -1993,31 +2128,7 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = { | |||
1993 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7, | 2128 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7, |
1994 | "Dell XPS M1210", STAC_922X_DELL_M82), | 2129 | "Dell XPS M1210", STAC_922X_DELL_M82), |
1995 | /* ECS/PC Chips boards */ | 2130 | /* ECS/PC Chips boards */ |
1996 | SND_PCI_QUIRK(0x1019, 0x2144, | 2131 | SND_PCI_QUIRK_MASK(0x1019, 0xf000, 0x2000, |
1997 | "ECS/PC chips", STAC_ECS_202), | ||
1998 | SND_PCI_QUIRK(0x1019, 0x2608, | ||
1999 | "ECS/PC chips", STAC_ECS_202), | ||
2000 | SND_PCI_QUIRK(0x1019, 0x2633, | ||
2001 | "ECS/PC chips P17G/1333", STAC_ECS_202), | ||
2002 | SND_PCI_QUIRK(0x1019, 0x2811, | ||
2003 | "ECS/PC chips", STAC_ECS_202), | ||
2004 | SND_PCI_QUIRK(0x1019, 0x2812, | ||
2005 | "ECS/PC chips", STAC_ECS_202), | ||
2006 | SND_PCI_QUIRK(0x1019, 0x2813, | ||
2007 | "ECS/PC chips", STAC_ECS_202), | ||
2008 | SND_PCI_QUIRK(0x1019, 0x2814, | ||
2009 | "ECS/PC chips", STAC_ECS_202), | ||
2010 | SND_PCI_QUIRK(0x1019, 0x2815, | ||
2011 | "ECS/PC chips", STAC_ECS_202), | ||
2012 | SND_PCI_QUIRK(0x1019, 0x2816, | ||
2013 | "ECS/PC chips", STAC_ECS_202), | ||
2014 | SND_PCI_QUIRK(0x1019, 0x2817, | ||
2015 | "ECS/PC chips", STAC_ECS_202), | ||
2016 | SND_PCI_QUIRK(0x1019, 0x2818, | ||
2017 | "ECS/PC chips", STAC_ECS_202), | ||
2018 | SND_PCI_QUIRK(0x1019, 0x2819, | ||
2019 | "ECS/PC chips", STAC_ECS_202), | ||
2020 | SND_PCI_QUIRK(0x1019, 0x2820, | ||
2021 | "ECS/PC chips", STAC_ECS_202), | 2132 | "ECS/PC chips", STAC_ECS_202), |
2022 | {} /* terminator */ | 2133 | {} /* terminator */ |
2023 | }; | 2134 | }; |
@@ -2060,6 +2171,7 @@ static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { | |||
2060 | }; | 2171 | }; |
2061 | 2172 | ||
2062 | static const char *stac927x_models[STAC_927X_MODELS] = { | 2173 | static const char *stac927x_models[STAC_927X_MODELS] = { |
2174 | [STAC_927X_AUTO] = "auto", | ||
2063 | [STAC_D965_REF_NO_JD] = "ref-no-jd", | 2175 | [STAC_D965_REF_NO_JD] = "ref-no-jd", |
2064 | [STAC_D965_REF] = "ref", | 2176 | [STAC_D965_REF] = "ref", |
2065 | [STAC_D965_3ST] = "3stack", | 2177 | [STAC_D965_3ST] = "3stack", |
@@ -2072,26 +2184,16 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = { | |||
2072 | /* SigmaTel reference board */ | 2184 | /* SigmaTel reference board */ |
2073 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 2185 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
2074 | "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), | ||
2075 | /* Intel 946 based systems */ | 2189 | /* Intel 946 based systems */ |
2076 | 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), |
2077 | 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), |
2078 | /* 965 based 3 stack systems */ | 2192 | /* 965 based 3 stack systems */ |
2079 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2116, "Intel D965", STAC_D965_3ST), | 2193 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2100, |
2080 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2115, "Intel D965", STAC_D965_3ST), | 2194 | "Intel D965", STAC_D965_3ST), |
2081 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2114, "Intel D965", STAC_D965_3ST), | 2195 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2000, |
2082 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2113, "Intel D965", STAC_D965_3ST), | 2196 | "Intel D965", STAC_D965_3ST), |
2083 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2112, "Intel D965", STAC_D965_3ST), | ||
2084 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2111, "Intel D965", STAC_D965_3ST), | ||
2085 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2110, "Intel D965", STAC_D965_3ST), | ||
2086 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2009, "Intel D965", STAC_D965_3ST), | ||
2087 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2008, "Intel D965", STAC_D965_3ST), | ||
2088 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2007, "Intel D965", STAC_D965_3ST), | ||
2089 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2006, "Intel D965", STAC_D965_3ST), | ||
2090 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2005, "Intel D965", STAC_D965_3ST), | ||
2091 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2004, "Intel D965", STAC_D965_3ST), | ||
2092 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2003, "Intel D965", STAC_D965_3ST), | ||
2093 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2002, "Intel D965", STAC_D965_3ST), | ||
2094 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2001, "Intel D965", STAC_D965_3ST), | ||
2095 | /* Dell 3 stack systems */ | 2197 | /* Dell 3 stack systems */ |
2096 | 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), |
2097 | 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), |
@@ -2107,15 +2209,10 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = { | |||
2107 | 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), |
2108 | 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), |
2109 | /* 965 based 5 stack systems */ | 2211 | /* 965 based 5 stack systems */ |
2110 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2301, "Intel D965", STAC_D965_5ST), | 2212 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2300, |
2111 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2302, "Intel D965", STAC_D965_5ST), | 2213 | "Intel D965", STAC_D965_5ST), |
2112 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2303, "Intel D965", STAC_D965_5ST), | 2214 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_INTEL, 0xff00, 0x2500, |
2113 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2304, "Intel D965", STAC_D965_5ST), | 2215 | "Intel D965", STAC_D965_5ST), |
2114 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2305, "Intel D965", STAC_D965_5ST), | ||
2115 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2501, "Intel D965", STAC_D965_5ST), | ||
2116 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2502, "Intel D965", STAC_D965_5ST), | ||
2117 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2503, "Intel D965", STAC_D965_5ST), | ||
2118 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2504, "Intel D965", STAC_D965_5ST), | ||
2119 | {} /* terminator */ | 2216 | {} /* terminator */ |
2120 | }; | 2217 | }; |
2121 | 2218 | ||
@@ -2168,19 +2265,25 @@ static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { | |||
2168 | [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs, | 2265 | [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs, |
2169 | [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs, | 2266 | [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs, |
2170 | [STAC_9205_DELL_M44] = dell_9205_m44_pin_configs, | 2267 | [STAC_9205_DELL_M44] = dell_9205_m44_pin_configs, |
2268 | [STAC_9205_EAPD] = NULL, | ||
2171 | }; | 2269 | }; |
2172 | 2270 | ||
2173 | static const char *stac9205_models[STAC_9205_MODELS] = { | 2271 | static const char *stac9205_models[STAC_9205_MODELS] = { |
2272 | [STAC_9205_AUTO] = "auto", | ||
2174 | [STAC_9205_REF] = "ref", | 2273 | [STAC_9205_REF] = "ref", |
2175 | [STAC_9205_DELL_M42] = "dell-m42", | 2274 | [STAC_9205_DELL_M42] = "dell-m42", |
2176 | [STAC_9205_DELL_M43] = "dell-m43", | 2275 | [STAC_9205_DELL_M43] = "dell-m43", |
2177 | [STAC_9205_DELL_M44] = "dell-m44", | 2276 | [STAC_9205_DELL_M44] = "dell-m44", |
2277 | [STAC_9205_EAPD] = "eapd", | ||
2178 | }; | 2278 | }; |
2179 | 2279 | ||
2180 | static struct snd_pci_quirk stac9205_cfg_tbl[] = { | 2280 | static struct snd_pci_quirk stac9205_cfg_tbl[] = { |
2181 | /* SigmaTel reference board */ | 2281 | /* SigmaTel reference board */ |
2182 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 2282 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
2183 | "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 */ | ||
2184 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1, | 2287 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1, |
2185 | "unknown Dell", STAC_9205_DELL_M42), | 2288 | "unknown Dell", STAC_9205_DELL_M42), |
2186 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2, | 2289 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f2, |
@@ -2211,101 +2314,24 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { | |||
2211 | "Dell Inspiron", STAC_9205_DELL_M44), | 2314 | "Dell Inspiron", STAC_9205_DELL_M44), |
2212 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228, | 2315 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0228, |
2213 | "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), | ||
2214 | {} /* terminator */ | 2319 | {} /* terminator */ |
2215 | }; | 2320 | }; |
2216 | 2321 | ||
2217 | static int stac92xx_save_bios_config_regs(struct hda_codec *codec) | 2322 | static void stac92xx_set_config_regs(struct hda_codec *codec, |
2323 | unsigned int *pincfgs) | ||
2218 | { | 2324 | { |
2219 | int i; | 2325 | int i; |
2220 | struct sigmatel_spec *spec = codec->spec; | 2326 | struct sigmatel_spec *spec = codec->spec; |
2221 | |||
2222 | kfree(spec->pin_configs); | ||
2223 | spec->pin_configs = kcalloc(spec->num_pins, sizeof(*spec->pin_configs), | ||
2224 | GFP_KERNEL); | ||
2225 | if (!spec->pin_configs) | ||
2226 | return -ENOMEM; | ||
2227 | |||
2228 | for (i = 0; i < spec->num_pins; i++) { | ||
2229 | hda_nid_t nid = spec->pin_nids[i]; | ||
2230 | unsigned int pin_cfg; | ||
2231 | |||
2232 | pin_cfg = snd_hda_codec_read(codec, nid, 0, | ||
2233 | AC_VERB_GET_CONFIG_DEFAULT, 0x00); | ||
2234 | snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x bios pin config %8.8x\n", | ||
2235 | nid, pin_cfg); | ||
2236 | spec->pin_configs[i] = pin_cfg; | ||
2237 | } | ||
2238 | |||
2239 | return 0; | ||
2240 | } | ||
2241 | 2327 | ||
2242 | static void stac92xx_set_config_reg(struct hda_codec *codec, | 2328 | if (!pincfgs) |
2243 | hda_nid_t pin_nid, unsigned int pin_config) | 2329 | return; |
2244 | { | ||
2245 | int i; | ||
2246 | snd_hda_codec_write(codec, pin_nid, 0, | ||
2247 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_0, | ||
2248 | pin_config & 0x000000ff); | ||
2249 | snd_hda_codec_write(codec, pin_nid, 0, | ||
2250 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, | ||
2251 | (pin_config & 0x0000ff00) >> 8); | ||
2252 | snd_hda_codec_write(codec, pin_nid, 0, | ||
2253 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, | ||
2254 | (pin_config & 0x00ff0000) >> 16); | ||
2255 | snd_hda_codec_write(codec, pin_nid, 0, | ||
2256 | AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, | ||
2257 | pin_config >> 24); | ||
2258 | i = snd_hda_codec_read(codec, pin_nid, 0, | ||
2259 | AC_VERB_GET_CONFIG_DEFAULT, | ||
2260 | 0x00); | ||
2261 | snd_printdd(KERN_INFO "hda_codec: pin nid %2.2x pin config %8.8x\n", | ||
2262 | pin_nid, i); | ||
2263 | } | ||
2264 | |||
2265 | static void stac92xx_set_config_regs(struct hda_codec *codec) | ||
2266 | { | ||
2267 | int i; | ||
2268 | struct sigmatel_spec *spec = codec->spec; | ||
2269 | |||
2270 | if (!spec->pin_configs) | ||
2271 | return; | ||
2272 | 2330 | ||
2273 | for (i = 0; i < spec->num_pins; i++) | 2331 | for (i = 0; i < spec->num_pins; i++) |
2274 | stac92xx_set_config_reg(codec, spec->pin_nids[i], | 2332 | if (spec->pin_nids[i] && pincfgs[i]) |
2275 | spec->pin_configs[i]); | 2333 | snd_hda_codec_set_pincfg(codec, spec->pin_nids[i], |
2276 | } | 2334 | pincfgs[i]); |
2277 | |||
2278 | static int stac_save_pin_cfgs(struct hda_codec *codec, unsigned int *pins) | ||
2279 | { | ||
2280 | struct sigmatel_spec *spec = codec->spec; | ||
2281 | |||
2282 | if (!pins) | ||
2283 | return stac92xx_save_bios_config_regs(codec); | ||
2284 | |||
2285 | kfree(spec->pin_configs); | ||
2286 | spec->pin_configs = kmemdup(pins, | ||
2287 | spec->num_pins * sizeof(*pins), | ||
2288 | GFP_KERNEL); | ||
2289 | if (!spec->pin_configs) | ||
2290 | return -ENOMEM; | ||
2291 | |||
2292 | stac92xx_set_config_regs(codec); | ||
2293 | return 0; | ||
2294 | } | ||
2295 | |||
2296 | static void stac_change_pin_config(struct hda_codec *codec, hda_nid_t nid, | ||
2297 | unsigned int cfg) | ||
2298 | { | ||
2299 | struct sigmatel_spec *spec = codec->spec; | ||
2300 | int i; | ||
2301 | |||
2302 | for (i = 0; i < spec->num_pins; i++) { | ||
2303 | if (spec->pin_nids[i] == nid) { | ||
2304 | spec->pin_configs[i] = cfg; | ||
2305 | stac92xx_set_config_reg(codec, nid, cfg); | ||
2306 | break; | ||
2307 | } | ||
2308 | } | ||
2309 | } | 2335 | } |
2310 | 2336 | ||
2311 | /* | 2337 | /* |
@@ -2370,6 +2396,14 @@ static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
2370 | stream_tag, format, substream); | 2396 | stream_tag, format, substream); |
2371 | } | 2397 | } |
2372 | 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 | |||
2373 | 2407 | ||
2374 | /* | 2408 | /* |
2375 | * Analog capture callbacks | 2409 | * Analog capture callbacks |
@@ -2414,7 +2448,8 @@ static struct hda_pcm_stream stac92xx_pcm_digital_playback = { | |||
2414 | .ops = { | 2448 | .ops = { |
2415 | .open = stac92xx_dig_playback_pcm_open, | 2449 | .open = stac92xx_dig_playback_pcm_open, |
2416 | .close = stac92xx_dig_playback_pcm_close, | 2450 | .close = stac92xx_dig_playback_pcm_close, |
2417 | .prepare = stac92xx_dig_playback_pcm_prepare | 2451 | .prepare = stac92xx_dig_playback_pcm_prepare, |
2452 | .cleanup = stac92xx_dig_playback_pcm_cleanup | ||
2418 | }, | 2453 | }, |
2419 | }; | 2454 | }; |
2420 | 2455 | ||
@@ -2469,6 +2504,8 @@ static int stac92xx_build_pcms(struct hda_codec *codec) | |||
2469 | 2504 | ||
2470 | info->name = "STAC92xx Analog"; | 2505 | info->name = "STAC92xx Analog"; |
2471 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback; | 2506 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_analog_playback; |
2507 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = | ||
2508 | spec->multiout.dac_nids[0]; | ||
2472 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture; | 2509 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = stac92xx_pcm_analog_capture; |
2473 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; | 2510 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; |
2474 | info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs; | 2511 | info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adcs; |
@@ -2484,7 +2521,7 @@ static int stac92xx_build_pcms(struct hda_codec *codec) | |||
2484 | codec->num_pcms++; | 2521 | codec->num_pcms++; |
2485 | info++; | 2522 | info++; |
2486 | info->name = "STAC92xx Digital"; | 2523 | info->name = "STAC92xx Digital"; |
2487 | info->pcm_type = HDA_PCM_TYPE_SPDIF; | 2524 | info->pcm_type = spec->autocfg.dig_out_type[0]; |
2488 | if (spec->multiout.dig_out_nid) { | 2525 | if (spec->multiout.dig_out_nid) { |
2489 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback; | 2526 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback; |
2490 | 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; |
@@ -2500,8 +2537,7 @@ static int stac92xx_build_pcms(struct hda_codec *codec) | |||
2500 | 2537 | ||
2501 | 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) |
2502 | { | 2539 | { |
2503 | unsigned int pincap = snd_hda_param_read(codec, nid, | 2540 | unsigned int pincap = snd_hda_query_pin_caps(codec, nid); |
2504 | AC_PAR_PIN_CAP); | ||
2505 | pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; | 2541 | pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; |
2506 | if (pincap & AC_PINCAP_VREF_100) | 2542 | if (pincap & AC_PINCAP_VREF_100) |
2507 | return AC_PINCTL_VREF_100; | 2543 | return AC_PINCTL_VREF_100; |
@@ -2676,22 +2712,37 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = { | |||
2676 | }; | 2712 | }; |
2677 | 2713 | ||
2678 | /* add dynamic controls */ | 2714 | /* add dynamic controls */ |
2679 | static int stac92xx_add_control_temp(struct sigmatel_spec *spec, | 2715 | static struct snd_kcontrol_new * |
2680 | struct snd_kcontrol_new *ktemp, | 2716 | stac_control_new(struct sigmatel_spec *spec, |
2681 | int idx, const char *name, | 2717 | struct snd_kcontrol_new *ktemp, |
2682 | unsigned long val) | 2718 | const char *name) |
2683 | { | 2719 | { |
2684 | struct snd_kcontrol_new *knew; | 2720 | struct snd_kcontrol_new *knew; |
2685 | 2721 | ||
2686 | snd_array_init(&spec->kctls, sizeof(*knew), 32); | 2722 | snd_array_init(&spec->kctls, sizeof(*knew), 32); |
2687 | knew = snd_array_new(&spec->kctls); | 2723 | knew = snd_array_new(&spec->kctls); |
2688 | if (!knew) | 2724 | if (!knew) |
2689 | return -ENOMEM; | 2725 | return NULL; |
2690 | *knew = *ktemp; | 2726 | *knew = *ktemp; |
2691 | knew->index = idx; | ||
2692 | knew->name = kstrdup(name, GFP_KERNEL); | 2727 | knew->name = kstrdup(name, GFP_KERNEL); |
2693 | 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) | ||
2694 | return -ENOMEM; | 2744 | return -ENOMEM; |
2745 | knew->index = idx; | ||
2695 | knew->private_value = val; | 2746 | knew->private_value = val; |
2696 | return 0; | 2747 | return 0; |
2697 | } | 2748 | } |
@@ -2713,6 +2764,29 @@ static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type, | |||
2713 | return stac92xx_add_control_idx(spec, type, 0, name, val); | 2764 | return stac92xx_add_control_idx(spec, type, 0, name, val); |
2714 | } | 2765 | } |
2715 | 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 | |||
2716 | /* check whether the line-input can be used as line-out */ | 2790 | /* check whether the line-input can be used as line-out */ |
2717 | 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) |
2718 | { | 2792 | { |
@@ -2724,7 +2798,7 @@ static hda_nid_t check_line_out_switch(struct hda_codec *codec) | |||
2724 | if (cfg->line_out_type != AUTO_PIN_LINE_OUT) | 2798 | if (cfg->line_out_type != AUTO_PIN_LINE_OUT) |
2725 | return 0; | 2799 | return 0; |
2726 | nid = cfg->input_pins[AUTO_PIN_LINE]; | 2800 | nid = cfg->input_pins[AUTO_PIN_LINE]; |
2727 | pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); | 2801 | pincap = snd_hda_query_pin_caps(codec, nid); |
2728 | if (pincap & AC_PINCAP_OUT) | 2802 | if (pincap & AC_PINCAP_OUT) |
2729 | return nid; | 2803 | return nid; |
2730 | return 0; | 2804 | return 0; |
@@ -2743,12 +2817,11 @@ static hda_nid_t check_mic_out_switch(struct hda_codec *codec) | |||
2743 | mic_pin = AUTO_PIN_MIC; | 2817 | mic_pin = AUTO_PIN_MIC; |
2744 | for (;;) { | 2818 | for (;;) { |
2745 | hda_nid_t nid = cfg->input_pins[mic_pin]; | 2819 | hda_nid_t nid = cfg->input_pins[mic_pin]; |
2746 | def_conf = snd_hda_codec_read(codec, nid, 0, | 2820 | def_conf = snd_hda_codec_get_pincfg(codec, nid); |
2747 | AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
2748 | /* some laptops have an internal analog microphone | 2821 | /* some laptops have an internal analog microphone |
2749 | * which can't be used as a output */ | 2822 | * which can't be used as a output */ |
2750 | if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) { | 2823 | if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) { |
2751 | pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); | 2824 | pincap = snd_hda_query_pin_caps(codec, nid); |
2752 | if (pincap & AC_PINCAP_OUT) | 2825 | if (pincap & AC_PINCAP_OUT) |
2753 | return nid; | 2826 | return nid; |
2754 | } | 2827 | } |
@@ -2796,8 +2869,7 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid) | |||
2796 | conn_len = snd_hda_get_connections(codec, nid, conn, | 2869 | conn_len = snd_hda_get_connections(codec, nid, conn, |
2797 | HDA_MAX_CONNECTIONS); | 2870 | HDA_MAX_CONNECTIONS); |
2798 | for (j = 0; j < conn_len; j++) { | 2871 | for (j = 0; j < conn_len; j++) { |
2799 | wcaps = snd_hda_param_read(codec, conn[j], | 2872 | wcaps = get_wcaps(codec, conn[j]); |
2800 | AC_PAR_AUDIO_WIDGET_CAP); | ||
2801 | wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; | 2873 | wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; |
2802 | /* we check only analog outputs */ | 2874 | /* we check only analog outputs */ |
2803 | if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL)) | 2875 | if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL)) |
@@ -2812,6 +2884,16 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid) | |||
2812 | return conn[j]; | 2884 | return conn[j]; |
2813 | } | 2885 | } |
2814 | } | 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 | } | ||
2815 | return 0; | 2897 | return 0; |
2816 | } | 2898 | } |
2817 | 2899 | ||
@@ -2852,6 +2934,26 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec) | |||
2852 | add_spec_dacs(spec, dac); | 2934 | add_spec_dacs(spec, dac); |
2853 | } | 2935 | } |
2854 | 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 | |||
2855 | /* add line-in as output */ | 2957 | /* add line-in as output */ |
2856 | nid = check_line_out_switch(codec); | 2958 | nid = check_line_out_switch(codec); |
2857 | if (nid) { | 2959 | if (nid) { |
@@ -2879,26 +2981,6 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec) | |||
2879 | } | 2981 | } |
2880 | } | 2982 | } |
2881 | 2983 | ||
2882 | for (i = 0; i < cfg->hp_outs; i++) { | ||
2883 | nid = cfg->hp_pins[i]; | ||
2884 | dac = get_unassigned_dac(codec, nid); | ||
2885 | if (dac) { | ||
2886 | if (!spec->multiout.hp_nid) | ||
2887 | spec->multiout.hp_nid = dac; | ||
2888 | else | ||
2889 | add_spec_extra_dacs(spec, dac); | ||
2890 | } | ||
2891 | spec->hp_dacs[i] = dac; | ||
2892 | } | ||
2893 | |||
2894 | for (i = 0; i < cfg->speaker_outs; i++) { | ||
2895 | nid = cfg->speaker_pins[i]; | ||
2896 | dac = get_unassigned_dac(codec, nid); | ||
2897 | if (dac) | ||
2898 | add_spec_extra_dacs(spec, dac); | ||
2899 | spec->speaker_dacs[i] = dac; | ||
2900 | } | ||
2901 | |||
2902 | 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", |
2903 | spec->multiout.num_dacs, | 2985 | spec->multiout.num_dacs, |
2904 | spec->multiout.dac_nids[0], | 2986 | spec->multiout.dac_nids[0], |
@@ -2911,24 +2993,47 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec) | |||
2911 | } | 2993 | } |
2912 | 2994 | ||
2913 | /* create volume control/switch for the given prefx type */ | 2995 | /* create volume control/switch for the given prefx type */ |
2914 | 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) | ||
2915 | { | 2998 | { |
2999 | struct sigmatel_spec *spec = codec->spec; | ||
2916 | char name[32]; | 3000 | char name[32]; |
2917 | int err; | 3001 | int err; |
2918 | 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 | |||
2919 | sprintf(name, "%s Playback Volume", pfx); | 3020 | sprintf(name, "%s Playback Volume", pfx); |
2920 | err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name, | 3021 | err = stac92xx_add_control_idx(spec, STAC_CTL_WIDGET_VOL, idx, name, |
2921 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); | 3022 | HDA_COMPOSE_AMP_VAL_OFS(nid, chs, 0, HDA_OUTPUT, |
3023 | spec->volume_offset)); | ||
2922 | if (err < 0) | 3024 | if (err < 0) |
2923 | return err; | 3025 | return err; |
2924 | sprintf(name, "%s Playback Switch", pfx); | 3026 | sprintf(name, "%s Playback Switch", pfx); |
2925 | err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, name, | 3027 | err = stac92xx_add_control_idx(spec, STAC_CTL_WIDGET_MUTE, idx, name, |
2926 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); | 3028 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); |
2927 | if (err < 0) | 3029 | if (err < 0) |
2928 | return err; | 3030 | return err; |
2929 | return 0; | 3031 | return 0; |
2930 | } | 3032 | } |
2931 | 3033 | ||
3034 | #define create_controls(codec, pfx, nid, chs) \ | ||
3035 | create_controls_idx(codec, pfx, 0, nid, chs) | ||
3036 | |||
2932 | 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) |
2933 | { | 3038 | { |
2934 | if (spec->multiout.num_dacs > 4) { | 3039 | if (spec->multiout.num_dacs > 4) { |
@@ -2954,40 +3059,37 @@ static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid) | |||
2954 | return 1; | 3059 | return 1; |
2955 | } | 3060 | } |
2956 | 3061 | ||
2957 | static int is_unique_dac(struct sigmatel_spec *spec, hda_nid_t nid) | 3062 | /* Create output controls |
2958 | { | 3063 | * The mixer elements are named depending on the given type (AUTO_PIN_XXX_OUT) |
2959 | int i; | 3064 | */ |
2960 | 3065 | static int create_multi_out_ctls(struct hda_codec *codec, int num_outs, | |
2961 | if (spec->autocfg.line_outs != 1) | 3066 | const hda_nid_t *pins, |
2962 | return 0; | 3067 | const hda_nid_t *dac_nids, |
2963 | if (spec->multiout.hp_nid == nid) | 3068 | int type) |
2964 | return 0; | ||
2965 | for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++) | ||
2966 | if (spec->multiout.extra_out_nid[i] == nid) | ||
2967 | return 0; | ||
2968 | return 1; | ||
2969 | } | ||
2970 | |||
2971 | /* add playback controls from the parsed DAC table */ | ||
2972 | static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, | ||
2973 | const struct auto_pin_cfg *cfg) | ||
2974 | { | 3069 | { |
2975 | struct sigmatel_spec *spec = codec->spec; | 3070 | struct sigmatel_spec *spec = codec->spec; |
2976 | static const char *chname[4] = { | 3071 | static const char *chname[4] = { |
2977 | "Front", "Surround", NULL /*CLFE*/, "Side" | 3072 | "Front", "Surround", NULL /*CLFE*/, "Side" |
2978 | }; | 3073 | }; |
2979 | hda_nid_t nid = 0; | 3074 | hda_nid_t nid; |
2980 | int i, err; | 3075 | int i, err; |
2981 | unsigned int wid_caps; | 3076 | unsigned int wid_caps; |
2982 | 3077 | ||
2983 | 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++) { |
2984 | nid = spec->multiout.dac_nids[i]; | 3079 | if (type == AUTO_PIN_HP_OUT && !spec->hp_detect) { |
2985 | if (i == 2) { | 3080 | wid_caps = get_wcaps(codec, pins[i]); |
3081 | if (wid_caps & AC_WCAP_UNSOL_CAP) | ||
3082 | spec->hp_detect = 1; | ||
3083 | } | ||
3084 | nid = dac_nids[i]; | ||
3085 | if (!nid) | ||
3086 | continue; | ||
3087 | if (type != AUTO_PIN_HP_OUT && i == 2) { | ||
2986 | /* Center/LFE */ | 3088 | /* Center/LFE */ |
2987 | err = create_controls(spec, "Center", nid, 1); | 3089 | err = create_controls(codec, "Center", nid, 1); |
2988 | if (err < 0) | 3090 | if (err < 0) |
2989 | return err; | 3091 | return err; |
2990 | err = create_controls(spec, "LFE", nid, 2); | 3092 | err = create_controls(codec, "LFE", nid, 2); |
2991 | if (err < 0) | 3093 | if (err < 0) |
2992 | return err; | 3094 | return err; |
2993 | 3095 | ||
@@ -3003,23 +3105,42 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
3003 | } | 3105 | } |
3004 | 3106 | ||
3005 | } else { | 3107 | } else { |
3006 | const char *name = chname[i]; | 3108 | const char *name; |
3007 | /* if it's a single DAC, assign a better name */ | 3109 | int idx; |
3008 | if (!i && is_unique_dac(spec, nid)) { | 3110 | switch (type) { |
3009 | switch (cfg->line_out_type) { | 3111 | case AUTO_PIN_HP_OUT: |
3010 | case AUTO_PIN_HP_OUT: | 3112 | name = "Headphone"; |
3011 | name = "Headphone"; | 3113 | idx = i; |
3012 | break; | 3114 | break; |
3013 | case AUTO_PIN_SPEAKER_OUT: | 3115 | case AUTO_PIN_SPEAKER_OUT: |
3014 | name = "Speaker"; | 3116 | name = "Speaker"; |
3015 | break; | 3117 | idx = i; |
3016 | } | 3118 | break; |
3119 | default: | ||
3120 | name = chname[i]; | ||
3121 | idx = 0; | ||
3122 | break; | ||
3017 | } | 3123 | } |
3018 | err = create_controls(spec, name, nid, 3); | 3124 | err = create_controls_idx(codec, name, idx, nid, 3); |
3019 | if (err < 0) | 3125 | if (err < 0) |
3020 | return err; | 3126 | return err; |
3021 | } | 3127 | } |
3022 | } | 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; | ||
3023 | 3144 | ||
3024 | 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) { |
3025 | err = stac92xx_add_control(spec, | 3146 | err = stac92xx_add_control(spec, |
@@ -3054,40 +3175,18 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, | |||
3054 | struct auto_pin_cfg *cfg) | 3175 | struct auto_pin_cfg *cfg) |
3055 | { | 3176 | { |
3056 | struct sigmatel_spec *spec = codec->spec; | 3177 | struct sigmatel_spec *spec = codec->spec; |
3057 | hda_nid_t nid; | 3178 | int err; |
3058 | 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; | ||
3059 | 3189 | ||
3060 | nums = 0; | ||
3061 | for (i = 0; i < cfg->hp_outs; i++) { | ||
3062 | static const char *pfxs[] = { | ||
3063 | "Headphone", "Headphone2", "Headphone3", | ||
3064 | }; | ||
3065 | unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]); | ||
3066 | if (wid_caps & AC_WCAP_UNSOL_CAP) | ||
3067 | spec->hp_detect = 1; | ||
3068 | if (nums >= ARRAY_SIZE(pfxs)) | ||
3069 | continue; | ||
3070 | nid = spec->hp_dacs[i]; | ||
3071 | if (!nid) | ||
3072 | continue; | ||
3073 | err = create_controls(spec, pfxs[nums++], nid, 3); | ||
3074 | if (err < 0) | ||
3075 | return err; | ||
3076 | } | ||
3077 | nums = 0; | ||
3078 | for (i = 0; i < cfg->speaker_outs; i++) { | ||
3079 | static const char *pfxs[] = { | ||
3080 | "Speaker", "External Speaker", "Speaker2", | ||
3081 | }; | ||
3082 | if (nums >= ARRAY_SIZE(pfxs)) | ||
3083 | continue; | ||
3084 | nid = spec->speaker_dacs[i]; | ||
3085 | if (!nid) | ||
3086 | continue; | ||
3087 | err = create_controls(spec, pfxs[nums++], nid, 3); | ||
3088 | if (err < 0) | ||
3089 | return err; | ||
3090 | } | ||
3091 | return 0; | 3190 | return 0; |
3092 | } | 3191 | } |
3093 | 3192 | ||
@@ -3296,11 +3395,7 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | |||
3296 | unsigned int wcaps; | 3395 | unsigned int wcaps; |
3297 | unsigned int def_conf; | 3396 | unsigned int def_conf; |
3298 | 3397 | ||
3299 | def_conf = snd_hda_codec_read(codec, | 3398 | def_conf = snd_hda_codec_get_pincfg(codec, spec->dmic_nids[i]); |
3300 | spec->dmic_nids[i], | ||
3301 | 0, | ||
3302 | AC_VERB_GET_CONFIG_DEFAULT, | ||
3303 | 0); | ||
3304 | if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) | 3399 | if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) |
3305 | continue; | 3400 | continue; |
3306 | 3401 | ||
@@ -3424,6 +3519,7 @@ static void stac92xx_auto_init_hp_out(struct hda_codec *codec) | |||
3424 | 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) |
3425 | { | 3520 | { |
3426 | struct sigmatel_spec *spec = codec->spec; | 3521 | struct sigmatel_spec *spec = codec->spec; |
3522 | int hp_swap = 0; | ||
3427 | int err; | 3523 | int err; |
3428 | 3524 | ||
3429 | if ((err = snd_hda_parse_pin_def_config(codec, | 3525 | if ((err = snd_hda_parse_pin_def_config(codec, |
@@ -3451,6 +3547,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
3451 | spec->autocfg.line_outs = spec->autocfg.hp_outs; | 3547 | spec->autocfg.line_outs = spec->autocfg.hp_outs; |
3452 | spec->autocfg.line_out_type = AUTO_PIN_HP_OUT; | 3548 | spec->autocfg.line_out_type = AUTO_PIN_HP_OUT; |
3453 | spec->autocfg.hp_outs = 0; | 3549 | spec->autocfg.hp_outs = 0; |
3550 | hp_swap = 1; | ||
3454 | } | 3551 | } |
3455 | if (spec->autocfg.mono_out_pin) { | 3552 | if (spec->autocfg.mono_out_pin) { |
3456 | int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) & | 3553 | int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) & |
@@ -3506,13 +3603,12 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
3506 | err = stac92xx_auto_fill_dac_nids(codec); | 3603 | err = stac92xx_auto_fill_dac_nids(codec); |
3507 | if (err < 0) | 3604 | if (err < 0) |
3508 | return err; | 3605 | return err; |
3606 | err = stac92xx_auto_create_multi_out_ctls(codec, | ||
3607 | &spec->autocfg); | ||
3608 | if (err < 0) | ||
3609 | return err; | ||
3509 | } | 3610 | } |
3510 | 3611 | ||
3511 | err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg); | ||
3512 | |||
3513 | if (err < 0) | ||
3514 | return err; | ||
3515 | |||
3516 | /* setup analog beep controls */ | 3612 | /* setup analog beep controls */ |
3517 | if (spec->anabeep_nid > 0) { | 3613 | if (spec->anabeep_nid > 0) { |
3518 | err = stac92xx_auto_create_beep_ctls(codec, | 3614 | err = stac92xx_auto_create_beep_ctls(codec, |
@@ -3545,12 +3641,19 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
3545 | #endif | 3641 | #endif |
3546 | 3642 | ||
3547 | err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg); | 3643 | err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg); |
3548 | |||
3549 | if (err < 0) | 3644 | if (err < 0) |
3550 | return err; | 3645 | return err; |
3551 | 3646 | ||
3552 | 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 | } | ||
3553 | 3655 | ||
3656 | err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg); | ||
3554 | if (err < 0) | 3657 | if (err < 0) |
3555 | return err; | 3658 | return err; |
3556 | 3659 | ||
@@ -3579,11 +3682,15 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
3579 | return err; | 3682 | return err; |
3580 | } | 3683 | } |
3581 | 3684 | ||
3685 | err = stac92xx_add_input_source(spec); | ||
3686 | if (err < 0) | ||
3687 | return err; | ||
3688 | |||
3582 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 3689 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
3583 | if (spec->multiout.max_channels > 2) | 3690 | if (spec->multiout.max_channels > 2) |
3584 | spec->surr_switch = 1; | 3691 | spec->surr_switch = 1; |
3585 | 3692 | ||
3586 | if (spec->autocfg.dig_out_pin) | 3693 | if (spec->autocfg.dig_outs) |
3587 | spec->multiout.dig_out_nid = dig_out; | 3694 | spec->multiout.dig_out_nid = dig_out; |
3588 | if (dig_in && spec->autocfg.dig_in_pin) | 3695 | if (dig_in && spec->autocfg.dig_in_pin) |
3589 | spec->dig_in_nid = dig_in; | 3696 | spec->dig_in_nid = dig_in; |
@@ -3646,9 +3753,7 @@ static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec, | |||
3646 | 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++) { |
3647 | hda_nid_t pin = spec->autocfg.line_out_pins[i]; | 3754 | hda_nid_t pin = spec->autocfg.line_out_pins[i]; |
3648 | unsigned int defcfg; | 3755 | unsigned int defcfg; |
3649 | defcfg = snd_hda_codec_read(codec, pin, 0, | 3756 | defcfg = snd_hda_codec_get_pincfg(codec, pin); |
3650 | AC_VERB_GET_CONFIG_DEFAULT, | ||
3651 | 0x00); | ||
3652 | if (get_defcfg_device(defcfg) == AC_JACK_SPEAKER) { | 3757 | if (get_defcfg_device(defcfg) == AC_JACK_SPEAKER) { |
3653 | unsigned int wcaps = get_wcaps(codec, pin); | 3758 | unsigned int wcaps = get_wcaps(codec, pin); |
3654 | wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP); | 3759 | wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP); |
@@ -3661,7 +3766,7 @@ static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec, | |||
3661 | } | 3766 | } |
3662 | 3767 | ||
3663 | if (lfe_pin) { | 3768 | if (lfe_pin) { |
3664 | err = create_controls(spec, "LFE", lfe_pin, 1); | 3769 | err = create_controls(codec, "LFE", lfe_pin, 1); |
3665 | if (err < 0) | 3770 | if (err < 0) |
3666 | return err; | 3771 | return err; |
3667 | } | 3772 | } |
@@ -3692,7 +3797,11 @@ static int stac9200_parse_auto_config(struct hda_codec *codec) | |||
3692 | return err; | 3797 | return err; |
3693 | } | 3798 | } |
3694 | 3799 | ||
3695 | 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) | ||
3696 | spec->multiout.dig_out_nid = 0x05; | 3805 | spec->multiout.dig_out_nid = 0x05; |
3697 | if (spec->autocfg.dig_in_pin) | 3806 | if (spec->autocfg.dig_in_pin) |
3698 | spec->dig_in_nid = 0x04; | 3807 | spec->dig_in_nid = 0x04; |
@@ -3742,16 +3851,25 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask, | |||
3742 | AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */ | 3851 | AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */ |
3743 | } | 3852 | } |
3744 | 3853 | ||
3854 | #ifdef CONFIG_SND_JACK | ||
3855 | static void stac92xx_free_jack_priv(struct snd_jack *jack) | ||
3856 | { | ||
3857 | struct sigmatel_jack *jacks = jack->private_data; | ||
3858 | jacks->nid = 0; | ||
3859 | jacks->jack = NULL; | ||
3860 | } | ||
3861 | #endif | ||
3862 | |||
3745 | static int stac92xx_add_jack(struct hda_codec *codec, | 3863 | static int stac92xx_add_jack(struct hda_codec *codec, |
3746 | hda_nid_t nid, int type) | 3864 | hda_nid_t nid, int type) |
3747 | { | 3865 | { |
3748 | #ifdef CONFIG_SND_JACK | 3866 | #ifdef CONFIG_SND_JACK |
3749 | struct sigmatel_spec *spec = codec->spec; | 3867 | struct sigmatel_spec *spec = codec->spec; |
3750 | struct sigmatel_jack *jack; | 3868 | struct sigmatel_jack *jack; |
3751 | int def_conf = snd_hda_codec_read(codec, nid, | 3869 | int def_conf = snd_hda_codec_get_pincfg(codec, nid); |
3752 | 0, AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
3753 | int connectivity = get_defcfg_connect(def_conf); | 3870 | int connectivity = get_defcfg_connect(def_conf); |
3754 | char name[32]; | 3871 | char name[32]; |
3872 | int err; | ||
3755 | 3873 | ||
3756 | if (connectivity && connectivity != AC_JACK_PORT_FIXED) | 3874 | if (connectivity && connectivity != AC_JACK_PORT_FIXED) |
3757 | return 0; | 3875 | return 0; |
@@ -3768,10 +3886,15 @@ static int stac92xx_add_jack(struct hda_codec *codec, | |||
3768 | snd_hda_get_jack_connectivity(def_conf), | 3886 | snd_hda_get_jack_connectivity(def_conf), |
3769 | snd_hda_get_jack_location(def_conf)); | 3887 | snd_hda_get_jack_location(def_conf)); |
3770 | 3888 | ||
3771 | return snd_jack_new(codec->bus->card, name, type, &jack->jack); | 3889 | err = snd_jack_new(codec->bus->card, name, type, &jack->jack); |
3772 | #else | 3890 | if (err < 0) { |
3773 | return 0; | 3891 | jack->nid = 0; |
3892 | return err; | ||
3893 | } | ||
3894 | jack->jack->private_data = jack; | ||
3895 | jack->jack->private_free = stac92xx_free_jack_priv; | ||
3774 | #endif | 3896 | #endif |
3897 | return 0; | ||
3775 | } | 3898 | } |
3776 | 3899 | ||
3777 | static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid, | 3900 | static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid, |
@@ -3864,6 +3987,36 @@ static void stac92xx_power_down(struct hda_codec *codec) | |||
3864 | static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, | 3987 | static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, |
3865 | int enable); | 3988 | int enable); |
3866 | 3989 | ||
3990 | /* override some hints from the hwdep entry */ | ||
3991 | static void stac_store_hints(struct hda_codec *codec) | ||
3992 | { | ||
3993 | struct sigmatel_spec *spec = codec->spec; | ||
3994 | const char *p; | ||
3995 | int val; | ||
3996 | |||
3997 | val = snd_hda_get_bool_hint(codec, "hp_detect"); | ||
3998 | if (val >= 0) | ||
3999 | spec->hp_detect = val; | ||
4000 | p = snd_hda_get_hint(codec, "gpio_mask"); | ||
4001 | if (p) { | ||
4002 | spec->gpio_mask = simple_strtoul(p, NULL, 0); | ||
4003 | spec->eapd_mask = spec->gpio_dir = spec->gpio_data = | ||
4004 | spec->gpio_mask; | ||
4005 | } | ||
4006 | p = snd_hda_get_hint(codec, "gpio_dir"); | ||
4007 | if (p) | ||
4008 | spec->gpio_dir = simple_strtoul(p, NULL, 0) & spec->gpio_mask; | ||
4009 | p = snd_hda_get_hint(codec, "gpio_data"); | ||
4010 | if (p) | ||
4011 | spec->gpio_data = simple_strtoul(p, NULL, 0) & spec->gpio_mask; | ||
4012 | p = snd_hda_get_hint(codec, "eapd_mask"); | ||
4013 | if (p) | ||
4014 | spec->eapd_mask = simple_strtoul(p, NULL, 0) & spec->gpio_mask; | ||
4015 | val = snd_hda_get_bool_hint(codec, "eapd_switch"); | ||
4016 | if (val >= 0) | ||
4017 | spec->eapd_switch = val; | ||
4018 | } | ||
4019 | |||
3867 | static int stac92xx_init(struct hda_codec *codec) | 4020 | static int stac92xx_init(struct hda_codec *codec) |
3868 | { | 4021 | { |
3869 | struct sigmatel_spec *spec = codec->spec; | 4022 | struct sigmatel_spec *spec = codec->spec; |
@@ -3880,6 +4033,9 @@ static int stac92xx_init(struct hda_codec *codec) | |||
3880 | spec->adc_nids[i], 0, | 4033 | spec->adc_nids[i], 0, |
3881 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | 4034 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); |
3882 | 4035 | ||
4036 | /* override some hints */ | ||
4037 | stac_store_hints(codec); | ||
4038 | |||
3883 | /* set up GPIO */ | 4039 | /* set up GPIO */ |
3884 | gpio = spec->gpio_data; | 4040 | gpio = spec->gpio_data; |
3885 | /* turn on EAPD statically when spec->eapd_switch isn't set. | 4041 | /* turn on EAPD statically when spec->eapd_switch isn't set. |
@@ -3929,8 +4085,7 @@ static int stac92xx_init(struct hda_codec *codec) | |||
3929 | pinctl); | 4085 | pinctl); |
3930 | } | 4086 | } |
3931 | } | 4087 | } |
3932 | conf = snd_hda_codec_read(codec, nid, 0, | 4088 | conf = snd_hda_codec_get_pincfg(codec, nid); |
3933 | AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
3934 | if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) { | 4089 | if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) { |
3935 | enable_pin_detect(codec, nid, | 4090 | enable_pin_detect(codec, nid, |
3936 | STAC_INSERT_EVENT); | 4091 | STAC_INSERT_EVENT); |
@@ -3942,8 +4097,8 @@ static int stac92xx_init(struct hda_codec *codec) | |||
3942 | for (i = 0; i < spec->num_dmics; i++) | 4097 | for (i = 0; i < spec->num_dmics; i++) |
3943 | stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i], | 4098 | stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i], |
3944 | AC_PINCTL_IN_EN); | 4099 | AC_PINCTL_IN_EN); |
3945 | if (cfg->dig_out_pin) | 4100 | if (cfg->dig_out_pins[0]) |
3946 | stac92xx_auto_set_pinctl(codec, cfg->dig_out_pin, | 4101 | stac92xx_auto_set_pinctl(codec, cfg->dig_out_pins[0], |
3947 | AC_PINCTL_OUT_EN); | 4102 | AC_PINCTL_OUT_EN); |
3948 | if (cfg->dig_in_pin) | 4103 | if (cfg->dig_in_pin) |
3949 | stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin, | 4104 | stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin, |
@@ -3971,8 +4126,7 @@ static int stac92xx_init(struct hda_codec *codec) | |||
3971 | stac_toggle_power_map(codec, nid, 1); | 4126 | stac_toggle_power_map(codec, nid, 1); |
3972 | continue; | 4127 | continue; |
3973 | } | 4128 | } |
3974 | def_conf = snd_hda_codec_read(codec, nid, 0, | 4129 | def_conf = snd_hda_codec_get_pincfg(codec, nid); |
3975 | AC_VERB_GET_CONFIG_DEFAULT, 0); | ||
3976 | def_conf = get_defcfg_connect(def_conf); | 4130 | def_conf = get_defcfg_connect(def_conf); |
3977 | /* skip any ports that don't have jacks since presence | 4131 | /* skip any ports that don't have jacks since presence |
3978 | * detection is useless */ | 4132 | * detection is useless */ |
@@ -3999,8 +4153,10 @@ static void stac92xx_free_jacks(struct hda_codec *codec) | |||
3999 | if (!codec->bus->shutdown && spec->jacks.list) { | 4153 | if (!codec->bus->shutdown && spec->jacks.list) { |
4000 | struct sigmatel_jack *jacks = spec->jacks.list; | 4154 | struct sigmatel_jack *jacks = spec->jacks.list; |
4001 | int i; | 4155 | int i; |
4002 | for (i = 0; i < spec->jacks.used; i++) | 4156 | for (i = 0; i < spec->jacks.used; i++, jacks++) { |
4003 | snd_device_free(codec->bus->card, &jacks[i].jack); | 4157 | if (jacks->jack) |
4158 | snd_device_free(codec->bus->card, jacks->jack); | ||
4159 | } | ||
4004 | } | 4160 | } |
4005 | snd_array_free(&spec->jacks); | 4161 | snd_array_free(&spec->jacks); |
4006 | #endif | 4162 | #endif |
@@ -4026,7 +4182,6 @@ static void stac92xx_free(struct hda_codec *codec) | |||
4026 | if (! spec) | 4182 | if (! spec) |
4027 | return; | 4183 | return; |
4028 | 4184 | ||
4029 | kfree(spec->pin_configs); | ||
4030 | stac92xx_free_jacks(codec); | 4185 | stac92xx_free_jacks(codec); |
4031 | snd_array_free(&spec->events); | 4186 | snd_array_free(&spec->events); |
4032 | 4187 | ||
@@ -4037,7 +4192,9 @@ static void stac92xx_free(struct hda_codec *codec) | |||
4037 | static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, | 4192 | static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, |
4038 | unsigned int flag) | 4193 | unsigned int flag) |
4039 | { | 4194 | { |
4040 | unsigned int pin_ctl = snd_hda_codec_read(codec, nid, | 4195 | unsigned int old_ctl, pin_ctl; |
4196 | |||
4197 | pin_ctl = snd_hda_codec_read(codec, nid, | ||
4041 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); | 4198 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); |
4042 | 4199 | ||
4043 | if (pin_ctl & AC_PINCTL_IN_EN) { | 4200 | if (pin_ctl & AC_PINCTL_IN_EN) { |
@@ -4051,14 +4208,17 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, | |||
4051 | return; | 4208 | return; |
4052 | } | 4209 | } |
4053 | 4210 | ||
4211 | old_ctl = pin_ctl; | ||
4054 | /* if setting pin direction bits, clear the current | 4212 | /* if setting pin direction bits, clear the current |
4055 | direction bits first */ | 4213 | direction bits first */ |
4056 | if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)) | 4214 | if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)) |
4057 | pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); | 4215 | pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); |
4058 | 4216 | ||
4059 | snd_hda_codec_write_cache(codec, nid, 0, | 4217 | pin_ctl |= flag; |
4060 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 4218 | if (old_ctl != pin_ctl) |
4061 | pin_ctl | flag); | 4219 | snd_hda_codec_write_cache(codec, nid, 0, |
4220 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
4221 | pin_ctl); | ||
4062 | } | 4222 | } |
4063 | 4223 | ||
4064 | static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid, | 4224 | static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid, |
@@ -4066,9 +4226,10 @@ static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid, | |||
4066 | { | 4226 | { |
4067 | unsigned int pin_ctl = snd_hda_codec_read(codec, nid, | 4227 | unsigned int pin_ctl = snd_hda_codec_read(codec, nid, |
4068 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); | 4228 | 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); |
4069 | snd_hda_codec_write_cache(codec, nid, 0, | 4229 | if (pin_ctl & flag) |
4070 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 4230 | snd_hda_codec_write_cache(codec, nid, 0, |
4071 | pin_ctl & ~flag); | 4231 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
4232 | pin_ctl & ~flag); | ||
4072 | } | 4233 | } |
4073 | 4234 | ||
4074 | static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid) | 4235 | static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid) |
@@ -4163,8 +4324,19 @@ static void stac92xx_hp_detect(struct hda_codec *codec) | |||
4163 | continue; | 4324 | continue; |
4164 | if (presence) | 4325 | if (presence) |
4165 | stac92xx_set_pinctl(codec, cfg->hp_pins[i], val); | 4326 | stac92xx_set_pinctl(codec, cfg->hp_pins[i], val); |
4327 | #if 0 /* FIXME */ | ||
4328 | /* Resetting the pinctl like below may lead to (a sort of) regressions | ||
4329 | * on some devices since they use the HP pin actually for line/speaker | ||
4330 | * outs although the default pin config shows a different pin (that is | ||
4331 | * wrong and useless). | ||
4332 | * | ||
4333 | * So, it's basically a problem of default pin configs, likely a BIOS issue. | ||
4334 | * But, disabling the code below just works around it, and I'm too tired of | ||
4335 | * bug reports with such devices... | ||
4336 | */ | ||
4166 | else | 4337 | else |
4167 | stac92xx_reset_pinctl(codec, cfg->hp_pins[i], val); | 4338 | stac92xx_reset_pinctl(codec, cfg->hp_pins[i], val); |
4339 | #endif /* FIXME */ | ||
4168 | } | 4340 | } |
4169 | } | 4341 | } |
4170 | 4342 | ||
@@ -4258,6 +4430,24 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) | |||
4258 | if (spec->num_pwrs > 0) | 4430 | if (spec->num_pwrs > 0) |
4259 | stac92xx_pin_sense(codec, event->nid); | 4431 | stac92xx_pin_sense(codec, event->nid); |
4260 | stac92xx_report_jack(codec, event->nid); | 4432 | stac92xx_report_jack(codec, event->nid); |
4433 | |||
4434 | switch (codec->subsystem_id) { | ||
4435 | case 0x103c308f: | ||
4436 | if (event->nid == 0xb) { | ||
4437 | int pin = AC_PINCTL_IN_EN; | ||
4438 | |||
4439 | if (get_pin_presence(codec, 0xa) | ||
4440 | && get_pin_presence(codec, 0xb)) | ||
4441 | pin |= AC_PINCTL_VREF_80; | ||
4442 | if (!get_pin_presence(codec, 0xb)) | ||
4443 | pin |= AC_PINCTL_VREF_80; | ||
4444 | |||
4445 | /* toggle VREF state based on mic + hp pin | ||
4446 | * status | ||
4447 | */ | ||
4448 | stac92xx_auto_set_pinctl(codec, 0x0a, pin); | ||
4449 | } | ||
4450 | } | ||
4261 | break; | 4451 | break; |
4262 | case STAC_VREF_EVENT: | 4452 | case STAC_VREF_EVENT: |
4263 | data = snd_hda_codec_read(codec, codec->afg, 0, | 4453 | data = snd_hda_codec_read(codec, codec->afg, 0, |
@@ -4320,7 +4510,6 @@ static int stac92xx_resume(struct hda_codec *codec) | |||
4320 | { | 4510 | { |
4321 | struct sigmatel_spec *spec = codec->spec; | 4511 | struct sigmatel_spec *spec = codec->spec; |
4322 | 4512 | ||
4323 | stac92xx_set_config_regs(codec); | ||
4324 | stac92xx_init(codec); | 4513 | stac92xx_init(codec); |
4325 | snd_hda_codec_resume_amp(codec); | 4514 | snd_hda_codec_resume_amp(codec); |
4326 | snd_hda_codec_resume_cache(codec); | 4515 | snd_hda_codec_resume_cache(codec); |
@@ -4331,6 +4520,37 @@ static int stac92xx_resume(struct hda_codec *codec) | |||
4331 | return 0; | 4520 | return 0; |
4332 | } | 4521 | } |
4333 | 4522 | ||
4523 | |||
4524 | /* | ||
4525 | * using power check for controlling mute led of HP HDX notebooks | ||
4526 | * check for mute state only on Speakers (nid = 0x10) | ||
4527 | * | ||
4528 | * For this feature CONFIG_SND_HDA_POWER_SAVE is needed, otherwise | ||
4529 | * the LED is NOT working properly ! | ||
4530 | */ | ||
4531 | |||
4532 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
4533 | static int stac92xx_hp_hdx_check_power_status(struct hda_codec *codec, | ||
4534 | hda_nid_t nid) | ||
4535 | { | ||
4536 | struct sigmatel_spec *spec = codec->spec; | ||
4537 | |||
4538 | if (nid == 0x10) { | ||
4539 | if (snd_hda_codec_amp_read(codec, nid, 0, HDA_OUTPUT, 0) & | ||
4540 | HDA_AMP_MUTE) | ||
4541 | spec->gpio_data &= ~0x08; /* orange */ | ||
4542 | else | ||
4543 | spec->gpio_data |= 0x08; /* white */ | ||
4544 | |||
4545 | stac_gpio_set(codec, spec->gpio_mask, | ||
4546 | spec->gpio_dir, | ||
4547 | spec->gpio_data); | ||
4548 | } | ||
4549 | |||
4550 | return 0; | ||
4551 | } | ||
4552 | #endif | ||
4553 | |||
4334 | static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) | 4554 | static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) |
4335 | { | 4555 | { |
4336 | struct sigmatel_spec *spec = codec->spec; | 4556 | struct sigmatel_spec *spec = codec->spec; |
@@ -4369,16 +4589,11 @@ static int patch_stac9200(struct hda_codec *codec) | |||
4369 | spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS, | 4589 | spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS, |
4370 | stac9200_models, | 4590 | stac9200_models, |
4371 | stac9200_cfg_tbl); | 4591 | stac9200_cfg_tbl); |
4372 | if (spec->board_config < 0) { | 4592 | if (spec->board_config < 0) |
4373 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n"); | 4593 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9200, using BIOS defaults\n"); |
4374 | err = stac92xx_save_bios_config_regs(codec); | 4594 | else |
4375 | } else | 4595 | stac92xx_set_config_regs(codec, |
4376 | err = stac_save_pin_cfgs(codec, | ||
4377 | stac9200_brd_tbl[spec->board_config]); | 4596 | stac9200_brd_tbl[spec->board_config]); |
4378 | if (err < 0) { | ||
4379 | stac92xx_free(codec); | ||
4380 | return err; | ||
4381 | } | ||
4382 | 4597 | ||
4383 | spec->multiout.max_channels = 2; | 4598 | spec->multiout.max_channels = 2; |
4384 | spec->multiout.num_dacs = 1; | 4599 | spec->multiout.num_dacs = 1; |
@@ -4390,7 +4605,8 @@ static int patch_stac9200(struct hda_codec *codec) | |||
4390 | spec->num_adcs = 1; | 4605 | spec->num_adcs = 1; |
4391 | spec->num_pwrs = 0; | 4606 | spec->num_pwrs = 0; |
4392 | 4607 | ||
4393 | if (spec->board_config == STAC_9200_GATEWAY || | 4608 | if (spec->board_config == STAC_9200_M4 || |
4609 | spec->board_config == STAC_9200_M4_2 || | ||
4394 | spec->board_config == STAC_9200_OQO) | 4610 | spec->board_config == STAC_9200_OQO) |
4395 | spec->init = stac9200_eapd_init; | 4611 | spec->init = stac9200_eapd_init; |
4396 | else | 4612 | else |
@@ -4408,6 +4624,12 @@ static int patch_stac9200(struct hda_codec *codec) | |||
4408 | return err; | 4624 | return err; |
4409 | } | 4625 | } |
4410 | 4626 | ||
4627 | /* CF-74 has no headphone detection, and the driver should *NOT* | ||
4628 | * do detection and HP/speaker toggle because the hardware does it. | ||
4629 | */ | ||
4630 | if (spec->board_config == STAC_9200_PANASONIC) | ||
4631 | spec->hp_detect = 0; | ||
4632 | |||
4411 | codec->patch_ops = stac92xx_patch_ops; | 4633 | codec->patch_ops = stac92xx_patch_ops; |
4412 | 4634 | ||
4413 | return 0; | 4635 | return 0; |
@@ -4425,21 +4647,26 @@ static int patch_stac925x(struct hda_codec *codec) | |||
4425 | codec->spec = spec; | 4647 | codec->spec = spec; |
4426 | spec->num_pins = ARRAY_SIZE(stac925x_pin_nids); | 4648 | spec->num_pins = ARRAY_SIZE(stac925x_pin_nids); |
4427 | spec->pin_nids = stac925x_pin_nids; | 4649 | spec->pin_nids = stac925x_pin_nids; |
4428 | spec->board_config = snd_hda_check_board_config(codec, STAC_925x_MODELS, | 4650 | |
4651 | /* Check first for codec ID */ | ||
4652 | spec->board_config = snd_hda_check_board_codec_sid_config(codec, | ||
4653 | STAC_925x_MODELS, | ||
4654 | stac925x_models, | ||
4655 | stac925x_codec_id_cfg_tbl); | ||
4656 | |||
4657 | /* Now checks for PCI ID, if codec ID is not found */ | ||
4658 | if (spec->board_config < 0) | ||
4659 | spec->board_config = snd_hda_check_board_config(codec, | ||
4660 | STAC_925x_MODELS, | ||
4429 | stac925x_models, | 4661 | stac925x_models, |
4430 | stac925x_cfg_tbl); | 4662 | stac925x_cfg_tbl); |
4431 | again: | 4663 | again: |
4432 | if (spec->board_config < 0) { | 4664 | if (spec->board_config < 0) |
4433 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x," | 4665 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC925x," |
4434 | "using BIOS defaults\n"); | 4666 | "using BIOS defaults\n"); |
4435 | err = stac92xx_save_bios_config_regs(codec); | 4667 | else |
4436 | } else | 4668 | stac92xx_set_config_regs(codec, |
4437 | err = stac_save_pin_cfgs(codec, | ||
4438 | stac925x_brd_tbl[spec->board_config]); | 4669 | stac925x_brd_tbl[spec->board_config]); |
4439 | if (err < 0) { | ||
4440 | stac92xx_free(codec); | ||
4441 | return err; | ||
4442 | } | ||
4443 | 4670 | ||
4444 | spec->multiout.max_channels = 2; | 4671 | spec->multiout.max_channels = 2; |
4445 | spec->multiout.num_dacs = 1; | 4672 | spec->multiout.num_dacs = 1; |
@@ -4517,17 +4744,12 @@ static int patch_stac92hd73xx(struct hda_codec *codec) | |||
4517 | stac92hd73xx_models, | 4744 | stac92hd73xx_models, |
4518 | stac92hd73xx_cfg_tbl); | 4745 | stac92hd73xx_cfg_tbl); |
4519 | again: | 4746 | again: |
4520 | if (spec->board_config < 0) { | 4747 | if (spec->board_config < 0) |
4521 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" | 4748 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" |
4522 | " STAC92HD73XX, using BIOS defaults\n"); | 4749 | " STAC92HD73XX, using BIOS defaults\n"); |
4523 | err = stac92xx_save_bios_config_regs(codec); | 4750 | else |
4524 | } else | 4751 | stac92xx_set_config_regs(codec, |
4525 | err = stac_save_pin_cfgs(codec, | ||
4526 | stac92hd73xx_brd_tbl[spec->board_config]); | 4752 | stac92hd73xx_brd_tbl[spec->board_config]); |
4527 | if (err < 0) { | ||
4528 | stac92xx_free(codec); | ||
4529 | return err; | ||
4530 | } | ||
4531 | 4753 | ||
4532 | num_dacs = snd_hda_get_connections(codec, 0x0a, | 4754 | num_dacs = snd_hda_get_connections(codec, 0x0a, |
4533 | conn, STAC92HD73_DAC_COUNT + 2) - 1; | 4755 | conn, STAC92HD73_DAC_COUNT + 2) - 1; |
@@ -4541,14 +4763,18 @@ again: | |||
4541 | case 0x3: /* 6 Channel */ | 4763 | case 0x3: /* 6 Channel */ |
4542 | spec->mixer = stac92hd73xx_6ch_mixer; | 4764 | spec->mixer = stac92hd73xx_6ch_mixer; |
4543 | spec->init = stac92hd73xx_6ch_core_init; | 4765 | spec->init = stac92hd73xx_6ch_core_init; |
4766 | spec->aloopback_ctl = stac92hd73xx_6ch_loopback; | ||
4544 | break; | 4767 | break; |
4545 | case 0x4: /* 8 Channel */ | 4768 | case 0x4: /* 8 Channel */ |
4546 | spec->mixer = stac92hd73xx_8ch_mixer; | 4769 | spec->mixer = stac92hd73xx_8ch_mixer; |
4547 | spec->init = stac92hd73xx_8ch_core_init; | 4770 | spec->init = stac92hd73xx_8ch_core_init; |
4771 | spec->aloopback_ctl = stac92hd73xx_8ch_loopback; | ||
4548 | break; | 4772 | break; |
4549 | case 0x5: /* 10 Channel */ | 4773 | case 0x5: /* 10 Channel */ |
4550 | spec->mixer = stac92hd73xx_10ch_mixer; | 4774 | spec->mixer = stac92hd73xx_10ch_mixer; |
4551 | spec->init = stac92hd73xx_10ch_core_init; | 4775 | spec->init = stac92hd73xx_10ch_core_init; |
4776 | spec->aloopback_ctl = stac92hd73xx_10ch_loopback; | ||
4777 | break; | ||
4552 | } | 4778 | } |
4553 | spec->multiout.dac_nids = spec->dac_nids; | 4779 | spec->multiout.dac_nids = spec->dac_nids; |
4554 | 4780 | ||
@@ -4587,18 +4813,18 @@ again: | |||
4587 | spec->init = dell_m6_core_init; | 4813 | spec->init = dell_m6_core_init; |
4588 | switch (spec->board_config) { | 4814 | switch (spec->board_config) { |
4589 | case STAC_DELL_M6_AMIC: /* Analog Mics */ | 4815 | case STAC_DELL_M6_AMIC: /* Analog Mics */ |
4590 | stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); | 4816 | snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170); |
4591 | spec->num_dmics = 0; | 4817 | spec->num_dmics = 0; |
4592 | spec->private_dimux.num_items = 1; | 4818 | spec->private_dimux.num_items = 1; |
4593 | break; | 4819 | break; |
4594 | case STAC_DELL_M6_DMIC: /* Digital Mics */ | 4820 | case STAC_DELL_M6_DMIC: /* Digital Mics */ |
4595 | stac92xx_set_config_reg(codec, 0x13, 0x90A60160); | 4821 | snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160); |
4596 | spec->num_dmics = 1; | 4822 | spec->num_dmics = 1; |
4597 | spec->private_dimux.num_items = 2; | 4823 | spec->private_dimux.num_items = 2; |
4598 | break; | 4824 | break; |
4599 | case STAC_DELL_M6_BOTH: /* Both */ | 4825 | case STAC_DELL_M6_BOTH: /* Both */ |
4600 | stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); | 4826 | snd_hda_codec_set_pincfg(codec, 0x0b, 0x90A70170); |
4601 | stac92xx_set_config_reg(codec, 0x13, 0x90A60160); | 4827 | snd_hda_codec_set_pincfg(codec, 0x13, 0x90A60160); |
4602 | spec->num_dmics = 1; | 4828 | spec->num_dmics = 1; |
4603 | spec->private_dimux.num_items = 2; | 4829 | spec->private_dimux.num_items = 2; |
4604 | break; | 4830 | break; |
@@ -4658,7 +4884,10 @@ static struct hda_input_mux stac92hd83xxx_dmux = { | |||
4658 | static int patch_stac92hd83xxx(struct hda_codec *codec) | 4884 | static int patch_stac92hd83xxx(struct hda_codec *codec) |
4659 | { | 4885 | { |
4660 | struct sigmatel_spec *spec; | 4886 | struct sigmatel_spec *spec; |
4887 | hda_nid_t conn[STAC92HD83_DAC_COUNT + 1]; | ||
4661 | int err; | 4888 | int err; |
4889 | int num_dacs; | ||
4890 | hda_nid_t nid; | ||
4662 | 4891 | ||
4663 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 4892 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
4664 | if (spec == NULL) | 4893 | if (spec == NULL) |
@@ -4672,23 +4901,17 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
4672 | spec->dmux_nids = stac92hd83xxx_dmux_nids; | 4901 | spec->dmux_nids = stac92hd83xxx_dmux_nids; |
4673 | spec->adc_nids = stac92hd83xxx_adc_nids; | 4902 | spec->adc_nids = stac92hd83xxx_adc_nids; |
4674 | spec->pwr_nids = stac92hd83xxx_pwr_nids; | 4903 | spec->pwr_nids = stac92hd83xxx_pwr_nids; |
4904 | spec->amp_nids = stac92hd83xxx_amp_nids; | ||
4675 | spec->pwr_mapping = stac92hd83xxx_pwr_mapping; | 4905 | spec->pwr_mapping = stac92hd83xxx_pwr_mapping; |
4676 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); | 4906 | spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); |
4677 | spec->multiout.dac_nids = spec->dac_nids; | 4907 | spec->multiout.dac_nids = spec->dac_nids; |
4678 | 4908 | ||
4679 | spec->init = stac92hd83xxx_core_init; | 4909 | spec->init = stac92hd83xxx_core_init; |
4680 | switch (codec->vendor_id) { | ||
4681 | case 0x111d7605: | ||
4682 | break; | ||
4683 | default: | ||
4684 | spec->num_pwrs--; | ||
4685 | spec->init++; /* switch to config #2 */ | ||
4686 | } | ||
4687 | |||
4688 | spec->mixer = stac92hd83xxx_mixer; | 4910 | spec->mixer = stac92hd83xxx_mixer; |
4689 | spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids); | 4911 | spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids); |
4690 | spec->num_dmuxes = ARRAY_SIZE(stac92hd83xxx_dmux_nids); | 4912 | spec->num_dmuxes = ARRAY_SIZE(stac92hd83xxx_dmux_nids); |
4691 | spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids); | 4913 | spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids); |
4914 | spec->num_amps = ARRAY_SIZE(stac92hd83xxx_amp_nids); | ||
4692 | spec->num_dmics = STAC92HD83XXX_NUM_DMICS; | 4915 | spec->num_dmics = STAC92HD83XXX_NUM_DMICS; |
4693 | spec->dinput_mux = &stac92hd83xxx_dmux; | 4916 | spec->dinput_mux = &stac92hd83xxx_dmux; |
4694 | spec->pin_nids = stac92hd83xxx_pin_nids; | 4917 | spec->pin_nids = stac92hd83xxx_pin_nids; |
@@ -4697,16 +4920,21 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) | |||
4697 | stac92hd83xxx_models, | 4920 | stac92hd83xxx_models, |
4698 | stac92hd83xxx_cfg_tbl); | 4921 | stac92hd83xxx_cfg_tbl); |
4699 | again: | 4922 | again: |
4700 | if (spec->board_config < 0) { | 4923 | if (spec->board_config < 0) |
4701 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" | 4924 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" |
4702 | " STAC92HD83XXX, using BIOS defaults\n"); | 4925 | " STAC92HD83XXX, using BIOS defaults\n"); |
4703 | err = stac92xx_save_bios_config_regs(codec); | 4926 | else |
4704 | } else | 4927 | stac92xx_set_config_regs(codec, |
4705 | err = stac_save_pin_cfgs(codec, | ||
4706 | stac92hd83xxx_brd_tbl[spec->board_config]); | 4928 | stac92hd83xxx_brd_tbl[spec->board_config]); |
4707 | if (err < 0) { | 4929 | |
4708 | stac92xx_free(codec); | 4930 | switch (codec->vendor_id) { |
4709 | return err; | 4931 | case 0x111d7604: |
4932 | case 0x111d7605: | ||
4933 | case 0x111d76d5: | ||
4934 | if (spec->board_config == STAC_92HD83XXX_PWR_REF) | ||
4935 | break; | ||
4936 | spec->num_pwrs = 0; | ||
4937 | break; | ||
4710 | } | 4938 | } |
4711 | 4939 | ||
4712 | err = stac92xx_parse_auto_config(codec, 0x1d, 0); | 4940 | err = stac92xx_parse_auto_config(codec, 0x1d, 0); |
@@ -4725,6 +4953,23 @@ again: | |||
4725 | return err; | 4953 | return err; |
4726 | } | 4954 | } |
4727 | 4955 | ||
4956 | switch (spec->board_config) { | ||
4957 | case STAC_DELL_S14: | ||
4958 | nid = 0xf; | ||
4959 | break; | ||
4960 | default: | ||
4961 | nid = 0xe; | ||
4962 | break; | ||
4963 | } | ||
4964 | |||
4965 | num_dacs = snd_hda_get_connections(codec, nid, | ||
4966 | conn, STAC92HD83_DAC_COUNT + 1) - 1; | ||
4967 | |||
4968 | /* set port X to select the last DAC | ||
4969 | */ | ||
4970 | snd_hda_codec_write_cache(codec, nid, 0, | ||
4971 | AC_VERB_SET_CONNECT_SEL, num_dacs); | ||
4972 | |||
4728 | codec->patch_ops = stac92xx_patch_ops; | 4973 | codec->patch_ops = stac92xx_patch_ops; |
4729 | 4974 | ||
4730 | codec->proc_widget_hook = stac92hd_proc_hook; | 4975 | codec->proc_widget_hook = stac92hd_proc_hook; |
@@ -4732,7 +4977,16 @@ again: | |||
4732 | return 0; | 4977 | return 0; |
4733 | } | 4978 | } |
4734 | 4979 | ||
4735 | static struct hda_input_mux stac92hd71bxx_dmux = { | 4980 | static struct hda_input_mux stac92hd71bxx_dmux_nomixer = { |
4981 | .num_items = 3, | ||
4982 | .items = { | ||
4983 | { "Analog Inputs", 0x00 }, | ||
4984 | { "Digital Mic 1", 0x02 }, | ||
4985 | { "Digital Mic 2", 0x03 }, | ||
4986 | } | ||
4987 | }; | ||
4988 | |||
4989 | static struct hda_input_mux stac92hd71bxx_dmux_amixer = { | ||
4736 | .num_items = 4, | 4990 | .num_items = 4, |
4737 | .items = { | 4991 | .items = { |
4738 | { "Analog Inputs", 0x00 }, | 4992 | { "Analog Inputs", 0x00 }, |
@@ -4742,10 +4996,67 @@ static struct hda_input_mux stac92hd71bxx_dmux = { | |||
4742 | } | 4996 | } |
4743 | }; | 4997 | }; |
4744 | 4998 | ||
4999 | /* get the pin connection (fixed, none, etc) */ | ||
5000 | static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx) | ||
5001 | { | ||
5002 | struct sigmatel_spec *spec = codec->spec; | ||
5003 | unsigned int cfg; | ||
5004 | |||
5005 | cfg = snd_hda_codec_get_pincfg(codec, spec->pin_nids[idx]); | ||
5006 | return get_defcfg_connect(cfg); | ||
5007 | } | ||
5008 | |||
5009 | static int stac92hd71bxx_connected_ports(struct hda_codec *codec, | ||
5010 | hda_nid_t *nids, int num_nids) | ||
5011 | { | ||
5012 | struct sigmatel_spec *spec = codec->spec; | ||
5013 | int idx, num; | ||
5014 | unsigned int def_conf; | ||
5015 | |||
5016 | for (num = 0; num < num_nids; num++) { | ||
5017 | for (idx = 0; idx < spec->num_pins; idx++) | ||
5018 | if (spec->pin_nids[idx] == nids[num]) | ||
5019 | break; | ||
5020 | if (idx >= spec->num_pins) | ||
5021 | break; | ||
5022 | def_conf = stac_get_defcfg_connect(codec, idx); | ||
5023 | if (def_conf == AC_JACK_PORT_NONE) | ||
5024 | break; | ||
5025 | } | ||
5026 | return num; | ||
5027 | } | ||
5028 | |||
5029 | static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec, | ||
5030 | hda_nid_t dig0pin) | ||
5031 | { | ||
5032 | struct sigmatel_spec *spec = codec->spec; | ||
5033 | int idx; | ||
5034 | |||
5035 | for (idx = 0; idx < spec->num_pins; idx++) | ||
5036 | if (spec->pin_nids[idx] == dig0pin) | ||
5037 | break; | ||
5038 | if ((idx + 2) >= spec->num_pins) | ||
5039 | return 0; | ||
5040 | |||
5041 | /* dig1pin case */ | ||
5042 | if (stac_get_defcfg_connect(codec, idx + 1) != AC_JACK_PORT_NONE) | ||
5043 | return 2; | ||
5044 | |||
5045 | /* dig0pin + dig2pin case */ | ||
5046 | if (stac_get_defcfg_connect(codec, idx + 2) != AC_JACK_PORT_NONE) | ||
5047 | return 2; | ||
5048 | if (stac_get_defcfg_connect(codec, idx) != AC_JACK_PORT_NONE) | ||
5049 | return 1; | ||
5050 | else | ||
5051 | return 0; | ||
5052 | } | ||
5053 | |||
4745 | static int patch_stac92hd71bxx(struct hda_codec *codec) | 5054 | static int patch_stac92hd71bxx(struct hda_codec *codec) |
4746 | { | 5055 | { |
4747 | struct sigmatel_spec *spec; | 5056 | struct sigmatel_spec *spec; |
5057 | struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init; | ||
4748 | int err = 0; | 5058 | int err = 0; |
5059 | unsigned int ndmic_nids = 0; | ||
4749 | 5060 | ||
4750 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 5061 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
4751 | if (spec == NULL) | 5062 | if (spec == NULL) |
@@ -4753,27 +5064,32 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) | |||
4753 | 5064 | ||
4754 | codec->spec = spec; | 5065 | codec->spec = spec; |
4755 | codec->patch_ops = stac92xx_patch_ops; | 5066 | codec->patch_ops = stac92xx_patch_ops; |
4756 | spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids); | 5067 | spec->num_pins = STAC92HD71BXX_NUM_PINS; |
5068 | switch (codec->vendor_id) { | ||
5069 | case 0x111d76b6: | ||
5070 | case 0x111d76b7: | ||
5071 | spec->pin_nids = stac92hd71bxx_pin_nids_4port; | ||
5072 | break; | ||
5073 | case 0x111d7603: | ||
5074 | case 0x111d7608: | ||
5075 | /* On 92HD75Bx 0x27 isn't a pin nid */ | ||
5076 | spec->num_pins--; | ||
5077 | /* fallthrough */ | ||
5078 | default: | ||
5079 | spec->pin_nids = stac92hd71bxx_pin_nids_6port; | ||
5080 | } | ||
4757 | spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); | 5081 | spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); |
4758 | spec->pin_nids = stac92hd71bxx_pin_nids; | ||
4759 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux, | ||
4760 | sizeof(stac92hd71bxx_dmux)); | ||
4761 | spec->board_config = snd_hda_check_board_config(codec, | 5082 | spec->board_config = snd_hda_check_board_config(codec, |
4762 | STAC_92HD71BXX_MODELS, | 5083 | STAC_92HD71BXX_MODELS, |
4763 | stac92hd71bxx_models, | 5084 | stac92hd71bxx_models, |
4764 | stac92hd71bxx_cfg_tbl); | 5085 | stac92hd71bxx_cfg_tbl); |
4765 | again: | 5086 | again: |
4766 | if (spec->board_config < 0) { | 5087 | if (spec->board_config < 0) |
4767 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" | 5088 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" |
4768 | " STAC92HD71BXX, using BIOS defaults\n"); | 5089 | " STAC92HD71BXX, using BIOS defaults\n"); |
4769 | err = stac92xx_save_bios_config_regs(codec); | 5090 | else |
4770 | } else | 5091 | stac92xx_set_config_regs(codec, |
4771 | err = stac_save_pin_cfgs(codec, | ||
4772 | stac92hd71bxx_brd_tbl[spec->board_config]); | 5092 | stac92hd71bxx_brd_tbl[spec->board_config]); |
4773 | if (err < 0) { | ||
4774 | stac92xx_free(codec); | ||
4775 | return err; | ||
4776 | } | ||
4777 | 5093 | ||
4778 | if (spec->board_config > STAC_92HD71BXX_REF) { | 5094 | if (spec->board_config > STAC_92HD71BXX_REF) { |
4779 | /* GPIO0 = EAPD */ | 5095 | /* GPIO0 = EAPD */ |
@@ -4782,16 +5098,34 @@ again: | |||
4782 | spec->gpio_data = 0x01; | 5098 | spec->gpio_data = 0x01; |
4783 | } | 5099 | } |
4784 | 5100 | ||
5101 | spec->dmic_nids = stac92hd71bxx_dmic_nids; | ||
5102 | spec->dmux_nids = stac92hd71bxx_dmux_nids; | ||
5103 | |||
4785 | switch (codec->vendor_id) { | 5104 | switch (codec->vendor_id) { |
4786 | case 0x111d76b6: /* 4 Port without Analog Mixer */ | 5105 | case 0x111d76b6: /* 4 Port without Analog Mixer */ |
4787 | case 0x111d76b7: | 5106 | case 0x111d76b7: |
5107 | unmute_init++; | ||
5108 | /* fallthru */ | ||
4788 | case 0x111d76b4: /* 6 Port without Analog Mixer */ | 5109 | case 0x111d76b4: /* 6 Port without Analog Mixer */ |
4789 | case 0x111d76b5: | 5110 | case 0x111d76b5: |
5111 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_nomixer, | ||
5112 | sizeof(stac92hd71bxx_dmux_nomixer)); | ||
4790 | spec->mixer = stac92hd71bxx_mixer; | 5113 | spec->mixer = stac92hd71bxx_mixer; |
4791 | spec->init = stac92hd71bxx_core_init; | 5114 | spec->init = stac92hd71bxx_core_init; |
4792 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; | 5115 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; |
5116 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, | ||
5117 | stac92hd71bxx_dmic_nids, | ||
5118 | STAC92HD71BXX_NUM_DMICS); | ||
5119 | if (spec->num_dmics) { | ||
5120 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | ||
5121 | spec->dinput_mux = &spec->private_dimux; | ||
5122 | ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1; | ||
5123 | } | ||
4793 | break; | 5124 | break; |
4794 | case 0x111d7608: /* 5 Port with Analog Mixer */ | 5125 | case 0x111d7608: /* 5 Port with Analog Mixer */ |
5126 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_amixer, | ||
5127 | sizeof(stac92hd71bxx_dmux_amixer)); | ||
5128 | spec->private_dimux.num_items--; | ||
4795 | switch (spec->board_config) { | 5129 | switch (spec->board_config) { |
4796 | case STAC_HP_M4: | 5130 | case STAC_HP_M4: |
4797 | /* Enable VREF power saving on GPIO1 detect */ | 5131 | /* Enable VREF power saving on GPIO1 detect */ |
@@ -4818,7 +5152,15 @@ again: | |||
4818 | 5152 | ||
4819 | /* disable VSW */ | 5153 | /* disable VSW */ |
4820 | spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF]; | 5154 | spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF]; |
4821 | stac_change_pin_config(codec, 0xf, 0x40f000f0); | 5155 | unmute_init++; |
5156 | snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); | ||
5157 | snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); | ||
5158 | stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS - 1] = 0; | ||
5159 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, | ||
5160 | stac92hd71bxx_dmic_nids, | ||
5161 | STAC92HD71BXX_NUM_DMICS - 1); | ||
5162 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | ||
5163 | ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 2; | ||
4822 | break; | 5164 | break; |
4823 | case 0x111d7603: /* 6 Port with Analog Mixer */ | 5165 | case 0x111d7603: /* 6 Port with Analog Mixer */ |
4824 | if ((codec->revision_id & 0xf) == 1) | 5166 | if ((codec->revision_id & 0xf) == 1) |
@@ -4828,12 +5170,23 @@ again: | |||
4828 | spec->num_pwrs = 0; | 5170 | spec->num_pwrs = 0; |
4829 | /* fallthru */ | 5171 | /* fallthru */ |
4830 | default: | 5172 | default: |
5173 | memcpy(&spec->private_dimux, &stac92hd71bxx_dmux_amixer, | ||
5174 | sizeof(stac92hd71bxx_dmux_amixer)); | ||
4831 | spec->dinput_mux = &spec->private_dimux; | 5175 | spec->dinput_mux = &spec->private_dimux; |
4832 | spec->mixer = stac92hd71bxx_analog_mixer; | 5176 | spec->mixer = stac92hd71bxx_analog_mixer; |
4833 | spec->init = stac92hd71bxx_analog_core_init; | 5177 | spec->init = stac92hd71bxx_analog_core_init; |
4834 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; | 5178 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; |
5179 | spec->num_dmics = stac92hd71bxx_connected_ports(codec, | ||
5180 | stac92hd71bxx_dmic_nids, | ||
5181 | STAC92HD71BXX_NUM_DMICS); | ||
5182 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | ||
5183 | ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1; | ||
4835 | } | 5184 | } |
4836 | 5185 | ||
5186 | if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) | ||
5187 | snd_hda_sequence_write_cache(codec, unmute_init); | ||
5188 | |||
5189 | spec->aloopback_ctl = stac92hd71bxx_loopback; | ||
4837 | spec->aloopback_mask = 0x50; | 5190 | spec->aloopback_mask = 0x50; |
4838 | spec->aloopback_shift = 0; | 5191 | spec->aloopback_shift = 0; |
4839 | 5192 | ||
@@ -4841,18 +5194,17 @@ again: | |||
4841 | spec->digbeep_nid = 0x26; | 5194 | spec->digbeep_nid = 0x26; |
4842 | spec->mux_nids = stac92hd71bxx_mux_nids; | 5195 | spec->mux_nids = stac92hd71bxx_mux_nids; |
4843 | spec->adc_nids = stac92hd71bxx_adc_nids; | 5196 | spec->adc_nids = stac92hd71bxx_adc_nids; |
4844 | spec->dmic_nids = stac92hd71bxx_dmic_nids; | ||
4845 | spec->dmux_nids = stac92hd71bxx_dmux_nids; | ||
4846 | spec->smux_nids = stac92hd71bxx_smux_nids; | 5197 | spec->smux_nids = stac92hd71bxx_smux_nids; |
4847 | spec->pwr_nids = stac92hd71bxx_pwr_nids; | 5198 | spec->pwr_nids = stac92hd71bxx_pwr_nids; |
4848 | 5199 | ||
4849 | spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); | 5200 | spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); |
4850 | spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); | 5201 | spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); |
5202 | spec->num_smuxes = stac92hd71bxx_connected_smuxes(codec, 0x1e); | ||
4851 | 5203 | ||
4852 | switch (spec->board_config) { | 5204 | switch (spec->board_config) { |
4853 | case STAC_HP_M4: | 5205 | case STAC_HP_M4: |
4854 | /* enable internal microphone */ | 5206 | /* enable internal microphone */ |
4855 | stac_change_pin_config(codec, 0x0e, 0x01813040); | 5207 | snd_hda_codec_set_pincfg(codec, 0x0e, 0x01813040); |
4856 | stac92xx_auto_set_pinctl(codec, 0x0e, | 5208 | stac92xx_auto_set_pinctl(codec, 0x0e, |
4857 | AC_PINCTL_IN_EN | AC_PINCTL_VREF_80); | 5209 | AC_PINCTL_IN_EN | AC_PINCTL_VREF_80); |
4858 | /* fallthru */ | 5210 | /* fallthru */ |
@@ -4865,21 +5217,38 @@ again: | |||
4865 | case STAC_DELL_M4_3: | 5217 | case STAC_DELL_M4_3: |
4866 | spec->num_dmics = 1; | 5218 | spec->num_dmics = 1; |
4867 | spec->num_smuxes = 0; | 5219 | spec->num_smuxes = 0; |
4868 | spec->num_dmuxes = 0; | 5220 | spec->num_dmuxes = 1; |
5221 | break; | ||
5222 | case STAC_HP_DV5: | ||
5223 | snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); | ||
5224 | stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN); | ||
5225 | break; | ||
5226 | case STAC_HP_HDX: | ||
5227 | spec->num_dmics = 1; | ||
5228 | spec->num_dmuxes = 1; | ||
5229 | spec->num_smuxes = 1; | ||
5230 | /* | ||
5231 | * For controlling MUTE LED on HP HDX16/HDX18 notebooks, | ||
5232 | * the CONFIG_SND_HDA_POWER_SAVE is needed to be set. | ||
5233 | */ | ||
5234 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
5235 | /* orange/white mute led on GPIO3, orange=0, white=1 */ | ||
5236 | spec->gpio_mask |= 0x08; | ||
5237 | spec->gpio_dir |= 0x08; | ||
5238 | spec->gpio_data |= 0x08; /* set to white */ | ||
5239 | |||
5240 | /* register check_power_status callback. */ | ||
5241 | codec->patch_ops.check_power_status = | ||
5242 | stac92xx_hp_hdx_check_power_status; | ||
5243 | #endif | ||
4869 | break; | 5244 | break; |
4870 | default: | ||
4871 | spec->num_dmics = STAC92HD71BXX_NUM_DMICS; | ||
4872 | spec->num_smuxes = ARRAY_SIZE(stac92hd71bxx_smux_nids); | ||
4873 | spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); | ||
4874 | }; | 5245 | }; |
4875 | 5246 | ||
4876 | spec->multiout.dac_nids = spec->dac_nids; | 5247 | spec->multiout.dac_nids = spec->dac_nids; |
4877 | if (spec->dinput_mux) | 5248 | if (spec->dinput_mux) |
4878 | spec->private_dimux.num_items += | 5249 | spec->private_dimux.num_items += spec->num_dmics - ndmic_nids; |
4879 | spec->num_dmics - | ||
4880 | (ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 1); | ||
4881 | 5250 | ||
4882 | err = stac92xx_parse_auto_config(codec, 0x21, 0x23); | 5251 | err = stac92xx_parse_auto_config(codec, 0x21, 0); |
4883 | if (!err) { | 5252 | if (!err) { |
4884 | if (spec->board_config < 0) { | 5253 | if (spec->board_config < 0) { |
4885 | printk(KERN_WARNING "hda_codec: No auto-config is " | 5254 | printk(KERN_WARNING "hda_codec: No auto-config is " |
@@ -4954,17 +5323,12 @@ static int patch_stac922x(struct hda_codec *codec) | |||
4954 | } | 5323 | } |
4955 | 5324 | ||
4956 | again: | 5325 | again: |
4957 | if (spec->board_config < 0) { | 5326 | if (spec->board_config < 0) |
4958 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, " | 5327 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC922x, " |
4959 | "using BIOS defaults\n"); | 5328 | "using BIOS defaults\n"); |
4960 | err = stac92xx_save_bios_config_regs(codec); | 5329 | else |
4961 | } else | 5330 | stac92xx_set_config_regs(codec, |
4962 | err = stac_save_pin_cfgs(codec, | ||
4963 | stac922x_brd_tbl[spec->board_config]); | 5331 | stac922x_brd_tbl[spec->board_config]); |
4964 | if (err < 0) { | ||
4965 | stac92xx_free(codec); | ||
4966 | return err; | ||
4967 | } | ||
4968 | 5332 | ||
4969 | spec->adc_nids = stac922x_adc_nids; | 5333 | spec->adc_nids = stac922x_adc_nids; |
4970 | spec->mux_nids = stac922x_mux_nids; | 5334 | spec->mux_nids = stac922x_mux_nids; |
@@ -5015,24 +5379,19 @@ static int patch_stac927x(struct hda_codec *codec) | |||
5015 | return -ENOMEM; | 5379 | return -ENOMEM; |
5016 | 5380 | ||
5017 | codec->spec = spec; | 5381 | codec->spec = spec; |
5382 | codec->slave_dig_outs = stac927x_slave_dig_outs; | ||
5018 | spec->num_pins = ARRAY_SIZE(stac927x_pin_nids); | 5383 | spec->num_pins = ARRAY_SIZE(stac927x_pin_nids); |
5019 | spec->pin_nids = stac927x_pin_nids; | 5384 | spec->pin_nids = stac927x_pin_nids; |
5020 | spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS, | 5385 | spec->board_config = snd_hda_check_board_config(codec, STAC_927X_MODELS, |
5021 | stac927x_models, | 5386 | stac927x_models, |
5022 | stac927x_cfg_tbl); | 5387 | stac927x_cfg_tbl); |
5023 | again: | 5388 | again: |
5024 | if (spec->board_config < 0 || !stac927x_brd_tbl[spec->board_config]) { | 5389 | if (spec->board_config < 0) |
5025 | if (spec->board_config < 0) | 5390 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" |
5026 | snd_printdd(KERN_INFO "hda_codec: Unknown model for" | 5391 | "STAC927x, using BIOS defaults\n"); |
5027 | "STAC927x, using BIOS defaults\n"); | 5392 | else |
5028 | err = stac92xx_save_bios_config_regs(codec); | 5393 | stac92xx_set_config_regs(codec, |
5029 | } else | ||
5030 | err = stac_save_pin_cfgs(codec, | ||
5031 | stac927x_brd_tbl[spec->board_config]); | 5394 | stac927x_brd_tbl[spec->board_config]); |
5032 | if (err < 0) { | ||
5033 | stac92xx_free(codec); | ||
5034 | return err; | ||
5035 | } | ||
5036 | 5395 | ||
5037 | spec->digbeep_nid = 0x23; | 5396 | spec->digbeep_nid = 0x23; |
5038 | spec->adc_nids = stac927x_adc_nids; | 5397 | spec->adc_nids = stac927x_adc_nids; |
@@ -5061,15 +5420,15 @@ static int patch_stac927x(struct hda_codec *codec) | |||
5061 | case 0x10280209: | 5420 | case 0x10280209: |
5062 | case 0x1028022e: | 5421 | case 0x1028022e: |
5063 | /* correct the device field to SPDIF out */ | 5422 | /* correct the device field to SPDIF out */ |
5064 | stac_change_pin_config(codec, 0x21, 0x01442070); | 5423 | snd_hda_codec_set_pincfg(codec, 0x21, 0x01442070); |
5065 | break; | 5424 | break; |
5066 | }; | 5425 | }; |
5067 | /* configure the analog microphone on some laptops */ | 5426 | /* configure the analog microphone on some laptops */ |
5068 | stac_change_pin_config(codec, 0x0c, 0x90a79130); | 5427 | snd_hda_codec_set_pincfg(codec, 0x0c, 0x90a79130); |
5069 | /* correct the front output jack as a hp out */ | 5428 | /* correct the front output jack as a hp out */ |
5070 | stac_change_pin_config(codec, 0x0f, 0x0227011f); | 5429 | snd_hda_codec_set_pincfg(codec, 0x0f, 0x0227011f); |
5071 | /* correct the front input jack as a mic */ | 5430 | /* correct the front input jack as a mic */ |
5072 | stac_change_pin_config(codec, 0x0e, 0x02a79130); | 5431 | snd_hda_codec_set_pincfg(codec, 0x0e, 0x02a79130); |
5073 | /* fallthru */ | 5432 | /* fallthru */ |
5074 | case STAC_DELL_3ST: | 5433 | case STAC_DELL_3ST: |
5075 | /* GPIO2 High = Enable EAPD */ | 5434 | /* GPIO2 High = Enable EAPD */ |
@@ -5096,6 +5455,7 @@ static int patch_stac927x(struct hda_codec *codec) | |||
5096 | } | 5455 | } |
5097 | 5456 | ||
5098 | spec->num_pwrs = 0; | 5457 | spec->num_pwrs = 0; |
5458 | spec->aloopback_ctl = stac927x_loopback; | ||
5099 | spec->aloopback_mask = 0x40; | 5459 | spec->aloopback_mask = 0x40; |
5100 | spec->aloopback_shift = 0; | 5460 | spec->aloopback_shift = 0; |
5101 | spec->eapd_switch = 1; | 5461 | spec->eapd_switch = 1; |
@@ -5154,16 +5514,11 @@ static int patch_stac9205(struct hda_codec *codec) | |||
5154 | stac9205_models, | 5514 | stac9205_models, |
5155 | stac9205_cfg_tbl); | 5515 | stac9205_cfg_tbl); |
5156 | again: | 5516 | again: |
5157 | if (spec->board_config < 0) { | 5517 | if (spec->board_config < 0) |
5158 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n"); | 5518 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9205, using BIOS defaults\n"); |
5159 | err = stac92xx_save_bios_config_regs(codec); | 5519 | else |
5160 | } else | 5520 | stac92xx_set_config_regs(codec, |
5161 | err = stac_save_pin_cfgs(codec, | ||
5162 | stac9205_brd_tbl[spec->board_config]); | 5521 | stac9205_brd_tbl[spec->board_config]); |
5163 | if (err < 0) { | ||
5164 | stac92xx_free(codec); | ||
5165 | return err; | ||
5166 | } | ||
5167 | 5522 | ||
5168 | spec->digbeep_nid = 0x23; | 5523 | spec->digbeep_nid = 0x23; |
5169 | spec->adc_nids = stac9205_adc_nids; | 5524 | spec->adc_nids = stac9205_adc_nids; |
@@ -5180,17 +5535,20 @@ static int patch_stac9205(struct hda_codec *codec) | |||
5180 | 5535 | ||
5181 | spec->init = stac9205_core_init; | 5536 | spec->init = stac9205_core_init; |
5182 | spec->mixer = stac9205_mixer; | 5537 | spec->mixer = stac9205_mixer; |
5538 | spec->aloopback_ctl = stac9205_loopback; | ||
5183 | 5539 | ||
5184 | spec->aloopback_mask = 0x40; | 5540 | spec->aloopback_mask = 0x40; |
5185 | spec->aloopback_shift = 0; | 5541 | spec->aloopback_shift = 0; |
5186 | spec->eapd_switch = 1; | 5542 | /* Turn on/off EAPD per HP plugging */ |
5543 | if (spec->board_config != STAC_9205_EAPD) | ||
5544 | spec->eapd_switch = 1; | ||
5187 | spec->multiout.dac_nids = spec->dac_nids; | 5545 | spec->multiout.dac_nids = spec->dac_nids; |
5188 | 5546 | ||
5189 | switch (spec->board_config){ | 5547 | switch (spec->board_config){ |
5190 | case STAC_9205_DELL_M43: | 5548 | case STAC_9205_DELL_M43: |
5191 | /* Enable SPDIF in/out */ | 5549 | /* Enable SPDIF in/out */ |
5192 | stac_change_pin_config(codec, 0x1f, 0x01441030); | 5550 | snd_hda_codec_set_pincfg(codec, 0x1f, 0x01441030); |
5193 | stac_change_pin_config(codec, 0x20, 0x1c410030); | 5551 | snd_hda_codec_set_pincfg(codec, 0x20, 0x1c410030); |
5194 | 5552 | ||
5195 | /* Enable unsol response for GPIO4/Dock HP connection */ | 5553 | /* Enable unsol response for GPIO4/Dock HP connection */ |
5196 | err = stac_add_event(spec, codec->afg, STAC_VREF_EVENT, 0x01); | 5554 | err = stac_add_event(spec, codec->afg, STAC_VREF_EVENT, 0x01); |
@@ -5247,223 +5605,87 @@ static int patch_stac9205(struct hda_codec *codec) | |||
5247 | * STAC9872 hack | 5605 | * STAC9872 hack |
5248 | */ | 5606 | */ |
5249 | 5607 | ||
5250 | /* static config for Sony VAIO FE550G and Sony VAIO AR */ | 5608 | static struct hda_verb stac9872_core_init[] = { |
5251 | static hda_nid_t vaio_dacs[] = { 0x2 }; | ||
5252 | #define VAIO_HP_DAC 0x5 | ||
5253 | static hda_nid_t vaio_adcs[] = { 0x8 /*,0x6*/ }; | ||
5254 | static hda_nid_t vaio_mux_nids[] = { 0x15 }; | ||
5255 | |||
5256 | static struct hda_input_mux vaio_mux = { | ||
5257 | .num_items = 3, | ||
5258 | .items = { | ||
5259 | /* { "HP", 0x0 }, */ | ||
5260 | { "Mic Jack", 0x1 }, | ||
5261 | { "Internal Mic", 0x2 }, | ||
5262 | { "PCM", 0x3 }, | ||
5263 | } | ||
5264 | }; | ||
5265 | |||
5266 | static struct hda_verb vaio_init[] = { | ||
5267 | {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */ | ||
5268 | {0x0a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | STAC_HP_EVENT}, | ||
5269 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */ | ||
5270 | {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */ | ||
5271 | {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ | ||
5272 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ | ||
5273 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ | 5609 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ |
5274 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ | ||
5275 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ | ||
5276 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */ | ||
5277 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */ | ||
5278 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ | 5610 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ |
5279 | {} | 5611 | {} |
5280 | }; | 5612 | }; |
5281 | 5613 | ||
5282 | static struct hda_verb vaio_ar_init[] = { | 5614 | static struct snd_kcontrol_new stac9872_mixer[] = { |
5283 | {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */ | ||
5284 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */ | ||
5285 | {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */ | ||
5286 | {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ | ||
5287 | /* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */ | ||
5288 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ | ||
5289 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ | ||
5290 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ | ||
5291 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ | ||
5292 | /* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */ | ||
5293 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */ | ||
5294 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */ | ||
5295 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ | ||
5296 | {} | ||
5297 | }; | ||
5298 | |||
5299 | static struct snd_kcontrol_new vaio_mixer[] = { | ||
5300 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x02, 0, HDA_OUTPUT), | ||
5301 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x02, 0, HDA_OUTPUT), | ||
5302 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x05, 0, HDA_OUTPUT), | ||
5303 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x05, 0, HDA_OUTPUT), | ||
5304 | /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */ | ||
5305 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), | 5615 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), |
5306 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), | 5616 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), |
5307 | { | 5617 | { } /* end */ |
5308 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
5309 | .name = "Capture Source", | ||
5310 | .count = 1, | ||
5311 | .info = stac92xx_mux_enum_info, | ||
5312 | .get = stac92xx_mux_enum_get, | ||
5313 | .put = stac92xx_mux_enum_put, | ||
5314 | }, | ||
5315 | {} | ||
5316 | }; | 5618 | }; |
5317 | 5619 | ||
5318 | static struct snd_kcontrol_new vaio_ar_mixer[] = { | 5620 | static hda_nid_t stac9872_pin_nids[] = { |
5319 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x02, 0, HDA_OUTPUT), | 5621 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
5320 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x02, 0, HDA_OUTPUT), | 5622 | 0x11, 0x13, 0x14, |
5321 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x05, 0, HDA_OUTPUT), | ||
5322 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x05, 0, HDA_OUTPUT), | ||
5323 | /* HDA_CODEC_VOLUME("CD Capture Volume", 0x07, 0, HDA_INPUT), */ | ||
5324 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_INPUT), | ||
5325 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0, HDA_INPUT), | ||
5326 | /*HDA_CODEC_MUTE("Optical Out Switch", 0x10, 0, HDA_OUTPUT), | ||
5327 | HDA_CODEC_VOLUME("Optical Out Volume", 0x10, 0, HDA_OUTPUT),*/ | ||
5328 | { | ||
5329 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
5330 | .name = "Capture Source", | ||
5331 | .count = 1, | ||
5332 | .info = stac92xx_mux_enum_info, | ||
5333 | .get = stac92xx_mux_enum_get, | ||
5334 | .put = stac92xx_mux_enum_put, | ||
5335 | }, | ||
5336 | {} | ||
5337 | }; | 5623 | }; |
5338 | 5624 | ||
5339 | static struct hda_codec_ops stac9872_patch_ops = { | 5625 | static hda_nid_t stac9872_adc_nids[] = { |
5340 | .build_controls = stac92xx_build_controls, | 5626 | 0x8 /*,0x6*/ |
5341 | .build_pcms = stac92xx_build_pcms, | ||
5342 | .init = stac92xx_init, | ||
5343 | .free = stac92xx_free, | ||
5344 | #ifdef SND_HDA_NEEDS_RESUME | ||
5345 | .resume = stac92xx_resume, | ||
5346 | #endif | ||
5347 | }; | 5627 | }; |
5348 | 5628 | ||
5349 | static int stac9872_vaio_init(struct hda_codec *codec) | 5629 | static hda_nid_t stac9872_mux_nids[] = { |
5350 | { | 5630 | 0x15 |
5351 | int err; | ||
5352 | |||
5353 | err = stac92xx_init(codec); | ||
5354 | if (err < 0) | ||
5355 | return err; | ||
5356 | if (codec->patch_ops.unsol_event) | ||
5357 | codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); | ||
5358 | return 0; | ||
5359 | } | ||
5360 | |||
5361 | static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res) | ||
5362 | { | ||
5363 | if (get_pin_presence(codec, 0x0a)) { | ||
5364 | stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN); | ||
5365 | stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN); | ||
5366 | } else { | ||
5367 | stac92xx_reset_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN); | ||
5368 | stac92xx_set_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN); | ||
5369 | } | ||
5370 | } | ||
5371 | |||
5372 | static void stac9872_vaio_unsol_event(struct hda_codec *codec, unsigned int res) | ||
5373 | { | ||
5374 | switch (res >> 26) { | ||
5375 | case STAC_HP_EVENT: | ||
5376 | stac9872_vaio_hp_detect(codec, res); | ||
5377 | break; | ||
5378 | } | ||
5379 | } | ||
5380 | |||
5381 | static struct hda_codec_ops stac9872_vaio_patch_ops = { | ||
5382 | .build_controls = stac92xx_build_controls, | ||
5383 | .build_pcms = stac92xx_build_pcms, | ||
5384 | .init = stac9872_vaio_init, | ||
5385 | .free = stac92xx_free, | ||
5386 | .unsol_event = stac9872_vaio_unsol_event, | ||
5387 | #ifdef CONFIG_PM | ||
5388 | .resume = stac92xx_resume, | ||
5389 | #endif | ||
5390 | }; | 5631 | }; |
5391 | 5632 | ||
5392 | enum { /* FE and SZ series. id=0x83847661 and subsys=0x104D0700 or 104D1000. */ | 5633 | static unsigned int stac9872_vaio_pin_configs[9] = { |
5393 | CXD9872RD_VAIO, | 5634 | 0x03211020, 0x411111f0, 0x411111f0, 0x03a15030, |
5394 | /* Unknown. id=0x83847662 and subsys=0x104D1200 or 104D1000. */ | 5635 | 0x411111f0, 0x90170110, 0x411111f0, 0x411111f0, |
5395 | STAC9872AK_VAIO, | 5636 | 0x90a7013e |
5396 | /* Unknown. id=0x83847661 and subsys=0x104D1200. */ | ||
5397 | STAC9872K_VAIO, | ||
5398 | /* AR Series. id=0x83847664 and subsys=104D1300 */ | ||
5399 | CXD9872AKD_VAIO, | ||
5400 | STAC_9872_MODELS, | ||
5401 | }; | 5637 | }; |
5402 | 5638 | ||
5403 | static const char *stac9872_models[STAC_9872_MODELS] = { | 5639 | static const char *stac9872_models[STAC_9872_MODELS] = { |
5404 | [CXD9872RD_VAIO] = "vaio", | 5640 | [STAC_9872_AUTO] = "auto", |
5405 | [CXD9872AKD_VAIO] = "vaio-ar", | 5641 | [STAC_9872_VAIO] = "vaio", |
5642 | }; | ||
5643 | |||
5644 | static unsigned int *stac9872_brd_tbl[STAC_9872_MODELS] = { | ||
5645 | [STAC_9872_VAIO] = stac9872_vaio_pin_configs, | ||
5406 | }; | 5646 | }; |
5407 | 5647 | ||
5408 | static struct snd_pci_quirk stac9872_cfg_tbl[] = { | 5648 | static struct snd_pci_quirk stac9872_cfg_tbl[] = { |
5409 | SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO), | 5649 | {} /* terminator */ |
5410 | SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO), | ||
5411 | SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO), | ||
5412 | SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO), | ||
5413 | {} | ||
5414 | }; | 5650 | }; |
5415 | 5651 | ||
5416 | static int patch_stac9872(struct hda_codec *codec) | 5652 | static int patch_stac9872(struct hda_codec *codec) |
5417 | { | 5653 | { |
5418 | struct sigmatel_spec *spec; | 5654 | struct sigmatel_spec *spec; |
5419 | int board_config; | 5655 | int err; |
5420 | 5656 | ||
5421 | board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS, | ||
5422 | stac9872_models, | ||
5423 | stac9872_cfg_tbl); | ||
5424 | if (board_config < 0) | ||
5425 | /* unknown config, let generic-parser do its job... */ | ||
5426 | return snd_hda_parse_generic_codec(codec); | ||
5427 | |||
5428 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 5657 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
5429 | if (spec == NULL) | 5658 | if (spec == NULL) |
5430 | return -ENOMEM; | 5659 | return -ENOMEM; |
5431 | |||
5432 | codec->spec = spec; | 5660 | codec->spec = spec; |
5433 | switch (board_config) { | ||
5434 | case CXD9872RD_VAIO: | ||
5435 | case STAC9872AK_VAIO: | ||
5436 | case STAC9872K_VAIO: | ||
5437 | spec->mixer = vaio_mixer; | ||
5438 | spec->init = vaio_init; | ||
5439 | spec->multiout.max_channels = 2; | ||
5440 | spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs); | ||
5441 | spec->multiout.dac_nids = vaio_dacs; | ||
5442 | spec->multiout.hp_nid = VAIO_HP_DAC; | ||
5443 | spec->num_adcs = ARRAY_SIZE(vaio_adcs); | ||
5444 | spec->adc_nids = vaio_adcs; | ||
5445 | spec->num_pwrs = 0; | ||
5446 | spec->input_mux = &vaio_mux; | ||
5447 | spec->mux_nids = vaio_mux_nids; | ||
5448 | codec->patch_ops = stac9872_vaio_patch_ops; | ||
5449 | break; | ||
5450 | |||
5451 | case CXD9872AKD_VAIO: | ||
5452 | spec->mixer = vaio_ar_mixer; | ||
5453 | spec->init = vaio_ar_init; | ||
5454 | spec->multiout.max_channels = 2; | ||
5455 | spec->multiout.num_dacs = ARRAY_SIZE(vaio_dacs); | ||
5456 | spec->multiout.dac_nids = vaio_dacs; | ||
5457 | spec->multiout.hp_nid = VAIO_HP_DAC; | ||
5458 | spec->num_adcs = ARRAY_SIZE(vaio_adcs); | ||
5459 | spec->num_pwrs = 0; | ||
5460 | spec->adc_nids = vaio_adcs; | ||
5461 | spec->input_mux = &vaio_mux; | ||
5462 | spec->mux_nids = vaio_mux_nids; | ||
5463 | codec->patch_ops = stac9872_patch_ops; | ||
5464 | break; | ||
5465 | } | ||
5466 | 5661 | ||
5662 | spec->board_config = snd_hda_check_board_config(codec, STAC_9872_MODELS, | ||
5663 | stac9872_models, | ||
5664 | stac9872_cfg_tbl); | ||
5665 | if (spec->board_config < 0) | ||
5666 | snd_printdd(KERN_INFO "hda_codec: Unknown model for STAC9872, " | ||
5667 | "using BIOS defaults\n"); | ||
5668 | else | ||
5669 | stac92xx_set_config_regs(codec, | ||
5670 | stac9872_brd_tbl[spec->board_config]); | ||
5671 | |||
5672 | spec->num_pins = ARRAY_SIZE(stac9872_pin_nids); | ||
5673 | spec->pin_nids = stac9872_pin_nids; | ||
5674 | spec->multiout.dac_nids = spec->dac_nids; | ||
5675 | spec->num_adcs = ARRAY_SIZE(stac9872_adc_nids); | ||
5676 | spec->adc_nids = stac9872_adc_nids; | ||
5677 | spec->num_muxes = ARRAY_SIZE(stac9872_mux_nids); | ||
5678 | spec->mux_nids = stac9872_mux_nids; | ||
5679 | spec->mixer = stac9872_mixer; | ||
5680 | spec->init = stac9872_core_init; | ||
5681 | |||
5682 | err = stac92xx_parse_auto_config(codec, 0x10, 0x12); | ||
5683 | if (err < 0) { | ||
5684 | stac92xx_free(codec); | ||
5685 | return -EINVAL; | ||
5686 | } | ||
5687 | spec->input_mux = &spec->private_imux; | ||
5688 | codec->patch_ops = stac92xx_patch_ops; | ||
5467 | return 0; | 5689 | return 0; |
5468 | } | 5690 | } |
5469 | 5691 | ||
@@ -5521,6 +5743,7 @@ static struct hda_codec_preset snd_hda_preset_sigmatel[] = { | |||
5521 | { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, | 5743 | { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, |
5522 | { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx}, | 5744 | { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx}, |
5523 | { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx}, | 5745 | { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx}, |
5746 | { .id = 0x111d76d5, .name = "92HD81B1C5", .patch = patch_stac92hd83xxx}, | ||
5524 | { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, | 5747 | { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, |
5525 | { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, | 5748 | { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, |
5526 | { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, | 5749 | { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, |