Commit d2cfd3105094f593bc1fbd0b042a7752ddf08691
Exists in
ti-lsk-linux-4.1.y
and in
12 other branches
Merge tag 'sound-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai: "A few addition of HD-audio fixups for ALC260 and AD1986A codecs. All marked as stable fixes. The fixes are pretty local and they are old machines, so quite safe to apply" * tag 'sound-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: ALSA: hda/realtek - Fix COEF widget NID for ALC260 replacer fixup ALSA: hda/realtek - Correction of fixup codes for PB V7900 laptop ALSA: hda/analog - Fix silent output on ASUS A8JN
Showing 2 changed files Inline Diff
sound/pci/hda/patch_analog.c
1 | /* | 1 | /* |
2 | * HD audio interface patch for AD1882, AD1884, AD1981HD, AD1983, AD1984, | 2 | * HD audio interface patch for AD1882, AD1884, AD1981HD, AD1983, AD1984, |
3 | * AD1986A, AD1988 | 3 | * AD1986A, AD1988 |
4 | * | 4 | * |
5 | * Copyright (c) 2005-2007 Takashi Iwai <tiwai@suse.de> | 5 | * Copyright (c) 2005-2007 Takashi Iwai <tiwai@suse.de> |
6 | * | 6 | * |
7 | * This driver is free software; you can redistribute it and/or modify | 7 | * This driver is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
11 | * | 11 | * |
12 | * This driver is distributed in the hope that it will be useful, | 12 | * This driver is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * GNU General Public License for more details. | 15 | * GNU General Public License for more details. |
16 | * | 16 | * |
17 | * You should have received a copy of the GNU General Public License | 17 | * You should have received a copy of the GNU General Public License |
18 | * along with this program; if not, write to the Free Software | 18 | * along with this program; if not, write to the Free Software |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | 25 | ||
26 | #include <sound/core.h> | 26 | #include <sound/core.h> |
27 | #include "hda_codec.h" | 27 | #include "hda_codec.h" |
28 | #include "hda_local.h" | 28 | #include "hda_local.h" |
29 | #include "hda_auto_parser.h" | 29 | #include "hda_auto_parser.h" |
30 | #include "hda_beep.h" | 30 | #include "hda_beep.h" |
31 | #include "hda_jack.h" | 31 | #include "hda_jack.h" |
32 | #include "hda_generic.h" | 32 | #include "hda_generic.h" |
33 | 33 | ||
34 | 34 | ||
35 | struct ad198x_spec { | 35 | struct ad198x_spec { |
36 | struct hda_gen_spec gen; | 36 | struct hda_gen_spec gen; |
37 | 37 | ||
38 | /* for auto parser */ | 38 | /* for auto parser */ |
39 | int smux_paths[4]; | 39 | int smux_paths[4]; |
40 | unsigned int cur_smux; | 40 | unsigned int cur_smux; |
41 | hda_nid_t eapd_nid; | 41 | hda_nid_t eapd_nid; |
42 | 42 | ||
43 | unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ | 43 | unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ |
44 | }; | 44 | }; |
45 | 45 | ||
46 | 46 | ||
47 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 47 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
48 | /* additional beep mixers; the actual parameters are overwritten at build */ | 48 | /* additional beep mixers; the actual parameters are overwritten at build */ |
49 | static const struct snd_kcontrol_new ad_beep_mixer[] = { | 49 | static const struct snd_kcontrol_new ad_beep_mixer[] = { |
50 | HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT), | 50 | HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT), |
51 | HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_OUTPUT), | 51 | HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_OUTPUT), |
52 | { } /* end */ | 52 | { } /* end */ |
53 | }; | 53 | }; |
54 | 54 | ||
55 | #define set_beep_amp(spec, nid, idx, dir) \ | 55 | #define set_beep_amp(spec, nid, idx, dir) \ |
56 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) /* mono */ | 56 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) /* mono */ |
57 | #else | 57 | #else |
58 | #define set_beep_amp(spec, nid, idx, dir) /* NOP */ | 58 | #define set_beep_amp(spec, nid, idx, dir) /* NOP */ |
59 | #endif | 59 | #endif |
60 | 60 | ||
61 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 61 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
62 | static int create_beep_ctls(struct hda_codec *codec) | 62 | static int create_beep_ctls(struct hda_codec *codec) |
63 | { | 63 | { |
64 | struct ad198x_spec *spec = codec->spec; | 64 | struct ad198x_spec *spec = codec->spec; |
65 | const struct snd_kcontrol_new *knew; | 65 | const struct snd_kcontrol_new *knew; |
66 | 66 | ||
67 | if (!spec->beep_amp) | 67 | if (!spec->beep_amp) |
68 | return 0; | 68 | return 0; |
69 | 69 | ||
70 | for (knew = ad_beep_mixer ; knew->name; knew++) { | 70 | for (knew = ad_beep_mixer ; knew->name; knew++) { |
71 | int err; | 71 | int err; |
72 | struct snd_kcontrol *kctl; | 72 | struct snd_kcontrol *kctl; |
73 | kctl = snd_ctl_new1(knew, codec); | 73 | kctl = snd_ctl_new1(knew, codec); |
74 | if (!kctl) | 74 | if (!kctl) |
75 | return -ENOMEM; | 75 | return -ENOMEM; |
76 | kctl->private_value = spec->beep_amp; | 76 | kctl->private_value = spec->beep_amp; |
77 | err = snd_hda_ctl_add(codec, 0, kctl); | 77 | err = snd_hda_ctl_add(codec, 0, kctl); |
78 | if (err < 0) | 78 | if (err < 0) |
79 | return err; | 79 | return err; |
80 | } | 80 | } |
81 | return 0; | 81 | return 0; |
82 | } | 82 | } |
83 | #else | 83 | #else |
84 | #define create_beep_ctls(codec) 0 | 84 | #define create_beep_ctls(codec) 0 |
85 | #endif | 85 | #endif |
86 | 86 | ||
87 | 87 | ||
88 | static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front, | 88 | static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front, |
89 | hda_nid_t hp) | 89 | hda_nid_t hp) |
90 | { | 90 | { |
91 | if (snd_hda_query_pin_caps(codec, front) & AC_PINCAP_EAPD) | 91 | if (snd_hda_query_pin_caps(codec, front) & AC_PINCAP_EAPD) |
92 | snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE, | 92 | snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE, |
93 | !codec->inv_eapd ? 0x00 : 0x02); | 93 | !codec->inv_eapd ? 0x00 : 0x02); |
94 | if (snd_hda_query_pin_caps(codec, hp) & AC_PINCAP_EAPD) | 94 | if (snd_hda_query_pin_caps(codec, hp) & AC_PINCAP_EAPD) |
95 | snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE, | 95 | snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE, |
96 | !codec->inv_eapd ? 0x00 : 0x02); | 96 | !codec->inv_eapd ? 0x00 : 0x02); |
97 | } | 97 | } |
98 | 98 | ||
99 | static void ad198x_power_eapd(struct hda_codec *codec) | 99 | static void ad198x_power_eapd(struct hda_codec *codec) |
100 | { | 100 | { |
101 | /* We currently only handle front, HP */ | 101 | /* We currently only handle front, HP */ |
102 | switch (codec->vendor_id) { | 102 | switch (codec->vendor_id) { |
103 | case 0x11d41882: | 103 | case 0x11d41882: |
104 | case 0x11d4882a: | 104 | case 0x11d4882a: |
105 | case 0x11d41884: | 105 | case 0x11d41884: |
106 | case 0x11d41984: | 106 | case 0x11d41984: |
107 | case 0x11d41883: | 107 | case 0x11d41883: |
108 | case 0x11d4184a: | 108 | case 0x11d4184a: |
109 | case 0x11d4194a: | 109 | case 0x11d4194a: |
110 | case 0x11d4194b: | 110 | case 0x11d4194b: |
111 | case 0x11d41988: | 111 | case 0x11d41988: |
112 | case 0x11d4198b: | 112 | case 0x11d4198b: |
113 | case 0x11d4989a: | 113 | case 0x11d4989a: |
114 | case 0x11d4989b: | 114 | case 0x11d4989b: |
115 | ad198x_power_eapd_write(codec, 0x12, 0x11); | 115 | ad198x_power_eapd_write(codec, 0x12, 0x11); |
116 | break; | 116 | break; |
117 | case 0x11d41981: | 117 | case 0x11d41981: |
118 | case 0x11d41983: | 118 | case 0x11d41983: |
119 | ad198x_power_eapd_write(codec, 0x05, 0x06); | 119 | ad198x_power_eapd_write(codec, 0x05, 0x06); |
120 | break; | 120 | break; |
121 | case 0x11d41986: | 121 | case 0x11d41986: |
122 | ad198x_power_eapd_write(codec, 0x1b, 0x1a); | 122 | ad198x_power_eapd_write(codec, 0x1b, 0x1a); |
123 | break; | 123 | break; |
124 | } | 124 | } |
125 | } | 125 | } |
126 | 126 | ||
127 | static void ad198x_shutup(struct hda_codec *codec) | 127 | static void ad198x_shutup(struct hda_codec *codec) |
128 | { | 128 | { |
129 | snd_hda_shutup_pins(codec); | 129 | snd_hda_shutup_pins(codec); |
130 | ad198x_power_eapd(codec); | 130 | ad198x_power_eapd(codec); |
131 | } | 131 | } |
132 | 132 | ||
133 | #ifdef CONFIG_PM | 133 | #ifdef CONFIG_PM |
134 | static int ad198x_suspend(struct hda_codec *codec) | 134 | static int ad198x_suspend(struct hda_codec *codec) |
135 | { | 135 | { |
136 | ad198x_shutup(codec); | 136 | ad198x_shutup(codec); |
137 | return 0; | 137 | return 0; |
138 | } | 138 | } |
139 | #endif | 139 | #endif |
140 | 140 | ||
141 | /* follow EAPD via vmaster hook */ | 141 | /* follow EAPD via vmaster hook */ |
142 | static void ad_vmaster_eapd_hook(void *private_data, int enabled) | 142 | static void ad_vmaster_eapd_hook(void *private_data, int enabled) |
143 | { | 143 | { |
144 | struct hda_codec *codec = private_data; | 144 | struct hda_codec *codec = private_data; |
145 | struct ad198x_spec *spec = codec->spec; | 145 | struct ad198x_spec *spec = codec->spec; |
146 | 146 | ||
147 | if (!spec->eapd_nid) | 147 | if (!spec->eapd_nid) |
148 | return; | 148 | return; |
149 | if (codec->inv_eapd) | 149 | if (codec->inv_eapd) |
150 | enabled = !enabled; | 150 | enabled = !enabled; |
151 | snd_hda_codec_update_cache(codec, spec->eapd_nid, 0, | 151 | snd_hda_codec_update_cache(codec, spec->eapd_nid, 0, |
152 | AC_VERB_SET_EAPD_BTLENABLE, | 152 | AC_VERB_SET_EAPD_BTLENABLE, |
153 | enabled ? 0x02 : 0x00); | 153 | enabled ? 0x02 : 0x00); |
154 | } | 154 | } |
155 | 155 | ||
156 | /* | 156 | /* |
157 | * Automatic parse of I/O pins from the BIOS configuration | 157 | * Automatic parse of I/O pins from the BIOS configuration |
158 | */ | 158 | */ |
159 | 159 | ||
160 | static int ad198x_auto_build_controls(struct hda_codec *codec) | 160 | static int ad198x_auto_build_controls(struct hda_codec *codec) |
161 | { | 161 | { |
162 | int err; | 162 | int err; |
163 | 163 | ||
164 | err = snd_hda_gen_build_controls(codec); | 164 | err = snd_hda_gen_build_controls(codec); |
165 | if (err < 0) | 165 | if (err < 0) |
166 | return err; | 166 | return err; |
167 | err = create_beep_ctls(codec); | 167 | err = create_beep_ctls(codec); |
168 | if (err < 0) | 168 | if (err < 0) |
169 | return err; | 169 | return err; |
170 | return 0; | 170 | return 0; |
171 | } | 171 | } |
172 | 172 | ||
173 | static const struct hda_codec_ops ad198x_auto_patch_ops = { | 173 | static const struct hda_codec_ops ad198x_auto_patch_ops = { |
174 | .build_controls = ad198x_auto_build_controls, | 174 | .build_controls = ad198x_auto_build_controls, |
175 | .build_pcms = snd_hda_gen_build_pcms, | 175 | .build_pcms = snd_hda_gen_build_pcms, |
176 | .init = snd_hda_gen_init, | 176 | .init = snd_hda_gen_init, |
177 | .free = snd_hda_gen_free, | 177 | .free = snd_hda_gen_free, |
178 | .unsol_event = snd_hda_jack_unsol_event, | 178 | .unsol_event = snd_hda_jack_unsol_event, |
179 | #ifdef CONFIG_PM | 179 | #ifdef CONFIG_PM |
180 | .check_power_status = snd_hda_gen_check_power_status, | 180 | .check_power_status = snd_hda_gen_check_power_status, |
181 | .suspend = ad198x_suspend, | 181 | .suspend = ad198x_suspend, |
182 | #endif | 182 | #endif |
183 | .reboot_notify = ad198x_shutup, | 183 | .reboot_notify = ad198x_shutup, |
184 | }; | 184 | }; |
185 | 185 | ||
186 | 186 | ||
187 | static int ad198x_parse_auto_config(struct hda_codec *codec, bool indep_hp) | 187 | static int ad198x_parse_auto_config(struct hda_codec *codec, bool indep_hp) |
188 | { | 188 | { |
189 | struct ad198x_spec *spec = codec->spec; | 189 | struct ad198x_spec *spec = codec->spec; |
190 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; | 190 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; |
191 | int err; | 191 | int err; |
192 | 192 | ||
193 | codec->spdif_status_reset = 1; | 193 | codec->spdif_status_reset = 1; |
194 | codec->no_trigger_sense = 1; | 194 | codec->no_trigger_sense = 1; |
195 | codec->no_sticky_stream = 1; | 195 | codec->no_sticky_stream = 1; |
196 | 196 | ||
197 | spec->gen.indep_hp = indep_hp; | 197 | spec->gen.indep_hp = indep_hp; |
198 | spec->gen.add_stereo_mix_input = 1; | 198 | spec->gen.add_stereo_mix_input = 1; |
199 | 199 | ||
200 | err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0); | 200 | err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0); |
201 | if (err < 0) | 201 | if (err < 0) |
202 | return err; | 202 | return err; |
203 | err = snd_hda_gen_parse_auto_config(codec, cfg); | 203 | err = snd_hda_gen_parse_auto_config(codec, cfg); |
204 | if (err < 0) | 204 | if (err < 0) |
205 | return err; | 205 | return err; |
206 | 206 | ||
207 | codec->patch_ops = ad198x_auto_patch_ops; | 207 | codec->patch_ops = ad198x_auto_patch_ops; |
208 | 208 | ||
209 | return 0; | 209 | return 0; |
210 | } | 210 | } |
211 | 211 | ||
212 | /* | 212 | /* |
213 | * AD1986A specific | 213 | * AD1986A specific |
214 | */ | 214 | */ |
215 | 215 | ||
216 | static int alloc_ad_spec(struct hda_codec *codec) | 216 | static int alloc_ad_spec(struct hda_codec *codec) |
217 | { | 217 | { |
218 | struct ad198x_spec *spec; | 218 | struct ad198x_spec *spec; |
219 | 219 | ||
220 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 220 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
221 | if (!spec) | 221 | if (!spec) |
222 | return -ENOMEM; | 222 | return -ENOMEM; |
223 | codec->spec = spec; | 223 | codec->spec = spec; |
224 | snd_hda_gen_spec_init(&spec->gen); | 224 | snd_hda_gen_spec_init(&spec->gen); |
225 | return 0; | 225 | return 0; |
226 | } | 226 | } |
227 | 227 | ||
228 | /* | 228 | /* |
229 | * AD1986A fixup codes | 229 | * AD1986A fixup codes |
230 | */ | 230 | */ |
231 | 231 | ||
232 | /* Lenovo N100 seems to report the reversed bit for HP jack-sensing */ | 232 | /* Lenovo N100 seems to report the reversed bit for HP jack-sensing */ |
233 | static void ad_fixup_inv_jack_detect(struct hda_codec *codec, | 233 | static void ad_fixup_inv_jack_detect(struct hda_codec *codec, |
234 | const struct hda_fixup *fix, int action) | 234 | const struct hda_fixup *fix, int action) |
235 | { | 235 | { |
236 | struct ad198x_spec *spec = codec->spec; | 236 | struct ad198x_spec *spec = codec->spec; |
237 | 237 | ||
238 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 238 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
239 | codec->inv_jack_detect = 1; | 239 | codec->inv_jack_detect = 1; |
240 | spec->gen.keep_eapd_on = 1; | 240 | spec->gen.keep_eapd_on = 1; |
241 | spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook; | 241 | spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook; |
242 | spec->eapd_nid = 0x1b; | 242 | spec->eapd_nid = 0x1b; |
243 | } | 243 | } |
244 | } | 244 | } |
245 | 245 | ||
246 | /* Toshiba Satellite L40 implements EAPD in a standard way unlike others */ | 246 | /* Toshiba Satellite L40 implements EAPD in a standard way unlike others */ |
247 | static void ad1986a_fixup_eapd(struct hda_codec *codec, | 247 | static void ad1986a_fixup_eapd(struct hda_codec *codec, |
248 | const struct hda_fixup *fix, int action) | 248 | const struct hda_fixup *fix, int action) |
249 | { | 249 | { |
250 | struct ad198x_spec *spec = codec->spec; | 250 | struct ad198x_spec *spec = codec->spec; |
251 | 251 | ||
252 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 252 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
253 | codec->inv_eapd = 0; | 253 | codec->inv_eapd = 0; |
254 | spec->gen.keep_eapd_on = 1; | 254 | spec->gen.keep_eapd_on = 1; |
255 | spec->eapd_nid = 0x1b; | 255 | spec->eapd_nid = 0x1b; |
256 | } | 256 | } |
257 | } | 257 | } |
258 | 258 | ||
259 | enum { | 259 | enum { |
260 | AD1986A_FIXUP_INV_JACK_DETECT, | 260 | AD1986A_FIXUP_INV_JACK_DETECT, |
261 | AD1986A_FIXUP_ULTRA, | 261 | AD1986A_FIXUP_ULTRA, |
262 | AD1986A_FIXUP_SAMSUNG, | 262 | AD1986A_FIXUP_SAMSUNG, |
263 | AD1986A_FIXUP_3STACK, | 263 | AD1986A_FIXUP_3STACK, |
264 | AD1986A_FIXUP_LAPTOP, | 264 | AD1986A_FIXUP_LAPTOP, |
265 | AD1986A_FIXUP_LAPTOP_IMIC, | 265 | AD1986A_FIXUP_LAPTOP_IMIC, |
266 | AD1986A_FIXUP_EAPD, | 266 | AD1986A_FIXUP_EAPD, |
267 | }; | 267 | }; |
268 | 268 | ||
269 | static const struct hda_fixup ad1986a_fixups[] = { | 269 | static const struct hda_fixup ad1986a_fixups[] = { |
270 | [AD1986A_FIXUP_INV_JACK_DETECT] = { | 270 | [AD1986A_FIXUP_INV_JACK_DETECT] = { |
271 | .type = HDA_FIXUP_FUNC, | 271 | .type = HDA_FIXUP_FUNC, |
272 | .v.func = ad_fixup_inv_jack_detect, | 272 | .v.func = ad_fixup_inv_jack_detect, |
273 | }, | 273 | }, |
274 | [AD1986A_FIXUP_ULTRA] = { | 274 | [AD1986A_FIXUP_ULTRA] = { |
275 | .type = HDA_FIXUP_PINS, | 275 | .type = HDA_FIXUP_PINS, |
276 | .v.pins = (const struct hda_pintbl[]) { | 276 | .v.pins = (const struct hda_pintbl[]) { |
277 | { 0x1b, 0x90170110 }, /* speaker */ | 277 | { 0x1b, 0x90170110 }, /* speaker */ |
278 | { 0x1d, 0x90a7013e }, /* int mic */ | 278 | { 0x1d, 0x90a7013e }, /* int mic */ |
279 | {} | 279 | {} |
280 | }, | 280 | }, |
281 | }, | 281 | }, |
282 | [AD1986A_FIXUP_SAMSUNG] = { | 282 | [AD1986A_FIXUP_SAMSUNG] = { |
283 | .type = HDA_FIXUP_PINS, | 283 | .type = HDA_FIXUP_PINS, |
284 | .v.pins = (const struct hda_pintbl[]) { | 284 | .v.pins = (const struct hda_pintbl[]) { |
285 | { 0x1b, 0x90170110 }, /* speaker */ | 285 | { 0x1b, 0x90170110 }, /* speaker */ |
286 | { 0x1d, 0x90a7013e }, /* int mic */ | 286 | { 0x1d, 0x90a7013e }, /* int mic */ |
287 | { 0x20, 0x411111f0 }, /* N/A */ | 287 | { 0x20, 0x411111f0 }, /* N/A */ |
288 | { 0x24, 0x411111f0 }, /* N/A */ | 288 | { 0x24, 0x411111f0 }, /* N/A */ |
289 | {} | 289 | {} |
290 | }, | 290 | }, |
291 | }, | 291 | }, |
292 | [AD1986A_FIXUP_3STACK] = { | 292 | [AD1986A_FIXUP_3STACK] = { |
293 | .type = HDA_FIXUP_PINS, | 293 | .type = HDA_FIXUP_PINS, |
294 | .v.pins = (const struct hda_pintbl[]) { | 294 | .v.pins = (const struct hda_pintbl[]) { |
295 | { 0x1a, 0x02214021 }, /* headphone */ | 295 | { 0x1a, 0x02214021 }, /* headphone */ |
296 | { 0x1b, 0x01014011 }, /* front */ | 296 | { 0x1b, 0x01014011 }, /* front */ |
297 | { 0x1c, 0x01813030 }, /* line-in */ | 297 | { 0x1c, 0x01813030 }, /* line-in */ |
298 | { 0x1d, 0x01a19020 }, /* rear mic */ | 298 | { 0x1d, 0x01a19020 }, /* rear mic */ |
299 | { 0x1e, 0x411111f0 }, /* N/A */ | 299 | { 0x1e, 0x411111f0 }, /* N/A */ |
300 | { 0x1f, 0x02a190f0 }, /* mic */ | 300 | { 0x1f, 0x02a190f0 }, /* mic */ |
301 | { 0x20, 0x411111f0 }, /* N/A */ | 301 | { 0x20, 0x411111f0 }, /* N/A */ |
302 | {} | 302 | {} |
303 | }, | 303 | }, |
304 | }, | 304 | }, |
305 | [AD1986A_FIXUP_LAPTOP] = { | 305 | [AD1986A_FIXUP_LAPTOP] = { |
306 | .type = HDA_FIXUP_PINS, | 306 | .type = HDA_FIXUP_PINS, |
307 | .v.pins = (const struct hda_pintbl[]) { | 307 | .v.pins = (const struct hda_pintbl[]) { |
308 | { 0x1a, 0x02214021 }, /* headphone */ | 308 | { 0x1a, 0x02214021 }, /* headphone */ |
309 | { 0x1b, 0x90170110 }, /* speaker */ | 309 | { 0x1b, 0x90170110 }, /* speaker */ |
310 | { 0x1c, 0x411111f0 }, /* N/A */ | 310 | { 0x1c, 0x411111f0 }, /* N/A */ |
311 | { 0x1d, 0x411111f0 }, /* N/A */ | 311 | { 0x1d, 0x411111f0 }, /* N/A */ |
312 | { 0x1e, 0x411111f0 }, /* N/A */ | 312 | { 0x1e, 0x411111f0 }, /* N/A */ |
313 | { 0x1f, 0x02a191f0 }, /* mic */ | 313 | { 0x1f, 0x02a191f0 }, /* mic */ |
314 | { 0x20, 0x411111f0 }, /* N/A */ | 314 | { 0x20, 0x411111f0 }, /* N/A */ |
315 | {} | 315 | {} |
316 | }, | 316 | }, |
317 | }, | 317 | }, |
318 | [AD1986A_FIXUP_LAPTOP_IMIC] = { | 318 | [AD1986A_FIXUP_LAPTOP_IMIC] = { |
319 | .type = HDA_FIXUP_PINS, | 319 | .type = HDA_FIXUP_PINS, |
320 | .v.pins = (const struct hda_pintbl[]) { | 320 | .v.pins = (const struct hda_pintbl[]) { |
321 | { 0x1d, 0x90a7013e }, /* int mic */ | 321 | { 0x1d, 0x90a7013e }, /* int mic */ |
322 | {} | 322 | {} |
323 | }, | 323 | }, |
324 | .chained_before = 1, | 324 | .chained_before = 1, |
325 | .chain_id = AD1986A_FIXUP_LAPTOP, | 325 | .chain_id = AD1986A_FIXUP_LAPTOP, |
326 | }, | 326 | }, |
327 | [AD1986A_FIXUP_EAPD] = { | 327 | [AD1986A_FIXUP_EAPD] = { |
328 | .type = HDA_FIXUP_FUNC, | 328 | .type = HDA_FIXUP_FUNC, |
329 | .v.func = ad1986a_fixup_eapd, | 329 | .v.func = ad1986a_fixup_eapd, |
330 | }, | 330 | }, |
331 | }; | 331 | }; |
332 | 332 | ||
333 | static const struct snd_pci_quirk ad1986a_fixup_tbl[] = { | 333 | static const struct snd_pci_quirk ad1986a_fixup_tbl[] = { |
334 | SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_FIXUP_LAPTOP_IMIC), | 334 | SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_FIXUP_LAPTOP_IMIC), |
335 | SND_PCI_QUIRK(0x1043, 0x1447, "ASUS A8JN", AD1986A_FIXUP_EAPD), | ||
335 | SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8100, "ASUS P5", AD1986A_FIXUP_3STACK), | 336 | SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8100, "ASUS P5", AD1986A_FIXUP_3STACK), |
336 | SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8200, "ASUS M2", AD1986A_FIXUP_3STACK), | 337 | SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8200, "ASUS M2", AD1986A_FIXUP_3STACK), |
337 | SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_FIXUP_3STACK), | 338 | SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_FIXUP_3STACK), |
338 | SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba Satellite L40", AD1986A_FIXUP_EAPD), | 339 | SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba Satellite L40", AD1986A_FIXUP_EAPD), |
339 | SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_FIXUP_LAPTOP), | 340 | SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_FIXUP_LAPTOP), |
340 | SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_FIXUP_SAMSUNG), | 341 | SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_FIXUP_SAMSUNG), |
341 | SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_FIXUP_ULTRA), | 342 | SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_FIXUP_ULTRA), |
342 | SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_FIXUP_INV_JACK_DETECT), | 343 | SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_FIXUP_INV_JACK_DETECT), |
343 | SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_FIXUP_3STACK), | 344 | SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_FIXUP_3STACK), |
344 | SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_FIXUP_3STACK), | 345 | SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_FIXUP_3STACK), |
345 | {} | 346 | {} |
346 | }; | 347 | }; |
347 | 348 | ||
348 | static const struct hda_model_fixup ad1986a_fixup_models[] = { | 349 | static const struct hda_model_fixup ad1986a_fixup_models[] = { |
349 | { .id = AD1986A_FIXUP_3STACK, .name = "3stack" }, | 350 | { .id = AD1986A_FIXUP_3STACK, .name = "3stack" }, |
350 | { .id = AD1986A_FIXUP_LAPTOP, .name = "laptop" }, | 351 | { .id = AD1986A_FIXUP_LAPTOP, .name = "laptop" }, |
351 | { .id = AD1986A_FIXUP_LAPTOP_IMIC, .name = "laptop-imic" }, | 352 | { .id = AD1986A_FIXUP_LAPTOP_IMIC, .name = "laptop-imic" }, |
352 | { .id = AD1986A_FIXUP_LAPTOP_IMIC, .name = "laptop-eapd" }, /* alias */ | 353 | { .id = AD1986A_FIXUP_LAPTOP_IMIC, .name = "laptop-eapd" }, /* alias */ |
353 | {} | 354 | {} |
354 | }; | 355 | }; |
355 | 356 | ||
356 | /* | 357 | /* |
357 | */ | 358 | */ |
358 | static int patch_ad1986a(struct hda_codec *codec) | 359 | static int patch_ad1986a(struct hda_codec *codec) |
359 | { | 360 | { |
360 | int err; | 361 | int err; |
361 | struct ad198x_spec *spec; | 362 | struct ad198x_spec *spec; |
362 | static hda_nid_t preferred_pairs[] = { | 363 | static hda_nid_t preferred_pairs[] = { |
363 | 0x1a, 0x03, | 364 | 0x1a, 0x03, |
364 | 0x1b, 0x03, | 365 | 0x1b, 0x03, |
365 | 0x1c, 0x04, | 366 | 0x1c, 0x04, |
366 | 0x1d, 0x05, | 367 | 0x1d, 0x05, |
367 | 0x1e, 0x03, | 368 | 0x1e, 0x03, |
368 | 0 | 369 | 0 |
369 | }; | 370 | }; |
370 | 371 | ||
371 | err = alloc_ad_spec(codec); | 372 | err = alloc_ad_spec(codec); |
372 | if (err < 0) | 373 | if (err < 0) |
373 | return err; | 374 | return err; |
374 | spec = codec->spec; | 375 | spec = codec->spec; |
375 | 376 | ||
376 | /* AD1986A has the inverted EAPD implementation */ | 377 | /* AD1986A has the inverted EAPD implementation */ |
377 | codec->inv_eapd = 1; | 378 | codec->inv_eapd = 1; |
378 | 379 | ||
379 | spec->gen.mixer_nid = 0x07; | 380 | spec->gen.mixer_nid = 0x07; |
380 | spec->gen.beep_nid = 0x19; | 381 | spec->gen.beep_nid = 0x19; |
381 | set_beep_amp(spec, 0x18, 0, HDA_OUTPUT); | 382 | set_beep_amp(spec, 0x18, 0, HDA_OUTPUT); |
382 | 383 | ||
383 | /* AD1986A has a hardware problem that it can't share a stream | 384 | /* AD1986A has a hardware problem that it can't share a stream |
384 | * with multiple output pins. The copy of front to surrounds | 385 | * with multiple output pins. The copy of front to surrounds |
385 | * causes noisy or silent outputs at a certain timing, e.g. | 386 | * causes noisy or silent outputs at a certain timing, e.g. |
386 | * changing the volume. | 387 | * changing the volume. |
387 | * So, let's disable the shared stream. | 388 | * So, let's disable the shared stream. |
388 | */ | 389 | */ |
389 | spec->gen.multiout.no_share_stream = 1; | 390 | spec->gen.multiout.no_share_stream = 1; |
390 | /* give fixed DAC/pin pairs */ | 391 | /* give fixed DAC/pin pairs */ |
391 | spec->gen.preferred_dacs = preferred_pairs; | 392 | spec->gen.preferred_dacs = preferred_pairs; |
392 | 393 | ||
393 | /* AD1986A can't manage the dynamic pin on/off smoothly */ | 394 | /* AD1986A can't manage the dynamic pin on/off smoothly */ |
394 | spec->gen.auto_mute_via_amp = 1; | 395 | spec->gen.auto_mute_via_amp = 1; |
395 | 396 | ||
396 | snd_hda_pick_fixup(codec, ad1986a_fixup_models, ad1986a_fixup_tbl, | 397 | snd_hda_pick_fixup(codec, ad1986a_fixup_models, ad1986a_fixup_tbl, |
397 | ad1986a_fixups); | 398 | ad1986a_fixups); |
398 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 399 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
399 | 400 | ||
400 | err = ad198x_parse_auto_config(codec, false); | 401 | err = ad198x_parse_auto_config(codec, false); |
401 | if (err < 0) { | 402 | if (err < 0) { |
402 | snd_hda_gen_free(codec); | 403 | snd_hda_gen_free(codec); |
403 | return err; | 404 | return err; |
404 | } | 405 | } |
405 | 406 | ||
406 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 407 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
407 | 408 | ||
408 | return 0; | 409 | return 0; |
409 | } | 410 | } |
410 | 411 | ||
411 | 412 | ||
412 | /* | 413 | /* |
413 | * AD1983 specific | 414 | * AD1983 specific |
414 | */ | 415 | */ |
415 | 416 | ||
416 | /* | 417 | /* |
417 | * SPDIF mux control for AD1983 auto-parser | 418 | * SPDIF mux control for AD1983 auto-parser |
418 | */ | 419 | */ |
419 | static int ad1983_auto_smux_enum_info(struct snd_kcontrol *kcontrol, | 420 | static int ad1983_auto_smux_enum_info(struct snd_kcontrol *kcontrol, |
420 | struct snd_ctl_elem_info *uinfo) | 421 | struct snd_ctl_elem_info *uinfo) |
421 | { | 422 | { |
422 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 423 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
423 | struct ad198x_spec *spec = codec->spec; | 424 | struct ad198x_spec *spec = codec->spec; |
424 | static const char * const texts2[] = { "PCM", "ADC" }; | 425 | static const char * const texts2[] = { "PCM", "ADC" }; |
425 | static const char * const texts3[] = { "PCM", "ADC1", "ADC2" }; | 426 | static const char * const texts3[] = { "PCM", "ADC1", "ADC2" }; |
426 | hda_nid_t dig_out = spec->gen.multiout.dig_out_nid; | 427 | hda_nid_t dig_out = spec->gen.multiout.dig_out_nid; |
427 | int num_conns = snd_hda_get_num_conns(codec, dig_out); | 428 | int num_conns = snd_hda_get_num_conns(codec, dig_out); |
428 | 429 | ||
429 | if (num_conns == 2) | 430 | if (num_conns == 2) |
430 | return snd_hda_enum_helper_info(kcontrol, uinfo, 2, texts2); | 431 | return snd_hda_enum_helper_info(kcontrol, uinfo, 2, texts2); |
431 | else if (num_conns == 3) | 432 | else if (num_conns == 3) |
432 | return snd_hda_enum_helper_info(kcontrol, uinfo, 3, texts3); | 433 | return snd_hda_enum_helper_info(kcontrol, uinfo, 3, texts3); |
433 | else | 434 | else |
434 | return -EINVAL; | 435 | return -EINVAL; |
435 | } | 436 | } |
436 | 437 | ||
437 | static int ad1983_auto_smux_enum_get(struct snd_kcontrol *kcontrol, | 438 | static int ad1983_auto_smux_enum_get(struct snd_kcontrol *kcontrol, |
438 | struct snd_ctl_elem_value *ucontrol) | 439 | struct snd_ctl_elem_value *ucontrol) |
439 | { | 440 | { |
440 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 441 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
441 | struct ad198x_spec *spec = codec->spec; | 442 | struct ad198x_spec *spec = codec->spec; |
442 | 443 | ||
443 | ucontrol->value.enumerated.item[0] = spec->cur_smux; | 444 | ucontrol->value.enumerated.item[0] = spec->cur_smux; |
444 | return 0; | 445 | return 0; |
445 | } | 446 | } |
446 | 447 | ||
447 | static int ad1983_auto_smux_enum_put(struct snd_kcontrol *kcontrol, | 448 | static int ad1983_auto_smux_enum_put(struct snd_kcontrol *kcontrol, |
448 | struct snd_ctl_elem_value *ucontrol) | 449 | struct snd_ctl_elem_value *ucontrol) |
449 | { | 450 | { |
450 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 451 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
451 | struct ad198x_spec *spec = codec->spec; | 452 | struct ad198x_spec *spec = codec->spec; |
452 | unsigned int val = ucontrol->value.enumerated.item[0]; | 453 | unsigned int val = ucontrol->value.enumerated.item[0]; |
453 | hda_nid_t dig_out = spec->gen.multiout.dig_out_nid; | 454 | hda_nid_t dig_out = spec->gen.multiout.dig_out_nid; |
454 | int num_conns = snd_hda_get_num_conns(codec, dig_out); | 455 | int num_conns = snd_hda_get_num_conns(codec, dig_out); |
455 | 456 | ||
456 | if (val >= num_conns) | 457 | if (val >= num_conns) |
457 | return -EINVAL; | 458 | return -EINVAL; |
458 | if (spec->cur_smux == val) | 459 | if (spec->cur_smux == val) |
459 | return 0; | 460 | return 0; |
460 | spec->cur_smux = val; | 461 | spec->cur_smux = val; |
461 | snd_hda_codec_write_cache(codec, dig_out, 0, | 462 | snd_hda_codec_write_cache(codec, dig_out, 0, |
462 | AC_VERB_SET_CONNECT_SEL, val); | 463 | AC_VERB_SET_CONNECT_SEL, val); |
463 | return 1; | 464 | return 1; |
464 | } | 465 | } |
465 | 466 | ||
466 | static struct snd_kcontrol_new ad1983_auto_smux_mixer = { | 467 | static struct snd_kcontrol_new ad1983_auto_smux_mixer = { |
467 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 468 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
468 | .name = "IEC958 Playback Source", | 469 | .name = "IEC958 Playback Source", |
469 | .info = ad1983_auto_smux_enum_info, | 470 | .info = ad1983_auto_smux_enum_info, |
470 | .get = ad1983_auto_smux_enum_get, | 471 | .get = ad1983_auto_smux_enum_get, |
471 | .put = ad1983_auto_smux_enum_put, | 472 | .put = ad1983_auto_smux_enum_put, |
472 | }; | 473 | }; |
473 | 474 | ||
474 | static int ad1983_add_spdif_mux_ctl(struct hda_codec *codec) | 475 | static int ad1983_add_spdif_mux_ctl(struct hda_codec *codec) |
475 | { | 476 | { |
476 | struct ad198x_spec *spec = codec->spec; | 477 | struct ad198x_spec *spec = codec->spec; |
477 | hda_nid_t dig_out = spec->gen.multiout.dig_out_nid; | 478 | hda_nid_t dig_out = spec->gen.multiout.dig_out_nid; |
478 | int num_conns; | 479 | int num_conns; |
479 | 480 | ||
480 | if (!dig_out) | 481 | if (!dig_out) |
481 | return 0; | 482 | return 0; |
482 | num_conns = snd_hda_get_num_conns(codec, dig_out); | 483 | num_conns = snd_hda_get_num_conns(codec, dig_out); |
483 | if (num_conns != 2 && num_conns != 3) | 484 | if (num_conns != 2 && num_conns != 3) |
484 | return 0; | 485 | return 0; |
485 | if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &ad1983_auto_smux_mixer)) | 486 | if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &ad1983_auto_smux_mixer)) |
486 | return -ENOMEM; | 487 | return -ENOMEM; |
487 | return 0; | 488 | return 0; |
488 | } | 489 | } |
489 | 490 | ||
490 | static int patch_ad1983(struct hda_codec *codec) | 491 | static int patch_ad1983(struct hda_codec *codec) |
491 | { | 492 | { |
492 | struct ad198x_spec *spec; | 493 | struct ad198x_spec *spec; |
493 | static hda_nid_t conn_0c[] = { 0x08 }; | 494 | static hda_nid_t conn_0c[] = { 0x08 }; |
494 | static hda_nid_t conn_0d[] = { 0x09 }; | 495 | static hda_nid_t conn_0d[] = { 0x09 }; |
495 | int err; | 496 | int err; |
496 | 497 | ||
497 | err = alloc_ad_spec(codec); | 498 | err = alloc_ad_spec(codec); |
498 | if (err < 0) | 499 | if (err < 0) |
499 | return err; | 500 | return err; |
500 | spec = codec->spec; | 501 | spec = codec->spec; |
501 | 502 | ||
502 | spec->gen.mixer_nid = 0x0e; | 503 | spec->gen.mixer_nid = 0x0e; |
503 | spec->gen.beep_nid = 0x10; | 504 | spec->gen.beep_nid = 0x10; |
504 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); | 505 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); |
505 | 506 | ||
506 | /* limit the loopback routes not to confuse the parser */ | 507 | /* limit the loopback routes not to confuse the parser */ |
507 | snd_hda_override_conn_list(codec, 0x0c, ARRAY_SIZE(conn_0c), conn_0c); | 508 | snd_hda_override_conn_list(codec, 0x0c, ARRAY_SIZE(conn_0c), conn_0c); |
508 | snd_hda_override_conn_list(codec, 0x0d, ARRAY_SIZE(conn_0d), conn_0d); | 509 | snd_hda_override_conn_list(codec, 0x0d, ARRAY_SIZE(conn_0d), conn_0d); |
509 | 510 | ||
510 | err = ad198x_parse_auto_config(codec, false); | 511 | err = ad198x_parse_auto_config(codec, false); |
511 | if (err < 0) | 512 | if (err < 0) |
512 | goto error; | 513 | goto error; |
513 | err = ad1983_add_spdif_mux_ctl(codec); | 514 | err = ad1983_add_spdif_mux_ctl(codec); |
514 | if (err < 0) | 515 | if (err < 0) |
515 | goto error; | 516 | goto error; |
516 | return 0; | 517 | return 0; |
517 | 518 | ||
518 | error: | 519 | error: |
519 | snd_hda_gen_free(codec); | 520 | snd_hda_gen_free(codec); |
520 | return err; | 521 | return err; |
521 | } | 522 | } |
522 | 523 | ||
523 | 524 | ||
524 | /* | 525 | /* |
525 | * AD1981 HD specific | 526 | * AD1981 HD specific |
526 | */ | 527 | */ |
527 | 528 | ||
528 | static void ad1981_fixup_hp_eapd(struct hda_codec *codec, | 529 | static void ad1981_fixup_hp_eapd(struct hda_codec *codec, |
529 | const struct hda_fixup *fix, int action) | 530 | const struct hda_fixup *fix, int action) |
530 | { | 531 | { |
531 | struct ad198x_spec *spec = codec->spec; | 532 | struct ad198x_spec *spec = codec->spec; |
532 | 533 | ||
533 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 534 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
534 | spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook; | 535 | spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook; |
535 | spec->eapd_nid = 0x05; | 536 | spec->eapd_nid = 0x05; |
536 | } | 537 | } |
537 | } | 538 | } |
538 | 539 | ||
539 | /* set the upper-limit for mixer amp to 0dB for avoiding the possible | 540 | /* set the upper-limit for mixer amp to 0dB for avoiding the possible |
540 | * damage by overloading | 541 | * damage by overloading |
541 | */ | 542 | */ |
542 | static void ad1981_fixup_amp_override(struct hda_codec *codec, | 543 | static void ad1981_fixup_amp_override(struct hda_codec *codec, |
543 | const struct hda_fixup *fix, int action) | 544 | const struct hda_fixup *fix, int action) |
544 | { | 545 | { |
545 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | 546 | if (action == HDA_FIXUP_ACT_PRE_PROBE) |
546 | snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT, | 547 | snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT, |
547 | (0x17 << AC_AMPCAP_OFFSET_SHIFT) | | 548 | (0x17 << AC_AMPCAP_OFFSET_SHIFT) | |
548 | (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | | 549 | (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | |
549 | (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | | 550 | (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | |
550 | (1 << AC_AMPCAP_MUTE_SHIFT)); | 551 | (1 << AC_AMPCAP_MUTE_SHIFT)); |
551 | } | 552 | } |
552 | 553 | ||
553 | enum { | 554 | enum { |
554 | AD1981_FIXUP_AMP_OVERRIDE, | 555 | AD1981_FIXUP_AMP_OVERRIDE, |
555 | AD1981_FIXUP_HP_EAPD, | 556 | AD1981_FIXUP_HP_EAPD, |
556 | }; | 557 | }; |
557 | 558 | ||
558 | static const struct hda_fixup ad1981_fixups[] = { | 559 | static const struct hda_fixup ad1981_fixups[] = { |
559 | [AD1981_FIXUP_AMP_OVERRIDE] = { | 560 | [AD1981_FIXUP_AMP_OVERRIDE] = { |
560 | .type = HDA_FIXUP_FUNC, | 561 | .type = HDA_FIXUP_FUNC, |
561 | .v.func = ad1981_fixup_amp_override, | 562 | .v.func = ad1981_fixup_amp_override, |
562 | }, | 563 | }, |
563 | [AD1981_FIXUP_HP_EAPD] = { | 564 | [AD1981_FIXUP_HP_EAPD] = { |
564 | .type = HDA_FIXUP_FUNC, | 565 | .type = HDA_FIXUP_FUNC, |
565 | .v.func = ad1981_fixup_hp_eapd, | 566 | .v.func = ad1981_fixup_hp_eapd, |
566 | .chained = true, | 567 | .chained = true, |
567 | .chain_id = AD1981_FIXUP_AMP_OVERRIDE, | 568 | .chain_id = AD1981_FIXUP_AMP_OVERRIDE, |
568 | }, | 569 | }, |
569 | }; | 570 | }; |
570 | 571 | ||
571 | static const struct snd_pci_quirk ad1981_fixup_tbl[] = { | 572 | static const struct snd_pci_quirk ad1981_fixup_tbl[] = { |
572 | SND_PCI_QUIRK_VENDOR(0x1014, "Lenovo", AD1981_FIXUP_AMP_OVERRIDE), | 573 | SND_PCI_QUIRK_VENDOR(0x1014, "Lenovo", AD1981_FIXUP_AMP_OVERRIDE), |
573 | SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1981_FIXUP_HP_EAPD), | 574 | SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1981_FIXUP_HP_EAPD), |
574 | SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", AD1981_FIXUP_AMP_OVERRIDE), | 575 | SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", AD1981_FIXUP_AMP_OVERRIDE), |
575 | /* HP nx6320 (reversed SSID, H/W bug) */ | 576 | /* HP nx6320 (reversed SSID, H/W bug) */ |
576 | SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_FIXUP_HP_EAPD), | 577 | SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_FIXUP_HP_EAPD), |
577 | {} | 578 | {} |
578 | }; | 579 | }; |
579 | 580 | ||
580 | static int patch_ad1981(struct hda_codec *codec) | 581 | static int patch_ad1981(struct hda_codec *codec) |
581 | { | 582 | { |
582 | struct ad198x_spec *spec; | 583 | struct ad198x_spec *spec; |
583 | int err; | 584 | int err; |
584 | 585 | ||
585 | err = alloc_ad_spec(codec); | 586 | err = alloc_ad_spec(codec); |
586 | if (err < 0) | 587 | if (err < 0) |
587 | return -ENOMEM; | 588 | return -ENOMEM; |
588 | spec = codec->spec; | 589 | spec = codec->spec; |
589 | 590 | ||
590 | spec->gen.mixer_nid = 0x0e; | 591 | spec->gen.mixer_nid = 0x0e; |
591 | spec->gen.beep_nid = 0x10; | 592 | spec->gen.beep_nid = 0x10; |
592 | set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT); | 593 | set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT); |
593 | 594 | ||
594 | snd_hda_pick_fixup(codec, NULL, ad1981_fixup_tbl, ad1981_fixups); | 595 | snd_hda_pick_fixup(codec, NULL, ad1981_fixup_tbl, ad1981_fixups); |
595 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 596 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
596 | 597 | ||
597 | err = ad198x_parse_auto_config(codec, false); | 598 | err = ad198x_parse_auto_config(codec, false); |
598 | if (err < 0) | 599 | if (err < 0) |
599 | goto error; | 600 | goto error; |
600 | err = ad1983_add_spdif_mux_ctl(codec); | 601 | err = ad1983_add_spdif_mux_ctl(codec); |
601 | if (err < 0) | 602 | if (err < 0) |
602 | goto error; | 603 | goto error; |
603 | 604 | ||
604 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 605 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
605 | 606 | ||
606 | return 0; | 607 | return 0; |
607 | 608 | ||
608 | error: | 609 | error: |
609 | snd_hda_gen_free(codec); | 610 | snd_hda_gen_free(codec); |
610 | return err; | 611 | return err; |
611 | } | 612 | } |
612 | 613 | ||
613 | 614 | ||
614 | /* | 615 | /* |
615 | * AD1988 | 616 | * AD1988 |
616 | * | 617 | * |
617 | * Output pins and routes | 618 | * Output pins and routes |
618 | * | 619 | * |
619 | * Pin Mix Sel DAC (*) | 620 | * Pin Mix Sel DAC (*) |
620 | * port-A 0x11 (mute/hp) <- 0x22 <- 0x37 <- 03/04/06 | 621 | * port-A 0x11 (mute/hp) <- 0x22 <- 0x37 <- 03/04/06 |
621 | * port-B 0x14 (mute/hp) <- 0x2b <- 0x30 <- 03/04/06 | 622 | * port-B 0x14 (mute/hp) <- 0x2b <- 0x30 <- 03/04/06 |
622 | * port-C 0x15 (mute) <- 0x2c <- 0x31 <- 05/0a | 623 | * port-C 0x15 (mute) <- 0x2c <- 0x31 <- 05/0a |
623 | * port-D 0x12 (mute/hp) <- 0x29 <- 04 | 624 | * port-D 0x12 (mute/hp) <- 0x29 <- 04 |
624 | * port-E 0x17 (mute/hp) <- 0x26 <- 0x32 <- 05/0a | 625 | * port-E 0x17 (mute/hp) <- 0x26 <- 0x32 <- 05/0a |
625 | * port-F 0x16 (mute) <- 0x2a <- 06 | 626 | * port-F 0x16 (mute) <- 0x2a <- 06 |
626 | * port-G 0x24 (mute) <- 0x27 <- 05 | 627 | * port-G 0x24 (mute) <- 0x27 <- 05 |
627 | * port-H 0x25 (mute) <- 0x28 <- 0a | 628 | * port-H 0x25 (mute) <- 0x28 <- 0a |
628 | * mono 0x13 (mute/amp)<- 0x1e <- 0x36 <- 03/04/06 | 629 | * mono 0x13 (mute/amp)<- 0x1e <- 0x36 <- 03/04/06 |
629 | * | 630 | * |
630 | * DAC0 = 03h, DAC1 = 04h, DAC2 = 05h, DAC3 = 06h, DAC4 = 0ah | 631 | * DAC0 = 03h, DAC1 = 04h, DAC2 = 05h, DAC3 = 06h, DAC4 = 0ah |
631 | * (*) DAC2/3/4 are swapped to DAC3/4/2 on AD198A rev.2 due to a h/w bug. | 632 | * (*) DAC2/3/4 are swapped to DAC3/4/2 on AD198A rev.2 due to a h/w bug. |
632 | * | 633 | * |
633 | * Input pins and routes | 634 | * Input pins and routes |
634 | * | 635 | * |
635 | * pin boost mix input # / adc input # | 636 | * pin boost mix input # / adc input # |
636 | * port-A 0x11 -> 0x38 -> mix 2, ADC 0 | 637 | * port-A 0x11 -> 0x38 -> mix 2, ADC 0 |
637 | * port-B 0x14 -> 0x39 -> mix 0, ADC 1 | 638 | * port-B 0x14 -> 0x39 -> mix 0, ADC 1 |
638 | * port-C 0x15 -> 0x3a -> 33:0 - mix 1, ADC 2 | 639 | * port-C 0x15 -> 0x3a -> 33:0 - mix 1, ADC 2 |
639 | * port-D 0x12 -> 0x3d -> mix 3, ADC 8 | 640 | * port-D 0x12 -> 0x3d -> mix 3, ADC 8 |
640 | * port-E 0x17 -> 0x3c -> 34:0 - mix 4, ADC 4 | 641 | * port-E 0x17 -> 0x3c -> 34:0 - mix 4, ADC 4 |
641 | * port-F 0x16 -> 0x3b -> mix 5, ADC 3 | 642 | * port-F 0x16 -> 0x3b -> mix 5, ADC 3 |
642 | * port-G 0x24 -> N/A -> 33:1 - mix 1, 34:1 - mix 4, ADC 6 | 643 | * port-G 0x24 -> N/A -> 33:1 - mix 1, 34:1 - mix 4, ADC 6 |
643 | * port-H 0x25 -> N/A -> 33:2 - mix 1, 34:2 - mix 4, ADC 7 | 644 | * port-H 0x25 -> N/A -> 33:2 - mix 1, 34:2 - mix 4, ADC 7 |
644 | * | 645 | * |
645 | * | 646 | * |
646 | * DAC assignment | 647 | * DAC assignment |
647 | * 6stack - front/surr/CLFE/side/opt DACs - 04/06/05/0a/03 | 648 | * 6stack - front/surr/CLFE/side/opt DACs - 04/06/05/0a/03 |
648 | * 3stack - front/surr/CLFE/opt DACs - 04/05/0a/03 | 649 | * 3stack - front/surr/CLFE/opt DACs - 04/05/0a/03 |
649 | * | 650 | * |
650 | * Inputs of Analog Mix (0x20) | 651 | * Inputs of Analog Mix (0x20) |
651 | * 0:Port-B (front mic) | 652 | * 0:Port-B (front mic) |
652 | * 1:Port-C/G/H (line-in) | 653 | * 1:Port-C/G/H (line-in) |
653 | * 2:Port-A | 654 | * 2:Port-A |
654 | * 3:Port-D (line-in/2) | 655 | * 3:Port-D (line-in/2) |
655 | * 4:Port-E/G/H (mic-in) | 656 | * 4:Port-E/G/H (mic-in) |
656 | * 5:Port-F (mic2-in) | 657 | * 5:Port-F (mic2-in) |
657 | * 6:CD | 658 | * 6:CD |
658 | * 7:Beep | 659 | * 7:Beep |
659 | * | 660 | * |
660 | * ADC selection | 661 | * ADC selection |
661 | * 0:Port-A | 662 | * 0:Port-A |
662 | * 1:Port-B (front mic-in) | 663 | * 1:Port-B (front mic-in) |
663 | * 2:Port-C (line-in) | 664 | * 2:Port-C (line-in) |
664 | * 3:Port-F (mic2-in) | 665 | * 3:Port-F (mic2-in) |
665 | * 4:Port-E (mic-in) | 666 | * 4:Port-E (mic-in) |
666 | * 5:CD | 667 | * 5:CD |
667 | * 6:Port-G | 668 | * 6:Port-G |
668 | * 7:Port-H | 669 | * 7:Port-H |
669 | * 8:Port-D (line-in/2) | 670 | * 8:Port-D (line-in/2) |
670 | * 9:Mix | 671 | * 9:Mix |
671 | * | 672 | * |
672 | * Proposed pin assignments by the datasheet | 673 | * Proposed pin assignments by the datasheet |
673 | * | 674 | * |
674 | * 6-stack | 675 | * 6-stack |
675 | * Port-A front headphone | 676 | * Port-A front headphone |
676 | * B front mic-in | 677 | * B front mic-in |
677 | * C rear line-in | 678 | * C rear line-in |
678 | * D rear front-out | 679 | * D rear front-out |
679 | * E rear mic-in | 680 | * E rear mic-in |
680 | * F rear surround | 681 | * F rear surround |
681 | * G rear CLFE | 682 | * G rear CLFE |
682 | * H rear side | 683 | * H rear side |
683 | * | 684 | * |
684 | * 3-stack | 685 | * 3-stack |
685 | * Port-A front headphone | 686 | * Port-A front headphone |
686 | * B front mic | 687 | * B front mic |
687 | * C rear line-in/surround | 688 | * C rear line-in/surround |
688 | * D rear front-out | 689 | * D rear front-out |
689 | * E rear mic-in/CLFE | 690 | * E rear mic-in/CLFE |
690 | * | 691 | * |
691 | * laptop | 692 | * laptop |
692 | * Port-A headphone | 693 | * Port-A headphone |
693 | * B mic-in | 694 | * B mic-in |
694 | * C docking station | 695 | * C docking station |
695 | * D internal speaker (with EAPD) | 696 | * D internal speaker (with EAPD) |
696 | * E/F quad mic array | 697 | * E/F quad mic array |
697 | */ | 698 | */ |
698 | 699 | ||
699 | #ifdef ENABLE_AD_STATIC_QUIRKS | 700 | #ifdef ENABLE_AD_STATIC_QUIRKS |
700 | static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol, | 701 | static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol, |
701 | struct snd_ctl_elem_info *uinfo) | 702 | struct snd_ctl_elem_info *uinfo) |
702 | { | 703 | { |
703 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 704 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
704 | struct ad198x_spec *spec = codec->spec; | 705 | struct ad198x_spec *spec = codec->spec; |
705 | return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, | 706 | return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode, |
706 | spec->num_channel_mode); | 707 | spec->num_channel_mode); |
707 | } | 708 | } |
708 | 709 | ||
709 | static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol, | 710 | static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol, |
710 | struct snd_ctl_elem_value *ucontrol) | 711 | struct snd_ctl_elem_value *ucontrol) |
711 | { | 712 | { |
712 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 713 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
713 | struct ad198x_spec *spec = codec->spec; | 714 | struct ad198x_spec *spec = codec->spec; |
714 | return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, | 715 | return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode, |
715 | spec->num_channel_mode, spec->multiout.max_channels); | 716 | spec->num_channel_mode, spec->multiout.max_channels); |
716 | } | 717 | } |
717 | 718 | ||
718 | static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol, | 719 | static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol, |
719 | struct snd_ctl_elem_value *ucontrol) | 720 | struct snd_ctl_elem_value *ucontrol) |
720 | { | 721 | { |
721 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 722 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
722 | struct ad198x_spec *spec = codec->spec; | 723 | struct ad198x_spec *spec = codec->spec; |
723 | int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, | 724 | int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode, |
724 | spec->num_channel_mode, | 725 | spec->num_channel_mode, |
725 | &spec->multiout.max_channels); | 726 | &spec->multiout.max_channels); |
726 | if (err >= 0 && spec->need_dac_fix) | 727 | if (err >= 0 && spec->need_dac_fix) |
727 | spec->multiout.num_dacs = spec->multiout.max_channels / 2; | 728 | spec->multiout.num_dacs = spec->multiout.max_channels / 2; |
728 | return err; | 729 | return err; |
729 | } | 730 | } |
730 | #endif /* ENABLE_AD_STATIC_QUIRKS */ | 731 | #endif /* ENABLE_AD_STATIC_QUIRKS */ |
731 | 732 | ||
732 | static int ad1988_auto_smux_enum_info(struct snd_kcontrol *kcontrol, | 733 | static int ad1988_auto_smux_enum_info(struct snd_kcontrol *kcontrol, |
733 | struct snd_ctl_elem_info *uinfo) | 734 | struct snd_ctl_elem_info *uinfo) |
734 | { | 735 | { |
735 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 736 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
736 | static const char * const texts[] = { | 737 | static const char * const texts[] = { |
737 | "PCM", "ADC1", "ADC2", "ADC3", | 738 | "PCM", "ADC1", "ADC2", "ADC3", |
738 | }; | 739 | }; |
739 | int num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1; | 740 | int num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1; |
740 | if (num_conns > 4) | 741 | if (num_conns > 4) |
741 | num_conns = 4; | 742 | num_conns = 4; |
742 | return snd_hda_enum_helper_info(kcontrol, uinfo, num_conns, texts); | 743 | return snd_hda_enum_helper_info(kcontrol, uinfo, num_conns, texts); |
743 | } | 744 | } |
744 | 745 | ||
745 | static int ad1988_auto_smux_enum_get(struct snd_kcontrol *kcontrol, | 746 | static int ad1988_auto_smux_enum_get(struct snd_kcontrol *kcontrol, |
746 | struct snd_ctl_elem_value *ucontrol) | 747 | struct snd_ctl_elem_value *ucontrol) |
747 | { | 748 | { |
748 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 749 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
749 | struct ad198x_spec *spec = codec->spec; | 750 | struct ad198x_spec *spec = codec->spec; |
750 | 751 | ||
751 | ucontrol->value.enumerated.item[0] = spec->cur_smux; | 752 | ucontrol->value.enumerated.item[0] = spec->cur_smux; |
752 | return 0; | 753 | return 0; |
753 | } | 754 | } |
754 | 755 | ||
755 | static int ad1988_auto_smux_enum_put(struct snd_kcontrol *kcontrol, | 756 | static int ad1988_auto_smux_enum_put(struct snd_kcontrol *kcontrol, |
756 | struct snd_ctl_elem_value *ucontrol) | 757 | struct snd_ctl_elem_value *ucontrol) |
757 | { | 758 | { |
758 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 759 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
759 | struct ad198x_spec *spec = codec->spec; | 760 | struct ad198x_spec *spec = codec->spec; |
760 | unsigned int val = ucontrol->value.enumerated.item[0]; | 761 | unsigned int val = ucontrol->value.enumerated.item[0]; |
761 | struct nid_path *path; | 762 | struct nid_path *path; |
762 | int num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1; | 763 | int num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1; |
763 | 764 | ||
764 | if (val >= num_conns) | 765 | if (val >= num_conns) |
765 | return -EINVAL; | 766 | return -EINVAL; |
766 | if (spec->cur_smux == val) | 767 | if (spec->cur_smux == val) |
767 | return 0; | 768 | return 0; |
768 | 769 | ||
769 | mutex_lock(&codec->control_mutex); | 770 | mutex_lock(&codec->control_mutex); |
770 | codec->cached_write = 1; | 771 | codec->cached_write = 1; |
771 | path = snd_hda_get_path_from_idx(codec, | 772 | path = snd_hda_get_path_from_idx(codec, |
772 | spec->smux_paths[spec->cur_smux]); | 773 | spec->smux_paths[spec->cur_smux]); |
773 | if (path) | 774 | if (path) |
774 | snd_hda_activate_path(codec, path, false, true); | 775 | snd_hda_activate_path(codec, path, false, true); |
775 | path = snd_hda_get_path_from_idx(codec, spec->smux_paths[val]); | 776 | path = snd_hda_get_path_from_idx(codec, spec->smux_paths[val]); |
776 | if (path) | 777 | if (path) |
777 | snd_hda_activate_path(codec, path, true, true); | 778 | snd_hda_activate_path(codec, path, true, true); |
778 | spec->cur_smux = val; | 779 | spec->cur_smux = val; |
779 | codec->cached_write = 0; | 780 | codec->cached_write = 0; |
780 | mutex_unlock(&codec->control_mutex); | 781 | mutex_unlock(&codec->control_mutex); |
781 | snd_hda_codec_flush_cache(codec); /* flush the updates */ | 782 | snd_hda_codec_flush_cache(codec); /* flush the updates */ |
782 | return 1; | 783 | return 1; |
783 | } | 784 | } |
784 | 785 | ||
785 | static struct snd_kcontrol_new ad1988_auto_smux_mixer = { | 786 | static struct snd_kcontrol_new ad1988_auto_smux_mixer = { |
786 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 787 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
787 | .name = "IEC958 Playback Source", | 788 | .name = "IEC958 Playback Source", |
788 | .info = ad1988_auto_smux_enum_info, | 789 | .info = ad1988_auto_smux_enum_info, |
789 | .get = ad1988_auto_smux_enum_get, | 790 | .get = ad1988_auto_smux_enum_get, |
790 | .put = ad1988_auto_smux_enum_put, | 791 | .put = ad1988_auto_smux_enum_put, |
791 | }; | 792 | }; |
792 | 793 | ||
793 | static int ad1988_auto_init(struct hda_codec *codec) | 794 | static int ad1988_auto_init(struct hda_codec *codec) |
794 | { | 795 | { |
795 | struct ad198x_spec *spec = codec->spec; | 796 | struct ad198x_spec *spec = codec->spec; |
796 | int i, err; | 797 | int i, err; |
797 | 798 | ||
798 | err = snd_hda_gen_init(codec); | 799 | err = snd_hda_gen_init(codec); |
799 | if (err < 0) | 800 | if (err < 0) |
800 | return err; | 801 | return err; |
801 | if (!spec->gen.autocfg.dig_outs) | 802 | if (!spec->gen.autocfg.dig_outs) |
802 | return 0; | 803 | return 0; |
803 | 804 | ||
804 | for (i = 0; i < 4; i++) { | 805 | for (i = 0; i < 4; i++) { |
805 | struct nid_path *path; | 806 | struct nid_path *path; |
806 | path = snd_hda_get_path_from_idx(codec, spec->smux_paths[i]); | 807 | path = snd_hda_get_path_from_idx(codec, spec->smux_paths[i]); |
807 | if (path) | 808 | if (path) |
808 | snd_hda_activate_path(codec, path, path->active, false); | 809 | snd_hda_activate_path(codec, path, path->active, false); |
809 | } | 810 | } |
810 | 811 | ||
811 | return 0; | 812 | return 0; |
812 | } | 813 | } |
813 | 814 | ||
814 | static int ad1988_add_spdif_mux_ctl(struct hda_codec *codec) | 815 | static int ad1988_add_spdif_mux_ctl(struct hda_codec *codec) |
815 | { | 816 | { |
816 | struct ad198x_spec *spec = codec->spec; | 817 | struct ad198x_spec *spec = codec->spec; |
817 | int i, num_conns; | 818 | int i, num_conns; |
818 | /* we create four static faked paths, since AD codecs have odd | 819 | /* we create four static faked paths, since AD codecs have odd |
819 | * widget connections regarding the SPDIF out source | 820 | * widget connections regarding the SPDIF out source |
820 | */ | 821 | */ |
821 | static struct nid_path fake_paths[4] = { | 822 | static struct nid_path fake_paths[4] = { |
822 | { | 823 | { |
823 | .depth = 3, | 824 | .depth = 3, |
824 | .path = { 0x02, 0x1d, 0x1b }, | 825 | .path = { 0x02, 0x1d, 0x1b }, |
825 | .idx = { 0, 0, 0 }, | 826 | .idx = { 0, 0, 0 }, |
826 | .multi = { 0, 0, 0 }, | 827 | .multi = { 0, 0, 0 }, |
827 | }, | 828 | }, |
828 | { | 829 | { |
829 | .depth = 4, | 830 | .depth = 4, |
830 | .path = { 0x08, 0x0b, 0x1d, 0x1b }, | 831 | .path = { 0x08, 0x0b, 0x1d, 0x1b }, |
831 | .idx = { 0, 0, 1, 0 }, | 832 | .idx = { 0, 0, 1, 0 }, |
832 | .multi = { 0, 1, 0, 0 }, | 833 | .multi = { 0, 1, 0, 0 }, |
833 | }, | 834 | }, |
834 | { | 835 | { |
835 | .depth = 4, | 836 | .depth = 4, |
836 | .path = { 0x09, 0x0b, 0x1d, 0x1b }, | 837 | .path = { 0x09, 0x0b, 0x1d, 0x1b }, |
837 | .idx = { 0, 1, 1, 0 }, | 838 | .idx = { 0, 1, 1, 0 }, |
838 | .multi = { 0, 1, 0, 0 }, | 839 | .multi = { 0, 1, 0, 0 }, |
839 | }, | 840 | }, |
840 | { | 841 | { |
841 | .depth = 4, | 842 | .depth = 4, |
842 | .path = { 0x0f, 0x0b, 0x1d, 0x1b }, | 843 | .path = { 0x0f, 0x0b, 0x1d, 0x1b }, |
843 | .idx = { 0, 2, 1, 0 }, | 844 | .idx = { 0, 2, 1, 0 }, |
844 | .multi = { 0, 1, 0, 0 }, | 845 | .multi = { 0, 1, 0, 0 }, |
845 | }, | 846 | }, |
846 | }; | 847 | }; |
847 | 848 | ||
848 | /* SPDIF source mux appears to be present only on AD1988A */ | 849 | /* SPDIF source mux appears to be present only on AD1988A */ |
849 | if (!spec->gen.autocfg.dig_outs || | 850 | if (!spec->gen.autocfg.dig_outs || |
850 | get_wcaps_type(get_wcaps(codec, 0x1d)) != AC_WID_AUD_MIX) | 851 | get_wcaps_type(get_wcaps(codec, 0x1d)) != AC_WID_AUD_MIX) |
851 | return 0; | 852 | return 0; |
852 | 853 | ||
853 | num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1; | 854 | num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1; |
854 | if (num_conns != 3 && num_conns != 4) | 855 | if (num_conns != 3 && num_conns != 4) |
855 | return 0; | 856 | return 0; |
856 | 857 | ||
857 | for (i = 0; i < num_conns; i++) { | 858 | for (i = 0; i < num_conns; i++) { |
858 | struct nid_path *path = snd_array_new(&spec->gen.paths); | 859 | struct nid_path *path = snd_array_new(&spec->gen.paths); |
859 | if (!path) | 860 | if (!path) |
860 | return -ENOMEM; | 861 | return -ENOMEM; |
861 | *path = fake_paths[i]; | 862 | *path = fake_paths[i]; |
862 | if (!i) | 863 | if (!i) |
863 | path->active = 1; | 864 | path->active = 1; |
864 | spec->smux_paths[i] = snd_hda_get_path_idx(codec, path); | 865 | spec->smux_paths[i] = snd_hda_get_path_idx(codec, path); |
865 | } | 866 | } |
866 | 867 | ||
867 | if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &ad1988_auto_smux_mixer)) | 868 | if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &ad1988_auto_smux_mixer)) |
868 | return -ENOMEM; | 869 | return -ENOMEM; |
869 | 870 | ||
870 | codec->patch_ops.init = ad1988_auto_init; | 871 | codec->patch_ops.init = ad1988_auto_init; |
871 | 872 | ||
872 | return 0; | 873 | return 0; |
873 | } | 874 | } |
874 | 875 | ||
875 | /* | 876 | /* |
876 | */ | 877 | */ |
877 | 878 | ||
878 | enum { | 879 | enum { |
879 | AD1988_FIXUP_6STACK_DIG, | 880 | AD1988_FIXUP_6STACK_DIG, |
880 | }; | 881 | }; |
881 | 882 | ||
882 | static const struct hda_fixup ad1988_fixups[] = { | 883 | static const struct hda_fixup ad1988_fixups[] = { |
883 | [AD1988_FIXUP_6STACK_DIG] = { | 884 | [AD1988_FIXUP_6STACK_DIG] = { |
884 | .type = HDA_FIXUP_PINS, | 885 | .type = HDA_FIXUP_PINS, |
885 | .v.pins = (const struct hda_pintbl[]) { | 886 | .v.pins = (const struct hda_pintbl[]) { |
886 | { 0x11, 0x02214130 }, /* front-hp */ | 887 | { 0x11, 0x02214130 }, /* front-hp */ |
887 | { 0x12, 0x01014010 }, /* line-out */ | 888 | { 0x12, 0x01014010 }, /* line-out */ |
888 | { 0x14, 0x02a19122 }, /* front-mic */ | 889 | { 0x14, 0x02a19122 }, /* front-mic */ |
889 | { 0x15, 0x01813021 }, /* line-in */ | 890 | { 0x15, 0x01813021 }, /* line-in */ |
890 | { 0x16, 0x01011012 }, /* line-out */ | 891 | { 0x16, 0x01011012 }, /* line-out */ |
891 | { 0x17, 0x01a19020 }, /* mic */ | 892 | { 0x17, 0x01a19020 }, /* mic */ |
892 | { 0x1b, 0x0145f1f0 }, /* SPDIF */ | 893 | { 0x1b, 0x0145f1f0 }, /* SPDIF */ |
893 | { 0x24, 0x01016011 }, /* line-out */ | 894 | { 0x24, 0x01016011 }, /* line-out */ |
894 | { 0x25, 0x01012013 }, /* line-out */ | 895 | { 0x25, 0x01012013 }, /* line-out */ |
895 | { } | 896 | { } |
896 | } | 897 | } |
897 | }, | 898 | }, |
898 | }; | 899 | }; |
899 | 900 | ||
900 | static const struct hda_model_fixup ad1988_fixup_models[] = { | 901 | static const struct hda_model_fixup ad1988_fixup_models[] = { |
901 | { .id = AD1988_FIXUP_6STACK_DIG, .name = "6stack-dig" }, | 902 | { .id = AD1988_FIXUP_6STACK_DIG, .name = "6stack-dig" }, |
902 | {} | 903 | {} |
903 | }; | 904 | }; |
904 | 905 | ||
905 | static int patch_ad1988(struct hda_codec *codec) | 906 | static int patch_ad1988(struct hda_codec *codec) |
906 | { | 907 | { |
907 | struct ad198x_spec *spec; | 908 | struct ad198x_spec *spec; |
908 | int err; | 909 | int err; |
909 | 910 | ||
910 | err = alloc_ad_spec(codec); | 911 | err = alloc_ad_spec(codec); |
911 | if (err < 0) | 912 | if (err < 0) |
912 | return err; | 913 | return err; |
913 | spec = codec->spec; | 914 | spec = codec->spec; |
914 | 915 | ||
915 | spec->gen.mixer_nid = 0x20; | 916 | spec->gen.mixer_nid = 0x20; |
916 | spec->gen.mixer_merge_nid = 0x21; | 917 | spec->gen.mixer_merge_nid = 0x21; |
917 | spec->gen.beep_nid = 0x10; | 918 | spec->gen.beep_nid = 0x10; |
918 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); | 919 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); |
919 | 920 | ||
920 | snd_hda_pick_fixup(codec, ad1988_fixup_models, NULL, ad1988_fixups); | 921 | snd_hda_pick_fixup(codec, ad1988_fixup_models, NULL, ad1988_fixups); |
921 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 922 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
922 | 923 | ||
923 | err = ad198x_parse_auto_config(codec, true); | 924 | err = ad198x_parse_auto_config(codec, true); |
924 | if (err < 0) | 925 | if (err < 0) |
925 | goto error; | 926 | goto error; |
926 | err = ad1988_add_spdif_mux_ctl(codec); | 927 | err = ad1988_add_spdif_mux_ctl(codec); |
927 | if (err < 0) | 928 | if (err < 0) |
928 | goto error; | 929 | goto error; |
929 | 930 | ||
930 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 931 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
931 | 932 | ||
932 | return 0; | 933 | return 0; |
933 | 934 | ||
934 | error: | 935 | error: |
935 | snd_hda_gen_free(codec); | 936 | snd_hda_gen_free(codec); |
936 | return err; | 937 | return err; |
937 | } | 938 | } |
938 | 939 | ||
939 | 940 | ||
940 | /* | 941 | /* |
941 | * AD1884 / AD1984 | 942 | * AD1884 / AD1984 |
942 | * | 943 | * |
943 | * port-B - front line/mic-in | 944 | * port-B - front line/mic-in |
944 | * port-E - aux in/out | 945 | * port-E - aux in/out |
945 | * port-F - aux in/out | 946 | * port-F - aux in/out |
946 | * port-C - rear line/mic-in | 947 | * port-C - rear line/mic-in |
947 | * port-D - rear line/hp-out | 948 | * port-D - rear line/hp-out |
948 | * port-A - front line/hp-out | 949 | * port-A - front line/hp-out |
949 | * | 950 | * |
950 | * AD1984 = AD1884 + two digital mic-ins | 951 | * AD1984 = AD1884 + two digital mic-ins |
951 | * | 952 | * |
952 | * AD1883 / AD1884A / AD1984A / AD1984B | 953 | * AD1883 / AD1884A / AD1984A / AD1984B |
953 | * | 954 | * |
954 | * port-B (0x14) - front mic-in | 955 | * port-B (0x14) - front mic-in |
955 | * port-E (0x1c) - rear mic-in | 956 | * port-E (0x1c) - rear mic-in |
956 | * port-F (0x16) - CD / ext out | 957 | * port-F (0x16) - CD / ext out |
957 | * port-C (0x15) - rear line-in | 958 | * port-C (0x15) - rear line-in |
958 | * port-D (0x12) - rear line-out | 959 | * port-D (0x12) - rear line-out |
959 | * port-A (0x11) - front hp-out | 960 | * port-A (0x11) - front hp-out |
960 | * | 961 | * |
961 | * AD1984A = AD1884A + digital-mic | 962 | * AD1984A = AD1884A + digital-mic |
962 | * AD1883 = equivalent with AD1984A | 963 | * AD1883 = equivalent with AD1984A |
963 | * AD1984B = AD1984A + extra SPDIF-out | 964 | * AD1984B = AD1984A + extra SPDIF-out |
964 | */ | 965 | */ |
965 | 966 | ||
966 | /* set the upper-limit for mixer amp to 0dB for avoiding the possible | 967 | /* set the upper-limit for mixer amp to 0dB for avoiding the possible |
967 | * damage by overloading | 968 | * damage by overloading |
968 | */ | 969 | */ |
969 | static void ad1884_fixup_amp_override(struct hda_codec *codec, | 970 | static void ad1884_fixup_amp_override(struct hda_codec *codec, |
970 | const struct hda_fixup *fix, int action) | 971 | const struct hda_fixup *fix, int action) |
971 | { | 972 | { |
972 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | 973 | if (action == HDA_FIXUP_ACT_PRE_PROBE) |
973 | snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT, | 974 | snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT, |
974 | (0x17 << AC_AMPCAP_OFFSET_SHIFT) | | 975 | (0x17 << AC_AMPCAP_OFFSET_SHIFT) | |
975 | (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | | 976 | (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | |
976 | (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | | 977 | (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | |
977 | (1 << AC_AMPCAP_MUTE_SHIFT)); | 978 | (1 << AC_AMPCAP_MUTE_SHIFT)); |
978 | } | 979 | } |
979 | 980 | ||
980 | /* toggle GPIO1 according to the mute state */ | 981 | /* toggle GPIO1 according to the mute state */ |
981 | static void ad1884_vmaster_hp_gpio_hook(void *private_data, int enabled) | 982 | static void ad1884_vmaster_hp_gpio_hook(void *private_data, int enabled) |
982 | { | 983 | { |
983 | struct hda_codec *codec = private_data; | 984 | struct hda_codec *codec = private_data; |
984 | struct ad198x_spec *spec = codec->spec; | 985 | struct ad198x_spec *spec = codec->spec; |
985 | 986 | ||
986 | if (spec->eapd_nid) | 987 | if (spec->eapd_nid) |
987 | ad_vmaster_eapd_hook(private_data, enabled); | 988 | ad_vmaster_eapd_hook(private_data, enabled); |
988 | snd_hda_codec_update_cache(codec, 0x01, 0, | 989 | snd_hda_codec_update_cache(codec, 0x01, 0, |
989 | AC_VERB_SET_GPIO_DATA, | 990 | AC_VERB_SET_GPIO_DATA, |
990 | enabled ? 0x00 : 0x02); | 991 | enabled ? 0x00 : 0x02); |
991 | } | 992 | } |
992 | 993 | ||
993 | static void ad1884_fixup_hp_eapd(struct hda_codec *codec, | 994 | static void ad1884_fixup_hp_eapd(struct hda_codec *codec, |
994 | const struct hda_fixup *fix, int action) | 995 | const struct hda_fixup *fix, int action) |
995 | { | 996 | { |
996 | struct ad198x_spec *spec = codec->spec; | 997 | struct ad198x_spec *spec = codec->spec; |
997 | static const struct hda_verb gpio_init_verbs[] = { | 998 | static const struct hda_verb gpio_init_verbs[] = { |
998 | {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, | 999 | {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, |
999 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, | 1000 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, |
1000 | {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, | 1001 | {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, |
1001 | {}, | 1002 | {}, |
1002 | }; | 1003 | }; |
1003 | 1004 | ||
1004 | switch (action) { | 1005 | switch (action) { |
1005 | case HDA_FIXUP_ACT_PRE_PROBE: | 1006 | case HDA_FIXUP_ACT_PRE_PROBE: |
1006 | spec->gen.vmaster_mute.hook = ad1884_vmaster_hp_gpio_hook; | 1007 | spec->gen.vmaster_mute.hook = ad1884_vmaster_hp_gpio_hook; |
1007 | spec->gen.own_eapd_ctl = 1; | 1008 | spec->gen.own_eapd_ctl = 1; |
1008 | snd_hda_sequence_write_cache(codec, gpio_init_verbs); | 1009 | snd_hda_sequence_write_cache(codec, gpio_init_verbs); |
1009 | break; | 1010 | break; |
1010 | case HDA_FIXUP_ACT_PROBE: | 1011 | case HDA_FIXUP_ACT_PROBE: |
1011 | if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) | 1012 | if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) |
1012 | spec->eapd_nid = spec->gen.autocfg.line_out_pins[0]; | 1013 | spec->eapd_nid = spec->gen.autocfg.line_out_pins[0]; |
1013 | else | 1014 | else |
1014 | spec->eapd_nid = spec->gen.autocfg.speaker_pins[0]; | 1015 | spec->eapd_nid = spec->gen.autocfg.speaker_pins[0]; |
1015 | break; | 1016 | break; |
1016 | } | 1017 | } |
1017 | } | 1018 | } |
1018 | 1019 | ||
1019 | static void ad1884_fixup_thinkpad(struct hda_codec *codec, | 1020 | static void ad1884_fixup_thinkpad(struct hda_codec *codec, |
1020 | const struct hda_fixup *fix, int action) | 1021 | const struct hda_fixup *fix, int action) |
1021 | { | 1022 | { |
1022 | struct ad198x_spec *spec = codec->spec; | 1023 | struct ad198x_spec *spec = codec->spec; |
1023 | 1024 | ||
1024 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 1025 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
1025 | spec->gen.keep_eapd_on = 1; | 1026 | spec->gen.keep_eapd_on = 1; |
1026 | spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook; | 1027 | spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook; |
1027 | spec->eapd_nid = 0x12; | 1028 | spec->eapd_nid = 0x12; |
1028 | /* Analog PC Beeper - allow firmware/ACPI beeps */ | 1029 | /* Analog PC Beeper - allow firmware/ACPI beeps */ |
1029 | spec->beep_amp = HDA_COMPOSE_AMP_VAL(0x20, 3, 3, HDA_INPUT); | 1030 | spec->beep_amp = HDA_COMPOSE_AMP_VAL(0x20, 3, 3, HDA_INPUT); |
1030 | spec->gen.beep_nid = 0; /* no digital beep */ | 1031 | spec->gen.beep_nid = 0; /* no digital beep */ |
1031 | } | 1032 | } |
1032 | } | 1033 | } |
1033 | 1034 | ||
1034 | /* set magic COEFs for dmic */ | 1035 | /* set magic COEFs for dmic */ |
1035 | static const struct hda_verb ad1884_dmic_init_verbs[] = { | 1036 | static const struct hda_verb ad1884_dmic_init_verbs[] = { |
1036 | {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7}, | 1037 | {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7}, |
1037 | {0x01, AC_VERB_SET_PROC_COEF, 0x08}, | 1038 | {0x01, AC_VERB_SET_PROC_COEF, 0x08}, |
1038 | {} | 1039 | {} |
1039 | }; | 1040 | }; |
1040 | 1041 | ||
1041 | enum { | 1042 | enum { |
1042 | AD1884_FIXUP_AMP_OVERRIDE, | 1043 | AD1884_FIXUP_AMP_OVERRIDE, |
1043 | AD1884_FIXUP_HP_EAPD, | 1044 | AD1884_FIXUP_HP_EAPD, |
1044 | AD1884_FIXUP_DMIC_COEF, | 1045 | AD1884_FIXUP_DMIC_COEF, |
1045 | AD1884_FIXUP_THINKPAD, | 1046 | AD1884_FIXUP_THINKPAD, |
1046 | AD1884_FIXUP_HP_TOUCHSMART, | 1047 | AD1884_FIXUP_HP_TOUCHSMART, |
1047 | }; | 1048 | }; |
1048 | 1049 | ||
1049 | static const struct hda_fixup ad1884_fixups[] = { | 1050 | static const struct hda_fixup ad1884_fixups[] = { |
1050 | [AD1884_FIXUP_AMP_OVERRIDE] = { | 1051 | [AD1884_FIXUP_AMP_OVERRIDE] = { |
1051 | .type = HDA_FIXUP_FUNC, | 1052 | .type = HDA_FIXUP_FUNC, |
1052 | .v.func = ad1884_fixup_amp_override, | 1053 | .v.func = ad1884_fixup_amp_override, |
1053 | }, | 1054 | }, |
1054 | [AD1884_FIXUP_HP_EAPD] = { | 1055 | [AD1884_FIXUP_HP_EAPD] = { |
1055 | .type = HDA_FIXUP_FUNC, | 1056 | .type = HDA_FIXUP_FUNC, |
1056 | .v.func = ad1884_fixup_hp_eapd, | 1057 | .v.func = ad1884_fixup_hp_eapd, |
1057 | .chained = true, | 1058 | .chained = true, |
1058 | .chain_id = AD1884_FIXUP_AMP_OVERRIDE, | 1059 | .chain_id = AD1884_FIXUP_AMP_OVERRIDE, |
1059 | }, | 1060 | }, |
1060 | [AD1884_FIXUP_DMIC_COEF] = { | 1061 | [AD1884_FIXUP_DMIC_COEF] = { |
1061 | .type = HDA_FIXUP_VERBS, | 1062 | .type = HDA_FIXUP_VERBS, |
1062 | .v.verbs = ad1884_dmic_init_verbs, | 1063 | .v.verbs = ad1884_dmic_init_verbs, |
1063 | }, | 1064 | }, |
1064 | [AD1884_FIXUP_THINKPAD] = { | 1065 | [AD1884_FIXUP_THINKPAD] = { |
1065 | .type = HDA_FIXUP_FUNC, | 1066 | .type = HDA_FIXUP_FUNC, |
1066 | .v.func = ad1884_fixup_thinkpad, | 1067 | .v.func = ad1884_fixup_thinkpad, |
1067 | .chained = true, | 1068 | .chained = true, |
1068 | .chain_id = AD1884_FIXUP_DMIC_COEF, | 1069 | .chain_id = AD1884_FIXUP_DMIC_COEF, |
1069 | }, | 1070 | }, |
1070 | [AD1884_FIXUP_HP_TOUCHSMART] = { | 1071 | [AD1884_FIXUP_HP_TOUCHSMART] = { |
1071 | .type = HDA_FIXUP_VERBS, | 1072 | .type = HDA_FIXUP_VERBS, |
1072 | .v.verbs = ad1884_dmic_init_verbs, | 1073 | .v.verbs = ad1884_dmic_init_verbs, |
1073 | .chained = true, | 1074 | .chained = true, |
1074 | .chain_id = AD1884_FIXUP_HP_EAPD, | 1075 | .chain_id = AD1884_FIXUP_HP_EAPD, |
1075 | }, | 1076 | }, |
1076 | }; | 1077 | }; |
1077 | 1078 | ||
1078 | static const struct snd_pci_quirk ad1884_fixup_tbl[] = { | 1079 | static const struct snd_pci_quirk ad1884_fixup_tbl[] = { |
1079 | SND_PCI_QUIRK(0x103c, 0x2a82, "HP Touchsmart", AD1884_FIXUP_HP_TOUCHSMART), | 1080 | SND_PCI_QUIRK(0x103c, 0x2a82, "HP Touchsmart", AD1884_FIXUP_HP_TOUCHSMART), |
1080 | SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1884_FIXUP_HP_EAPD), | 1081 | SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1884_FIXUP_HP_EAPD), |
1081 | SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1884_FIXUP_THINKPAD), | 1082 | SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1884_FIXUP_THINKPAD), |
1082 | {} | 1083 | {} |
1083 | }; | 1084 | }; |
1084 | 1085 | ||
1085 | 1086 | ||
1086 | static int patch_ad1884(struct hda_codec *codec) | 1087 | static int patch_ad1884(struct hda_codec *codec) |
1087 | { | 1088 | { |
1088 | struct ad198x_spec *spec; | 1089 | struct ad198x_spec *spec; |
1089 | int err; | 1090 | int err; |
1090 | 1091 | ||
1091 | err = alloc_ad_spec(codec); | 1092 | err = alloc_ad_spec(codec); |
1092 | if (err < 0) | 1093 | if (err < 0) |
1093 | return err; | 1094 | return err; |
1094 | spec = codec->spec; | 1095 | spec = codec->spec; |
1095 | 1096 | ||
1096 | spec->gen.mixer_nid = 0x20; | 1097 | spec->gen.mixer_nid = 0x20; |
1097 | spec->gen.mixer_merge_nid = 0x21; | 1098 | spec->gen.mixer_merge_nid = 0x21; |
1098 | spec->gen.beep_nid = 0x10; | 1099 | spec->gen.beep_nid = 0x10; |
1099 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); | 1100 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); |
1100 | 1101 | ||
1101 | snd_hda_pick_fixup(codec, NULL, ad1884_fixup_tbl, ad1884_fixups); | 1102 | snd_hda_pick_fixup(codec, NULL, ad1884_fixup_tbl, ad1884_fixups); |
1102 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 1103 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
1103 | 1104 | ||
1104 | err = ad198x_parse_auto_config(codec, true); | 1105 | err = ad198x_parse_auto_config(codec, true); |
1105 | if (err < 0) | 1106 | if (err < 0) |
1106 | goto error; | 1107 | goto error; |
1107 | err = ad1983_add_spdif_mux_ctl(codec); | 1108 | err = ad1983_add_spdif_mux_ctl(codec); |
1108 | if (err < 0) | 1109 | if (err < 0) |
1109 | goto error; | 1110 | goto error; |
1110 | 1111 | ||
1111 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 1112 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
1112 | 1113 | ||
1113 | return 0; | 1114 | return 0; |
1114 | 1115 | ||
1115 | error: | 1116 | error: |
1116 | snd_hda_gen_free(codec); | 1117 | snd_hda_gen_free(codec); |
1117 | return err; | 1118 | return err; |
1118 | } | 1119 | } |
1119 | 1120 | ||
1120 | /* | 1121 | /* |
1121 | * AD1882 / AD1882A | 1122 | * AD1882 / AD1882A |
1122 | * | 1123 | * |
1123 | * port-A - front hp-out | 1124 | * port-A - front hp-out |
1124 | * port-B - front mic-in | 1125 | * port-B - front mic-in |
1125 | * port-C - rear line-in, shared surr-out (3stack) | 1126 | * port-C - rear line-in, shared surr-out (3stack) |
1126 | * port-D - rear line-out | 1127 | * port-D - rear line-out |
1127 | * port-E - rear mic-in, shared clfe-out (3stack) | 1128 | * port-E - rear mic-in, shared clfe-out (3stack) |
1128 | * port-F - rear surr-out (6stack) | 1129 | * port-F - rear surr-out (6stack) |
1129 | * port-G - rear clfe-out (6stack) | 1130 | * port-G - rear clfe-out (6stack) |
1130 | */ | 1131 | */ |
1131 | 1132 | ||
1132 | static int patch_ad1882(struct hda_codec *codec) | 1133 | static int patch_ad1882(struct hda_codec *codec) |
1133 | { | 1134 | { |
1134 | struct ad198x_spec *spec; | 1135 | struct ad198x_spec *spec; |
1135 | int err; | 1136 | int err; |
1136 | 1137 | ||
1137 | err = alloc_ad_spec(codec); | 1138 | err = alloc_ad_spec(codec); |
1138 | if (err < 0) | 1139 | if (err < 0) |
1139 | return err; | 1140 | return err; |
1140 | spec = codec->spec; | 1141 | spec = codec->spec; |
1141 | 1142 | ||
1142 | spec->gen.mixer_nid = 0x20; | 1143 | spec->gen.mixer_nid = 0x20; |
1143 | spec->gen.mixer_merge_nid = 0x21; | 1144 | spec->gen.mixer_merge_nid = 0x21; |
1144 | spec->gen.beep_nid = 0x10; | 1145 | spec->gen.beep_nid = 0x10; |
1145 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); | 1146 | set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); |
1146 | err = ad198x_parse_auto_config(codec, true); | 1147 | err = ad198x_parse_auto_config(codec, true); |
1147 | if (err < 0) | 1148 | if (err < 0) |
1148 | goto error; | 1149 | goto error; |
1149 | err = ad1988_add_spdif_mux_ctl(codec); | 1150 | err = ad1988_add_spdif_mux_ctl(codec); |
1150 | if (err < 0) | 1151 | if (err < 0) |
1151 | goto error; | 1152 | goto error; |
1152 | return 0; | 1153 | return 0; |
1153 | 1154 | ||
1154 | error: | 1155 | error: |
1155 | snd_hda_gen_free(codec); | 1156 | snd_hda_gen_free(codec); |
1156 | return err; | 1157 | return err; |
1157 | } | 1158 | } |
1158 | 1159 | ||
1159 | 1160 | ||
1160 | /* | 1161 | /* |
1161 | * patch entries | 1162 | * patch entries |
1162 | */ | 1163 | */ |
1163 | static const struct hda_codec_preset snd_hda_preset_analog[] = { | 1164 | static const struct hda_codec_preset snd_hda_preset_analog[] = { |
1164 | { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884 }, | 1165 | { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884 }, |
1165 | { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 }, | 1166 | { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 }, |
1166 | { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884 }, | 1167 | { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884 }, |
1167 | { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 }, | 1168 | { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 }, |
1168 | { .id = 0x11d4194a, .name = "AD1984A", .patch = patch_ad1884 }, | 1169 | { .id = 0x11d4194a, .name = "AD1984A", .patch = patch_ad1884 }, |
1169 | { .id = 0x11d4194b, .name = "AD1984B", .patch = patch_ad1884 }, | 1170 | { .id = 0x11d4194b, .name = "AD1984B", .patch = patch_ad1884 }, |
1170 | { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 }, | 1171 | { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 }, |
1171 | { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 }, | 1172 | { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 }, |
1172 | { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1884 }, | 1173 | { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1884 }, |
1173 | { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a }, | 1174 | { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a }, |
1174 | { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 }, | 1175 | { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 }, |
1175 | { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 }, | 1176 | { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 }, |
1176 | { .id = 0x11d4882a, .name = "AD1882A", .patch = patch_ad1882 }, | 1177 | { .id = 0x11d4882a, .name = "AD1882A", .patch = patch_ad1882 }, |
1177 | { .id = 0x11d4989a, .name = "AD1989A", .patch = patch_ad1988 }, | 1178 | { .id = 0x11d4989a, .name = "AD1989A", .patch = patch_ad1988 }, |
1178 | { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 }, | 1179 | { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 }, |
1179 | {} /* terminator */ | 1180 | {} /* terminator */ |
1180 | }; | 1181 | }; |
1181 | 1182 | ||
1182 | MODULE_ALIAS("snd-hda-codec-id:11d4*"); | 1183 | MODULE_ALIAS("snd-hda-codec-id:11d4*"); |
1183 | 1184 | ||
1184 | MODULE_LICENSE("GPL"); | 1185 | MODULE_LICENSE("GPL"); |
1185 | MODULE_DESCRIPTION("Analog Devices HD-audio codec"); | 1186 | MODULE_DESCRIPTION("Analog Devices HD-audio codec"); |
1186 | 1187 | ||
1187 | static struct hda_codec_preset_list analog_list = { | 1188 | static struct hda_codec_preset_list analog_list = { |
1188 | .preset = snd_hda_preset_analog, | 1189 | .preset = snd_hda_preset_analog, |
1189 | .owner = THIS_MODULE, | 1190 | .owner = THIS_MODULE, |
1190 | }; | 1191 | }; |
1191 | 1192 | ||
1192 | static int __init patch_analog_init(void) | 1193 | static int __init patch_analog_init(void) |
1193 | { | 1194 | { |
1194 | return snd_hda_add_codec_preset(&analog_list); | 1195 | return snd_hda_add_codec_preset(&analog_list); |
1195 | } | 1196 | } |
1196 | 1197 | ||
1197 | static void __exit patch_analog_exit(void) | 1198 | static void __exit patch_analog_exit(void) |
1198 | { | 1199 | { |
1199 | snd_hda_delete_codec_preset(&analog_list); | 1200 | snd_hda_delete_codec_preset(&analog_list); |
1200 | } | 1201 | } |
1201 | 1202 | ||
1202 | module_init(patch_analog_init) | 1203 | module_init(patch_analog_init) |
1203 | module_exit(patch_analog_exit) | 1204 | module_exit(patch_analog_exit) |
1204 | 1205 |
sound/pci/hda/patch_realtek.c
1 | /* | 1 | /* |
2 | * Universal Interface for Intel High Definition Audio Codec | 2 | * Universal Interface for Intel High Definition Audio Codec |
3 | * | 3 | * |
4 | * HD audio interface patch for Realtek ALC codecs | 4 | * HD audio interface patch for Realtek ALC codecs |
5 | * | 5 | * |
6 | * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw> | 6 | * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw> |
7 | * PeiSen Hou <pshou@realtek.com.tw> | 7 | * PeiSen Hou <pshou@realtek.com.tw> |
8 | * Takashi Iwai <tiwai@suse.de> | 8 | * Takashi Iwai <tiwai@suse.de> |
9 | * Jonathan Woithe <jwoithe@just42.net> | 9 | * Jonathan Woithe <jwoithe@just42.net> |
10 | * | 10 | * |
11 | * This driver is free software; you can redistribute it and/or modify | 11 | * This driver is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License as published by | 12 | * it under the terms of the GNU General Public License as published by |
13 | * the Free Software Foundation; either version 2 of the License, or | 13 | * the Free Software Foundation; either version 2 of the License, or |
14 | * (at your option) any later version. | 14 | * (at your option) any later version. |
15 | * | 15 | * |
16 | * This driver is distributed in the hope that it will be useful, | 16 | * This driver is distributed in the hope that it will be useful, |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 | * GNU General Public License for more details. | 19 | * GNU General Public License for more details. |
20 | * | 20 | * |
21 | * You should have received a copy of the GNU General Public License | 21 | * You should have received a copy of the GNU General Public License |
22 | * along with this program; if not, write to the Free Software | 22 | * along with this program; if not, write to the Free Software |
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/pci.h> | 29 | #include <linux/pci.h> |
30 | #include <linux/dmi.h> | 30 | #include <linux/dmi.h> |
31 | #include <linux/module.h> | 31 | #include <linux/module.h> |
32 | #include <sound/core.h> | 32 | #include <sound/core.h> |
33 | #include <sound/jack.h> | 33 | #include <sound/jack.h> |
34 | #include "hda_codec.h" | 34 | #include "hda_codec.h" |
35 | #include "hda_local.h" | 35 | #include "hda_local.h" |
36 | #include "hda_auto_parser.h" | 36 | #include "hda_auto_parser.h" |
37 | #include "hda_jack.h" | 37 | #include "hda_jack.h" |
38 | #include "hda_generic.h" | 38 | #include "hda_generic.h" |
39 | 39 | ||
40 | /* keep halting ALC5505 DSP, for power saving */ | 40 | /* keep halting ALC5505 DSP, for power saving */ |
41 | #define HALT_REALTEK_ALC5505 | 41 | #define HALT_REALTEK_ALC5505 |
42 | 42 | ||
43 | /* unsol event tags */ | 43 | /* unsol event tags */ |
44 | #define ALC_DCVOL_EVENT 0x08 | 44 | #define ALC_DCVOL_EVENT 0x08 |
45 | 45 | ||
46 | /* for GPIO Poll */ | 46 | /* for GPIO Poll */ |
47 | #define GPIO_MASK 0x03 | 47 | #define GPIO_MASK 0x03 |
48 | 48 | ||
49 | /* extra amp-initialization sequence types */ | 49 | /* extra amp-initialization sequence types */ |
50 | enum { | 50 | enum { |
51 | ALC_INIT_NONE, | 51 | ALC_INIT_NONE, |
52 | ALC_INIT_DEFAULT, | 52 | ALC_INIT_DEFAULT, |
53 | ALC_INIT_GPIO1, | 53 | ALC_INIT_GPIO1, |
54 | ALC_INIT_GPIO2, | 54 | ALC_INIT_GPIO2, |
55 | ALC_INIT_GPIO3, | 55 | ALC_INIT_GPIO3, |
56 | }; | 56 | }; |
57 | 57 | ||
58 | enum { | 58 | enum { |
59 | ALC_HEADSET_MODE_UNKNOWN, | 59 | ALC_HEADSET_MODE_UNKNOWN, |
60 | ALC_HEADSET_MODE_UNPLUGGED, | 60 | ALC_HEADSET_MODE_UNPLUGGED, |
61 | ALC_HEADSET_MODE_HEADSET, | 61 | ALC_HEADSET_MODE_HEADSET, |
62 | ALC_HEADSET_MODE_MIC, | 62 | ALC_HEADSET_MODE_MIC, |
63 | ALC_HEADSET_MODE_HEADPHONE, | 63 | ALC_HEADSET_MODE_HEADPHONE, |
64 | }; | 64 | }; |
65 | 65 | ||
66 | enum { | 66 | enum { |
67 | ALC_HEADSET_TYPE_UNKNOWN, | 67 | ALC_HEADSET_TYPE_UNKNOWN, |
68 | ALC_HEADSET_TYPE_CTIA, | 68 | ALC_HEADSET_TYPE_CTIA, |
69 | ALC_HEADSET_TYPE_OMTP, | 69 | ALC_HEADSET_TYPE_OMTP, |
70 | }; | 70 | }; |
71 | 71 | ||
72 | struct alc_customize_define { | 72 | struct alc_customize_define { |
73 | unsigned int sku_cfg; | 73 | unsigned int sku_cfg; |
74 | unsigned char port_connectivity; | 74 | unsigned char port_connectivity; |
75 | unsigned char check_sum; | 75 | unsigned char check_sum; |
76 | unsigned char customization; | 76 | unsigned char customization; |
77 | unsigned char external_amp; | 77 | unsigned char external_amp; |
78 | unsigned int enable_pcbeep:1; | 78 | unsigned int enable_pcbeep:1; |
79 | unsigned int platform_type:1; | 79 | unsigned int platform_type:1; |
80 | unsigned int swap:1; | 80 | unsigned int swap:1; |
81 | unsigned int override:1; | 81 | unsigned int override:1; |
82 | unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */ | 82 | unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */ |
83 | }; | 83 | }; |
84 | 84 | ||
85 | struct alc_spec { | 85 | struct alc_spec { |
86 | struct hda_gen_spec gen; /* must be at head */ | 86 | struct hda_gen_spec gen; /* must be at head */ |
87 | 87 | ||
88 | /* codec parameterization */ | 88 | /* codec parameterization */ |
89 | const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ | 89 | const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ |
90 | unsigned int num_mixers; | 90 | unsigned int num_mixers; |
91 | unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ | 91 | unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ |
92 | 92 | ||
93 | struct alc_customize_define cdefine; | 93 | struct alc_customize_define cdefine; |
94 | unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */ | 94 | unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */ |
95 | 95 | ||
96 | /* inverted dmic fix */ | 96 | /* inverted dmic fix */ |
97 | unsigned int inv_dmic_fixup:1; /* has inverted digital-mic workaround */ | 97 | unsigned int inv_dmic_fixup:1; /* has inverted digital-mic workaround */ |
98 | unsigned int inv_dmic_muted:1; /* R-ch of inv d-mic is muted? */ | 98 | unsigned int inv_dmic_muted:1; /* R-ch of inv d-mic is muted? */ |
99 | hda_nid_t inv_dmic_pin; | 99 | hda_nid_t inv_dmic_pin; |
100 | 100 | ||
101 | /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */ | 101 | /* mute LED for HP laptops, see alc269_fixup_mic_mute_hook() */ |
102 | int mute_led_polarity; | 102 | int mute_led_polarity; |
103 | hda_nid_t mute_led_nid; | 103 | hda_nid_t mute_led_nid; |
104 | 104 | ||
105 | unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */ | 105 | unsigned int gpio_led; /* used for alc269_fixup_hp_gpio_led() */ |
106 | 106 | ||
107 | hda_nid_t headset_mic_pin; | 107 | hda_nid_t headset_mic_pin; |
108 | hda_nid_t headphone_mic_pin; | 108 | hda_nid_t headphone_mic_pin; |
109 | int current_headset_mode; | 109 | int current_headset_mode; |
110 | int current_headset_type; | 110 | int current_headset_type; |
111 | 111 | ||
112 | /* hooks */ | 112 | /* hooks */ |
113 | void (*init_hook)(struct hda_codec *codec); | 113 | void (*init_hook)(struct hda_codec *codec); |
114 | #ifdef CONFIG_PM | 114 | #ifdef CONFIG_PM |
115 | void (*power_hook)(struct hda_codec *codec); | 115 | void (*power_hook)(struct hda_codec *codec); |
116 | #endif | 116 | #endif |
117 | void (*shutup)(struct hda_codec *codec); | 117 | void (*shutup)(struct hda_codec *codec); |
118 | 118 | ||
119 | int init_amp; | 119 | int init_amp; |
120 | int codec_variant; /* flag for other variants */ | 120 | int codec_variant; /* flag for other variants */ |
121 | unsigned int has_alc5505_dsp:1; | 121 | unsigned int has_alc5505_dsp:1; |
122 | unsigned int no_depop_delay:1; | 122 | unsigned int no_depop_delay:1; |
123 | 123 | ||
124 | /* for PLL fix */ | 124 | /* for PLL fix */ |
125 | hda_nid_t pll_nid; | 125 | hda_nid_t pll_nid; |
126 | unsigned int pll_coef_idx, pll_coef_bit; | 126 | unsigned int pll_coef_idx, pll_coef_bit; |
127 | unsigned int coef0; | 127 | unsigned int coef0; |
128 | }; | 128 | }; |
129 | 129 | ||
130 | /* | 130 | /* |
131 | * Append the given mixer and verb elements for the later use | 131 | * Append the given mixer and verb elements for the later use |
132 | * The mixer array is referred in build_controls(), and init_verbs are | 132 | * The mixer array is referred in build_controls(), and init_verbs are |
133 | * called in init(). | 133 | * called in init(). |
134 | */ | 134 | */ |
135 | static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix) | 135 | static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix) |
136 | { | 136 | { |
137 | if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers))) | 137 | if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers))) |
138 | return; | 138 | return; |
139 | spec->mixers[spec->num_mixers++] = mix; | 139 | spec->mixers[spec->num_mixers++] = mix; |
140 | } | 140 | } |
141 | 141 | ||
142 | /* | 142 | /* |
143 | * GPIO setup tables, used in initialization | 143 | * GPIO setup tables, used in initialization |
144 | */ | 144 | */ |
145 | /* Enable GPIO mask and set output */ | 145 | /* Enable GPIO mask and set output */ |
146 | static const struct hda_verb alc_gpio1_init_verbs[] = { | 146 | static const struct hda_verb alc_gpio1_init_verbs[] = { |
147 | {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, | 147 | {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, |
148 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | 148 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, |
149 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, | 149 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, |
150 | { } | 150 | { } |
151 | }; | 151 | }; |
152 | 152 | ||
153 | static const struct hda_verb alc_gpio2_init_verbs[] = { | 153 | static const struct hda_verb alc_gpio2_init_verbs[] = { |
154 | {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, | 154 | {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, |
155 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, | 155 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, |
156 | {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, | 156 | {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, |
157 | { } | 157 | { } |
158 | }; | 158 | }; |
159 | 159 | ||
160 | static const struct hda_verb alc_gpio3_init_verbs[] = { | 160 | static const struct hda_verb alc_gpio3_init_verbs[] = { |
161 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, | 161 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, |
162 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, | 162 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, |
163 | {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, | 163 | {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, |
164 | { } | 164 | { } |
165 | }; | 165 | }; |
166 | 166 | ||
167 | /* | 167 | /* |
168 | * Fix hardware PLL issue | 168 | * Fix hardware PLL issue |
169 | * On some codecs, the analog PLL gating control must be off while | 169 | * On some codecs, the analog PLL gating control must be off while |
170 | * the default value is 1. | 170 | * the default value is 1. |
171 | */ | 171 | */ |
172 | static void alc_fix_pll(struct hda_codec *codec) | 172 | static void alc_fix_pll(struct hda_codec *codec) |
173 | { | 173 | { |
174 | struct alc_spec *spec = codec->spec; | 174 | struct alc_spec *spec = codec->spec; |
175 | unsigned int val; | 175 | unsigned int val; |
176 | 176 | ||
177 | if (!spec->pll_nid) | 177 | if (!spec->pll_nid) |
178 | return; | 178 | return; |
179 | snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, | 179 | snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, |
180 | spec->pll_coef_idx); | 180 | spec->pll_coef_idx); |
181 | val = snd_hda_codec_read(codec, spec->pll_nid, 0, | 181 | val = snd_hda_codec_read(codec, spec->pll_nid, 0, |
182 | AC_VERB_GET_PROC_COEF, 0); | 182 | AC_VERB_GET_PROC_COEF, 0); |
183 | snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, | 183 | snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX, |
184 | spec->pll_coef_idx); | 184 | spec->pll_coef_idx); |
185 | snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, | 185 | snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF, |
186 | val & ~(1 << spec->pll_coef_bit)); | 186 | val & ~(1 << spec->pll_coef_bit)); |
187 | } | 187 | } |
188 | 188 | ||
189 | static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, | 189 | static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid, |
190 | unsigned int coef_idx, unsigned int coef_bit) | 190 | unsigned int coef_idx, unsigned int coef_bit) |
191 | { | 191 | { |
192 | struct alc_spec *spec = codec->spec; | 192 | struct alc_spec *spec = codec->spec; |
193 | spec->pll_nid = nid; | 193 | spec->pll_nid = nid; |
194 | spec->pll_coef_idx = coef_idx; | 194 | spec->pll_coef_idx = coef_idx; |
195 | spec->pll_coef_bit = coef_bit; | 195 | spec->pll_coef_bit = coef_bit; |
196 | alc_fix_pll(codec); | 196 | alc_fix_pll(codec); |
197 | } | 197 | } |
198 | 198 | ||
199 | /* update the master volume per volume-knob's unsol event */ | 199 | /* update the master volume per volume-knob's unsol event */ |
200 | static void alc_update_knob_master(struct hda_codec *codec, struct hda_jack_tbl *jack) | 200 | static void alc_update_knob_master(struct hda_codec *codec, struct hda_jack_tbl *jack) |
201 | { | 201 | { |
202 | unsigned int val; | 202 | unsigned int val; |
203 | struct snd_kcontrol *kctl; | 203 | struct snd_kcontrol *kctl; |
204 | struct snd_ctl_elem_value *uctl; | 204 | struct snd_ctl_elem_value *uctl; |
205 | 205 | ||
206 | kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume"); | 206 | kctl = snd_hda_find_mixer_ctl(codec, "Master Playback Volume"); |
207 | if (!kctl) | 207 | if (!kctl) |
208 | return; | 208 | return; |
209 | uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); | 209 | uctl = kzalloc(sizeof(*uctl), GFP_KERNEL); |
210 | if (!uctl) | 210 | if (!uctl) |
211 | return; | 211 | return; |
212 | val = snd_hda_codec_read(codec, jack->nid, 0, | 212 | val = snd_hda_codec_read(codec, jack->nid, 0, |
213 | AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); | 213 | AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); |
214 | val &= HDA_AMP_VOLMASK; | 214 | val &= HDA_AMP_VOLMASK; |
215 | uctl->value.integer.value[0] = val; | 215 | uctl->value.integer.value[0] = val; |
216 | uctl->value.integer.value[1] = val; | 216 | uctl->value.integer.value[1] = val; |
217 | kctl->put(kctl, uctl); | 217 | kctl->put(kctl, uctl); |
218 | kfree(uctl); | 218 | kfree(uctl); |
219 | } | 219 | } |
220 | 220 | ||
221 | static void alc880_unsol_event(struct hda_codec *codec, unsigned int res) | 221 | static void alc880_unsol_event(struct hda_codec *codec, unsigned int res) |
222 | { | 222 | { |
223 | /* For some reason, the res given from ALC880 is broken. | 223 | /* For some reason, the res given from ALC880 is broken. |
224 | Here we adjust it properly. */ | 224 | Here we adjust it properly. */ |
225 | snd_hda_jack_unsol_event(codec, res >> 2); | 225 | snd_hda_jack_unsol_event(codec, res >> 2); |
226 | } | 226 | } |
227 | 227 | ||
228 | /* additional initialization for ALC888 variants */ | 228 | /* additional initialization for ALC888 variants */ |
229 | static void alc888_coef_init(struct hda_codec *codec) | 229 | static void alc888_coef_init(struct hda_codec *codec) |
230 | { | 230 | { |
231 | unsigned int tmp; | 231 | unsigned int tmp; |
232 | 232 | ||
233 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0); | 233 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0); |
234 | tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); | 234 | tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); |
235 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); | 235 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); |
236 | if ((tmp & 0xf0) == 0x20) | 236 | if ((tmp & 0xf0) == 0x20) |
237 | /* alc888S-VC */ | 237 | /* alc888S-VC */ |
238 | snd_hda_codec_read(codec, 0x20, 0, | 238 | snd_hda_codec_read(codec, 0x20, 0, |
239 | AC_VERB_SET_PROC_COEF, 0x830); | 239 | AC_VERB_SET_PROC_COEF, 0x830); |
240 | else | 240 | else |
241 | /* alc888-VB */ | 241 | /* alc888-VB */ |
242 | snd_hda_codec_read(codec, 0x20, 0, | 242 | snd_hda_codec_read(codec, 0x20, 0, |
243 | AC_VERB_SET_PROC_COEF, 0x3030); | 243 | AC_VERB_SET_PROC_COEF, 0x3030); |
244 | } | 244 | } |
245 | 245 | ||
246 | /* additional initialization for ALC889 variants */ | 246 | /* additional initialization for ALC889 variants */ |
247 | static void alc889_coef_init(struct hda_codec *codec) | 247 | static void alc889_coef_init(struct hda_codec *codec) |
248 | { | 248 | { |
249 | unsigned int tmp; | 249 | unsigned int tmp; |
250 | 250 | ||
251 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); | 251 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); |
252 | tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); | 252 | tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); |
253 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); | 253 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7); |
254 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010); | 254 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010); |
255 | } | 255 | } |
256 | 256 | ||
257 | /* turn on/off EAPD control (only if available) */ | 257 | /* turn on/off EAPD control (only if available) */ |
258 | static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on) | 258 | static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on) |
259 | { | 259 | { |
260 | if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) | 260 | if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN) |
261 | return; | 261 | return; |
262 | if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD) | 262 | if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD) |
263 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, | 263 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE, |
264 | on ? 2 : 0); | 264 | on ? 2 : 0); |
265 | } | 265 | } |
266 | 266 | ||
267 | /* turn on/off EAPD controls of the codec */ | 267 | /* turn on/off EAPD controls of the codec */ |
268 | static void alc_auto_setup_eapd(struct hda_codec *codec, bool on) | 268 | static void alc_auto_setup_eapd(struct hda_codec *codec, bool on) |
269 | { | 269 | { |
270 | /* We currently only handle front, HP */ | 270 | /* We currently only handle front, HP */ |
271 | static hda_nid_t pins[] = { | 271 | static hda_nid_t pins[] = { |
272 | 0x0f, 0x10, 0x14, 0x15, 0 | 272 | 0x0f, 0x10, 0x14, 0x15, 0 |
273 | }; | 273 | }; |
274 | hda_nid_t *p; | 274 | hda_nid_t *p; |
275 | for (p = pins; *p; p++) | 275 | for (p = pins; *p; p++) |
276 | set_eapd(codec, *p, on); | 276 | set_eapd(codec, *p, on); |
277 | } | 277 | } |
278 | 278 | ||
279 | /* generic shutup callback; | 279 | /* generic shutup callback; |
280 | * just turning off EPAD and a little pause for avoiding pop-noise | 280 | * just turning off EPAD and a little pause for avoiding pop-noise |
281 | */ | 281 | */ |
282 | static void alc_eapd_shutup(struct hda_codec *codec) | 282 | static void alc_eapd_shutup(struct hda_codec *codec) |
283 | { | 283 | { |
284 | struct alc_spec *spec = codec->spec; | 284 | struct alc_spec *spec = codec->spec; |
285 | 285 | ||
286 | alc_auto_setup_eapd(codec, false); | 286 | alc_auto_setup_eapd(codec, false); |
287 | if (!spec->no_depop_delay) | 287 | if (!spec->no_depop_delay) |
288 | msleep(200); | 288 | msleep(200); |
289 | snd_hda_shutup_pins(codec); | 289 | snd_hda_shutup_pins(codec); |
290 | } | 290 | } |
291 | 291 | ||
292 | /* generic EAPD initialization */ | 292 | /* generic EAPD initialization */ |
293 | static void alc_auto_init_amp(struct hda_codec *codec, int type) | 293 | static void alc_auto_init_amp(struct hda_codec *codec, int type) |
294 | { | 294 | { |
295 | unsigned int tmp; | 295 | unsigned int tmp; |
296 | 296 | ||
297 | alc_auto_setup_eapd(codec, true); | 297 | alc_auto_setup_eapd(codec, true); |
298 | switch (type) { | 298 | switch (type) { |
299 | case ALC_INIT_GPIO1: | 299 | case ALC_INIT_GPIO1: |
300 | snd_hda_sequence_write(codec, alc_gpio1_init_verbs); | 300 | snd_hda_sequence_write(codec, alc_gpio1_init_verbs); |
301 | break; | 301 | break; |
302 | case ALC_INIT_GPIO2: | 302 | case ALC_INIT_GPIO2: |
303 | snd_hda_sequence_write(codec, alc_gpio2_init_verbs); | 303 | snd_hda_sequence_write(codec, alc_gpio2_init_verbs); |
304 | break; | 304 | break; |
305 | case ALC_INIT_GPIO3: | 305 | case ALC_INIT_GPIO3: |
306 | snd_hda_sequence_write(codec, alc_gpio3_init_verbs); | 306 | snd_hda_sequence_write(codec, alc_gpio3_init_verbs); |
307 | break; | 307 | break; |
308 | case ALC_INIT_DEFAULT: | 308 | case ALC_INIT_DEFAULT: |
309 | switch (codec->vendor_id) { | 309 | switch (codec->vendor_id) { |
310 | case 0x10ec0260: | 310 | case 0x10ec0260: |
311 | snd_hda_codec_write(codec, 0x1a, 0, | 311 | snd_hda_codec_write(codec, 0x1a, 0, |
312 | AC_VERB_SET_COEF_INDEX, 7); | 312 | AC_VERB_SET_COEF_INDEX, 7); |
313 | tmp = snd_hda_codec_read(codec, 0x1a, 0, | 313 | tmp = snd_hda_codec_read(codec, 0x1a, 0, |
314 | AC_VERB_GET_PROC_COEF, 0); | 314 | AC_VERB_GET_PROC_COEF, 0); |
315 | snd_hda_codec_write(codec, 0x1a, 0, | 315 | snd_hda_codec_write(codec, 0x1a, 0, |
316 | AC_VERB_SET_COEF_INDEX, 7); | 316 | AC_VERB_SET_COEF_INDEX, 7); |
317 | snd_hda_codec_write(codec, 0x1a, 0, | 317 | snd_hda_codec_write(codec, 0x1a, 0, |
318 | AC_VERB_SET_PROC_COEF, | 318 | AC_VERB_SET_PROC_COEF, |
319 | tmp | 0x2010); | 319 | tmp | 0x2010); |
320 | break; | 320 | break; |
321 | case 0x10ec0262: | 321 | case 0x10ec0262: |
322 | case 0x10ec0880: | 322 | case 0x10ec0880: |
323 | case 0x10ec0882: | 323 | case 0x10ec0882: |
324 | case 0x10ec0883: | 324 | case 0x10ec0883: |
325 | case 0x10ec0885: | 325 | case 0x10ec0885: |
326 | case 0x10ec0887: | 326 | case 0x10ec0887: |
327 | /*case 0x10ec0889:*/ /* this causes an SPDIF problem */ | 327 | /*case 0x10ec0889:*/ /* this causes an SPDIF problem */ |
328 | alc889_coef_init(codec); | 328 | alc889_coef_init(codec); |
329 | break; | 329 | break; |
330 | case 0x10ec0888: | 330 | case 0x10ec0888: |
331 | alc888_coef_init(codec); | 331 | alc888_coef_init(codec); |
332 | break; | 332 | break; |
333 | #if 0 /* XXX: This may cause the silent output on speaker on some machines */ | 333 | #if 0 /* XXX: This may cause the silent output on speaker on some machines */ |
334 | case 0x10ec0267: | 334 | case 0x10ec0267: |
335 | case 0x10ec0268: | 335 | case 0x10ec0268: |
336 | snd_hda_codec_write(codec, 0x20, 0, | 336 | snd_hda_codec_write(codec, 0x20, 0, |
337 | AC_VERB_SET_COEF_INDEX, 7); | 337 | AC_VERB_SET_COEF_INDEX, 7); |
338 | tmp = snd_hda_codec_read(codec, 0x20, 0, | 338 | tmp = snd_hda_codec_read(codec, 0x20, 0, |
339 | AC_VERB_GET_PROC_COEF, 0); | 339 | AC_VERB_GET_PROC_COEF, 0); |
340 | snd_hda_codec_write(codec, 0x20, 0, | 340 | snd_hda_codec_write(codec, 0x20, 0, |
341 | AC_VERB_SET_COEF_INDEX, 7); | 341 | AC_VERB_SET_COEF_INDEX, 7); |
342 | snd_hda_codec_write(codec, 0x20, 0, | 342 | snd_hda_codec_write(codec, 0x20, 0, |
343 | AC_VERB_SET_PROC_COEF, | 343 | AC_VERB_SET_PROC_COEF, |
344 | tmp | 0x3000); | 344 | tmp | 0x3000); |
345 | break; | 345 | break; |
346 | #endif /* XXX */ | 346 | #endif /* XXX */ |
347 | } | 347 | } |
348 | break; | 348 | break; |
349 | } | 349 | } |
350 | } | 350 | } |
351 | 351 | ||
352 | 352 | ||
353 | /* | 353 | /* |
354 | * Realtek SSID verification | 354 | * Realtek SSID verification |
355 | */ | 355 | */ |
356 | 356 | ||
357 | /* Could be any non-zero and even value. When used as fixup, tells | 357 | /* Could be any non-zero and even value. When used as fixup, tells |
358 | * the driver to ignore any present sku defines. | 358 | * the driver to ignore any present sku defines. |
359 | */ | 359 | */ |
360 | #define ALC_FIXUP_SKU_IGNORE (2) | 360 | #define ALC_FIXUP_SKU_IGNORE (2) |
361 | 361 | ||
362 | static void alc_fixup_sku_ignore(struct hda_codec *codec, | 362 | static void alc_fixup_sku_ignore(struct hda_codec *codec, |
363 | const struct hda_fixup *fix, int action) | 363 | const struct hda_fixup *fix, int action) |
364 | { | 364 | { |
365 | struct alc_spec *spec = codec->spec; | 365 | struct alc_spec *spec = codec->spec; |
366 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 366 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
367 | spec->cdefine.fixup = 1; | 367 | spec->cdefine.fixup = 1; |
368 | spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE; | 368 | spec->cdefine.sku_cfg = ALC_FIXUP_SKU_IGNORE; |
369 | } | 369 | } |
370 | } | 370 | } |
371 | 371 | ||
372 | static void alc_fixup_no_depop_delay(struct hda_codec *codec, | 372 | static void alc_fixup_no_depop_delay(struct hda_codec *codec, |
373 | const struct hda_fixup *fix, int action) | 373 | const struct hda_fixup *fix, int action) |
374 | { | 374 | { |
375 | struct alc_spec *spec = codec->spec; | 375 | struct alc_spec *spec = codec->spec; |
376 | 376 | ||
377 | if (action == HDA_FIXUP_ACT_PROBE) { | 377 | if (action == HDA_FIXUP_ACT_PROBE) { |
378 | spec->no_depop_delay = 1; | 378 | spec->no_depop_delay = 1; |
379 | codec->depop_delay = 0; | 379 | codec->depop_delay = 0; |
380 | } | 380 | } |
381 | } | 381 | } |
382 | 382 | ||
383 | static int alc_auto_parse_customize_define(struct hda_codec *codec) | 383 | static int alc_auto_parse_customize_define(struct hda_codec *codec) |
384 | { | 384 | { |
385 | unsigned int ass, tmp, i; | 385 | unsigned int ass, tmp, i; |
386 | unsigned nid = 0; | 386 | unsigned nid = 0; |
387 | struct alc_spec *spec = codec->spec; | 387 | struct alc_spec *spec = codec->spec; |
388 | 388 | ||
389 | spec->cdefine.enable_pcbeep = 1; /* assume always enabled */ | 389 | spec->cdefine.enable_pcbeep = 1; /* assume always enabled */ |
390 | 390 | ||
391 | if (spec->cdefine.fixup) { | 391 | if (spec->cdefine.fixup) { |
392 | ass = spec->cdefine.sku_cfg; | 392 | ass = spec->cdefine.sku_cfg; |
393 | if (ass == ALC_FIXUP_SKU_IGNORE) | 393 | if (ass == ALC_FIXUP_SKU_IGNORE) |
394 | return -1; | 394 | return -1; |
395 | goto do_sku; | 395 | goto do_sku; |
396 | } | 396 | } |
397 | 397 | ||
398 | if (!codec->bus->pci) | 398 | if (!codec->bus->pci) |
399 | return -1; | 399 | return -1; |
400 | ass = codec->subsystem_id & 0xffff; | 400 | ass = codec->subsystem_id & 0xffff; |
401 | if (ass != codec->bus->pci->subsystem_device && (ass & 1)) | 401 | if (ass != codec->bus->pci->subsystem_device && (ass & 1)) |
402 | goto do_sku; | 402 | goto do_sku; |
403 | 403 | ||
404 | nid = 0x1d; | 404 | nid = 0x1d; |
405 | if (codec->vendor_id == 0x10ec0260) | 405 | if (codec->vendor_id == 0x10ec0260) |
406 | nid = 0x17; | 406 | nid = 0x17; |
407 | ass = snd_hda_codec_get_pincfg(codec, nid); | 407 | ass = snd_hda_codec_get_pincfg(codec, nid); |
408 | 408 | ||
409 | if (!(ass & 1)) { | 409 | if (!(ass & 1)) { |
410 | codec_info(codec, "%s: SKU not ready 0x%08x\n", | 410 | codec_info(codec, "%s: SKU not ready 0x%08x\n", |
411 | codec->chip_name, ass); | 411 | codec->chip_name, ass); |
412 | return -1; | 412 | return -1; |
413 | } | 413 | } |
414 | 414 | ||
415 | /* check sum */ | 415 | /* check sum */ |
416 | tmp = 0; | 416 | tmp = 0; |
417 | for (i = 1; i < 16; i++) { | 417 | for (i = 1; i < 16; i++) { |
418 | if ((ass >> i) & 1) | 418 | if ((ass >> i) & 1) |
419 | tmp++; | 419 | tmp++; |
420 | } | 420 | } |
421 | if (((ass >> 16) & 0xf) != tmp) | 421 | if (((ass >> 16) & 0xf) != tmp) |
422 | return -1; | 422 | return -1; |
423 | 423 | ||
424 | spec->cdefine.port_connectivity = ass >> 30; | 424 | spec->cdefine.port_connectivity = ass >> 30; |
425 | spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20; | 425 | spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20; |
426 | spec->cdefine.check_sum = (ass >> 16) & 0xf; | 426 | spec->cdefine.check_sum = (ass >> 16) & 0xf; |
427 | spec->cdefine.customization = ass >> 8; | 427 | spec->cdefine.customization = ass >> 8; |
428 | do_sku: | 428 | do_sku: |
429 | spec->cdefine.sku_cfg = ass; | 429 | spec->cdefine.sku_cfg = ass; |
430 | spec->cdefine.external_amp = (ass & 0x38) >> 3; | 430 | spec->cdefine.external_amp = (ass & 0x38) >> 3; |
431 | spec->cdefine.platform_type = (ass & 0x4) >> 2; | 431 | spec->cdefine.platform_type = (ass & 0x4) >> 2; |
432 | spec->cdefine.swap = (ass & 0x2) >> 1; | 432 | spec->cdefine.swap = (ass & 0x2) >> 1; |
433 | spec->cdefine.override = ass & 0x1; | 433 | spec->cdefine.override = ass & 0x1; |
434 | 434 | ||
435 | codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n", | 435 | codec_dbg(codec, "SKU: Nid=0x%x sku_cfg=0x%08x\n", |
436 | nid, spec->cdefine.sku_cfg); | 436 | nid, spec->cdefine.sku_cfg); |
437 | codec_dbg(codec, "SKU: port_connectivity=0x%x\n", | 437 | codec_dbg(codec, "SKU: port_connectivity=0x%x\n", |
438 | spec->cdefine.port_connectivity); | 438 | spec->cdefine.port_connectivity); |
439 | codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep); | 439 | codec_dbg(codec, "SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep); |
440 | codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum); | 440 | codec_dbg(codec, "SKU: check_sum=0x%08x\n", spec->cdefine.check_sum); |
441 | codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization); | 441 | codec_dbg(codec, "SKU: customization=0x%08x\n", spec->cdefine.customization); |
442 | codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp); | 442 | codec_dbg(codec, "SKU: external_amp=0x%x\n", spec->cdefine.external_amp); |
443 | codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type); | 443 | codec_dbg(codec, "SKU: platform_type=0x%x\n", spec->cdefine.platform_type); |
444 | codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap); | 444 | codec_dbg(codec, "SKU: swap=0x%x\n", spec->cdefine.swap); |
445 | codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override); | 445 | codec_dbg(codec, "SKU: override=0x%x\n", spec->cdefine.override); |
446 | 446 | ||
447 | return 0; | 447 | return 0; |
448 | } | 448 | } |
449 | 449 | ||
450 | /* return the position of NID in the list, or -1 if not found */ | 450 | /* return the position of NID in the list, or -1 if not found */ |
451 | static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) | 451 | static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) |
452 | { | 452 | { |
453 | int i; | 453 | int i; |
454 | for (i = 0; i < nums; i++) | 454 | for (i = 0; i < nums; i++) |
455 | if (list[i] == nid) | 455 | if (list[i] == nid) |
456 | return i; | 456 | return i; |
457 | return -1; | 457 | return -1; |
458 | } | 458 | } |
459 | /* return true if the given NID is found in the list */ | 459 | /* return true if the given NID is found in the list */ |
460 | static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) | 460 | static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) |
461 | { | 461 | { |
462 | return find_idx_in_nid_list(nid, list, nums) >= 0; | 462 | return find_idx_in_nid_list(nid, list, nums) >= 0; |
463 | } | 463 | } |
464 | 464 | ||
465 | /* check subsystem ID and set up device-specific initialization; | 465 | /* check subsystem ID and set up device-specific initialization; |
466 | * return 1 if initialized, 0 if invalid SSID | 466 | * return 1 if initialized, 0 if invalid SSID |
467 | */ | 467 | */ |
468 | /* 32-bit subsystem ID for BIOS loading in HD Audio codec. | 468 | /* 32-bit subsystem ID for BIOS loading in HD Audio codec. |
469 | * 31 ~ 16 : Manufacture ID | 469 | * 31 ~ 16 : Manufacture ID |
470 | * 15 ~ 8 : SKU ID | 470 | * 15 ~ 8 : SKU ID |
471 | * 7 ~ 0 : Assembly ID | 471 | * 7 ~ 0 : Assembly ID |
472 | * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 | 472 | * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 |
473 | */ | 473 | */ |
474 | static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports) | 474 | static int alc_subsystem_id(struct hda_codec *codec, const hda_nid_t *ports) |
475 | { | 475 | { |
476 | unsigned int ass, tmp, i; | 476 | unsigned int ass, tmp, i; |
477 | unsigned nid; | 477 | unsigned nid; |
478 | struct alc_spec *spec = codec->spec; | 478 | struct alc_spec *spec = codec->spec; |
479 | 479 | ||
480 | if (spec->cdefine.fixup) { | 480 | if (spec->cdefine.fixup) { |
481 | ass = spec->cdefine.sku_cfg; | 481 | ass = spec->cdefine.sku_cfg; |
482 | if (ass == ALC_FIXUP_SKU_IGNORE) | 482 | if (ass == ALC_FIXUP_SKU_IGNORE) |
483 | return 0; | 483 | return 0; |
484 | goto do_sku; | 484 | goto do_sku; |
485 | } | 485 | } |
486 | 486 | ||
487 | ass = codec->subsystem_id & 0xffff; | 487 | ass = codec->subsystem_id & 0xffff; |
488 | if (codec->bus->pci && | 488 | if (codec->bus->pci && |
489 | ass != codec->bus->pci->subsystem_device && (ass & 1)) | 489 | ass != codec->bus->pci->subsystem_device && (ass & 1)) |
490 | goto do_sku; | 490 | goto do_sku; |
491 | 491 | ||
492 | /* invalid SSID, check the special NID pin defcfg instead */ | 492 | /* invalid SSID, check the special NID pin defcfg instead */ |
493 | /* | 493 | /* |
494 | * 31~30 : port connectivity | 494 | * 31~30 : port connectivity |
495 | * 29~21 : reserve | 495 | * 29~21 : reserve |
496 | * 20 : PCBEEP input | 496 | * 20 : PCBEEP input |
497 | * 19~16 : Check sum (15:1) | 497 | * 19~16 : Check sum (15:1) |
498 | * 15~1 : Custom | 498 | * 15~1 : Custom |
499 | * 0 : override | 499 | * 0 : override |
500 | */ | 500 | */ |
501 | nid = 0x1d; | 501 | nid = 0x1d; |
502 | if (codec->vendor_id == 0x10ec0260) | 502 | if (codec->vendor_id == 0x10ec0260) |
503 | nid = 0x17; | 503 | nid = 0x17; |
504 | ass = snd_hda_codec_get_pincfg(codec, nid); | 504 | ass = snd_hda_codec_get_pincfg(codec, nid); |
505 | codec_dbg(codec, | 505 | codec_dbg(codec, |
506 | "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n", | 506 | "realtek: No valid SSID, checking pincfg 0x%08x for NID 0x%x\n", |
507 | ass, nid); | 507 | ass, nid); |
508 | if (!(ass & 1)) | 508 | if (!(ass & 1)) |
509 | return 0; | 509 | return 0; |
510 | if ((ass >> 30) != 1) /* no physical connection */ | 510 | if ((ass >> 30) != 1) /* no physical connection */ |
511 | return 0; | 511 | return 0; |
512 | 512 | ||
513 | /* check sum */ | 513 | /* check sum */ |
514 | tmp = 0; | 514 | tmp = 0; |
515 | for (i = 1; i < 16; i++) { | 515 | for (i = 1; i < 16; i++) { |
516 | if ((ass >> i) & 1) | 516 | if ((ass >> i) & 1) |
517 | tmp++; | 517 | tmp++; |
518 | } | 518 | } |
519 | if (((ass >> 16) & 0xf) != tmp) | 519 | if (((ass >> 16) & 0xf) != tmp) |
520 | return 0; | 520 | return 0; |
521 | do_sku: | 521 | do_sku: |
522 | codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n", | 522 | codec_dbg(codec, "realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n", |
523 | ass & 0xffff, codec->vendor_id); | 523 | ass & 0xffff, codec->vendor_id); |
524 | /* | 524 | /* |
525 | * 0 : override | 525 | * 0 : override |
526 | * 1 : Swap Jack | 526 | * 1 : Swap Jack |
527 | * 2 : 0 --> Desktop, 1 --> Laptop | 527 | * 2 : 0 --> Desktop, 1 --> Laptop |
528 | * 3~5 : External Amplifier control | 528 | * 3~5 : External Amplifier control |
529 | * 7~6 : Reserved | 529 | * 7~6 : Reserved |
530 | */ | 530 | */ |
531 | tmp = (ass & 0x38) >> 3; /* external Amp control */ | 531 | tmp = (ass & 0x38) >> 3; /* external Amp control */ |
532 | switch (tmp) { | 532 | switch (tmp) { |
533 | case 1: | 533 | case 1: |
534 | spec->init_amp = ALC_INIT_GPIO1; | 534 | spec->init_amp = ALC_INIT_GPIO1; |
535 | break; | 535 | break; |
536 | case 3: | 536 | case 3: |
537 | spec->init_amp = ALC_INIT_GPIO2; | 537 | spec->init_amp = ALC_INIT_GPIO2; |
538 | break; | 538 | break; |
539 | case 7: | 539 | case 7: |
540 | spec->init_amp = ALC_INIT_GPIO3; | 540 | spec->init_amp = ALC_INIT_GPIO3; |
541 | break; | 541 | break; |
542 | case 5: | 542 | case 5: |
543 | default: | 543 | default: |
544 | spec->init_amp = ALC_INIT_DEFAULT; | 544 | spec->init_amp = ALC_INIT_DEFAULT; |
545 | break; | 545 | break; |
546 | } | 546 | } |
547 | 547 | ||
548 | /* is laptop or Desktop and enable the function "Mute internal speaker | 548 | /* is laptop or Desktop and enable the function "Mute internal speaker |
549 | * when the external headphone out jack is plugged" | 549 | * when the external headphone out jack is plugged" |
550 | */ | 550 | */ |
551 | if (!(ass & 0x8000)) | 551 | if (!(ass & 0x8000)) |
552 | return 1; | 552 | return 1; |
553 | /* | 553 | /* |
554 | * 10~8 : Jack location | 554 | * 10~8 : Jack location |
555 | * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered | 555 | * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered |
556 | * 14~13: Resvered | 556 | * 14~13: Resvered |
557 | * 15 : 1 --> enable the function "Mute internal speaker | 557 | * 15 : 1 --> enable the function "Mute internal speaker |
558 | * when the external headphone out jack is plugged" | 558 | * when the external headphone out jack is plugged" |
559 | */ | 559 | */ |
560 | if (!spec->gen.autocfg.hp_pins[0] && | 560 | if (!spec->gen.autocfg.hp_pins[0] && |
561 | !(spec->gen.autocfg.line_out_pins[0] && | 561 | !(spec->gen.autocfg.line_out_pins[0] && |
562 | spec->gen.autocfg.line_out_type == AUTO_PIN_HP_OUT)) { | 562 | spec->gen.autocfg.line_out_type == AUTO_PIN_HP_OUT)) { |
563 | hda_nid_t nid; | 563 | hda_nid_t nid; |
564 | tmp = (ass >> 11) & 0x3; /* HP to chassis */ | 564 | tmp = (ass >> 11) & 0x3; /* HP to chassis */ |
565 | nid = ports[tmp]; | 565 | nid = ports[tmp]; |
566 | if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins, | 566 | if (found_in_nid_list(nid, spec->gen.autocfg.line_out_pins, |
567 | spec->gen.autocfg.line_outs)) | 567 | spec->gen.autocfg.line_outs)) |
568 | return 1; | 568 | return 1; |
569 | spec->gen.autocfg.hp_pins[0] = nid; | 569 | spec->gen.autocfg.hp_pins[0] = nid; |
570 | } | 570 | } |
571 | return 1; | 571 | return 1; |
572 | } | 572 | } |
573 | 573 | ||
574 | /* Check the validity of ALC subsystem-id | 574 | /* Check the validity of ALC subsystem-id |
575 | * ports contains an array of 4 pin NIDs for port-A, E, D and I */ | 575 | * ports contains an array of 4 pin NIDs for port-A, E, D and I */ |
576 | static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports) | 576 | static void alc_ssid_check(struct hda_codec *codec, const hda_nid_t *ports) |
577 | { | 577 | { |
578 | if (!alc_subsystem_id(codec, ports)) { | 578 | if (!alc_subsystem_id(codec, ports)) { |
579 | struct alc_spec *spec = codec->spec; | 579 | struct alc_spec *spec = codec->spec; |
580 | codec_dbg(codec, | 580 | codec_dbg(codec, |
581 | "realtek: Enable default setup for auto mode as fallback\n"); | 581 | "realtek: Enable default setup for auto mode as fallback\n"); |
582 | spec->init_amp = ALC_INIT_DEFAULT; | 582 | spec->init_amp = ALC_INIT_DEFAULT; |
583 | } | 583 | } |
584 | } | 584 | } |
585 | 585 | ||
586 | /* | 586 | /* |
587 | * COEF access helper functions | 587 | * COEF access helper functions |
588 | */ | 588 | */ |
589 | 589 | ||
590 | static int alc_read_coefex_idx(struct hda_codec *codec, | 590 | static int alc_read_coefex_idx(struct hda_codec *codec, |
591 | hda_nid_t nid, | 591 | hda_nid_t nid, |
592 | unsigned int coef_idx) | 592 | unsigned int coef_idx) |
593 | { | 593 | { |
594 | unsigned int val; | 594 | unsigned int val; |
595 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, | 595 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, |
596 | coef_idx); | 596 | coef_idx); |
597 | val = snd_hda_codec_read(codec, nid, 0, | 597 | val = snd_hda_codec_read(codec, nid, 0, |
598 | AC_VERB_GET_PROC_COEF, 0); | 598 | AC_VERB_GET_PROC_COEF, 0); |
599 | return val; | 599 | return val; |
600 | } | 600 | } |
601 | 601 | ||
602 | #define alc_read_coef_idx(codec, coef_idx) \ | 602 | #define alc_read_coef_idx(codec, coef_idx) \ |
603 | alc_read_coefex_idx(codec, 0x20, coef_idx) | 603 | alc_read_coefex_idx(codec, 0x20, coef_idx) |
604 | 604 | ||
605 | static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid, | 605 | static void alc_write_coefex_idx(struct hda_codec *codec, hda_nid_t nid, |
606 | unsigned int coef_idx, | 606 | unsigned int coef_idx, |
607 | unsigned int coef_val) | 607 | unsigned int coef_val) |
608 | { | 608 | { |
609 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, | 609 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_COEF_INDEX, |
610 | coef_idx); | 610 | coef_idx); |
611 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, | 611 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PROC_COEF, |
612 | coef_val); | 612 | coef_val); |
613 | } | 613 | } |
614 | 614 | ||
615 | #define alc_write_coef_idx(codec, coef_idx, coef_val) \ | 615 | #define alc_write_coef_idx(codec, coef_idx, coef_val) \ |
616 | alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val) | 616 | alc_write_coefex_idx(codec, 0x20, coef_idx, coef_val) |
617 | 617 | ||
618 | /* a special bypass for COEF 0; read the cached value at the second time */ | 618 | /* a special bypass for COEF 0; read the cached value at the second time */ |
619 | static unsigned int alc_get_coef0(struct hda_codec *codec) | 619 | static unsigned int alc_get_coef0(struct hda_codec *codec) |
620 | { | 620 | { |
621 | struct alc_spec *spec = codec->spec; | 621 | struct alc_spec *spec = codec->spec; |
622 | if (!spec->coef0) | 622 | if (!spec->coef0) |
623 | spec->coef0 = alc_read_coef_idx(codec, 0); | 623 | spec->coef0 = alc_read_coef_idx(codec, 0); |
624 | return spec->coef0; | 624 | return spec->coef0; |
625 | } | 625 | } |
626 | 626 | ||
627 | /* | 627 | /* |
628 | */ | 628 | */ |
629 | 629 | ||
630 | static hda_nid_t get_adc_nid(struct hda_codec *codec, int adc_idx, int imux_idx) | 630 | static hda_nid_t get_adc_nid(struct hda_codec *codec, int adc_idx, int imux_idx) |
631 | { | 631 | { |
632 | struct hda_gen_spec *spec = codec->spec; | 632 | struct hda_gen_spec *spec = codec->spec; |
633 | if (spec->dyn_adc_switch) | 633 | if (spec->dyn_adc_switch) |
634 | adc_idx = spec->dyn_adc_idx[imux_idx]; | 634 | adc_idx = spec->dyn_adc_idx[imux_idx]; |
635 | return spec->adc_nids[adc_idx]; | 635 | return spec->adc_nids[adc_idx]; |
636 | } | 636 | } |
637 | 637 | ||
638 | static void alc_inv_dmic_sync_adc(struct hda_codec *codec, int adc_idx) | 638 | static void alc_inv_dmic_sync_adc(struct hda_codec *codec, int adc_idx) |
639 | { | 639 | { |
640 | struct alc_spec *spec = codec->spec; | 640 | struct alc_spec *spec = codec->spec; |
641 | struct hda_input_mux *imux = &spec->gen.input_mux; | 641 | struct hda_input_mux *imux = &spec->gen.input_mux; |
642 | struct nid_path *path; | 642 | struct nid_path *path; |
643 | hda_nid_t nid; | 643 | hda_nid_t nid; |
644 | int i, dir, parm; | 644 | int i, dir, parm; |
645 | unsigned int val; | 645 | unsigned int val; |
646 | 646 | ||
647 | for (i = 0; i < imux->num_items; i++) { | 647 | for (i = 0; i < imux->num_items; i++) { |
648 | if (spec->gen.imux_pins[i] == spec->inv_dmic_pin) | 648 | if (spec->gen.imux_pins[i] == spec->inv_dmic_pin) |
649 | break; | 649 | break; |
650 | } | 650 | } |
651 | if (i >= imux->num_items) | 651 | if (i >= imux->num_items) |
652 | return; | 652 | return; |
653 | 653 | ||
654 | path = snd_hda_get_nid_path(codec, spec->inv_dmic_pin, | 654 | path = snd_hda_get_nid_path(codec, spec->inv_dmic_pin, |
655 | get_adc_nid(codec, adc_idx, i)); | 655 | get_adc_nid(codec, adc_idx, i)); |
656 | val = path->ctls[NID_PATH_MUTE_CTL]; | 656 | val = path->ctls[NID_PATH_MUTE_CTL]; |
657 | if (!val) | 657 | if (!val) |
658 | return; | 658 | return; |
659 | nid = get_amp_nid_(val); | 659 | nid = get_amp_nid_(val); |
660 | dir = get_amp_direction_(val); | 660 | dir = get_amp_direction_(val); |
661 | parm = AC_AMP_SET_RIGHT | | 661 | parm = AC_AMP_SET_RIGHT | |
662 | (dir == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT); | 662 | (dir == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT); |
663 | 663 | ||
664 | /* flush all cached amps at first */ | 664 | /* flush all cached amps at first */ |
665 | snd_hda_codec_flush_cache(codec); | 665 | snd_hda_codec_flush_cache(codec); |
666 | 666 | ||
667 | /* we care only right channel */ | 667 | /* we care only right channel */ |
668 | val = snd_hda_codec_amp_read(codec, nid, 1, dir, 0); | 668 | val = snd_hda_codec_amp_read(codec, nid, 1, dir, 0); |
669 | if (val & 0x80) /* if already muted, we don't need to touch */ | 669 | if (val & 0x80) /* if already muted, we don't need to touch */ |
670 | return; | 670 | return; |
671 | val |= 0x80; | 671 | val |= 0x80; |
672 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 672 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, |
673 | parm | val); | 673 | parm | val); |
674 | } | 674 | } |
675 | 675 | ||
676 | /* | 676 | /* |
677 | * Inverted digital-mic handling | 677 | * Inverted digital-mic handling |
678 | * | 678 | * |
679 | * First off, it's a bit tricky. The "Inverted Internal Mic Capture Switch" | 679 | * First off, it's a bit tricky. The "Inverted Internal Mic Capture Switch" |
680 | * gives the additional mute only to the right channel of the digital mic | 680 | * gives the additional mute only to the right channel of the digital mic |
681 | * capture stream. This is a workaround for avoiding the almost silence | 681 | * capture stream. This is a workaround for avoiding the almost silence |
682 | * by summing the stereo stream from some (known to be ForteMedia) | 682 | * by summing the stereo stream from some (known to be ForteMedia) |
683 | * digital mic unit. | 683 | * digital mic unit. |
684 | * | 684 | * |
685 | * The logic is to call alc_inv_dmic_sync() after each action (possibly) | 685 | * The logic is to call alc_inv_dmic_sync() after each action (possibly) |
686 | * modifying ADC amp. When the mute flag is set, it mutes the R-channel | 686 | * modifying ADC amp. When the mute flag is set, it mutes the R-channel |
687 | * without caching so that the cache can still keep the original value. | 687 | * without caching so that the cache can still keep the original value. |
688 | * The cached value is then restored when the flag is set off or any other | 688 | * The cached value is then restored when the flag is set off or any other |
689 | * than d-mic is used as the current input source. | 689 | * than d-mic is used as the current input source. |
690 | */ | 690 | */ |
691 | static void alc_inv_dmic_sync(struct hda_codec *codec, bool force) | 691 | static void alc_inv_dmic_sync(struct hda_codec *codec, bool force) |
692 | { | 692 | { |
693 | struct alc_spec *spec = codec->spec; | 693 | struct alc_spec *spec = codec->spec; |
694 | int src, nums; | 694 | int src, nums; |
695 | 695 | ||
696 | if (!spec->inv_dmic_fixup) | 696 | if (!spec->inv_dmic_fixup) |
697 | return; | 697 | return; |
698 | if (!spec->inv_dmic_muted && !force) | 698 | if (!spec->inv_dmic_muted && !force) |
699 | return; | 699 | return; |
700 | nums = spec->gen.dyn_adc_switch ? 1 : spec->gen.num_adc_nids; | 700 | nums = spec->gen.dyn_adc_switch ? 1 : spec->gen.num_adc_nids; |
701 | for (src = 0; src < nums; src++) { | 701 | for (src = 0; src < nums; src++) { |
702 | bool dmic_fixup = false; | 702 | bool dmic_fixup = false; |
703 | 703 | ||
704 | if (spec->inv_dmic_muted && | 704 | if (spec->inv_dmic_muted && |
705 | spec->gen.imux_pins[spec->gen.cur_mux[src]] == spec->inv_dmic_pin) | 705 | spec->gen.imux_pins[spec->gen.cur_mux[src]] == spec->inv_dmic_pin) |
706 | dmic_fixup = true; | 706 | dmic_fixup = true; |
707 | if (!dmic_fixup && !force) | 707 | if (!dmic_fixup && !force) |
708 | continue; | 708 | continue; |
709 | alc_inv_dmic_sync_adc(codec, src); | 709 | alc_inv_dmic_sync_adc(codec, src); |
710 | } | 710 | } |
711 | } | 711 | } |
712 | 712 | ||
713 | static void alc_inv_dmic_hook(struct hda_codec *codec, | 713 | static void alc_inv_dmic_hook(struct hda_codec *codec, |
714 | struct snd_kcontrol *kcontrol, | 714 | struct snd_kcontrol *kcontrol, |
715 | struct snd_ctl_elem_value *ucontrol) | 715 | struct snd_ctl_elem_value *ucontrol) |
716 | { | 716 | { |
717 | alc_inv_dmic_sync(codec, false); | 717 | alc_inv_dmic_sync(codec, false); |
718 | } | 718 | } |
719 | 719 | ||
720 | static int alc_inv_dmic_sw_get(struct snd_kcontrol *kcontrol, | 720 | static int alc_inv_dmic_sw_get(struct snd_kcontrol *kcontrol, |
721 | struct snd_ctl_elem_value *ucontrol) | 721 | struct snd_ctl_elem_value *ucontrol) |
722 | { | 722 | { |
723 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 723 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
724 | struct alc_spec *spec = codec->spec; | 724 | struct alc_spec *spec = codec->spec; |
725 | 725 | ||
726 | ucontrol->value.integer.value[0] = !spec->inv_dmic_muted; | 726 | ucontrol->value.integer.value[0] = !spec->inv_dmic_muted; |
727 | return 0; | 727 | return 0; |
728 | } | 728 | } |
729 | 729 | ||
730 | static int alc_inv_dmic_sw_put(struct snd_kcontrol *kcontrol, | 730 | static int alc_inv_dmic_sw_put(struct snd_kcontrol *kcontrol, |
731 | struct snd_ctl_elem_value *ucontrol) | 731 | struct snd_ctl_elem_value *ucontrol) |
732 | { | 732 | { |
733 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 733 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
734 | struct alc_spec *spec = codec->spec; | 734 | struct alc_spec *spec = codec->spec; |
735 | unsigned int val = !ucontrol->value.integer.value[0]; | 735 | unsigned int val = !ucontrol->value.integer.value[0]; |
736 | 736 | ||
737 | if (val == spec->inv_dmic_muted) | 737 | if (val == spec->inv_dmic_muted) |
738 | return 0; | 738 | return 0; |
739 | spec->inv_dmic_muted = val; | 739 | spec->inv_dmic_muted = val; |
740 | alc_inv_dmic_sync(codec, true); | 740 | alc_inv_dmic_sync(codec, true); |
741 | return 0; | 741 | return 0; |
742 | } | 742 | } |
743 | 743 | ||
744 | static const struct snd_kcontrol_new alc_inv_dmic_sw = { | 744 | static const struct snd_kcontrol_new alc_inv_dmic_sw = { |
745 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 745 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
746 | .name = "Inverted Internal Mic Capture Switch", | 746 | .name = "Inverted Internal Mic Capture Switch", |
747 | .info = snd_ctl_boolean_mono_info, | 747 | .info = snd_ctl_boolean_mono_info, |
748 | .get = alc_inv_dmic_sw_get, | 748 | .get = alc_inv_dmic_sw_get, |
749 | .put = alc_inv_dmic_sw_put, | 749 | .put = alc_inv_dmic_sw_put, |
750 | }; | 750 | }; |
751 | 751 | ||
752 | static int alc_add_inv_dmic_mixer(struct hda_codec *codec, hda_nid_t nid) | 752 | static int alc_add_inv_dmic_mixer(struct hda_codec *codec, hda_nid_t nid) |
753 | { | 753 | { |
754 | struct alc_spec *spec = codec->spec; | 754 | struct alc_spec *spec = codec->spec; |
755 | 755 | ||
756 | if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &alc_inv_dmic_sw)) | 756 | if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &alc_inv_dmic_sw)) |
757 | return -ENOMEM; | 757 | return -ENOMEM; |
758 | spec->inv_dmic_fixup = 1; | 758 | spec->inv_dmic_fixup = 1; |
759 | spec->inv_dmic_muted = 0; | 759 | spec->inv_dmic_muted = 0; |
760 | spec->inv_dmic_pin = nid; | 760 | spec->inv_dmic_pin = nid; |
761 | spec->gen.cap_sync_hook = alc_inv_dmic_hook; | 761 | spec->gen.cap_sync_hook = alc_inv_dmic_hook; |
762 | return 0; | 762 | return 0; |
763 | } | 763 | } |
764 | 764 | ||
765 | /* typically the digital mic is put at node 0x12 */ | 765 | /* typically the digital mic is put at node 0x12 */ |
766 | static void alc_fixup_inv_dmic_0x12(struct hda_codec *codec, | 766 | static void alc_fixup_inv_dmic_0x12(struct hda_codec *codec, |
767 | const struct hda_fixup *fix, int action) | 767 | const struct hda_fixup *fix, int action) |
768 | { | 768 | { |
769 | if (action == HDA_FIXUP_ACT_PROBE) | 769 | if (action == HDA_FIXUP_ACT_PROBE) |
770 | alc_add_inv_dmic_mixer(codec, 0x12); | 770 | alc_add_inv_dmic_mixer(codec, 0x12); |
771 | } | 771 | } |
772 | 772 | ||
773 | 773 | ||
774 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 774 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
775 | /* additional beep mixers; the actual parameters are overwritten at build */ | 775 | /* additional beep mixers; the actual parameters are overwritten at build */ |
776 | static const struct snd_kcontrol_new alc_beep_mixer[] = { | 776 | static const struct snd_kcontrol_new alc_beep_mixer[] = { |
777 | HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), | 777 | HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), |
778 | HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT), | 778 | HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT), |
779 | { } /* end */ | 779 | { } /* end */ |
780 | }; | 780 | }; |
781 | #endif | 781 | #endif |
782 | 782 | ||
783 | static int alc_build_controls(struct hda_codec *codec) | 783 | static int alc_build_controls(struct hda_codec *codec) |
784 | { | 784 | { |
785 | struct alc_spec *spec = codec->spec; | 785 | struct alc_spec *spec = codec->spec; |
786 | int i, err; | 786 | int i, err; |
787 | 787 | ||
788 | err = snd_hda_gen_build_controls(codec); | 788 | err = snd_hda_gen_build_controls(codec); |
789 | if (err < 0) | 789 | if (err < 0) |
790 | return err; | 790 | return err; |
791 | 791 | ||
792 | for (i = 0; i < spec->num_mixers; i++) { | 792 | for (i = 0; i < spec->num_mixers; i++) { |
793 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); | 793 | err = snd_hda_add_new_ctls(codec, spec->mixers[i]); |
794 | if (err < 0) | 794 | if (err < 0) |
795 | return err; | 795 | return err; |
796 | } | 796 | } |
797 | 797 | ||
798 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 798 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
799 | /* create beep controls if needed */ | 799 | /* create beep controls if needed */ |
800 | if (spec->beep_amp) { | 800 | if (spec->beep_amp) { |
801 | const struct snd_kcontrol_new *knew; | 801 | const struct snd_kcontrol_new *knew; |
802 | for (knew = alc_beep_mixer; knew->name; knew++) { | 802 | for (knew = alc_beep_mixer; knew->name; knew++) { |
803 | struct snd_kcontrol *kctl; | 803 | struct snd_kcontrol *kctl; |
804 | kctl = snd_ctl_new1(knew, codec); | 804 | kctl = snd_ctl_new1(knew, codec); |
805 | if (!kctl) | 805 | if (!kctl) |
806 | return -ENOMEM; | 806 | return -ENOMEM; |
807 | kctl->private_value = spec->beep_amp; | 807 | kctl->private_value = spec->beep_amp; |
808 | err = snd_hda_ctl_add(codec, 0, kctl); | 808 | err = snd_hda_ctl_add(codec, 0, kctl); |
809 | if (err < 0) | 809 | if (err < 0) |
810 | return err; | 810 | return err; |
811 | } | 811 | } |
812 | } | 812 | } |
813 | #endif | 813 | #endif |
814 | 814 | ||
815 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD); | 815 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_BUILD); |
816 | return 0; | 816 | return 0; |
817 | } | 817 | } |
818 | 818 | ||
819 | 819 | ||
820 | /* | 820 | /* |
821 | * Common callbacks | 821 | * Common callbacks |
822 | */ | 822 | */ |
823 | 823 | ||
824 | static int alc_init(struct hda_codec *codec) | 824 | static int alc_init(struct hda_codec *codec) |
825 | { | 825 | { |
826 | struct alc_spec *spec = codec->spec; | 826 | struct alc_spec *spec = codec->spec; |
827 | 827 | ||
828 | if (spec->init_hook) | 828 | if (spec->init_hook) |
829 | spec->init_hook(codec); | 829 | spec->init_hook(codec); |
830 | 830 | ||
831 | alc_fix_pll(codec); | 831 | alc_fix_pll(codec); |
832 | alc_auto_init_amp(codec, spec->init_amp); | 832 | alc_auto_init_amp(codec, spec->init_amp); |
833 | 833 | ||
834 | snd_hda_gen_init(codec); | 834 | snd_hda_gen_init(codec); |
835 | 835 | ||
836 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT); | 836 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT); |
837 | 837 | ||
838 | return 0; | 838 | return 0; |
839 | } | 839 | } |
840 | 840 | ||
841 | static inline void alc_shutup(struct hda_codec *codec) | 841 | static inline void alc_shutup(struct hda_codec *codec) |
842 | { | 842 | { |
843 | struct alc_spec *spec = codec->spec; | 843 | struct alc_spec *spec = codec->spec; |
844 | 844 | ||
845 | if (spec && spec->shutup) | 845 | if (spec && spec->shutup) |
846 | spec->shutup(codec); | 846 | spec->shutup(codec); |
847 | else | 847 | else |
848 | snd_hda_shutup_pins(codec); | 848 | snd_hda_shutup_pins(codec); |
849 | } | 849 | } |
850 | 850 | ||
851 | #define alc_free snd_hda_gen_free | 851 | #define alc_free snd_hda_gen_free |
852 | 852 | ||
853 | #ifdef CONFIG_PM | 853 | #ifdef CONFIG_PM |
854 | static void alc_power_eapd(struct hda_codec *codec) | 854 | static void alc_power_eapd(struct hda_codec *codec) |
855 | { | 855 | { |
856 | alc_auto_setup_eapd(codec, false); | 856 | alc_auto_setup_eapd(codec, false); |
857 | } | 857 | } |
858 | 858 | ||
859 | static int alc_suspend(struct hda_codec *codec) | 859 | static int alc_suspend(struct hda_codec *codec) |
860 | { | 860 | { |
861 | struct alc_spec *spec = codec->spec; | 861 | struct alc_spec *spec = codec->spec; |
862 | alc_shutup(codec); | 862 | alc_shutup(codec); |
863 | if (spec && spec->power_hook) | 863 | if (spec && spec->power_hook) |
864 | spec->power_hook(codec); | 864 | spec->power_hook(codec); |
865 | return 0; | 865 | return 0; |
866 | } | 866 | } |
867 | #endif | 867 | #endif |
868 | 868 | ||
869 | #ifdef CONFIG_PM | 869 | #ifdef CONFIG_PM |
870 | static int alc_resume(struct hda_codec *codec) | 870 | static int alc_resume(struct hda_codec *codec) |
871 | { | 871 | { |
872 | struct alc_spec *spec = codec->spec; | 872 | struct alc_spec *spec = codec->spec; |
873 | 873 | ||
874 | if (!spec->no_depop_delay) | 874 | if (!spec->no_depop_delay) |
875 | msleep(150); /* to avoid pop noise */ | 875 | msleep(150); /* to avoid pop noise */ |
876 | codec->patch_ops.init(codec); | 876 | codec->patch_ops.init(codec); |
877 | snd_hda_codec_resume_amp(codec); | 877 | snd_hda_codec_resume_amp(codec); |
878 | snd_hda_codec_resume_cache(codec); | 878 | snd_hda_codec_resume_cache(codec); |
879 | alc_inv_dmic_sync(codec, true); | 879 | alc_inv_dmic_sync(codec, true); |
880 | hda_call_check_power_status(codec, 0x01); | 880 | hda_call_check_power_status(codec, 0x01); |
881 | return 0; | 881 | return 0; |
882 | } | 882 | } |
883 | #endif | 883 | #endif |
884 | 884 | ||
885 | /* | 885 | /* |
886 | */ | 886 | */ |
887 | static const struct hda_codec_ops alc_patch_ops = { | 887 | static const struct hda_codec_ops alc_patch_ops = { |
888 | .build_controls = alc_build_controls, | 888 | .build_controls = alc_build_controls, |
889 | .build_pcms = snd_hda_gen_build_pcms, | 889 | .build_pcms = snd_hda_gen_build_pcms, |
890 | .init = alc_init, | 890 | .init = alc_init, |
891 | .free = alc_free, | 891 | .free = alc_free, |
892 | .unsol_event = snd_hda_jack_unsol_event, | 892 | .unsol_event = snd_hda_jack_unsol_event, |
893 | #ifdef CONFIG_PM | 893 | #ifdef CONFIG_PM |
894 | .resume = alc_resume, | 894 | .resume = alc_resume, |
895 | .suspend = alc_suspend, | 895 | .suspend = alc_suspend, |
896 | .check_power_status = snd_hda_gen_check_power_status, | 896 | .check_power_status = snd_hda_gen_check_power_status, |
897 | #endif | 897 | #endif |
898 | .reboot_notify = alc_shutup, | 898 | .reboot_notify = alc_shutup, |
899 | }; | 899 | }; |
900 | 900 | ||
901 | 901 | ||
902 | /* replace the codec chip_name with the given string */ | 902 | /* replace the codec chip_name with the given string */ |
903 | static int alc_codec_rename(struct hda_codec *codec, const char *name) | 903 | static int alc_codec_rename(struct hda_codec *codec, const char *name) |
904 | { | 904 | { |
905 | kfree(codec->chip_name); | 905 | kfree(codec->chip_name); |
906 | codec->chip_name = kstrdup(name, GFP_KERNEL); | 906 | codec->chip_name = kstrdup(name, GFP_KERNEL); |
907 | if (!codec->chip_name) { | 907 | if (!codec->chip_name) { |
908 | alc_free(codec); | 908 | alc_free(codec); |
909 | return -ENOMEM; | 909 | return -ENOMEM; |
910 | } | 910 | } |
911 | return 0; | 911 | return 0; |
912 | } | 912 | } |
913 | 913 | ||
914 | /* | 914 | /* |
915 | * Rename codecs appropriately from COEF value or subvendor id | 915 | * Rename codecs appropriately from COEF value or subvendor id |
916 | */ | 916 | */ |
917 | struct alc_codec_rename_table { | 917 | struct alc_codec_rename_table { |
918 | unsigned int vendor_id; | 918 | unsigned int vendor_id; |
919 | unsigned short coef_mask; | 919 | unsigned short coef_mask; |
920 | unsigned short coef_bits; | 920 | unsigned short coef_bits; |
921 | const char *name; | 921 | const char *name; |
922 | }; | 922 | }; |
923 | 923 | ||
924 | struct alc_codec_rename_pci_table { | 924 | struct alc_codec_rename_pci_table { |
925 | unsigned int codec_vendor_id; | 925 | unsigned int codec_vendor_id; |
926 | unsigned short pci_subvendor; | 926 | unsigned short pci_subvendor; |
927 | unsigned short pci_subdevice; | 927 | unsigned short pci_subdevice; |
928 | const char *name; | 928 | const char *name; |
929 | }; | 929 | }; |
930 | 930 | ||
931 | static struct alc_codec_rename_table rename_tbl[] = { | 931 | static struct alc_codec_rename_table rename_tbl[] = { |
932 | { 0x10ec0269, 0xfff0, 0x3010, "ALC277" }, | 932 | { 0x10ec0269, 0xfff0, 0x3010, "ALC277" }, |
933 | { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" }, | 933 | { 0x10ec0269, 0xf0f0, 0x2010, "ALC259" }, |
934 | { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" }, | 934 | { 0x10ec0269, 0xf0f0, 0x3010, "ALC258" }, |
935 | { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" }, | 935 | { 0x10ec0269, 0x00f0, 0x0010, "ALC269VB" }, |
936 | { 0x10ec0269, 0xffff, 0xa023, "ALC259" }, | 936 | { 0x10ec0269, 0xffff, 0xa023, "ALC259" }, |
937 | { 0x10ec0269, 0xffff, 0x6023, "ALC281X" }, | 937 | { 0x10ec0269, 0xffff, 0x6023, "ALC281X" }, |
938 | { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" }, | 938 | { 0x10ec0269, 0x00f0, 0x0020, "ALC269VC" }, |
939 | { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" }, | 939 | { 0x10ec0269, 0x00f0, 0x0030, "ALC269VD" }, |
940 | { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" }, | 940 | { 0x10ec0887, 0x00f0, 0x0030, "ALC887-VD" }, |
941 | { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" }, | 941 | { 0x10ec0888, 0x00f0, 0x0030, "ALC888-VD" }, |
942 | { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" }, | 942 | { 0x10ec0888, 0xf0f0, 0x3020, "ALC886" }, |
943 | { 0x10ec0899, 0x2000, 0x2000, "ALC899" }, | 943 | { 0x10ec0899, 0x2000, 0x2000, "ALC899" }, |
944 | { 0x10ec0892, 0xffff, 0x8020, "ALC661" }, | 944 | { 0x10ec0892, 0xffff, 0x8020, "ALC661" }, |
945 | { 0x10ec0892, 0xffff, 0x8011, "ALC661" }, | 945 | { 0x10ec0892, 0xffff, 0x8011, "ALC661" }, |
946 | { 0x10ec0892, 0xffff, 0x4011, "ALC656" }, | 946 | { 0x10ec0892, 0xffff, 0x4011, "ALC656" }, |
947 | { } /* terminator */ | 947 | { } /* terminator */ |
948 | }; | 948 | }; |
949 | 949 | ||
950 | static struct alc_codec_rename_pci_table rename_pci_tbl[] = { | 950 | static struct alc_codec_rename_pci_table rename_pci_tbl[] = { |
951 | { 0x10ec0280, 0x1028, 0, "ALC3220" }, | 951 | { 0x10ec0280, 0x1028, 0, "ALC3220" }, |
952 | { 0x10ec0282, 0x1028, 0, "ALC3221" }, | 952 | { 0x10ec0282, 0x1028, 0, "ALC3221" }, |
953 | { 0x10ec0283, 0x1028, 0, "ALC3223" }, | 953 | { 0x10ec0283, 0x1028, 0, "ALC3223" }, |
954 | { 0x10ec0292, 0x1028, 0, "ALC3226" }, | 954 | { 0x10ec0292, 0x1028, 0, "ALC3226" }, |
955 | { 0x10ec0255, 0x1028, 0, "ALC3234" }, | 955 | { 0x10ec0255, 0x1028, 0, "ALC3234" }, |
956 | { 0x10ec0668, 0x1028, 0, "ALC3661" }, | 956 | { 0x10ec0668, 0x1028, 0, "ALC3661" }, |
957 | { } /* terminator */ | 957 | { } /* terminator */ |
958 | }; | 958 | }; |
959 | 959 | ||
960 | static int alc_codec_rename_from_preset(struct hda_codec *codec) | 960 | static int alc_codec_rename_from_preset(struct hda_codec *codec) |
961 | { | 961 | { |
962 | const struct alc_codec_rename_table *p; | 962 | const struct alc_codec_rename_table *p; |
963 | const struct alc_codec_rename_pci_table *q; | 963 | const struct alc_codec_rename_pci_table *q; |
964 | 964 | ||
965 | for (p = rename_tbl; p->vendor_id; p++) { | 965 | for (p = rename_tbl; p->vendor_id; p++) { |
966 | if (p->vendor_id != codec->vendor_id) | 966 | if (p->vendor_id != codec->vendor_id) |
967 | continue; | 967 | continue; |
968 | if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits) | 968 | if ((alc_get_coef0(codec) & p->coef_mask) == p->coef_bits) |
969 | return alc_codec_rename(codec, p->name); | 969 | return alc_codec_rename(codec, p->name); |
970 | } | 970 | } |
971 | 971 | ||
972 | if (!codec->bus->pci) | 972 | if (!codec->bus->pci) |
973 | return 0; | 973 | return 0; |
974 | for (q = rename_pci_tbl; q->codec_vendor_id; q++) { | 974 | for (q = rename_pci_tbl; q->codec_vendor_id; q++) { |
975 | if (q->codec_vendor_id != codec->vendor_id) | 975 | if (q->codec_vendor_id != codec->vendor_id) |
976 | continue; | 976 | continue; |
977 | if (q->pci_subvendor != codec->bus->pci->subsystem_vendor) | 977 | if (q->pci_subvendor != codec->bus->pci->subsystem_vendor) |
978 | continue; | 978 | continue; |
979 | if (!q->pci_subdevice || | 979 | if (!q->pci_subdevice || |
980 | q->pci_subdevice == codec->bus->pci->subsystem_device) | 980 | q->pci_subdevice == codec->bus->pci->subsystem_device) |
981 | return alc_codec_rename(codec, q->name); | 981 | return alc_codec_rename(codec, q->name); |
982 | } | 982 | } |
983 | 983 | ||
984 | return 0; | 984 | return 0; |
985 | } | 985 | } |
986 | 986 | ||
987 | 987 | ||
988 | /* | 988 | /* |
989 | * Digital-beep handlers | 989 | * Digital-beep handlers |
990 | */ | 990 | */ |
991 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 991 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
992 | #define set_beep_amp(spec, nid, idx, dir) \ | 992 | #define set_beep_amp(spec, nid, idx, dir) \ |
993 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) | 993 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) |
994 | 994 | ||
995 | static const struct snd_pci_quirk beep_white_list[] = { | 995 | static const struct snd_pci_quirk beep_white_list[] = { |
996 | SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1), | 996 | SND_PCI_QUIRK(0x1043, 0x103c, "ASUS", 1), |
997 | SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1), | 997 | SND_PCI_QUIRK(0x1043, 0x115d, "ASUS", 1), |
998 | SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), | 998 | SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), |
999 | SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1), | 999 | SND_PCI_QUIRK(0x1043, 0x8376, "EeePC", 1), |
1000 | SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), | 1000 | SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), |
1001 | SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1), | 1001 | SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1), |
1002 | SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1), | 1002 | SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1), |
1003 | SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1), | 1003 | SND_PCI_QUIRK(0x1458, 0xa002, "GA-MA790X", 1), |
1004 | SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), | 1004 | SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), |
1005 | {} | 1005 | {} |
1006 | }; | 1006 | }; |
1007 | 1007 | ||
1008 | static inline int has_cdefine_beep(struct hda_codec *codec) | 1008 | static inline int has_cdefine_beep(struct hda_codec *codec) |
1009 | { | 1009 | { |
1010 | struct alc_spec *spec = codec->spec; | 1010 | struct alc_spec *spec = codec->spec; |
1011 | const struct snd_pci_quirk *q; | 1011 | const struct snd_pci_quirk *q; |
1012 | q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list); | 1012 | q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list); |
1013 | if (q) | 1013 | if (q) |
1014 | return q->value; | 1014 | return q->value; |
1015 | return spec->cdefine.enable_pcbeep; | 1015 | return spec->cdefine.enable_pcbeep; |
1016 | } | 1016 | } |
1017 | #else | 1017 | #else |
1018 | #define set_beep_amp(spec, nid, idx, dir) /* NOP */ | 1018 | #define set_beep_amp(spec, nid, idx, dir) /* NOP */ |
1019 | #define has_cdefine_beep(codec) 0 | 1019 | #define has_cdefine_beep(codec) 0 |
1020 | #endif | 1020 | #endif |
1021 | 1021 | ||
1022 | /* parse the BIOS configuration and set up the alc_spec */ | 1022 | /* parse the BIOS configuration and set up the alc_spec */ |
1023 | /* return 1 if successful, 0 if the proper config is not found, | 1023 | /* return 1 if successful, 0 if the proper config is not found, |
1024 | * or a negative error code | 1024 | * or a negative error code |
1025 | */ | 1025 | */ |
1026 | static int alc_parse_auto_config(struct hda_codec *codec, | 1026 | static int alc_parse_auto_config(struct hda_codec *codec, |
1027 | const hda_nid_t *ignore_nids, | 1027 | const hda_nid_t *ignore_nids, |
1028 | const hda_nid_t *ssid_nids) | 1028 | const hda_nid_t *ssid_nids) |
1029 | { | 1029 | { |
1030 | struct alc_spec *spec = codec->spec; | 1030 | struct alc_spec *spec = codec->spec; |
1031 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; | 1031 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; |
1032 | int err; | 1032 | int err; |
1033 | 1033 | ||
1034 | err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids, | 1034 | err = snd_hda_parse_pin_defcfg(codec, cfg, ignore_nids, |
1035 | spec->parse_flags); | 1035 | spec->parse_flags); |
1036 | if (err < 0) | 1036 | if (err < 0) |
1037 | return err; | 1037 | return err; |
1038 | 1038 | ||
1039 | if (ssid_nids) | 1039 | if (ssid_nids) |
1040 | alc_ssid_check(codec, ssid_nids); | 1040 | alc_ssid_check(codec, ssid_nids); |
1041 | 1041 | ||
1042 | err = snd_hda_gen_parse_auto_config(codec, cfg); | 1042 | err = snd_hda_gen_parse_auto_config(codec, cfg); |
1043 | if (err < 0) | 1043 | if (err < 0) |
1044 | return err; | 1044 | return err; |
1045 | 1045 | ||
1046 | return 1; | 1046 | return 1; |
1047 | } | 1047 | } |
1048 | 1048 | ||
1049 | /* common preparation job for alc_spec */ | 1049 | /* common preparation job for alc_spec */ |
1050 | static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid) | 1050 | static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid) |
1051 | { | 1051 | { |
1052 | struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 1052 | struct alc_spec *spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
1053 | int err; | 1053 | int err; |
1054 | 1054 | ||
1055 | if (!spec) | 1055 | if (!spec) |
1056 | return -ENOMEM; | 1056 | return -ENOMEM; |
1057 | codec->spec = spec; | 1057 | codec->spec = spec; |
1058 | snd_hda_gen_spec_init(&spec->gen); | 1058 | snd_hda_gen_spec_init(&spec->gen); |
1059 | spec->gen.mixer_nid = mixer_nid; | 1059 | spec->gen.mixer_nid = mixer_nid; |
1060 | spec->gen.own_eapd_ctl = 1; | 1060 | spec->gen.own_eapd_ctl = 1; |
1061 | codec->single_adc_amp = 1; | 1061 | codec->single_adc_amp = 1; |
1062 | /* FIXME: do we need this for all Realtek codec models? */ | 1062 | /* FIXME: do we need this for all Realtek codec models? */ |
1063 | codec->spdif_status_reset = 1; | 1063 | codec->spdif_status_reset = 1; |
1064 | 1064 | ||
1065 | err = alc_codec_rename_from_preset(codec); | 1065 | err = alc_codec_rename_from_preset(codec); |
1066 | if (err < 0) { | 1066 | if (err < 0) { |
1067 | kfree(spec); | 1067 | kfree(spec); |
1068 | return err; | 1068 | return err; |
1069 | } | 1069 | } |
1070 | return 0; | 1070 | return 0; |
1071 | } | 1071 | } |
1072 | 1072 | ||
1073 | static int alc880_parse_auto_config(struct hda_codec *codec) | 1073 | static int alc880_parse_auto_config(struct hda_codec *codec) |
1074 | { | 1074 | { |
1075 | static const hda_nid_t alc880_ignore[] = { 0x1d, 0 }; | 1075 | static const hda_nid_t alc880_ignore[] = { 0x1d, 0 }; |
1076 | static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 }; | 1076 | static const hda_nid_t alc880_ssids[] = { 0x15, 0x1b, 0x14, 0 }; |
1077 | return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids); | 1077 | return alc_parse_auto_config(codec, alc880_ignore, alc880_ssids); |
1078 | } | 1078 | } |
1079 | 1079 | ||
1080 | /* | 1080 | /* |
1081 | * ALC880 fix-ups | 1081 | * ALC880 fix-ups |
1082 | */ | 1082 | */ |
1083 | enum { | 1083 | enum { |
1084 | ALC880_FIXUP_GPIO1, | 1084 | ALC880_FIXUP_GPIO1, |
1085 | ALC880_FIXUP_GPIO2, | 1085 | ALC880_FIXUP_GPIO2, |
1086 | ALC880_FIXUP_MEDION_RIM, | 1086 | ALC880_FIXUP_MEDION_RIM, |
1087 | ALC880_FIXUP_LG, | 1087 | ALC880_FIXUP_LG, |
1088 | ALC880_FIXUP_LG_LW25, | 1088 | ALC880_FIXUP_LG_LW25, |
1089 | ALC880_FIXUP_W810, | 1089 | ALC880_FIXUP_W810, |
1090 | ALC880_FIXUP_EAPD_COEF, | 1090 | ALC880_FIXUP_EAPD_COEF, |
1091 | ALC880_FIXUP_TCL_S700, | 1091 | ALC880_FIXUP_TCL_S700, |
1092 | ALC880_FIXUP_VOL_KNOB, | 1092 | ALC880_FIXUP_VOL_KNOB, |
1093 | ALC880_FIXUP_FUJITSU, | 1093 | ALC880_FIXUP_FUJITSU, |
1094 | ALC880_FIXUP_F1734, | 1094 | ALC880_FIXUP_F1734, |
1095 | ALC880_FIXUP_UNIWILL, | 1095 | ALC880_FIXUP_UNIWILL, |
1096 | ALC880_FIXUP_UNIWILL_DIG, | 1096 | ALC880_FIXUP_UNIWILL_DIG, |
1097 | ALC880_FIXUP_Z71V, | 1097 | ALC880_FIXUP_Z71V, |
1098 | ALC880_FIXUP_ASUS_W5A, | 1098 | ALC880_FIXUP_ASUS_W5A, |
1099 | ALC880_FIXUP_3ST_BASE, | 1099 | ALC880_FIXUP_3ST_BASE, |
1100 | ALC880_FIXUP_3ST, | 1100 | ALC880_FIXUP_3ST, |
1101 | ALC880_FIXUP_3ST_DIG, | 1101 | ALC880_FIXUP_3ST_DIG, |
1102 | ALC880_FIXUP_5ST_BASE, | 1102 | ALC880_FIXUP_5ST_BASE, |
1103 | ALC880_FIXUP_5ST, | 1103 | ALC880_FIXUP_5ST, |
1104 | ALC880_FIXUP_5ST_DIG, | 1104 | ALC880_FIXUP_5ST_DIG, |
1105 | ALC880_FIXUP_6ST_BASE, | 1105 | ALC880_FIXUP_6ST_BASE, |
1106 | ALC880_FIXUP_6ST, | 1106 | ALC880_FIXUP_6ST, |
1107 | ALC880_FIXUP_6ST_DIG, | 1107 | ALC880_FIXUP_6ST_DIG, |
1108 | ALC880_FIXUP_6ST_AUTOMUTE, | 1108 | ALC880_FIXUP_6ST_AUTOMUTE, |
1109 | }; | 1109 | }; |
1110 | 1110 | ||
1111 | /* enable the volume-knob widget support on NID 0x21 */ | 1111 | /* enable the volume-knob widget support on NID 0x21 */ |
1112 | static void alc880_fixup_vol_knob(struct hda_codec *codec, | 1112 | static void alc880_fixup_vol_knob(struct hda_codec *codec, |
1113 | const struct hda_fixup *fix, int action) | 1113 | const struct hda_fixup *fix, int action) |
1114 | { | 1114 | { |
1115 | if (action == HDA_FIXUP_ACT_PROBE) | 1115 | if (action == HDA_FIXUP_ACT_PROBE) |
1116 | snd_hda_jack_detect_enable_callback(codec, 0x21, ALC_DCVOL_EVENT, alc_update_knob_master); | 1116 | snd_hda_jack_detect_enable_callback(codec, 0x21, ALC_DCVOL_EVENT, alc_update_knob_master); |
1117 | } | 1117 | } |
1118 | 1118 | ||
1119 | static const struct hda_fixup alc880_fixups[] = { | 1119 | static const struct hda_fixup alc880_fixups[] = { |
1120 | [ALC880_FIXUP_GPIO1] = { | 1120 | [ALC880_FIXUP_GPIO1] = { |
1121 | .type = HDA_FIXUP_VERBS, | 1121 | .type = HDA_FIXUP_VERBS, |
1122 | .v.verbs = alc_gpio1_init_verbs, | 1122 | .v.verbs = alc_gpio1_init_verbs, |
1123 | }, | 1123 | }, |
1124 | [ALC880_FIXUP_GPIO2] = { | 1124 | [ALC880_FIXUP_GPIO2] = { |
1125 | .type = HDA_FIXUP_VERBS, | 1125 | .type = HDA_FIXUP_VERBS, |
1126 | .v.verbs = alc_gpio2_init_verbs, | 1126 | .v.verbs = alc_gpio2_init_verbs, |
1127 | }, | 1127 | }, |
1128 | [ALC880_FIXUP_MEDION_RIM] = { | 1128 | [ALC880_FIXUP_MEDION_RIM] = { |
1129 | .type = HDA_FIXUP_VERBS, | 1129 | .type = HDA_FIXUP_VERBS, |
1130 | .v.verbs = (const struct hda_verb[]) { | 1130 | .v.verbs = (const struct hda_verb[]) { |
1131 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 1131 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
1132 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, | 1132 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, |
1133 | { } | 1133 | { } |
1134 | }, | 1134 | }, |
1135 | .chained = true, | 1135 | .chained = true, |
1136 | .chain_id = ALC880_FIXUP_GPIO2, | 1136 | .chain_id = ALC880_FIXUP_GPIO2, |
1137 | }, | 1137 | }, |
1138 | [ALC880_FIXUP_LG] = { | 1138 | [ALC880_FIXUP_LG] = { |
1139 | .type = HDA_FIXUP_PINS, | 1139 | .type = HDA_FIXUP_PINS, |
1140 | .v.pins = (const struct hda_pintbl[]) { | 1140 | .v.pins = (const struct hda_pintbl[]) { |
1141 | /* disable bogus unused pins */ | 1141 | /* disable bogus unused pins */ |
1142 | { 0x16, 0x411111f0 }, | 1142 | { 0x16, 0x411111f0 }, |
1143 | { 0x18, 0x411111f0 }, | 1143 | { 0x18, 0x411111f0 }, |
1144 | { 0x1a, 0x411111f0 }, | 1144 | { 0x1a, 0x411111f0 }, |
1145 | { } | 1145 | { } |
1146 | } | 1146 | } |
1147 | }, | 1147 | }, |
1148 | [ALC880_FIXUP_LG_LW25] = { | 1148 | [ALC880_FIXUP_LG_LW25] = { |
1149 | .type = HDA_FIXUP_PINS, | 1149 | .type = HDA_FIXUP_PINS, |
1150 | .v.pins = (const struct hda_pintbl[]) { | 1150 | .v.pins = (const struct hda_pintbl[]) { |
1151 | { 0x1a, 0x0181344f }, /* line-in */ | 1151 | { 0x1a, 0x0181344f }, /* line-in */ |
1152 | { 0x1b, 0x0321403f }, /* headphone */ | 1152 | { 0x1b, 0x0321403f }, /* headphone */ |
1153 | { } | 1153 | { } |
1154 | } | 1154 | } |
1155 | }, | 1155 | }, |
1156 | [ALC880_FIXUP_W810] = { | 1156 | [ALC880_FIXUP_W810] = { |
1157 | .type = HDA_FIXUP_PINS, | 1157 | .type = HDA_FIXUP_PINS, |
1158 | .v.pins = (const struct hda_pintbl[]) { | 1158 | .v.pins = (const struct hda_pintbl[]) { |
1159 | /* disable bogus unused pins */ | 1159 | /* disable bogus unused pins */ |
1160 | { 0x17, 0x411111f0 }, | 1160 | { 0x17, 0x411111f0 }, |
1161 | { } | 1161 | { } |
1162 | }, | 1162 | }, |
1163 | .chained = true, | 1163 | .chained = true, |
1164 | .chain_id = ALC880_FIXUP_GPIO2, | 1164 | .chain_id = ALC880_FIXUP_GPIO2, |
1165 | }, | 1165 | }, |
1166 | [ALC880_FIXUP_EAPD_COEF] = { | 1166 | [ALC880_FIXUP_EAPD_COEF] = { |
1167 | .type = HDA_FIXUP_VERBS, | 1167 | .type = HDA_FIXUP_VERBS, |
1168 | .v.verbs = (const struct hda_verb[]) { | 1168 | .v.verbs = (const struct hda_verb[]) { |
1169 | /* change to EAPD mode */ | 1169 | /* change to EAPD mode */ |
1170 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 1170 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
1171 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, | 1171 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, |
1172 | {} | 1172 | {} |
1173 | }, | 1173 | }, |
1174 | }, | 1174 | }, |
1175 | [ALC880_FIXUP_TCL_S700] = { | 1175 | [ALC880_FIXUP_TCL_S700] = { |
1176 | .type = HDA_FIXUP_VERBS, | 1176 | .type = HDA_FIXUP_VERBS, |
1177 | .v.verbs = (const struct hda_verb[]) { | 1177 | .v.verbs = (const struct hda_verb[]) { |
1178 | /* change to EAPD mode */ | 1178 | /* change to EAPD mode */ |
1179 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 1179 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
1180 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, | 1180 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, |
1181 | {} | 1181 | {} |
1182 | }, | 1182 | }, |
1183 | .chained = true, | 1183 | .chained = true, |
1184 | .chain_id = ALC880_FIXUP_GPIO2, | 1184 | .chain_id = ALC880_FIXUP_GPIO2, |
1185 | }, | 1185 | }, |
1186 | [ALC880_FIXUP_VOL_KNOB] = { | 1186 | [ALC880_FIXUP_VOL_KNOB] = { |
1187 | .type = HDA_FIXUP_FUNC, | 1187 | .type = HDA_FIXUP_FUNC, |
1188 | .v.func = alc880_fixup_vol_knob, | 1188 | .v.func = alc880_fixup_vol_knob, |
1189 | }, | 1189 | }, |
1190 | [ALC880_FIXUP_FUJITSU] = { | 1190 | [ALC880_FIXUP_FUJITSU] = { |
1191 | /* override all pins as BIOS on old Amilo is broken */ | 1191 | /* override all pins as BIOS on old Amilo is broken */ |
1192 | .type = HDA_FIXUP_PINS, | 1192 | .type = HDA_FIXUP_PINS, |
1193 | .v.pins = (const struct hda_pintbl[]) { | 1193 | .v.pins = (const struct hda_pintbl[]) { |
1194 | { 0x14, 0x0121411f }, /* HP */ | 1194 | { 0x14, 0x0121411f }, /* HP */ |
1195 | { 0x15, 0x99030120 }, /* speaker */ | 1195 | { 0x15, 0x99030120 }, /* speaker */ |
1196 | { 0x16, 0x99030130 }, /* bass speaker */ | 1196 | { 0x16, 0x99030130 }, /* bass speaker */ |
1197 | { 0x17, 0x411111f0 }, /* N/A */ | 1197 | { 0x17, 0x411111f0 }, /* N/A */ |
1198 | { 0x18, 0x411111f0 }, /* N/A */ | 1198 | { 0x18, 0x411111f0 }, /* N/A */ |
1199 | { 0x19, 0x01a19950 }, /* mic-in */ | 1199 | { 0x19, 0x01a19950 }, /* mic-in */ |
1200 | { 0x1a, 0x411111f0 }, /* N/A */ | 1200 | { 0x1a, 0x411111f0 }, /* N/A */ |
1201 | { 0x1b, 0x411111f0 }, /* N/A */ | 1201 | { 0x1b, 0x411111f0 }, /* N/A */ |
1202 | { 0x1c, 0x411111f0 }, /* N/A */ | 1202 | { 0x1c, 0x411111f0 }, /* N/A */ |
1203 | { 0x1d, 0x411111f0 }, /* N/A */ | 1203 | { 0x1d, 0x411111f0 }, /* N/A */ |
1204 | { 0x1e, 0x01454140 }, /* SPDIF out */ | 1204 | { 0x1e, 0x01454140 }, /* SPDIF out */ |
1205 | { } | 1205 | { } |
1206 | }, | 1206 | }, |
1207 | .chained = true, | 1207 | .chained = true, |
1208 | .chain_id = ALC880_FIXUP_VOL_KNOB, | 1208 | .chain_id = ALC880_FIXUP_VOL_KNOB, |
1209 | }, | 1209 | }, |
1210 | [ALC880_FIXUP_F1734] = { | 1210 | [ALC880_FIXUP_F1734] = { |
1211 | /* almost compatible with FUJITSU, but no bass and SPDIF */ | 1211 | /* almost compatible with FUJITSU, but no bass and SPDIF */ |
1212 | .type = HDA_FIXUP_PINS, | 1212 | .type = HDA_FIXUP_PINS, |
1213 | .v.pins = (const struct hda_pintbl[]) { | 1213 | .v.pins = (const struct hda_pintbl[]) { |
1214 | { 0x14, 0x0121411f }, /* HP */ | 1214 | { 0x14, 0x0121411f }, /* HP */ |
1215 | { 0x15, 0x99030120 }, /* speaker */ | 1215 | { 0x15, 0x99030120 }, /* speaker */ |
1216 | { 0x16, 0x411111f0 }, /* N/A */ | 1216 | { 0x16, 0x411111f0 }, /* N/A */ |
1217 | { 0x17, 0x411111f0 }, /* N/A */ | 1217 | { 0x17, 0x411111f0 }, /* N/A */ |
1218 | { 0x18, 0x411111f0 }, /* N/A */ | 1218 | { 0x18, 0x411111f0 }, /* N/A */ |
1219 | { 0x19, 0x01a19950 }, /* mic-in */ | 1219 | { 0x19, 0x01a19950 }, /* mic-in */ |
1220 | { 0x1a, 0x411111f0 }, /* N/A */ | 1220 | { 0x1a, 0x411111f0 }, /* N/A */ |
1221 | { 0x1b, 0x411111f0 }, /* N/A */ | 1221 | { 0x1b, 0x411111f0 }, /* N/A */ |
1222 | { 0x1c, 0x411111f0 }, /* N/A */ | 1222 | { 0x1c, 0x411111f0 }, /* N/A */ |
1223 | { 0x1d, 0x411111f0 }, /* N/A */ | 1223 | { 0x1d, 0x411111f0 }, /* N/A */ |
1224 | { 0x1e, 0x411111f0 }, /* N/A */ | 1224 | { 0x1e, 0x411111f0 }, /* N/A */ |
1225 | { } | 1225 | { } |
1226 | }, | 1226 | }, |
1227 | .chained = true, | 1227 | .chained = true, |
1228 | .chain_id = ALC880_FIXUP_VOL_KNOB, | 1228 | .chain_id = ALC880_FIXUP_VOL_KNOB, |
1229 | }, | 1229 | }, |
1230 | [ALC880_FIXUP_UNIWILL] = { | 1230 | [ALC880_FIXUP_UNIWILL] = { |
1231 | /* need to fix HP and speaker pins to be parsed correctly */ | 1231 | /* need to fix HP and speaker pins to be parsed correctly */ |
1232 | .type = HDA_FIXUP_PINS, | 1232 | .type = HDA_FIXUP_PINS, |
1233 | .v.pins = (const struct hda_pintbl[]) { | 1233 | .v.pins = (const struct hda_pintbl[]) { |
1234 | { 0x14, 0x0121411f }, /* HP */ | 1234 | { 0x14, 0x0121411f }, /* HP */ |
1235 | { 0x15, 0x99030120 }, /* speaker */ | 1235 | { 0x15, 0x99030120 }, /* speaker */ |
1236 | { 0x16, 0x99030130 }, /* bass speaker */ | 1236 | { 0x16, 0x99030130 }, /* bass speaker */ |
1237 | { } | 1237 | { } |
1238 | }, | 1238 | }, |
1239 | }, | 1239 | }, |
1240 | [ALC880_FIXUP_UNIWILL_DIG] = { | 1240 | [ALC880_FIXUP_UNIWILL_DIG] = { |
1241 | .type = HDA_FIXUP_PINS, | 1241 | .type = HDA_FIXUP_PINS, |
1242 | .v.pins = (const struct hda_pintbl[]) { | 1242 | .v.pins = (const struct hda_pintbl[]) { |
1243 | /* disable bogus unused pins */ | 1243 | /* disable bogus unused pins */ |
1244 | { 0x17, 0x411111f0 }, | 1244 | { 0x17, 0x411111f0 }, |
1245 | { 0x19, 0x411111f0 }, | 1245 | { 0x19, 0x411111f0 }, |
1246 | { 0x1b, 0x411111f0 }, | 1246 | { 0x1b, 0x411111f0 }, |
1247 | { 0x1f, 0x411111f0 }, | 1247 | { 0x1f, 0x411111f0 }, |
1248 | { } | 1248 | { } |
1249 | } | 1249 | } |
1250 | }, | 1250 | }, |
1251 | [ALC880_FIXUP_Z71V] = { | 1251 | [ALC880_FIXUP_Z71V] = { |
1252 | .type = HDA_FIXUP_PINS, | 1252 | .type = HDA_FIXUP_PINS, |
1253 | .v.pins = (const struct hda_pintbl[]) { | 1253 | .v.pins = (const struct hda_pintbl[]) { |
1254 | /* set up the whole pins as BIOS is utterly broken */ | 1254 | /* set up the whole pins as BIOS is utterly broken */ |
1255 | { 0x14, 0x99030120 }, /* speaker */ | 1255 | { 0x14, 0x99030120 }, /* speaker */ |
1256 | { 0x15, 0x0121411f }, /* HP */ | 1256 | { 0x15, 0x0121411f }, /* HP */ |
1257 | { 0x16, 0x411111f0 }, /* N/A */ | 1257 | { 0x16, 0x411111f0 }, /* N/A */ |
1258 | { 0x17, 0x411111f0 }, /* N/A */ | 1258 | { 0x17, 0x411111f0 }, /* N/A */ |
1259 | { 0x18, 0x01a19950 }, /* mic-in */ | 1259 | { 0x18, 0x01a19950 }, /* mic-in */ |
1260 | { 0x19, 0x411111f0 }, /* N/A */ | 1260 | { 0x19, 0x411111f0 }, /* N/A */ |
1261 | { 0x1a, 0x01813031 }, /* line-in */ | 1261 | { 0x1a, 0x01813031 }, /* line-in */ |
1262 | { 0x1b, 0x411111f0 }, /* N/A */ | 1262 | { 0x1b, 0x411111f0 }, /* N/A */ |
1263 | { 0x1c, 0x411111f0 }, /* N/A */ | 1263 | { 0x1c, 0x411111f0 }, /* N/A */ |
1264 | { 0x1d, 0x411111f0 }, /* N/A */ | 1264 | { 0x1d, 0x411111f0 }, /* N/A */ |
1265 | { 0x1e, 0x0144111e }, /* SPDIF */ | 1265 | { 0x1e, 0x0144111e }, /* SPDIF */ |
1266 | { } | 1266 | { } |
1267 | } | 1267 | } |
1268 | }, | 1268 | }, |
1269 | [ALC880_FIXUP_ASUS_W5A] = { | 1269 | [ALC880_FIXUP_ASUS_W5A] = { |
1270 | .type = HDA_FIXUP_PINS, | 1270 | .type = HDA_FIXUP_PINS, |
1271 | .v.pins = (const struct hda_pintbl[]) { | 1271 | .v.pins = (const struct hda_pintbl[]) { |
1272 | /* set up the whole pins as BIOS is utterly broken */ | 1272 | /* set up the whole pins as BIOS is utterly broken */ |
1273 | { 0x14, 0x0121411f }, /* HP */ | 1273 | { 0x14, 0x0121411f }, /* HP */ |
1274 | { 0x15, 0x411111f0 }, /* N/A */ | 1274 | { 0x15, 0x411111f0 }, /* N/A */ |
1275 | { 0x16, 0x411111f0 }, /* N/A */ | 1275 | { 0x16, 0x411111f0 }, /* N/A */ |
1276 | { 0x17, 0x411111f0 }, /* N/A */ | 1276 | { 0x17, 0x411111f0 }, /* N/A */ |
1277 | { 0x18, 0x90a60160 }, /* mic */ | 1277 | { 0x18, 0x90a60160 }, /* mic */ |
1278 | { 0x19, 0x411111f0 }, /* N/A */ | 1278 | { 0x19, 0x411111f0 }, /* N/A */ |
1279 | { 0x1a, 0x411111f0 }, /* N/A */ | 1279 | { 0x1a, 0x411111f0 }, /* N/A */ |
1280 | { 0x1b, 0x411111f0 }, /* N/A */ | 1280 | { 0x1b, 0x411111f0 }, /* N/A */ |
1281 | { 0x1c, 0x411111f0 }, /* N/A */ | 1281 | { 0x1c, 0x411111f0 }, /* N/A */ |
1282 | { 0x1d, 0x411111f0 }, /* N/A */ | 1282 | { 0x1d, 0x411111f0 }, /* N/A */ |
1283 | { 0x1e, 0xb743111e }, /* SPDIF out */ | 1283 | { 0x1e, 0xb743111e }, /* SPDIF out */ |
1284 | { } | 1284 | { } |
1285 | }, | 1285 | }, |
1286 | .chained = true, | 1286 | .chained = true, |
1287 | .chain_id = ALC880_FIXUP_GPIO1, | 1287 | .chain_id = ALC880_FIXUP_GPIO1, |
1288 | }, | 1288 | }, |
1289 | [ALC880_FIXUP_3ST_BASE] = { | 1289 | [ALC880_FIXUP_3ST_BASE] = { |
1290 | .type = HDA_FIXUP_PINS, | 1290 | .type = HDA_FIXUP_PINS, |
1291 | .v.pins = (const struct hda_pintbl[]) { | 1291 | .v.pins = (const struct hda_pintbl[]) { |
1292 | { 0x14, 0x01014010 }, /* line-out */ | 1292 | { 0x14, 0x01014010 }, /* line-out */ |
1293 | { 0x15, 0x411111f0 }, /* N/A */ | 1293 | { 0x15, 0x411111f0 }, /* N/A */ |
1294 | { 0x16, 0x411111f0 }, /* N/A */ | 1294 | { 0x16, 0x411111f0 }, /* N/A */ |
1295 | { 0x17, 0x411111f0 }, /* N/A */ | 1295 | { 0x17, 0x411111f0 }, /* N/A */ |
1296 | { 0x18, 0x01a19c30 }, /* mic-in */ | 1296 | { 0x18, 0x01a19c30 }, /* mic-in */ |
1297 | { 0x19, 0x0121411f }, /* HP */ | 1297 | { 0x19, 0x0121411f }, /* HP */ |
1298 | { 0x1a, 0x01813031 }, /* line-in */ | 1298 | { 0x1a, 0x01813031 }, /* line-in */ |
1299 | { 0x1b, 0x02a19c40 }, /* front-mic */ | 1299 | { 0x1b, 0x02a19c40 }, /* front-mic */ |
1300 | { 0x1c, 0x411111f0 }, /* N/A */ | 1300 | { 0x1c, 0x411111f0 }, /* N/A */ |
1301 | { 0x1d, 0x411111f0 }, /* N/A */ | 1301 | { 0x1d, 0x411111f0 }, /* N/A */ |
1302 | /* 0x1e is filled in below */ | 1302 | /* 0x1e is filled in below */ |
1303 | { 0x1f, 0x411111f0 }, /* N/A */ | 1303 | { 0x1f, 0x411111f0 }, /* N/A */ |
1304 | { } | 1304 | { } |
1305 | } | 1305 | } |
1306 | }, | 1306 | }, |
1307 | [ALC880_FIXUP_3ST] = { | 1307 | [ALC880_FIXUP_3ST] = { |
1308 | .type = HDA_FIXUP_PINS, | 1308 | .type = HDA_FIXUP_PINS, |
1309 | .v.pins = (const struct hda_pintbl[]) { | 1309 | .v.pins = (const struct hda_pintbl[]) { |
1310 | { 0x1e, 0x411111f0 }, /* N/A */ | 1310 | { 0x1e, 0x411111f0 }, /* N/A */ |
1311 | { } | 1311 | { } |
1312 | }, | 1312 | }, |
1313 | .chained = true, | 1313 | .chained = true, |
1314 | .chain_id = ALC880_FIXUP_3ST_BASE, | 1314 | .chain_id = ALC880_FIXUP_3ST_BASE, |
1315 | }, | 1315 | }, |
1316 | [ALC880_FIXUP_3ST_DIG] = { | 1316 | [ALC880_FIXUP_3ST_DIG] = { |
1317 | .type = HDA_FIXUP_PINS, | 1317 | .type = HDA_FIXUP_PINS, |
1318 | .v.pins = (const struct hda_pintbl[]) { | 1318 | .v.pins = (const struct hda_pintbl[]) { |
1319 | { 0x1e, 0x0144111e }, /* SPDIF */ | 1319 | { 0x1e, 0x0144111e }, /* SPDIF */ |
1320 | { } | 1320 | { } |
1321 | }, | 1321 | }, |
1322 | .chained = true, | 1322 | .chained = true, |
1323 | .chain_id = ALC880_FIXUP_3ST_BASE, | 1323 | .chain_id = ALC880_FIXUP_3ST_BASE, |
1324 | }, | 1324 | }, |
1325 | [ALC880_FIXUP_5ST_BASE] = { | 1325 | [ALC880_FIXUP_5ST_BASE] = { |
1326 | .type = HDA_FIXUP_PINS, | 1326 | .type = HDA_FIXUP_PINS, |
1327 | .v.pins = (const struct hda_pintbl[]) { | 1327 | .v.pins = (const struct hda_pintbl[]) { |
1328 | { 0x14, 0x01014010 }, /* front */ | 1328 | { 0x14, 0x01014010 }, /* front */ |
1329 | { 0x15, 0x411111f0 }, /* N/A */ | 1329 | { 0x15, 0x411111f0 }, /* N/A */ |
1330 | { 0x16, 0x01011411 }, /* CLFE */ | 1330 | { 0x16, 0x01011411 }, /* CLFE */ |
1331 | { 0x17, 0x01016412 }, /* surr */ | 1331 | { 0x17, 0x01016412 }, /* surr */ |
1332 | { 0x18, 0x01a19c30 }, /* mic-in */ | 1332 | { 0x18, 0x01a19c30 }, /* mic-in */ |
1333 | { 0x19, 0x0121411f }, /* HP */ | 1333 | { 0x19, 0x0121411f }, /* HP */ |
1334 | { 0x1a, 0x01813031 }, /* line-in */ | 1334 | { 0x1a, 0x01813031 }, /* line-in */ |
1335 | { 0x1b, 0x02a19c40 }, /* front-mic */ | 1335 | { 0x1b, 0x02a19c40 }, /* front-mic */ |
1336 | { 0x1c, 0x411111f0 }, /* N/A */ | 1336 | { 0x1c, 0x411111f0 }, /* N/A */ |
1337 | { 0x1d, 0x411111f0 }, /* N/A */ | 1337 | { 0x1d, 0x411111f0 }, /* N/A */ |
1338 | /* 0x1e is filled in below */ | 1338 | /* 0x1e is filled in below */ |
1339 | { 0x1f, 0x411111f0 }, /* N/A */ | 1339 | { 0x1f, 0x411111f0 }, /* N/A */ |
1340 | { } | 1340 | { } |
1341 | } | 1341 | } |
1342 | }, | 1342 | }, |
1343 | [ALC880_FIXUP_5ST] = { | 1343 | [ALC880_FIXUP_5ST] = { |
1344 | .type = HDA_FIXUP_PINS, | 1344 | .type = HDA_FIXUP_PINS, |
1345 | .v.pins = (const struct hda_pintbl[]) { | 1345 | .v.pins = (const struct hda_pintbl[]) { |
1346 | { 0x1e, 0x411111f0 }, /* N/A */ | 1346 | { 0x1e, 0x411111f0 }, /* N/A */ |
1347 | { } | 1347 | { } |
1348 | }, | 1348 | }, |
1349 | .chained = true, | 1349 | .chained = true, |
1350 | .chain_id = ALC880_FIXUP_5ST_BASE, | 1350 | .chain_id = ALC880_FIXUP_5ST_BASE, |
1351 | }, | 1351 | }, |
1352 | [ALC880_FIXUP_5ST_DIG] = { | 1352 | [ALC880_FIXUP_5ST_DIG] = { |
1353 | .type = HDA_FIXUP_PINS, | 1353 | .type = HDA_FIXUP_PINS, |
1354 | .v.pins = (const struct hda_pintbl[]) { | 1354 | .v.pins = (const struct hda_pintbl[]) { |
1355 | { 0x1e, 0x0144111e }, /* SPDIF */ | 1355 | { 0x1e, 0x0144111e }, /* SPDIF */ |
1356 | { } | 1356 | { } |
1357 | }, | 1357 | }, |
1358 | .chained = true, | 1358 | .chained = true, |
1359 | .chain_id = ALC880_FIXUP_5ST_BASE, | 1359 | .chain_id = ALC880_FIXUP_5ST_BASE, |
1360 | }, | 1360 | }, |
1361 | [ALC880_FIXUP_6ST_BASE] = { | 1361 | [ALC880_FIXUP_6ST_BASE] = { |
1362 | .type = HDA_FIXUP_PINS, | 1362 | .type = HDA_FIXUP_PINS, |
1363 | .v.pins = (const struct hda_pintbl[]) { | 1363 | .v.pins = (const struct hda_pintbl[]) { |
1364 | { 0x14, 0x01014010 }, /* front */ | 1364 | { 0x14, 0x01014010 }, /* front */ |
1365 | { 0x15, 0x01016412 }, /* surr */ | 1365 | { 0x15, 0x01016412 }, /* surr */ |
1366 | { 0x16, 0x01011411 }, /* CLFE */ | 1366 | { 0x16, 0x01011411 }, /* CLFE */ |
1367 | { 0x17, 0x01012414 }, /* side */ | 1367 | { 0x17, 0x01012414 }, /* side */ |
1368 | { 0x18, 0x01a19c30 }, /* mic-in */ | 1368 | { 0x18, 0x01a19c30 }, /* mic-in */ |
1369 | { 0x19, 0x02a19c40 }, /* front-mic */ | 1369 | { 0x19, 0x02a19c40 }, /* front-mic */ |
1370 | { 0x1a, 0x01813031 }, /* line-in */ | 1370 | { 0x1a, 0x01813031 }, /* line-in */ |
1371 | { 0x1b, 0x0121411f }, /* HP */ | 1371 | { 0x1b, 0x0121411f }, /* HP */ |
1372 | { 0x1c, 0x411111f0 }, /* N/A */ | 1372 | { 0x1c, 0x411111f0 }, /* N/A */ |
1373 | { 0x1d, 0x411111f0 }, /* N/A */ | 1373 | { 0x1d, 0x411111f0 }, /* N/A */ |
1374 | /* 0x1e is filled in below */ | 1374 | /* 0x1e is filled in below */ |
1375 | { 0x1f, 0x411111f0 }, /* N/A */ | 1375 | { 0x1f, 0x411111f0 }, /* N/A */ |
1376 | { } | 1376 | { } |
1377 | } | 1377 | } |
1378 | }, | 1378 | }, |
1379 | [ALC880_FIXUP_6ST] = { | 1379 | [ALC880_FIXUP_6ST] = { |
1380 | .type = HDA_FIXUP_PINS, | 1380 | .type = HDA_FIXUP_PINS, |
1381 | .v.pins = (const struct hda_pintbl[]) { | 1381 | .v.pins = (const struct hda_pintbl[]) { |
1382 | { 0x1e, 0x411111f0 }, /* N/A */ | 1382 | { 0x1e, 0x411111f0 }, /* N/A */ |
1383 | { } | 1383 | { } |
1384 | }, | 1384 | }, |
1385 | .chained = true, | 1385 | .chained = true, |
1386 | .chain_id = ALC880_FIXUP_6ST_BASE, | 1386 | .chain_id = ALC880_FIXUP_6ST_BASE, |
1387 | }, | 1387 | }, |
1388 | [ALC880_FIXUP_6ST_DIG] = { | 1388 | [ALC880_FIXUP_6ST_DIG] = { |
1389 | .type = HDA_FIXUP_PINS, | 1389 | .type = HDA_FIXUP_PINS, |
1390 | .v.pins = (const struct hda_pintbl[]) { | 1390 | .v.pins = (const struct hda_pintbl[]) { |
1391 | { 0x1e, 0x0144111e }, /* SPDIF */ | 1391 | { 0x1e, 0x0144111e }, /* SPDIF */ |
1392 | { } | 1392 | { } |
1393 | }, | 1393 | }, |
1394 | .chained = true, | 1394 | .chained = true, |
1395 | .chain_id = ALC880_FIXUP_6ST_BASE, | 1395 | .chain_id = ALC880_FIXUP_6ST_BASE, |
1396 | }, | 1396 | }, |
1397 | [ALC880_FIXUP_6ST_AUTOMUTE] = { | 1397 | [ALC880_FIXUP_6ST_AUTOMUTE] = { |
1398 | .type = HDA_FIXUP_PINS, | 1398 | .type = HDA_FIXUP_PINS, |
1399 | .v.pins = (const struct hda_pintbl[]) { | 1399 | .v.pins = (const struct hda_pintbl[]) { |
1400 | { 0x1b, 0x0121401f }, /* HP with jack detect */ | 1400 | { 0x1b, 0x0121401f }, /* HP with jack detect */ |
1401 | { } | 1401 | { } |
1402 | }, | 1402 | }, |
1403 | .chained_before = true, | 1403 | .chained_before = true, |
1404 | .chain_id = ALC880_FIXUP_6ST_BASE, | 1404 | .chain_id = ALC880_FIXUP_6ST_BASE, |
1405 | }, | 1405 | }, |
1406 | }; | 1406 | }; |
1407 | 1407 | ||
1408 | static const struct snd_pci_quirk alc880_fixup_tbl[] = { | 1408 | static const struct snd_pci_quirk alc880_fixup_tbl[] = { |
1409 | SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810), | 1409 | SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_FIXUP_W810), |
1410 | SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A), | 1410 | SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS W5A", ALC880_FIXUP_ASUS_W5A), |
1411 | SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V), | 1411 | SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_FIXUP_Z71V), |
1412 | SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1), | 1412 | SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_FIXUP_GPIO1), |
1413 | SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2), | 1413 | SND_PCI_QUIRK(0x1558, 0x5401, "Clevo GPIO2", ALC880_FIXUP_GPIO2), |
1414 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF), | 1414 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo", ALC880_FIXUP_EAPD_COEF), |
1415 | SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG), | 1415 | SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_FIXUP_UNIWILL_DIG), |
1416 | SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734), | 1416 | SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_FIXUP_F1734), |
1417 | SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL), | 1417 | SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_FIXUP_UNIWILL), |
1418 | SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB), | 1418 | SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_FIXUP_VOL_KNOB), |
1419 | SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810), | 1419 | SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_FIXUP_W810), |
1420 | SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM), | 1420 | SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_FIXUP_MEDION_RIM), |
1421 | SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE), | 1421 | SND_PCI_QUIRK(0x1631, 0xe011, "PB 13201056", ALC880_FIXUP_6ST_AUTOMUTE), |
1422 | SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_FIXUP_F1734), | 1422 | SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_FIXUP_F1734), |
1423 | SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU), | 1423 | SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FIXUP_FUJITSU), |
1424 | SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734), | 1424 | SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_FIXUP_F1734), |
1425 | SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU), | 1425 | SND_PCI_QUIRK(0x1734, 0x10b0, "FSC Amilo Pi1556", ALC880_FIXUP_FUJITSU), |
1426 | SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG), | 1426 | SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_FIXUP_LG), |
1427 | SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG), | 1427 | SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_FIXUP_LG), |
1428 | SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG), | 1428 | SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_FIXUP_LG), |
1429 | SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25), | 1429 | SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_FIXUP_LG_LW25), |
1430 | SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700), | 1430 | SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_FIXUP_TCL_S700), |
1431 | 1431 | ||
1432 | /* Below is the copied entries from alc880_quirks.c. | 1432 | /* Below is the copied entries from alc880_quirks.c. |
1433 | * It's not quite sure whether BIOS sets the correct pin-config table | 1433 | * It's not quite sure whether BIOS sets the correct pin-config table |
1434 | * on these machines, thus they are kept to be compatible with | 1434 | * on these machines, thus they are kept to be compatible with |
1435 | * the old static quirks. Once when it's confirmed to work without | 1435 | * the old static quirks. Once when it's confirmed to work without |
1436 | * these overrides, it'd be better to remove. | 1436 | * these overrides, it'd be better to remove. |
1437 | */ | 1437 | */ |
1438 | SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG), | 1438 | SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_FIXUP_5ST_DIG), |
1439 | SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST), | 1439 | SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_FIXUP_6ST), |
1440 | SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG), | 1440 | SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_FIXUP_3ST_DIG), |
1441 | SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG), | 1441 | SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_FIXUP_6ST_DIG), |
1442 | SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG), | 1442 | SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_FIXUP_6ST_DIG), |
1443 | SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG), | 1443 | SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_FIXUP_6ST_DIG), |
1444 | SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG), | 1444 | SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_FIXUP_3ST_DIG), |
1445 | SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST), | 1445 | SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_FIXUP_3ST), |
1446 | SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG), | 1446 | SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_FIXUP_6ST_DIG), |
1447 | SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST), | 1447 | SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_FIXUP_3ST), |
1448 | SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST), | 1448 | SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_FIXUP_3ST), |
1449 | SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST), | 1449 | SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_FIXUP_5ST), |
1450 | SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST), | 1450 | SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_FIXUP_5ST), |
1451 | SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST), | 1451 | SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_FIXUP_5ST), |
1452 | SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG), | 1452 | SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_FIXUP_6ST_DIG), |
1453 | SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG), | 1453 | SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_FIXUP_6ST_DIG), |
1454 | SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG), | 1454 | SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_FIXUP_6ST_DIG), |
1455 | SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG), | 1455 | SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_FIXUP_6ST_DIG), |
1456 | SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG), | 1456 | SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_FIXUP_5ST_DIG), |
1457 | SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG), | 1457 | SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_FIXUP_5ST_DIG), |
1458 | SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG), | 1458 | SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_FIXUP_5ST_DIG), |
1459 | SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */ | 1459 | SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_FIXUP_6ST_DIG), /* broken BIOS */ |
1460 | SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG), | 1460 | SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_FIXUP_6ST_DIG), |
1461 | SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG), | 1461 | SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_FIXUP_5ST_DIG), |
1462 | SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG), | 1462 | SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_FIXUP_5ST_DIG), |
1463 | SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG), | 1463 | SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_FIXUP_5ST_DIG), |
1464 | SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG), | 1464 | SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_FIXUP_3ST_DIG), |
1465 | SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG), | 1465 | SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_FIXUP_5ST_DIG), |
1466 | SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG), | 1466 | SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_FIXUP_3ST_DIG), |
1467 | SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG), | 1467 | SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_FIXUP_3ST_DIG), |
1468 | SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG), | 1468 | SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_FIXUP_5ST_DIG), |
1469 | SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG), | 1469 | SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_FIXUP_5ST_DIG), |
1470 | SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG), | 1470 | SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_FIXUP_5ST_DIG), |
1471 | /* default Intel */ | 1471 | /* default Intel */ |
1472 | SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST), | 1472 | SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_FIXUP_3ST), |
1473 | SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG), | 1473 | SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_FIXUP_5ST_DIG), |
1474 | SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG), | 1474 | SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_FIXUP_6ST_DIG), |
1475 | {} | 1475 | {} |
1476 | }; | 1476 | }; |
1477 | 1477 | ||
1478 | static const struct hda_model_fixup alc880_fixup_models[] = { | 1478 | static const struct hda_model_fixup alc880_fixup_models[] = { |
1479 | {.id = ALC880_FIXUP_3ST, .name = "3stack"}, | 1479 | {.id = ALC880_FIXUP_3ST, .name = "3stack"}, |
1480 | {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"}, | 1480 | {.id = ALC880_FIXUP_3ST_DIG, .name = "3stack-digout"}, |
1481 | {.id = ALC880_FIXUP_5ST, .name = "5stack"}, | 1481 | {.id = ALC880_FIXUP_5ST, .name = "5stack"}, |
1482 | {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"}, | 1482 | {.id = ALC880_FIXUP_5ST_DIG, .name = "5stack-digout"}, |
1483 | {.id = ALC880_FIXUP_6ST, .name = "6stack"}, | 1483 | {.id = ALC880_FIXUP_6ST, .name = "6stack"}, |
1484 | {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"}, | 1484 | {.id = ALC880_FIXUP_6ST_DIG, .name = "6stack-digout"}, |
1485 | {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"}, | 1485 | {.id = ALC880_FIXUP_6ST_AUTOMUTE, .name = "6stack-automute"}, |
1486 | {} | 1486 | {} |
1487 | }; | 1487 | }; |
1488 | 1488 | ||
1489 | 1489 | ||
1490 | /* | 1490 | /* |
1491 | * OK, here we have finally the patch for ALC880 | 1491 | * OK, here we have finally the patch for ALC880 |
1492 | */ | 1492 | */ |
1493 | static int patch_alc880(struct hda_codec *codec) | 1493 | static int patch_alc880(struct hda_codec *codec) |
1494 | { | 1494 | { |
1495 | struct alc_spec *spec; | 1495 | struct alc_spec *spec; |
1496 | int err; | 1496 | int err; |
1497 | 1497 | ||
1498 | err = alc_alloc_spec(codec, 0x0b); | 1498 | err = alc_alloc_spec(codec, 0x0b); |
1499 | if (err < 0) | 1499 | if (err < 0) |
1500 | return err; | 1500 | return err; |
1501 | 1501 | ||
1502 | spec = codec->spec; | 1502 | spec = codec->spec; |
1503 | spec->gen.need_dac_fix = 1; | 1503 | spec->gen.need_dac_fix = 1; |
1504 | spec->gen.beep_nid = 0x01; | 1504 | spec->gen.beep_nid = 0x01; |
1505 | 1505 | ||
1506 | snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl, | 1506 | snd_hda_pick_fixup(codec, alc880_fixup_models, alc880_fixup_tbl, |
1507 | alc880_fixups); | 1507 | alc880_fixups); |
1508 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 1508 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
1509 | 1509 | ||
1510 | /* automatic parse from the BIOS config */ | 1510 | /* automatic parse from the BIOS config */ |
1511 | err = alc880_parse_auto_config(codec); | 1511 | err = alc880_parse_auto_config(codec); |
1512 | if (err < 0) | 1512 | if (err < 0) |
1513 | goto error; | 1513 | goto error; |
1514 | 1514 | ||
1515 | if (!spec->gen.no_analog) | 1515 | if (!spec->gen.no_analog) |
1516 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 1516 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
1517 | 1517 | ||
1518 | codec->patch_ops = alc_patch_ops; | 1518 | codec->patch_ops = alc_patch_ops; |
1519 | codec->patch_ops.unsol_event = alc880_unsol_event; | 1519 | codec->patch_ops.unsol_event = alc880_unsol_event; |
1520 | 1520 | ||
1521 | 1521 | ||
1522 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 1522 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
1523 | 1523 | ||
1524 | return 0; | 1524 | return 0; |
1525 | 1525 | ||
1526 | error: | 1526 | error: |
1527 | alc_free(codec); | 1527 | alc_free(codec); |
1528 | return err; | 1528 | return err; |
1529 | } | 1529 | } |
1530 | 1530 | ||
1531 | 1531 | ||
1532 | /* | 1532 | /* |
1533 | * ALC260 support | 1533 | * ALC260 support |
1534 | */ | 1534 | */ |
1535 | static int alc260_parse_auto_config(struct hda_codec *codec) | 1535 | static int alc260_parse_auto_config(struct hda_codec *codec) |
1536 | { | 1536 | { |
1537 | static const hda_nid_t alc260_ignore[] = { 0x17, 0 }; | 1537 | static const hda_nid_t alc260_ignore[] = { 0x17, 0 }; |
1538 | static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 }; | 1538 | static const hda_nid_t alc260_ssids[] = { 0x10, 0x15, 0x0f, 0 }; |
1539 | return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids); | 1539 | return alc_parse_auto_config(codec, alc260_ignore, alc260_ssids); |
1540 | } | 1540 | } |
1541 | 1541 | ||
1542 | /* | 1542 | /* |
1543 | * Pin config fixes | 1543 | * Pin config fixes |
1544 | */ | 1544 | */ |
1545 | enum { | 1545 | enum { |
1546 | ALC260_FIXUP_HP_DC5750, | 1546 | ALC260_FIXUP_HP_DC5750, |
1547 | ALC260_FIXUP_HP_PIN_0F, | 1547 | ALC260_FIXUP_HP_PIN_0F, |
1548 | ALC260_FIXUP_COEF, | 1548 | ALC260_FIXUP_COEF, |
1549 | ALC260_FIXUP_GPIO1, | 1549 | ALC260_FIXUP_GPIO1, |
1550 | ALC260_FIXUP_GPIO1_TOGGLE, | 1550 | ALC260_FIXUP_GPIO1_TOGGLE, |
1551 | ALC260_FIXUP_REPLACER, | 1551 | ALC260_FIXUP_REPLACER, |
1552 | ALC260_FIXUP_HP_B1900, | 1552 | ALC260_FIXUP_HP_B1900, |
1553 | ALC260_FIXUP_KN1, | 1553 | ALC260_FIXUP_KN1, |
1554 | ALC260_FIXUP_FSC_S7020, | 1554 | ALC260_FIXUP_FSC_S7020, |
1555 | ALC260_FIXUP_FSC_S7020_JWSE, | 1555 | ALC260_FIXUP_FSC_S7020_JWSE, |
1556 | ALC260_FIXUP_VAIO_PINS, | 1556 | ALC260_FIXUP_VAIO_PINS, |
1557 | }; | 1557 | }; |
1558 | 1558 | ||
1559 | static void alc260_gpio1_automute(struct hda_codec *codec) | 1559 | static void alc260_gpio1_automute(struct hda_codec *codec) |
1560 | { | 1560 | { |
1561 | struct alc_spec *spec = codec->spec; | 1561 | struct alc_spec *spec = codec->spec; |
1562 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | 1562 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, |
1563 | spec->gen.hp_jack_present); | 1563 | spec->gen.hp_jack_present); |
1564 | } | 1564 | } |
1565 | 1565 | ||
1566 | static void alc260_fixup_gpio1_toggle(struct hda_codec *codec, | 1566 | static void alc260_fixup_gpio1_toggle(struct hda_codec *codec, |
1567 | const struct hda_fixup *fix, int action) | 1567 | const struct hda_fixup *fix, int action) |
1568 | { | 1568 | { |
1569 | struct alc_spec *spec = codec->spec; | 1569 | struct alc_spec *spec = codec->spec; |
1570 | if (action == HDA_FIXUP_ACT_PROBE) { | 1570 | if (action == HDA_FIXUP_ACT_PROBE) { |
1571 | /* although the machine has only one output pin, we need to | 1571 | /* although the machine has only one output pin, we need to |
1572 | * toggle GPIO1 according to the jack state | 1572 | * toggle GPIO1 according to the jack state |
1573 | */ | 1573 | */ |
1574 | spec->gen.automute_hook = alc260_gpio1_automute; | 1574 | spec->gen.automute_hook = alc260_gpio1_automute; |
1575 | spec->gen.detect_hp = 1; | 1575 | spec->gen.detect_hp = 1; |
1576 | spec->gen.automute_speaker = 1; | 1576 | spec->gen.automute_speaker = 1; |
1577 | spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */ | 1577 | spec->gen.autocfg.hp_pins[0] = 0x0f; /* copy it for automute */ |
1578 | snd_hda_jack_detect_enable_callback(codec, 0x0f, HDA_GEN_HP_EVENT, | 1578 | snd_hda_jack_detect_enable_callback(codec, 0x0f, HDA_GEN_HP_EVENT, |
1579 | snd_hda_gen_hp_automute); | 1579 | snd_hda_gen_hp_automute); |
1580 | snd_hda_add_verbs(codec, alc_gpio1_init_verbs); | 1580 | snd_hda_add_verbs(codec, alc_gpio1_init_verbs); |
1581 | } | 1581 | } |
1582 | } | 1582 | } |
1583 | 1583 | ||
1584 | static void alc260_fixup_kn1(struct hda_codec *codec, | 1584 | static void alc260_fixup_kn1(struct hda_codec *codec, |
1585 | const struct hda_fixup *fix, int action) | 1585 | const struct hda_fixup *fix, int action) |
1586 | { | 1586 | { |
1587 | struct alc_spec *spec = codec->spec; | 1587 | struct alc_spec *spec = codec->spec; |
1588 | static const struct hda_pintbl pincfgs[] = { | 1588 | static const struct hda_pintbl pincfgs[] = { |
1589 | { 0x0f, 0x02214000 }, /* HP/speaker */ | 1589 | { 0x0f, 0x02214000 }, /* HP/speaker */ |
1590 | { 0x12, 0x90a60160 }, /* int mic */ | 1590 | { 0x12, 0x90a60160 }, /* int mic */ |
1591 | { 0x13, 0x02a19000 }, /* ext mic */ | 1591 | { 0x13, 0x02a19000 }, /* ext mic */ |
1592 | { 0x18, 0x01446000 }, /* SPDIF out */ | 1592 | { 0x18, 0x01446000 }, /* SPDIF out */ |
1593 | /* disable bogus I/O pins */ | 1593 | /* disable bogus I/O pins */ |
1594 | { 0x10, 0x411111f0 }, | 1594 | { 0x10, 0x411111f0 }, |
1595 | { 0x11, 0x411111f0 }, | 1595 | { 0x11, 0x411111f0 }, |
1596 | { 0x14, 0x411111f0 }, | 1596 | { 0x14, 0x411111f0 }, |
1597 | { 0x15, 0x411111f0 }, | 1597 | { 0x15, 0x411111f0 }, |
1598 | { 0x16, 0x411111f0 }, | 1598 | { 0x16, 0x411111f0 }, |
1599 | { 0x17, 0x411111f0 }, | 1599 | { 0x17, 0x411111f0 }, |
1600 | { 0x19, 0x411111f0 }, | 1600 | { 0x19, 0x411111f0 }, |
1601 | { } | 1601 | { } |
1602 | }; | 1602 | }; |
1603 | 1603 | ||
1604 | switch (action) { | 1604 | switch (action) { |
1605 | case HDA_FIXUP_ACT_PRE_PROBE: | 1605 | case HDA_FIXUP_ACT_PRE_PROBE: |
1606 | snd_hda_apply_pincfgs(codec, pincfgs); | 1606 | snd_hda_apply_pincfgs(codec, pincfgs); |
1607 | break; | 1607 | break; |
1608 | case HDA_FIXUP_ACT_PROBE: | 1608 | case HDA_FIXUP_ACT_PROBE: |
1609 | spec->init_amp = ALC_INIT_NONE; | 1609 | spec->init_amp = ALC_INIT_NONE; |
1610 | break; | 1610 | break; |
1611 | } | 1611 | } |
1612 | } | 1612 | } |
1613 | 1613 | ||
1614 | static void alc260_fixup_fsc_s7020(struct hda_codec *codec, | 1614 | static void alc260_fixup_fsc_s7020(struct hda_codec *codec, |
1615 | const struct hda_fixup *fix, int action) | 1615 | const struct hda_fixup *fix, int action) |
1616 | { | 1616 | { |
1617 | struct alc_spec *spec = codec->spec; | 1617 | struct alc_spec *spec = codec->spec; |
1618 | if (action == HDA_FIXUP_ACT_PROBE) | 1618 | if (action == HDA_FIXUP_ACT_PROBE) |
1619 | spec->init_amp = ALC_INIT_NONE; | 1619 | spec->init_amp = ALC_INIT_NONE; |
1620 | } | 1620 | } |
1621 | 1621 | ||
1622 | static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec, | 1622 | static void alc260_fixup_fsc_s7020_jwse(struct hda_codec *codec, |
1623 | const struct hda_fixup *fix, int action) | 1623 | const struct hda_fixup *fix, int action) |
1624 | { | 1624 | { |
1625 | struct alc_spec *spec = codec->spec; | 1625 | struct alc_spec *spec = codec->spec; |
1626 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 1626 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
1627 | spec->gen.add_jack_modes = 1; | 1627 | spec->gen.add_jack_modes = 1; |
1628 | spec->gen.hp_mic = 1; | 1628 | spec->gen.hp_mic = 1; |
1629 | } | 1629 | } |
1630 | } | 1630 | } |
1631 | 1631 | ||
1632 | static const struct hda_fixup alc260_fixups[] = { | 1632 | static const struct hda_fixup alc260_fixups[] = { |
1633 | [ALC260_FIXUP_HP_DC5750] = { | 1633 | [ALC260_FIXUP_HP_DC5750] = { |
1634 | .type = HDA_FIXUP_PINS, | 1634 | .type = HDA_FIXUP_PINS, |
1635 | .v.pins = (const struct hda_pintbl[]) { | 1635 | .v.pins = (const struct hda_pintbl[]) { |
1636 | { 0x11, 0x90130110 }, /* speaker */ | 1636 | { 0x11, 0x90130110 }, /* speaker */ |
1637 | { } | 1637 | { } |
1638 | } | 1638 | } |
1639 | }, | 1639 | }, |
1640 | [ALC260_FIXUP_HP_PIN_0F] = { | 1640 | [ALC260_FIXUP_HP_PIN_0F] = { |
1641 | .type = HDA_FIXUP_PINS, | 1641 | .type = HDA_FIXUP_PINS, |
1642 | .v.pins = (const struct hda_pintbl[]) { | 1642 | .v.pins = (const struct hda_pintbl[]) { |
1643 | { 0x0f, 0x01214000 }, /* HP */ | 1643 | { 0x0f, 0x01214000 }, /* HP */ |
1644 | { } | 1644 | { } |
1645 | } | 1645 | } |
1646 | }, | 1646 | }, |
1647 | [ALC260_FIXUP_COEF] = { | 1647 | [ALC260_FIXUP_COEF] = { |
1648 | .type = HDA_FIXUP_VERBS, | 1648 | .type = HDA_FIXUP_VERBS, |
1649 | .v.verbs = (const struct hda_verb[]) { | 1649 | .v.verbs = (const struct hda_verb[]) { |
1650 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 1650 | { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 }, |
1651 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3040 }, | 1651 | { 0x1a, AC_VERB_SET_PROC_COEF, 0x3040 }, |
1652 | { } | 1652 | { } |
1653 | }, | 1653 | }, |
1654 | .chained = true, | ||
1655 | .chain_id = ALC260_FIXUP_HP_PIN_0F, | ||
1656 | }, | 1654 | }, |
1657 | [ALC260_FIXUP_GPIO1] = { | 1655 | [ALC260_FIXUP_GPIO1] = { |
1658 | .type = HDA_FIXUP_VERBS, | 1656 | .type = HDA_FIXUP_VERBS, |
1659 | .v.verbs = alc_gpio1_init_verbs, | 1657 | .v.verbs = alc_gpio1_init_verbs, |
1660 | }, | 1658 | }, |
1661 | [ALC260_FIXUP_GPIO1_TOGGLE] = { | 1659 | [ALC260_FIXUP_GPIO1_TOGGLE] = { |
1662 | .type = HDA_FIXUP_FUNC, | 1660 | .type = HDA_FIXUP_FUNC, |
1663 | .v.func = alc260_fixup_gpio1_toggle, | 1661 | .v.func = alc260_fixup_gpio1_toggle, |
1664 | .chained = true, | 1662 | .chained = true, |
1665 | .chain_id = ALC260_FIXUP_HP_PIN_0F, | 1663 | .chain_id = ALC260_FIXUP_HP_PIN_0F, |
1666 | }, | 1664 | }, |
1667 | [ALC260_FIXUP_REPLACER] = { | 1665 | [ALC260_FIXUP_REPLACER] = { |
1668 | .type = HDA_FIXUP_VERBS, | 1666 | .type = HDA_FIXUP_VERBS, |
1669 | .v.verbs = (const struct hda_verb[]) { | 1667 | .v.verbs = (const struct hda_verb[]) { |
1670 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 1668 | { 0x1a, AC_VERB_SET_COEF_INDEX, 0x07 }, |
1671 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, | 1669 | { 0x1a, AC_VERB_SET_PROC_COEF, 0x3050 }, |
1672 | { } | 1670 | { } |
1673 | }, | 1671 | }, |
1674 | .chained = true, | 1672 | .chained = true, |
1675 | .chain_id = ALC260_FIXUP_GPIO1_TOGGLE, | 1673 | .chain_id = ALC260_FIXUP_GPIO1_TOGGLE, |
1676 | }, | 1674 | }, |
1677 | [ALC260_FIXUP_HP_B1900] = { | 1675 | [ALC260_FIXUP_HP_B1900] = { |
1678 | .type = HDA_FIXUP_FUNC, | 1676 | .type = HDA_FIXUP_FUNC, |
1679 | .v.func = alc260_fixup_gpio1_toggle, | 1677 | .v.func = alc260_fixup_gpio1_toggle, |
1680 | .chained = true, | 1678 | .chained = true, |
1681 | .chain_id = ALC260_FIXUP_COEF, | 1679 | .chain_id = ALC260_FIXUP_COEF, |
1682 | }, | 1680 | }, |
1683 | [ALC260_FIXUP_KN1] = { | 1681 | [ALC260_FIXUP_KN1] = { |
1684 | .type = HDA_FIXUP_FUNC, | 1682 | .type = HDA_FIXUP_FUNC, |
1685 | .v.func = alc260_fixup_kn1, | 1683 | .v.func = alc260_fixup_kn1, |
1686 | }, | 1684 | }, |
1687 | [ALC260_FIXUP_FSC_S7020] = { | 1685 | [ALC260_FIXUP_FSC_S7020] = { |
1688 | .type = HDA_FIXUP_FUNC, | 1686 | .type = HDA_FIXUP_FUNC, |
1689 | .v.func = alc260_fixup_fsc_s7020, | 1687 | .v.func = alc260_fixup_fsc_s7020, |
1690 | }, | 1688 | }, |
1691 | [ALC260_FIXUP_FSC_S7020_JWSE] = { | 1689 | [ALC260_FIXUP_FSC_S7020_JWSE] = { |
1692 | .type = HDA_FIXUP_FUNC, | 1690 | .type = HDA_FIXUP_FUNC, |
1693 | .v.func = alc260_fixup_fsc_s7020_jwse, | 1691 | .v.func = alc260_fixup_fsc_s7020_jwse, |
1694 | .chained = true, | 1692 | .chained = true, |
1695 | .chain_id = ALC260_FIXUP_FSC_S7020, | 1693 | .chain_id = ALC260_FIXUP_FSC_S7020, |
1696 | }, | 1694 | }, |
1697 | [ALC260_FIXUP_VAIO_PINS] = { | 1695 | [ALC260_FIXUP_VAIO_PINS] = { |
1698 | .type = HDA_FIXUP_PINS, | 1696 | .type = HDA_FIXUP_PINS, |
1699 | .v.pins = (const struct hda_pintbl[]) { | 1697 | .v.pins = (const struct hda_pintbl[]) { |
1700 | /* Pin configs are missing completely on some VAIOs */ | 1698 | /* Pin configs are missing completely on some VAIOs */ |
1701 | { 0x0f, 0x01211020 }, | 1699 | { 0x0f, 0x01211020 }, |
1702 | { 0x10, 0x0001003f }, | 1700 | { 0x10, 0x0001003f }, |
1703 | { 0x11, 0x411111f0 }, | 1701 | { 0x11, 0x411111f0 }, |
1704 | { 0x12, 0x01a15930 }, | 1702 | { 0x12, 0x01a15930 }, |
1705 | { 0x13, 0x411111f0 }, | 1703 | { 0x13, 0x411111f0 }, |
1706 | { 0x14, 0x411111f0 }, | 1704 | { 0x14, 0x411111f0 }, |
1707 | { 0x15, 0x411111f0 }, | 1705 | { 0x15, 0x411111f0 }, |
1708 | { 0x16, 0x411111f0 }, | 1706 | { 0x16, 0x411111f0 }, |
1709 | { 0x17, 0x411111f0 }, | 1707 | { 0x17, 0x411111f0 }, |
1710 | { 0x18, 0x411111f0 }, | 1708 | { 0x18, 0x411111f0 }, |
1711 | { 0x19, 0x411111f0 }, | 1709 | { 0x19, 0x411111f0 }, |
1712 | { } | 1710 | { } |
1713 | } | 1711 | } |
1714 | }, | 1712 | }, |
1715 | }; | 1713 | }; |
1716 | 1714 | ||
1717 | static const struct snd_pci_quirk alc260_fixup_tbl[] = { | 1715 | static const struct snd_pci_quirk alc260_fixup_tbl[] = { |
1718 | SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1), | 1716 | SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_FIXUP_GPIO1), |
1719 | SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF), | 1717 | SND_PCI_QUIRK(0x1025, 0x007f, "Acer Aspire 9500", ALC260_FIXUP_COEF), |
1720 | SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1), | 1718 | SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_FIXUP_GPIO1), |
1721 | SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750), | 1719 | SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", ALC260_FIXUP_HP_DC5750), |
1722 | SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900), | 1720 | SND_PCI_QUIRK(0x103c, 0x30ba, "HP Presario B1900", ALC260_FIXUP_HP_B1900), |
1723 | SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS), | 1721 | SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_FIXUP_VAIO_PINS), |
1724 | SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F), | 1722 | SND_PCI_QUIRK(0x104d, 0x81e2, "Sony VAIO TX", ALC260_FIXUP_HP_PIN_0F), |
1725 | SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020), | 1723 | SND_PCI_QUIRK(0x10cf, 0x1326, "FSC LifeBook S7020", ALC260_FIXUP_FSC_S7020), |
1726 | SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1), | 1724 | SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FIXUP_GPIO1), |
1727 | SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1), | 1725 | SND_PCI_QUIRK(0x152d, 0x0729, "Quanta KN1", ALC260_FIXUP_KN1), |
1728 | SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER), | 1726 | SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_FIXUP_REPLACER), |
1729 | SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF), | 1727 | SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_FIXUP_COEF), |
1730 | {} | 1728 | {} |
1731 | }; | 1729 | }; |
1732 | 1730 | ||
1733 | static const struct hda_model_fixup alc260_fixup_models[] = { | 1731 | static const struct hda_model_fixup alc260_fixup_models[] = { |
1734 | {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"}, | 1732 | {.id = ALC260_FIXUP_GPIO1, .name = "gpio1"}, |
1735 | {.id = ALC260_FIXUP_COEF, .name = "coef"}, | 1733 | {.id = ALC260_FIXUP_COEF, .name = "coef"}, |
1736 | {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"}, | 1734 | {.id = ALC260_FIXUP_FSC_S7020, .name = "fujitsu"}, |
1737 | {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"}, | 1735 | {.id = ALC260_FIXUP_FSC_S7020_JWSE, .name = "fujitsu-jwse"}, |
1738 | {} | 1736 | {} |
1739 | }; | 1737 | }; |
1740 | 1738 | ||
1741 | /* | 1739 | /* |
1742 | */ | 1740 | */ |
1743 | static int patch_alc260(struct hda_codec *codec) | 1741 | static int patch_alc260(struct hda_codec *codec) |
1744 | { | 1742 | { |
1745 | struct alc_spec *spec; | 1743 | struct alc_spec *spec; |
1746 | int err; | 1744 | int err; |
1747 | 1745 | ||
1748 | err = alc_alloc_spec(codec, 0x07); | 1746 | err = alc_alloc_spec(codec, 0x07); |
1749 | if (err < 0) | 1747 | if (err < 0) |
1750 | return err; | 1748 | return err; |
1751 | 1749 | ||
1752 | spec = codec->spec; | 1750 | spec = codec->spec; |
1753 | /* as quite a few machines require HP amp for speaker outputs, | 1751 | /* as quite a few machines require HP amp for speaker outputs, |
1754 | * it's easier to enable it unconditionally; even if it's unneeded, | 1752 | * it's easier to enable it unconditionally; even if it's unneeded, |
1755 | * it's almost harmless. | 1753 | * it's almost harmless. |
1756 | */ | 1754 | */ |
1757 | spec->gen.prefer_hp_amp = 1; | 1755 | spec->gen.prefer_hp_amp = 1; |
1758 | spec->gen.beep_nid = 0x01; | 1756 | spec->gen.beep_nid = 0x01; |
1759 | 1757 | ||
1760 | snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl, | 1758 | snd_hda_pick_fixup(codec, alc260_fixup_models, alc260_fixup_tbl, |
1761 | alc260_fixups); | 1759 | alc260_fixups); |
1762 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 1760 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
1763 | 1761 | ||
1764 | /* automatic parse from the BIOS config */ | 1762 | /* automatic parse from the BIOS config */ |
1765 | err = alc260_parse_auto_config(codec); | 1763 | err = alc260_parse_auto_config(codec); |
1766 | if (err < 0) | 1764 | if (err < 0) |
1767 | goto error; | 1765 | goto error; |
1768 | 1766 | ||
1769 | if (!spec->gen.no_analog) | 1767 | if (!spec->gen.no_analog) |
1770 | set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); | 1768 | set_beep_amp(spec, 0x07, 0x05, HDA_INPUT); |
1771 | 1769 | ||
1772 | codec->patch_ops = alc_patch_ops; | 1770 | codec->patch_ops = alc_patch_ops; |
1773 | spec->shutup = alc_eapd_shutup; | 1771 | spec->shutup = alc_eapd_shutup; |
1774 | 1772 | ||
1775 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 1773 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
1776 | 1774 | ||
1777 | return 0; | 1775 | return 0; |
1778 | 1776 | ||
1779 | error: | 1777 | error: |
1780 | alc_free(codec); | 1778 | alc_free(codec); |
1781 | return err; | 1779 | return err; |
1782 | } | 1780 | } |
1783 | 1781 | ||
1784 | 1782 | ||
1785 | /* | 1783 | /* |
1786 | * ALC882/883/885/888/889 support | 1784 | * ALC882/883/885/888/889 support |
1787 | * | 1785 | * |
1788 | * ALC882 is almost identical with ALC880 but has cleaner and more flexible | 1786 | * ALC882 is almost identical with ALC880 but has cleaner and more flexible |
1789 | * configuration. Each pin widget can choose any input DACs and a mixer. | 1787 | * configuration. Each pin widget can choose any input DACs and a mixer. |
1790 | * Each ADC is connected from a mixer of all inputs. This makes possible | 1788 | * Each ADC is connected from a mixer of all inputs. This makes possible |
1791 | * 6-channel independent captures. | 1789 | * 6-channel independent captures. |
1792 | * | 1790 | * |
1793 | * In addition, an independent DAC for the multi-playback (not used in this | 1791 | * In addition, an independent DAC for the multi-playback (not used in this |
1794 | * driver yet). | 1792 | * driver yet). |
1795 | */ | 1793 | */ |
1796 | 1794 | ||
1797 | /* | 1795 | /* |
1798 | * Pin config fixes | 1796 | * Pin config fixes |
1799 | */ | 1797 | */ |
1800 | enum { | 1798 | enum { |
1801 | ALC882_FIXUP_ABIT_AW9D_MAX, | 1799 | ALC882_FIXUP_ABIT_AW9D_MAX, |
1802 | ALC882_FIXUP_LENOVO_Y530, | 1800 | ALC882_FIXUP_LENOVO_Y530, |
1803 | ALC882_FIXUP_PB_M5210, | 1801 | ALC882_FIXUP_PB_M5210, |
1804 | ALC882_FIXUP_ACER_ASPIRE_7736, | 1802 | ALC882_FIXUP_ACER_ASPIRE_7736, |
1805 | ALC882_FIXUP_ASUS_W90V, | 1803 | ALC882_FIXUP_ASUS_W90V, |
1806 | ALC889_FIXUP_CD, | 1804 | ALC889_FIXUP_CD, |
1807 | ALC889_FIXUP_FRONT_HP_NO_PRESENCE, | 1805 | ALC889_FIXUP_FRONT_HP_NO_PRESENCE, |
1808 | ALC889_FIXUP_VAIO_TT, | 1806 | ALC889_FIXUP_VAIO_TT, |
1809 | ALC888_FIXUP_EEE1601, | 1807 | ALC888_FIXUP_EEE1601, |
1810 | ALC882_FIXUP_EAPD, | 1808 | ALC882_FIXUP_EAPD, |
1811 | ALC883_FIXUP_EAPD, | 1809 | ALC883_FIXUP_EAPD, |
1812 | ALC883_FIXUP_ACER_EAPD, | 1810 | ALC883_FIXUP_ACER_EAPD, |
1813 | ALC882_FIXUP_GPIO1, | 1811 | ALC882_FIXUP_GPIO1, |
1814 | ALC882_FIXUP_GPIO2, | 1812 | ALC882_FIXUP_GPIO2, |
1815 | ALC882_FIXUP_GPIO3, | 1813 | ALC882_FIXUP_GPIO3, |
1816 | ALC889_FIXUP_COEF, | 1814 | ALC889_FIXUP_COEF, |
1817 | ALC882_FIXUP_ASUS_W2JC, | 1815 | ALC882_FIXUP_ASUS_W2JC, |
1818 | ALC882_FIXUP_ACER_ASPIRE_4930G, | 1816 | ALC882_FIXUP_ACER_ASPIRE_4930G, |
1819 | ALC882_FIXUP_ACER_ASPIRE_8930G, | 1817 | ALC882_FIXUP_ACER_ASPIRE_8930G, |
1820 | ALC882_FIXUP_ASPIRE_8930G_VERBS, | 1818 | ALC882_FIXUP_ASPIRE_8930G_VERBS, |
1821 | ALC885_FIXUP_MACPRO_GPIO, | 1819 | ALC885_FIXUP_MACPRO_GPIO, |
1822 | ALC889_FIXUP_DAC_ROUTE, | 1820 | ALC889_FIXUP_DAC_ROUTE, |
1823 | ALC889_FIXUP_MBP_VREF, | 1821 | ALC889_FIXUP_MBP_VREF, |
1824 | ALC889_FIXUP_IMAC91_VREF, | 1822 | ALC889_FIXUP_IMAC91_VREF, |
1825 | ALC889_FIXUP_MBA11_VREF, | 1823 | ALC889_FIXUP_MBA11_VREF, |
1826 | ALC889_FIXUP_MBA21_VREF, | 1824 | ALC889_FIXUP_MBA21_VREF, |
1827 | ALC889_FIXUP_MP11_VREF, | 1825 | ALC889_FIXUP_MP11_VREF, |
1828 | ALC882_FIXUP_INV_DMIC, | 1826 | ALC882_FIXUP_INV_DMIC, |
1829 | ALC882_FIXUP_NO_PRIMARY_HP, | 1827 | ALC882_FIXUP_NO_PRIMARY_HP, |
1830 | ALC887_FIXUP_ASUS_BASS, | 1828 | ALC887_FIXUP_ASUS_BASS, |
1831 | ALC887_FIXUP_BASS_CHMAP, | 1829 | ALC887_FIXUP_BASS_CHMAP, |
1832 | }; | 1830 | }; |
1833 | 1831 | ||
1834 | static void alc889_fixup_coef(struct hda_codec *codec, | 1832 | static void alc889_fixup_coef(struct hda_codec *codec, |
1835 | const struct hda_fixup *fix, int action) | 1833 | const struct hda_fixup *fix, int action) |
1836 | { | 1834 | { |
1837 | if (action != HDA_FIXUP_ACT_INIT) | 1835 | if (action != HDA_FIXUP_ACT_INIT) |
1838 | return; | 1836 | return; |
1839 | alc889_coef_init(codec); | 1837 | alc889_coef_init(codec); |
1840 | } | 1838 | } |
1841 | 1839 | ||
1842 | /* toggle speaker-output according to the hp-jack state */ | 1840 | /* toggle speaker-output according to the hp-jack state */ |
1843 | static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) | 1841 | static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) |
1844 | { | 1842 | { |
1845 | unsigned int gpiostate, gpiomask, gpiodir; | 1843 | unsigned int gpiostate, gpiomask, gpiodir; |
1846 | 1844 | ||
1847 | gpiostate = snd_hda_codec_read(codec, codec->afg, 0, | 1845 | gpiostate = snd_hda_codec_read(codec, codec->afg, 0, |
1848 | AC_VERB_GET_GPIO_DATA, 0); | 1846 | AC_VERB_GET_GPIO_DATA, 0); |
1849 | 1847 | ||
1850 | if (!muted) | 1848 | if (!muted) |
1851 | gpiostate |= (1 << pin); | 1849 | gpiostate |= (1 << pin); |
1852 | else | 1850 | else |
1853 | gpiostate &= ~(1 << pin); | 1851 | gpiostate &= ~(1 << pin); |
1854 | 1852 | ||
1855 | gpiomask = snd_hda_codec_read(codec, codec->afg, 0, | 1853 | gpiomask = snd_hda_codec_read(codec, codec->afg, 0, |
1856 | AC_VERB_GET_GPIO_MASK, 0); | 1854 | AC_VERB_GET_GPIO_MASK, 0); |
1857 | gpiomask |= (1 << pin); | 1855 | gpiomask |= (1 << pin); |
1858 | 1856 | ||
1859 | gpiodir = snd_hda_codec_read(codec, codec->afg, 0, | 1857 | gpiodir = snd_hda_codec_read(codec, codec->afg, 0, |
1860 | AC_VERB_GET_GPIO_DIRECTION, 0); | 1858 | AC_VERB_GET_GPIO_DIRECTION, 0); |
1861 | gpiodir |= (1 << pin); | 1859 | gpiodir |= (1 << pin); |
1862 | 1860 | ||
1863 | 1861 | ||
1864 | snd_hda_codec_write(codec, codec->afg, 0, | 1862 | snd_hda_codec_write(codec, codec->afg, 0, |
1865 | AC_VERB_SET_GPIO_MASK, gpiomask); | 1863 | AC_VERB_SET_GPIO_MASK, gpiomask); |
1866 | snd_hda_codec_write(codec, codec->afg, 0, | 1864 | snd_hda_codec_write(codec, codec->afg, 0, |
1867 | AC_VERB_SET_GPIO_DIRECTION, gpiodir); | 1865 | AC_VERB_SET_GPIO_DIRECTION, gpiodir); |
1868 | 1866 | ||
1869 | msleep(1); | 1867 | msleep(1); |
1870 | 1868 | ||
1871 | snd_hda_codec_write(codec, codec->afg, 0, | 1869 | snd_hda_codec_write(codec, codec->afg, 0, |
1872 | AC_VERB_SET_GPIO_DATA, gpiostate); | 1870 | AC_VERB_SET_GPIO_DATA, gpiostate); |
1873 | } | 1871 | } |
1874 | 1872 | ||
1875 | /* set up GPIO at initialization */ | 1873 | /* set up GPIO at initialization */ |
1876 | static void alc885_fixup_macpro_gpio(struct hda_codec *codec, | 1874 | static void alc885_fixup_macpro_gpio(struct hda_codec *codec, |
1877 | const struct hda_fixup *fix, int action) | 1875 | const struct hda_fixup *fix, int action) |
1878 | { | 1876 | { |
1879 | if (action != HDA_FIXUP_ACT_INIT) | 1877 | if (action != HDA_FIXUP_ACT_INIT) |
1880 | return; | 1878 | return; |
1881 | alc882_gpio_mute(codec, 0, 0); | 1879 | alc882_gpio_mute(codec, 0, 0); |
1882 | alc882_gpio_mute(codec, 1, 0); | 1880 | alc882_gpio_mute(codec, 1, 0); |
1883 | } | 1881 | } |
1884 | 1882 | ||
1885 | /* Fix the connection of some pins for ALC889: | 1883 | /* Fix the connection of some pins for ALC889: |
1886 | * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't | 1884 | * At least, Acer Aspire 5935 shows the connections to DAC3/4 don't |
1887 | * work correctly (bko#42740) | 1885 | * work correctly (bko#42740) |
1888 | */ | 1886 | */ |
1889 | static void alc889_fixup_dac_route(struct hda_codec *codec, | 1887 | static void alc889_fixup_dac_route(struct hda_codec *codec, |
1890 | const struct hda_fixup *fix, int action) | 1888 | const struct hda_fixup *fix, int action) |
1891 | { | 1889 | { |
1892 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 1890 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
1893 | /* fake the connections during parsing the tree */ | 1891 | /* fake the connections during parsing the tree */ |
1894 | hda_nid_t conn1[2] = { 0x0c, 0x0d }; | 1892 | hda_nid_t conn1[2] = { 0x0c, 0x0d }; |
1895 | hda_nid_t conn2[2] = { 0x0e, 0x0f }; | 1893 | hda_nid_t conn2[2] = { 0x0e, 0x0f }; |
1896 | snd_hda_override_conn_list(codec, 0x14, 2, conn1); | 1894 | snd_hda_override_conn_list(codec, 0x14, 2, conn1); |
1897 | snd_hda_override_conn_list(codec, 0x15, 2, conn1); | 1895 | snd_hda_override_conn_list(codec, 0x15, 2, conn1); |
1898 | snd_hda_override_conn_list(codec, 0x18, 2, conn2); | 1896 | snd_hda_override_conn_list(codec, 0x18, 2, conn2); |
1899 | snd_hda_override_conn_list(codec, 0x1a, 2, conn2); | 1897 | snd_hda_override_conn_list(codec, 0x1a, 2, conn2); |
1900 | } else if (action == HDA_FIXUP_ACT_PROBE) { | 1898 | } else if (action == HDA_FIXUP_ACT_PROBE) { |
1901 | /* restore the connections */ | 1899 | /* restore the connections */ |
1902 | hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 }; | 1900 | hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 }; |
1903 | snd_hda_override_conn_list(codec, 0x14, 5, conn); | 1901 | snd_hda_override_conn_list(codec, 0x14, 5, conn); |
1904 | snd_hda_override_conn_list(codec, 0x15, 5, conn); | 1902 | snd_hda_override_conn_list(codec, 0x15, 5, conn); |
1905 | snd_hda_override_conn_list(codec, 0x18, 5, conn); | 1903 | snd_hda_override_conn_list(codec, 0x18, 5, conn); |
1906 | snd_hda_override_conn_list(codec, 0x1a, 5, conn); | 1904 | snd_hda_override_conn_list(codec, 0x1a, 5, conn); |
1907 | } | 1905 | } |
1908 | } | 1906 | } |
1909 | 1907 | ||
1910 | /* Set VREF on HP pin */ | 1908 | /* Set VREF on HP pin */ |
1911 | static void alc889_fixup_mbp_vref(struct hda_codec *codec, | 1909 | static void alc889_fixup_mbp_vref(struct hda_codec *codec, |
1912 | const struct hda_fixup *fix, int action) | 1910 | const struct hda_fixup *fix, int action) |
1913 | { | 1911 | { |
1914 | struct alc_spec *spec = codec->spec; | 1912 | struct alc_spec *spec = codec->spec; |
1915 | static hda_nid_t nids[2] = { 0x14, 0x15 }; | 1913 | static hda_nid_t nids[2] = { 0x14, 0x15 }; |
1916 | int i; | 1914 | int i; |
1917 | 1915 | ||
1918 | if (action != HDA_FIXUP_ACT_INIT) | 1916 | if (action != HDA_FIXUP_ACT_INIT) |
1919 | return; | 1917 | return; |
1920 | for (i = 0; i < ARRAY_SIZE(nids); i++) { | 1918 | for (i = 0; i < ARRAY_SIZE(nids); i++) { |
1921 | unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]); | 1919 | unsigned int val = snd_hda_codec_get_pincfg(codec, nids[i]); |
1922 | if (get_defcfg_device(val) != AC_JACK_HP_OUT) | 1920 | if (get_defcfg_device(val) != AC_JACK_HP_OUT) |
1923 | continue; | 1921 | continue; |
1924 | val = snd_hda_codec_get_pin_target(codec, nids[i]); | 1922 | val = snd_hda_codec_get_pin_target(codec, nids[i]); |
1925 | val |= AC_PINCTL_VREF_80; | 1923 | val |= AC_PINCTL_VREF_80; |
1926 | snd_hda_set_pin_ctl(codec, nids[i], val); | 1924 | snd_hda_set_pin_ctl(codec, nids[i], val); |
1927 | spec->gen.keep_vref_in_automute = 1; | 1925 | spec->gen.keep_vref_in_automute = 1; |
1928 | break; | 1926 | break; |
1929 | } | 1927 | } |
1930 | } | 1928 | } |
1931 | 1929 | ||
1932 | static void alc889_fixup_mac_pins(struct hda_codec *codec, | 1930 | static void alc889_fixup_mac_pins(struct hda_codec *codec, |
1933 | const hda_nid_t *nids, int num_nids) | 1931 | const hda_nid_t *nids, int num_nids) |
1934 | { | 1932 | { |
1935 | struct alc_spec *spec = codec->spec; | 1933 | struct alc_spec *spec = codec->spec; |
1936 | int i; | 1934 | int i; |
1937 | 1935 | ||
1938 | for (i = 0; i < num_nids; i++) { | 1936 | for (i = 0; i < num_nids; i++) { |
1939 | unsigned int val; | 1937 | unsigned int val; |
1940 | val = snd_hda_codec_get_pin_target(codec, nids[i]); | 1938 | val = snd_hda_codec_get_pin_target(codec, nids[i]); |
1941 | val |= AC_PINCTL_VREF_50; | 1939 | val |= AC_PINCTL_VREF_50; |
1942 | snd_hda_set_pin_ctl(codec, nids[i], val); | 1940 | snd_hda_set_pin_ctl(codec, nids[i], val); |
1943 | } | 1941 | } |
1944 | spec->gen.keep_vref_in_automute = 1; | 1942 | spec->gen.keep_vref_in_automute = 1; |
1945 | } | 1943 | } |
1946 | 1944 | ||
1947 | /* Set VREF on speaker pins on imac91 */ | 1945 | /* Set VREF on speaker pins on imac91 */ |
1948 | static void alc889_fixup_imac91_vref(struct hda_codec *codec, | 1946 | static void alc889_fixup_imac91_vref(struct hda_codec *codec, |
1949 | const struct hda_fixup *fix, int action) | 1947 | const struct hda_fixup *fix, int action) |
1950 | { | 1948 | { |
1951 | static hda_nid_t nids[2] = { 0x18, 0x1a }; | 1949 | static hda_nid_t nids[2] = { 0x18, 0x1a }; |
1952 | 1950 | ||
1953 | if (action == HDA_FIXUP_ACT_INIT) | 1951 | if (action == HDA_FIXUP_ACT_INIT) |
1954 | alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); | 1952 | alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); |
1955 | } | 1953 | } |
1956 | 1954 | ||
1957 | /* Set VREF on speaker pins on mba11 */ | 1955 | /* Set VREF on speaker pins on mba11 */ |
1958 | static void alc889_fixup_mba11_vref(struct hda_codec *codec, | 1956 | static void alc889_fixup_mba11_vref(struct hda_codec *codec, |
1959 | const struct hda_fixup *fix, int action) | 1957 | const struct hda_fixup *fix, int action) |
1960 | { | 1958 | { |
1961 | static hda_nid_t nids[1] = { 0x18 }; | 1959 | static hda_nid_t nids[1] = { 0x18 }; |
1962 | 1960 | ||
1963 | if (action == HDA_FIXUP_ACT_INIT) | 1961 | if (action == HDA_FIXUP_ACT_INIT) |
1964 | alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); | 1962 | alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); |
1965 | } | 1963 | } |
1966 | 1964 | ||
1967 | /* Set VREF on speaker pins on mba21 */ | 1965 | /* Set VREF on speaker pins on mba21 */ |
1968 | static void alc889_fixup_mba21_vref(struct hda_codec *codec, | 1966 | static void alc889_fixup_mba21_vref(struct hda_codec *codec, |
1969 | const struct hda_fixup *fix, int action) | 1967 | const struct hda_fixup *fix, int action) |
1970 | { | 1968 | { |
1971 | static hda_nid_t nids[2] = { 0x18, 0x19 }; | 1969 | static hda_nid_t nids[2] = { 0x18, 0x19 }; |
1972 | 1970 | ||
1973 | if (action == HDA_FIXUP_ACT_INIT) | 1971 | if (action == HDA_FIXUP_ACT_INIT) |
1974 | alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); | 1972 | alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids)); |
1975 | } | 1973 | } |
1976 | 1974 | ||
1977 | /* Don't take HP output as primary | 1975 | /* Don't take HP output as primary |
1978 | * Strangely, the speaker output doesn't work on Vaio Z and some Vaio | 1976 | * Strangely, the speaker output doesn't work on Vaio Z and some Vaio |
1979 | * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05 | 1977 | * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05 |
1980 | */ | 1978 | */ |
1981 | static void alc882_fixup_no_primary_hp(struct hda_codec *codec, | 1979 | static void alc882_fixup_no_primary_hp(struct hda_codec *codec, |
1982 | const struct hda_fixup *fix, int action) | 1980 | const struct hda_fixup *fix, int action) |
1983 | { | 1981 | { |
1984 | struct alc_spec *spec = codec->spec; | 1982 | struct alc_spec *spec = codec->spec; |
1985 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 1983 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
1986 | spec->gen.no_primary_hp = 1; | 1984 | spec->gen.no_primary_hp = 1; |
1987 | spec->gen.no_multi_io = 1; | 1985 | spec->gen.no_multi_io = 1; |
1988 | } | 1986 | } |
1989 | } | 1987 | } |
1990 | 1988 | ||
1991 | static void alc_fixup_bass_chmap(struct hda_codec *codec, | 1989 | static void alc_fixup_bass_chmap(struct hda_codec *codec, |
1992 | const struct hda_fixup *fix, int action); | 1990 | const struct hda_fixup *fix, int action); |
1993 | 1991 | ||
1994 | static const struct hda_fixup alc882_fixups[] = { | 1992 | static const struct hda_fixup alc882_fixups[] = { |
1995 | [ALC882_FIXUP_ABIT_AW9D_MAX] = { | 1993 | [ALC882_FIXUP_ABIT_AW9D_MAX] = { |
1996 | .type = HDA_FIXUP_PINS, | 1994 | .type = HDA_FIXUP_PINS, |
1997 | .v.pins = (const struct hda_pintbl[]) { | 1995 | .v.pins = (const struct hda_pintbl[]) { |
1998 | { 0x15, 0x01080104 }, /* side */ | 1996 | { 0x15, 0x01080104 }, /* side */ |
1999 | { 0x16, 0x01011012 }, /* rear */ | 1997 | { 0x16, 0x01011012 }, /* rear */ |
2000 | { 0x17, 0x01016011 }, /* clfe */ | 1998 | { 0x17, 0x01016011 }, /* clfe */ |
2001 | { } | 1999 | { } |
2002 | } | 2000 | } |
2003 | }, | 2001 | }, |
2004 | [ALC882_FIXUP_LENOVO_Y530] = { | 2002 | [ALC882_FIXUP_LENOVO_Y530] = { |
2005 | .type = HDA_FIXUP_PINS, | 2003 | .type = HDA_FIXUP_PINS, |
2006 | .v.pins = (const struct hda_pintbl[]) { | 2004 | .v.pins = (const struct hda_pintbl[]) { |
2007 | { 0x15, 0x99130112 }, /* rear int speakers */ | 2005 | { 0x15, 0x99130112 }, /* rear int speakers */ |
2008 | { 0x16, 0x99130111 }, /* subwoofer */ | 2006 | { 0x16, 0x99130111 }, /* subwoofer */ |
2009 | { } | 2007 | { } |
2010 | } | 2008 | } |
2011 | }, | 2009 | }, |
2012 | [ALC882_FIXUP_PB_M5210] = { | 2010 | [ALC882_FIXUP_PB_M5210] = { |
2013 | .type = HDA_FIXUP_PINCTLS, | 2011 | .type = HDA_FIXUP_PINCTLS, |
2014 | .v.pins = (const struct hda_pintbl[]) { | 2012 | .v.pins = (const struct hda_pintbl[]) { |
2015 | { 0x19, PIN_VREF50 }, | 2013 | { 0x19, PIN_VREF50 }, |
2016 | {} | 2014 | {} |
2017 | } | 2015 | } |
2018 | }, | 2016 | }, |
2019 | [ALC882_FIXUP_ACER_ASPIRE_7736] = { | 2017 | [ALC882_FIXUP_ACER_ASPIRE_7736] = { |
2020 | .type = HDA_FIXUP_FUNC, | 2018 | .type = HDA_FIXUP_FUNC, |
2021 | .v.func = alc_fixup_sku_ignore, | 2019 | .v.func = alc_fixup_sku_ignore, |
2022 | }, | 2020 | }, |
2023 | [ALC882_FIXUP_ASUS_W90V] = { | 2021 | [ALC882_FIXUP_ASUS_W90V] = { |
2024 | .type = HDA_FIXUP_PINS, | 2022 | .type = HDA_FIXUP_PINS, |
2025 | .v.pins = (const struct hda_pintbl[]) { | 2023 | .v.pins = (const struct hda_pintbl[]) { |
2026 | { 0x16, 0x99130110 }, /* fix sequence for CLFE */ | 2024 | { 0x16, 0x99130110 }, /* fix sequence for CLFE */ |
2027 | { } | 2025 | { } |
2028 | } | 2026 | } |
2029 | }, | 2027 | }, |
2030 | [ALC889_FIXUP_CD] = { | 2028 | [ALC889_FIXUP_CD] = { |
2031 | .type = HDA_FIXUP_PINS, | 2029 | .type = HDA_FIXUP_PINS, |
2032 | .v.pins = (const struct hda_pintbl[]) { | 2030 | .v.pins = (const struct hda_pintbl[]) { |
2033 | { 0x1c, 0x993301f0 }, /* CD */ | 2031 | { 0x1c, 0x993301f0 }, /* CD */ |
2034 | { } | 2032 | { } |
2035 | } | 2033 | } |
2036 | }, | 2034 | }, |
2037 | [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = { | 2035 | [ALC889_FIXUP_FRONT_HP_NO_PRESENCE] = { |
2038 | .type = HDA_FIXUP_PINS, | 2036 | .type = HDA_FIXUP_PINS, |
2039 | .v.pins = (const struct hda_pintbl[]) { | 2037 | .v.pins = (const struct hda_pintbl[]) { |
2040 | { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */ | 2038 | { 0x1b, 0x02214120 }, /* Front HP jack is flaky, disable jack detect */ |
2041 | { } | 2039 | { } |
2042 | }, | 2040 | }, |
2043 | .chained = true, | 2041 | .chained = true, |
2044 | .chain_id = ALC889_FIXUP_CD, | 2042 | .chain_id = ALC889_FIXUP_CD, |
2045 | }, | 2043 | }, |
2046 | [ALC889_FIXUP_VAIO_TT] = { | 2044 | [ALC889_FIXUP_VAIO_TT] = { |
2047 | .type = HDA_FIXUP_PINS, | 2045 | .type = HDA_FIXUP_PINS, |
2048 | .v.pins = (const struct hda_pintbl[]) { | 2046 | .v.pins = (const struct hda_pintbl[]) { |
2049 | { 0x17, 0x90170111 }, /* hidden surround speaker */ | 2047 | { 0x17, 0x90170111 }, /* hidden surround speaker */ |
2050 | { } | 2048 | { } |
2051 | } | 2049 | } |
2052 | }, | 2050 | }, |
2053 | [ALC888_FIXUP_EEE1601] = { | 2051 | [ALC888_FIXUP_EEE1601] = { |
2054 | .type = HDA_FIXUP_VERBS, | 2052 | .type = HDA_FIXUP_VERBS, |
2055 | .v.verbs = (const struct hda_verb[]) { | 2053 | .v.verbs = (const struct hda_verb[]) { |
2056 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, | 2054 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, |
2057 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 }, | 2055 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0838 }, |
2058 | { } | 2056 | { } |
2059 | } | 2057 | } |
2060 | }, | 2058 | }, |
2061 | [ALC882_FIXUP_EAPD] = { | 2059 | [ALC882_FIXUP_EAPD] = { |
2062 | .type = HDA_FIXUP_VERBS, | 2060 | .type = HDA_FIXUP_VERBS, |
2063 | .v.verbs = (const struct hda_verb[]) { | 2061 | .v.verbs = (const struct hda_verb[]) { |
2064 | /* change to EAPD mode */ | 2062 | /* change to EAPD mode */ |
2065 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 2063 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
2066 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, | 2064 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3060 }, |
2067 | { } | 2065 | { } |
2068 | } | 2066 | } |
2069 | }, | 2067 | }, |
2070 | [ALC883_FIXUP_EAPD] = { | 2068 | [ALC883_FIXUP_EAPD] = { |
2071 | .type = HDA_FIXUP_VERBS, | 2069 | .type = HDA_FIXUP_VERBS, |
2072 | .v.verbs = (const struct hda_verb[]) { | 2070 | .v.verbs = (const struct hda_verb[]) { |
2073 | /* change to EAPD mode */ | 2071 | /* change to EAPD mode */ |
2074 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 2072 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
2075 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, | 2073 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, |
2076 | { } | 2074 | { } |
2077 | } | 2075 | } |
2078 | }, | 2076 | }, |
2079 | [ALC883_FIXUP_ACER_EAPD] = { | 2077 | [ALC883_FIXUP_ACER_EAPD] = { |
2080 | .type = HDA_FIXUP_VERBS, | 2078 | .type = HDA_FIXUP_VERBS, |
2081 | .v.verbs = (const struct hda_verb[]) { | 2079 | .v.verbs = (const struct hda_verb[]) { |
2082 | /* eanable EAPD on Acer laptops */ | 2080 | /* eanable EAPD on Acer laptops */ |
2083 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 2081 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
2084 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, | 2082 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, |
2085 | { } | 2083 | { } |
2086 | } | 2084 | } |
2087 | }, | 2085 | }, |
2088 | [ALC882_FIXUP_GPIO1] = { | 2086 | [ALC882_FIXUP_GPIO1] = { |
2089 | .type = HDA_FIXUP_VERBS, | 2087 | .type = HDA_FIXUP_VERBS, |
2090 | .v.verbs = alc_gpio1_init_verbs, | 2088 | .v.verbs = alc_gpio1_init_verbs, |
2091 | }, | 2089 | }, |
2092 | [ALC882_FIXUP_GPIO2] = { | 2090 | [ALC882_FIXUP_GPIO2] = { |
2093 | .type = HDA_FIXUP_VERBS, | 2091 | .type = HDA_FIXUP_VERBS, |
2094 | .v.verbs = alc_gpio2_init_verbs, | 2092 | .v.verbs = alc_gpio2_init_verbs, |
2095 | }, | 2093 | }, |
2096 | [ALC882_FIXUP_GPIO3] = { | 2094 | [ALC882_FIXUP_GPIO3] = { |
2097 | .type = HDA_FIXUP_VERBS, | 2095 | .type = HDA_FIXUP_VERBS, |
2098 | .v.verbs = alc_gpio3_init_verbs, | 2096 | .v.verbs = alc_gpio3_init_verbs, |
2099 | }, | 2097 | }, |
2100 | [ALC882_FIXUP_ASUS_W2JC] = { | 2098 | [ALC882_FIXUP_ASUS_W2JC] = { |
2101 | .type = HDA_FIXUP_VERBS, | 2099 | .type = HDA_FIXUP_VERBS, |
2102 | .v.verbs = alc_gpio1_init_verbs, | 2100 | .v.verbs = alc_gpio1_init_verbs, |
2103 | .chained = true, | 2101 | .chained = true, |
2104 | .chain_id = ALC882_FIXUP_EAPD, | 2102 | .chain_id = ALC882_FIXUP_EAPD, |
2105 | }, | 2103 | }, |
2106 | [ALC889_FIXUP_COEF] = { | 2104 | [ALC889_FIXUP_COEF] = { |
2107 | .type = HDA_FIXUP_FUNC, | 2105 | .type = HDA_FIXUP_FUNC, |
2108 | .v.func = alc889_fixup_coef, | 2106 | .v.func = alc889_fixup_coef, |
2109 | }, | 2107 | }, |
2110 | [ALC882_FIXUP_ACER_ASPIRE_4930G] = { | 2108 | [ALC882_FIXUP_ACER_ASPIRE_4930G] = { |
2111 | .type = HDA_FIXUP_PINS, | 2109 | .type = HDA_FIXUP_PINS, |
2112 | .v.pins = (const struct hda_pintbl[]) { | 2110 | .v.pins = (const struct hda_pintbl[]) { |
2113 | { 0x16, 0x99130111 }, /* CLFE speaker */ | 2111 | { 0x16, 0x99130111 }, /* CLFE speaker */ |
2114 | { 0x17, 0x99130112 }, /* surround speaker */ | 2112 | { 0x17, 0x99130112 }, /* surround speaker */ |
2115 | { } | 2113 | { } |
2116 | }, | 2114 | }, |
2117 | .chained = true, | 2115 | .chained = true, |
2118 | .chain_id = ALC882_FIXUP_GPIO1, | 2116 | .chain_id = ALC882_FIXUP_GPIO1, |
2119 | }, | 2117 | }, |
2120 | [ALC882_FIXUP_ACER_ASPIRE_8930G] = { | 2118 | [ALC882_FIXUP_ACER_ASPIRE_8930G] = { |
2121 | .type = HDA_FIXUP_PINS, | 2119 | .type = HDA_FIXUP_PINS, |
2122 | .v.pins = (const struct hda_pintbl[]) { | 2120 | .v.pins = (const struct hda_pintbl[]) { |
2123 | { 0x16, 0x99130111 }, /* CLFE speaker */ | 2121 | { 0x16, 0x99130111 }, /* CLFE speaker */ |
2124 | { 0x1b, 0x99130112 }, /* surround speaker */ | 2122 | { 0x1b, 0x99130112 }, /* surround speaker */ |
2125 | { } | 2123 | { } |
2126 | }, | 2124 | }, |
2127 | .chained = true, | 2125 | .chained = true, |
2128 | .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS, | 2126 | .chain_id = ALC882_FIXUP_ASPIRE_8930G_VERBS, |
2129 | }, | 2127 | }, |
2130 | [ALC882_FIXUP_ASPIRE_8930G_VERBS] = { | 2128 | [ALC882_FIXUP_ASPIRE_8930G_VERBS] = { |
2131 | /* additional init verbs for Acer Aspire 8930G */ | 2129 | /* additional init verbs for Acer Aspire 8930G */ |
2132 | .type = HDA_FIXUP_VERBS, | 2130 | .type = HDA_FIXUP_VERBS, |
2133 | .v.verbs = (const struct hda_verb[]) { | 2131 | .v.verbs = (const struct hda_verb[]) { |
2134 | /* Enable all DACs */ | 2132 | /* Enable all DACs */ |
2135 | /* DAC DISABLE/MUTE 1? */ | 2133 | /* DAC DISABLE/MUTE 1? */ |
2136 | /* setting bits 1-5 disables DAC nids 0x02-0x06 | 2134 | /* setting bits 1-5 disables DAC nids 0x02-0x06 |
2137 | * apparently. Init=0x38 */ | 2135 | * apparently. Init=0x38 */ |
2138 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 }, | 2136 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x03 }, |
2139 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, | 2137 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, |
2140 | /* DAC DISABLE/MUTE 2? */ | 2138 | /* DAC DISABLE/MUTE 2? */ |
2141 | /* some bit here disables the other DACs. | 2139 | /* some bit here disables the other DACs. |
2142 | * Init=0x4900 */ | 2140 | * Init=0x4900 */ |
2143 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 }, | 2141 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x08 }, |
2144 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, | 2142 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0000 }, |
2145 | /* DMIC fix | 2143 | /* DMIC fix |
2146 | * This laptop has a stereo digital microphone. | 2144 | * This laptop has a stereo digital microphone. |
2147 | * The mics are only 1cm apart which makes the stereo | 2145 | * The mics are only 1cm apart which makes the stereo |
2148 | * useless. However, either the mic or the ALC889 | 2146 | * useless. However, either the mic or the ALC889 |
2149 | * makes the signal become a difference/sum signal | 2147 | * makes the signal become a difference/sum signal |
2150 | * instead of standard stereo, which is annoying. | 2148 | * instead of standard stereo, which is annoying. |
2151 | * So instead we flip this bit which makes the | 2149 | * So instead we flip this bit which makes the |
2152 | * codec replicate the sum signal to both channels, | 2150 | * codec replicate the sum signal to both channels, |
2153 | * turning it into a normal mono mic. | 2151 | * turning it into a normal mono mic. |
2154 | */ | 2152 | */ |
2155 | /* DMIC_CONTROL? Init value = 0x0001 */ | 2153 | /* DMIC_CONTROL? Init value = 0x0001 */ |
2156 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, | 2154 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x0b }, |
2157 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 }, | 2155 | { 0x20, AC_VERB_SET_PROC_COEF, 0x0003 }, |
2158 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 2156 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
2159 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, | 2157 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, |
2160 | { } | 2158 | { } |
2161 | }, | 2159 | }, |
2162 | .chained = true, | 2160 | .chained = true, |
2163 | .chain_id = ALC882_FIXUP_GPIO1, | 2161 | .chain_id = ALC882_FIXUP_GPIO1, |
2164 | }, | 2162 | }, |
2165 | [ALC885_FIXUP_MACPRO_GPIO] = { | 2163 | [ALC885_FIXUP_MACPRO_GPIO] = { |
2166 | .type = HDA_FIXUP_FUNC, | 2164 | .type = HDA_FIXUP_FUNC, |
2167 | .v.func = alc885_fixup_macpro_gpio, | 2165 | .v.func = alc885_fixup_macpro_gpio, |
2168 | }, | 2166 | }, |
2169 | [ALC889_FIXUP_DAC_ROUTE] = { | 2167 | [ALC889_FIXUP_DAC_ROUTE] = { |
2170 | .type = HDA_FIXUP_FUNC, | 2168 | .type = HDA_FIXUP_FUNC, |
2171 | .v.func = alc889_fixup_dac_route, | 2169 | .v.func = alc889_fixup_dac_route, |
2172 | }, | 2170 | }, |
2173 | [ALC889_FIXUP_MBP_VREF] = { | 2171 | [ALC889_FIXUP_MBP_VREF] = { |
2174 | .type = HDA_FIXUP_FUNC, | 2172 | .type = HDA_FIXUP_FUNC, |
2175 | .v.func = alc889_fixup_mbp_vref, | 2173 | .v.func = alc889_fixup_mbp_vref, |
2176 | .chained = true, | 2174 | .chained = true, |
2177 | .chain_id = ALC882_FIXUP_GPIO1, | 2175 | .chain_id = ALC882_FIXUP_GPIO1, |
2178 | }, | 2176 | }, |
2179 | [ALC889_FIXUP_IMAC91_VREF] = { | 2177 | [ALC889_FIXUP_IMAC91_VREF] = { |
2180 | .type = HDA_FIXUP_FUNC, | 2178 | .type = HDA_FIXUP_FUNC, |
2181 | .v.func = alc889_fixup_imac91_vref, | 2179 | .v.func = alc889_fixup_imac91_vref, |
2182 | .chained = true, | 2180 | .chained = true, |
2183 | .chain_id = ALC882_FIXUP_GPIO1, | 2181 | .chain_id = ALC882_FIXUP_GPIO1, |
2184 | }, | 2182 | }, |
2185 | [ALC889_FIXUP_MBA11_VREF] = { | 2183 | [ALC889_FIXUP_MBA11_VREF] = { |
2186 | .type = HDA_FIXUP_FUNC, | 2184 | .type = HDA_FIXUP_FUNC, |
2187 | .v.func = alc889_fixup_mba11_vref, | 2185 | .v.func = alc889_fixup_mba11_vref, |
2188 | .chained = true, | 2186 | .chained = true, |
2189 | .chain_id = ALC889_FIXUP_MBP_VREF, | 2187 | .chain_id = ALC889_FIXUP_MBP_VREF, |
2190 | }, | 2188 | }, |
2191 | [ALC889_FIXUP_MBA21_VREF] = { | 2189 | [ALC889_FIXUP_MBA21_VREF] = { |
2192 | .type = HDA_FIXUP_FUNC, | 2190 | .type = HDA_FIXUP_FUNC, |
2193 | .v.func = alc889_fixup_mba21_vref, | 2191 | .v.func = alc889_fixup_mba21_vref, |
2194 | .chained = true, | 2192 | .chained = true, |
2195 | .chain_id = ALC889_FIXUP_MBP_VREF, | 2193 | .chain_id = ALC889_FIXUP_MBP_VREF, |
2196 | }, | 2194 | }, |
2197 | [ALC889_FIXUP_MP11_VREF] = { | 2195 | [ALC889_FIXUP_MP11_VREF] = { |
2198 | .type = HDA_FIXUP_FUNC, | 2196 | .type = HDA_FIXUP_FUNC, |
2199 | .v.func = alc889_fixup_mba11_vref, | 2197 | .v.func = alc889_fixup_mba11_vref, |
2200 | .chained = true, | 2198 | .chained = true, |
2201 | .chain_id = ALC885_FIXUP_MACPRO_GPIO, | 2199 | .chain_id = ALC885_FIXUP_MACPRO_GPIO, |
2202 | }, | 2200 | }, |
2203 | [ALC882_FIXUP_INV_DMIC] = { | 2201 | [ALC882_FIXUP_INV_DMIC] = { |
2204 | .type = HDA_FIXUP_FUNC, | 2202 | .type = HDA_FIXUP_FUNC, |
2205 | .v.func = alc_fixup_inv_dmic_0x12, | 2203 | .v.func = alc_fixup_inv_dmic_0x12, |
2206 | }, | 2204 | }, |
2207 | [ALC882_FIXUP_NO_PRIMARY_HP] = { | 2205 | [ALC882_FIXUP_NO_PRIMARY_HP] = { |
2208 | .type = HDA_FIXUP_FUNC, | 2206 | .type = HDA_FIXUP_FUNC, |
2209 | .v.func = alc882_fixup_no_primary_hp, | 2207 | .v.func = alc882_fixup_no_primary_hp, |
2210 | }, | 2208 | }, |
2211 | [ALC887_FIXUP_ASUS_BASS] = { | 2209 | [ALC887_FIXUP_ASUS_BASS] = { |
2212 | .type = HDA_FIXUP_PINS, | 2210 | .type = HDA_FIXUP_PINS, |
2213 | .v.pins = (const struct hda_pintbl[]) { | 2211 | .v.pins = (const struct hda_pintbl[]) { |
2214 | {0x16, 0x99130130}, /* bass speaker */ | 2212 | {0x16, 0x99130130}, /* bass speaker */ |
2215 | {} | 2213 | {} |
2216 | }, | 2214 | }, |
2217 | .chained = true, | 2215 | .chained = true, |
2218 | .chain_id = ALC887_FIXUP_BASS_CHMAP, | 2216 | .chain_id = ALC887_FIXUP_BASS_CHMAP, |
2219 | }, | 2217 | }, |
2220 | [ALC887_FIXUP_BASS_CHMAP] = { | 2218 | [ALC887_FIXUP_BASS_CHMAP] = { |
2221 | .type = HDA_FIXUP_FUNC, | 2219 | .type = HDA_FIXUP_FUNC, |
2222 | .v.func = alc_fixup_bass_chmap, | 2220 | .v.func = alc_fixup_bass_chmap, |
2223 | }, | 2221 | }, |
2224 | }; | 2222 | }; |
2225 | 2223 | ||
2226 | static const struct snd_pci_quirk alc882_fixup_tbl[] = { | 2224 | static const struct snd_pci_quirk alc882_fixup_tbl[] = { |
2227 | SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD), | 2225 | SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_FIXUP_ACER_EAPD), |
2228 | SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), | 2226 | SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), |
2229 | SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD), | 2227 | SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_FIXUP_ACER_EAPD), |
2230 | SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), | 2228 | SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_FIXUP_ACER_EAPD), |
2231 | SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD), | 2229 | SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_FIXUP_ACER_EAPD), |
2232 | SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD), | 2230 | SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_FIXUP_ACER_EAPD), |
2233 | SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G", | 2231 | SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G", |
2234 | ALC882_FIXUP_ACER_ASPIRE_4930G), | 2232 | ALC882_FIXUP_ACER_ASPIRE_4930G), |
2235 | SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", | 2233 | SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G", |
2236 | ALC882_FIXUP_ACER_ASPIRE_4930G), | 2234 | ALC882_FIXUP_ACER_ASPIRE_4930G), |
2237 | SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G", | 2235 | SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G", |
2238 | ALC882_FIXUP_ACER_ASPIRE_8930G), | 2236 | ALC882_FIXUP_ACER_ASPIRE_8930G), |
2239 | SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", | 2237 | SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G", |
2240 | ALC882_FIXUP_ACER_ASPIRE_8930G), | 2238 | ALC882_FIXUP_ACER_ASPIRE_8930G), |
2241 | SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", | 2239 | SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G", |
2242 | ALC882_FIXUP_ACER_ASPIRE_4930G), | 2240 | ALC882_FIXUP_ACER_ASPIRE_4930G), |
2243 | SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", | 2241 | SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G", |
2244 | ALC882_FIXUP_ACER_ASPIRE_4930G), | 2242 | ALC882_FIXUP_ACER_ASPIRE_4930G), |
2245 | SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", | 2243 | SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G", |
2246 | ALC882_FIXUP_ACER_ASPIRE_4930G), | 2244 | ALC882_FIXUP_ACER_ASPIRE_4930G), |
2247 | SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), | 2245 | SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", ALC882_FIXUP_PB_M5210), |
2248 | SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G", | 2246 | SND_PCI_QUIRK(0x1025, 0x021e, "Acer Aspire 5739G", |
2249 | ALC882_FIXUP_ACER_ASPIRE_4930G), | 2247 | ALC882_FIXUP_ACER_ASPIRE_4930G), |
2250 | SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE), | 2248 | SND_PCI_QUIRK(0x1025, 0x0259, "Acer Aspire 5935", ALC889_FIXUP_DAC_ROUTE), |
2251 | SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G), | 2249 | SND_PCI_QUIRK(0x1025, 0x026b, "Acer Aspire 8940G", ALC882_FIXUP_ACER_ASPIRE_8930G), |
2252 | SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736), | 2250 | SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", ALC882_FIXUP_ACER_ASPIRE_7736), |
2253 | SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD), | 2251 | SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_FIXUP_EAPD), |
2254 | SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V), | 2252 | SND_PCI_QUIRK(0x1043, 0x1873, "ASUS W90V", ALC882_FIXUP_ASUS_W90V), |
2255 | SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC), | 2253 | SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_FIXUP_ASUS_W2JC), |
2256 | SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601), | 2254 | SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_FIXUP_EEE1601), |
2257 | SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS), | 2255 | SND_PCI_QUIRK(0x1043, 0x84bc, "ASUS ET2700", ALC887_FIXUP_ASUS_BASS), |
2258 | SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), | 2256 | SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT), |
2259 | SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP), | 2257 | SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP), |
2260 | SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP), | 2258 | SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP), |
2261 | 2259 | ||
2262 | /* All Apple entries are in codec SSIDs */ | 2260 | /* All Apple entries are in codec SSIDs */ |
2263 | SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF), | 2261 | SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF), |
2264 | SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF), | 2262 | SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC889_FIXUP_MBP_VREF), |
2265 | SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), | 2263 | SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), |
2266 | SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF), | 2264 | SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC889_FIXUP_MP11_VREF), |
2267 | SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO), | 2265 | SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_FIXUP_MACPRO_GPIO), |
2268 | SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO), | 2266 | SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_FIXUP_MACPRO_GPIO), |
2269 | SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF), | 2267 | SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC889_FIXUP_MBP_VREF), |
2270 | SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF), | 2268 | SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889_FIXUP_MBP_VREF), |
2271 | SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD), | 2269 | SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_FIXUP_EAPD), |
2272 | SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF), | 2270 | SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC889_FIXUP_MBA11_VREF), |
2273 | SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF), | 2271 | SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC889_FIXUP_MBA21_VREF), |
2274 | SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF), | 2272 | SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889_FIXUP_MBP_VREF), |
2275 | SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), | 2273 | SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC889_FIXUP_MBP_VREF), |
2276 | SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO), | 2274 | SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_FIXUP_MACPRO_GPIO), |
2277 | SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF), | 2275 | SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC889_FIXUP_IMAC91_VREF), |
2278 | SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF), | 2276 | SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC889_FIXUP_IMAC91_VREF), |
2279 | SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF), | 2277 | SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC889_FIXUP_IMAC91_VREF), |
2280 | SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO), | 2278 | SND_PCI_QUIRK(0x106b, 0x4200, "Mac Pro 5,1", ALC885_FIXUP_MACPRO_GPIO), |
2281 | SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF), | 2279 | SND_PCI_QUIRK(0x106b, 0x4300, "iMac 9,1", ALC889_FIXUP_IMAC91_VREF), |
2282 | SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF), | 2280 | SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC889_FIXUP_IMAC91_VREF), |
2283 | SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF), | 2281 | SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC889_FIXUP_IMAC91_VREF), |
2284 | SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF), | 2282 | SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC889_FIXUP_IMAC91_VREF), |
2285 | 2283 | ||
2286 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), | 2284 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC882_FIXUP_EAPD), |
2287 | SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD), | 2285 | SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD), |
2288 | SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), | 2286 | SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3), |
2289 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE), | 2287 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE), |
2290 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), | 2288 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX), |
2291 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), | 2289 | SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD), |
2292 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), | 2290 | SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD), |
2293 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530), | 2291 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", ALC882_FIXUP_LENOVO_Y530), |
2294 | SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF), | 2292 | SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_FIXUP_COEF), |
2295 | {} | 2293 | {} |
2296 | }; | 2294 | }; |
2297 | 2295 | ||
2298 | static const struct hda_model_fixup alc882_fixup_models[] = { | 2296 | static const struct hda_model_fixup alc882_fixup_models[] = { |
2299 | {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"}, | 2297 | {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"}, |
2300 | {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"}, | 2298 | {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"}, |
2301 | {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"}, | 2299 | {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"}, |
2302 | {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"}, | 2300 | {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"}, |
2303 | {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"}, | 2301 | {.id = ALC882_FIXUP_NO_PRIMARY_HP, .name = "no-primary-hp"}, |
2304 | {} | 2302 | {} |
2305 | }; | 2303 | }; |
2306 | 2304 | ||
2307 | /* | 2305 | /* |
2308 | * BIOS auto configuration | 2306 | * BIOS auto configuration |
2309 | */ | 2307 | */ |
2310 | /* almost identical with ALC880 parser... */ | 2308 | /* almost identical with ALC880 parser... */ |
2311 | static int alc882_parse_auto_config(struct hda_codec *codec) | 2309 | static int alc882_parse_auto_config(struct hda_codec *codec) |
2312 | { | 2310 | { |
2313 | static const hda_nid_t alc882_ignore[] = { 0x1d, 0 }; | 2311 | static const hda_nid_t alc882_ignore[] = { 0x1d, 0 }; |
2314 | static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 }; | 2312 | static const hda_nid_t alc882_ssids[] = { 0x15, 0x1b, 0x14, 0 }; |
2315 | return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids); | 2313 | return alc_parse_auto_config(codec, alc882_ignore, alc882_ssids); |
2316 | } | 2314 | } |
2317 | 2315 | ||
2318 | /* | 2316 | /* |
2319 | */ | 2317 | */ |
2320 | static int patch_alc882(struct hda_codec *codec) | 2318 | static int patch_alc882(struct hda_codec *codec) |
2321 | { | 2319 | { |
2322 | struct alc_spec *spec; | 2320 | struct alc_spec *spec; |
2323 | int err; | 2321 | int err; |
2324 | 2322 | ||
2325 | err = alc_alloc_spec(codec, 0x0b); | 2323 | err = alc_alloc_spec(codec, 0x0b); |
2326 | if (err < 0) | 2324 | if (err < 0) |
2327 | return err; | 2325 | return err; |
2328 | 2326 | ||
2329 | spec = codec->spec; | 2327 | spec = codec->spec; |
2330 | 2328 | ||
2331 | switch (codec->vendor_id) { | 2329 | switch (codec->vendor_id) { |
2332 | case 0x10ec0882: | 2330 | case 0x10ec0882: |
2333 | case 0x10ec0885: | 2331 | case 0x10ec0885: |
2334 | break; | 2332 | break; |
2335 | default: | 2333 | default: |
2336 | /* ALC883 and variants */ | 2334 | /* ALC883 and variants */ |
2337 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); | 2335 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); |
2338 | break; | 2336 | break; |
2339 | } | 2337 | } |
2340 | 2338 | ||
2341 | snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl, | 2339 | snd_hda_pick_fixup(codec, alc882_fixup_models, alc882_fixup_tbl, |
2342 | alc882_fixups); | 2340 | alc882_fixups); |
2343 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 2341 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
2344 | 2342 | ||
2345 | alc_auto_parse_customize_define(codec); | 2343 | alc_auto_parse_customize_define(codec); |
2346 | 2344 | ||
2347 | if (has_cdefine_beep(codec)) | 2345 | if (has_cdefine_beep(codec)) |
2348 | spec->gen.beep_nid = 0x01; | 2346 | spec->gen.beep_nid = 0x01; |
2349 | 2347 | ||
2350 | /* automatic parse from the BIOS config */ | 2348 | /* automatic parse from the BIOS config */ |
2351 | err = alc882_parse_auto_config(codec); | 2349 | err = alc882_parse_auto_config(codec); |
2352 | if (err < 0) | 2350 | if (err < 0) |
2353 | goto error; | 2351 | goto error; |
2354 | 2352 | ||
2355 | if (!spec->gen.no_analog && spec->gen.beep_nid) | 2353 | if (!spec->gen.no_analog && spec->gen.beep_nid) |
2356 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 2354 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
2357 | 2355 | ||
2358 | codec->patch_ops = alc_patch_ops; | 2356 | codec->patch_ops = alc_patch_ops; |
2359 | 2357 | ||
2360 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 2358 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
2361 | 2359 | ||
2362 | return 0; | 2360 | return 0; |
2363 | 2361 | ||
2364 | error: | 2362 | error: |
2365 | alc_free(codec); | 2363 | alc_free(codec); |
2366 | return err; | 2364 | return err; |
2367 | } | 2365 | } |
2368 | 2366 | ||
2369 | 2367 | ||
2370 | /* | 2368 | /* |
2371 | * ALC262 support | 2369 | * ALC262 support |
2372 | */ | 2370 | */ |
2373 | static int alc262_parse_auto_config(struct hda_codec *codec) | 2371 | static int alc262_parse_auto_config(struct hda_codec *codec) |
2374 | { | 2372 | { |
2375 | static const hda_nid_t alc262_ignore[] = { 0x1d, 0 }; | 2373 | static const hda_nid_t alc262_ignore[] = { 0x1d, 0 }; |
2376 | static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 }; | 2374 | static const hda_nid_t alc262_ssids[] = { 0x15, 0x1b, 0x14, 0 }; |
2377 | return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids); | 2375 | return alc_parse_auto_config(codec, alc262_ignore, alc262_ssids); |
2378 | } | 2376 | } |
2379 | 2377 | ||
2380 | /* | 2378 | /* |
2381 | * Pin config fixes | 2379 | * Pin config fixes |
2382 | */ | 2380 | */ |
2383 | enum { | 2381 | enum { |
2384 | ALC262_FIXUP_FSC_H270, | 2382 | ALC262_FIXUP_FSC_H270, |
2385 | ALC262_FIXUP_FSC_S7110, | 2383 | ALC262_FIXUP_FSC_S7110, |
2386 | ALC262_FIXUP_HP_Z200, | 2384 | ALC262_FIXUP_HP_Z200, |
2387 | ALC262_FIXUP_TYAN, | 2385 | ALC262_FIXUP_TYAN, |
2388 | ALC262_FIXUP_LENOVO_3000, | 2386 | ALC262_FIXUP_LENOVO_3000, |
2389 | ALC262_FIXUP_BENQ, | 2387 | ALC262_FIXUP_BENQ, |
2390 | ALC262_FIXUP_BENQ_T31, | 2388 | ALC262_FIXUP_BENQ_T31, |
2391 | ALC262_FIXUP_INV_DMIC, | 2389 | ALC262_FIXUP_INV_DMIC, |
2392 | ALC262_FIXUP_INTEL_BAYLEYBAY, | 2390 | ALC262_FIXUP_INTEL_BAYLEYBAY, |
2393 | }; | 2391 | }; |
2394 | 2392 | ||
2395 | static const struct hda_fixup alc262_fixups[] = { | 2393 | static const struct hda_fixup alc262_fixups[] = { |
2396 | [ALC262_FIXUP_FSC_H270] = { | 2394 | [ALC262_FIXUP_FSC_H270] = { |
2397 | .type = HDA_FIXUP_PINS, | 2395 | .type = HDA_FIXUP_PINS, |
2398 | .v.pins = (const struct hda_pintbl[]) { | 2396 | .v.pins = (const struct hda_pintbl[]) { |
2399 | { 0x14, 0x99130110 }, /* speaker */ | 2397 | { 0x14, 0x99130110 }, /* speaker */ |
2400 | { 0x15, 0x0221142f }, /* front HP */ | 2398 | { 0x15, 0x0221142f }, /* front HP */ |
2401 | { 0x1b, 0x0121141f }, /* rear HP */ | 2399 | { 0x1b, 0x0121141f }, /* rear HP */ |
2402 | { } | 2400 | { } |
2403 | } | 2401 | } |
2404 | }, | 2402 | }, |
2405 | [ALC262_FIXUP_FSC_S7110] = { | 2403 | [ALC262_FIXUP_FSC_S7110] = { |
2406 | .type = HDA_FIXUP_PINS, | 2404 | .type = HDA_FIXUP_PINS, |
2407 | .v.pins = (const struct hda_pintbl[]) { | 2405 | .v.pins = (const struct hda_pintbl[]) { |
2408 | { 0x15, 0x90170110 }, /* speaker */ | 2406 | { 0x15, 0x90170110 }, /* speaker */ |
2409 | { } | 2407 | { } |
2410 | }, | 2408 | }, |
2411 | .chained = true, | 2409 | .chained = true, |
2412 | .chain_id = ALC262_FIXUP_BENQ, | 2410 | .chain_id = ALC262_FIXUP_BENQ, |
2413 | }, | 2411 | }, |
2414 | [ALC262_FIXUP_HP_Z200] = { | 2412 | [ALC262_FIXUP_HP_Z200] = { |
2415 | .type = HDA_FIXUP_PINS, | 2413 | .type = HDA_FIXUP_PINS, |
2416 | .v.pins = (const struct hda_pintbl[]) { | 2414 | .v.pins = (const struct hda_pintbl[]) { |
2417 | { 0x16, 0x99130120 }, /* internal speaker */ | 2415 | { 0x16, 0x99130120 }, /* internal speaker */ |
2418 | { } | 2416 | { } |
2419 | } | 2417 | } |
2420 | }, | 2418 | }, |
2421 | [ALC262_FIXUP_TYAN] = { | 2419 | [ALC262_FIXUP_TYAN] = { |
2422 | .type = HDA_FIXUP_PINS, | 2420 | .type = HDA_FIXUP_PINS, |
2423 | .v.pins = (const struct hda_pintbl[]) { | 2421 | .v.pins = (const struct hda_pintbl[]) { |
2424 | { 0x14, 0x1993e1f0 }, /* int AUX */ | 2422 | { 0x14, 0x1993e1f0 }, /* int AUX */ |
2425 | { } | 2423 | { } |
2426 | } | 2424 | } |
2427 | }, | 2425 | }, |
2428 | [ALC262_FIXUP_LENOVO_3000] = { | 2426 | [ALC262_FIXUP_LENOVO_3000] = { |
2429 | .type = HDA_FIXUP_PINCTLS, | 2427 | .type = HDA_FIXUP_PINCTLS, |
2430 | .v.pins = (const struct hda_pintbl[]) { | 2428 | .v.pins = (const struct hda_pintbl[]) { |
2431 | { 0x19, PIN_VREF50 }, | 2429 | { 0x19, PIN_VREF50 }, |
2432 | {} | 2430 | {} |
2433 | }, | 2431 | }, |
2434 | .chained = true, | 2432 | .chained = true, |
2435 | .chain_id = ALC262_FIXUP_BENQ, | 2433 | .chain_id = ALC262_FIXUP_BENQ, |
2436 | }, | 2434 | }, |
2437 | [ALC262_FIXUP_BENQ] = { | 2435 | [ALC262_FIXUP_BENQ] = { |
2438 | .type = HDA_FIXUP_VERBS, | 2436 | .type = HDA_FIXUP_VERBS, |
2439 | .v.verbs = (const struct hda_verb[]) { | 2437 | .v.verbs = (const struct hda_verb[]) { |
2440 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 2438 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
2441 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, | 2439 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3070 }, |
2442 | {} | 2440 | {} |
2443 | } | 2441 | } |
2444 | }, | 2442 | }, |
2445 | [ALC262_FIXUP_BENQ_T31] = { | 2443 | [ALC262_FIXUP_BENQ_T31] = { |
2446 | .type = HDA_FIXUP_VERBS, | 2444 | .type = HDA_FIXUP_VERBS, |
2447 | .v.verbs = (const struct hda_verb[]) { | 2445 | .v.verbs = (const struct hda_verb[]) { |
2448 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, | 2446 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x07 }, |
2449 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, | 2447 | { 0x20, AC_VERB_SET_PROC_COEF, 0x3050 }, |
2450 | {} | 2448 | {} |
2451 | } | 2449 | } |
2452 | }, | 2450 | }, |
2453 | [ALC262_FIXUP_INV_DMIC] = { | 2451 | [ALC262_FIXUP_INV_DMIC] = { |
2454 | .type = HDA_FIXUP_FUNC, | 2452 | .type = HDA_FIXUP_FUNC, |
2455 | .v.func = alc_fixup_inv_dmic_0x12, | 2453 | .v.func = alc_fixup_inv_dmic_0x12, |
2456 | }, | 2454 | }, |
2457 | [ALC262_FIXUP_INTEL_BAYLEYBAY] = { | 2455 | [ALC262_FIXUP_INTEL_BAYLEYBAY] = { |
2458 | .type = HDA_FIXUP_FUNC, | 2456 | .type = HDA_FIXUP_FUNC, |
2459 | .v.func = alc_fixup_no_depop_delay, | 2457 | .v.func = alc_fixup_no_depop_delay, |
2460 | }, | 2458 | }, |
2461 | }; | 2459 | }; |
2462 | 2460 | ||
2463 | static const struct snd_pci_quirk alc262_fixup_tbl[] = { | 2461 | static const struct snd_pci_quirk alc262_fixup_tbl[] = { |
2464 | SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200), | 2462 | SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", ALC262_FIXUP_HP_Z200), |
2465 | SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110), | 2463 | SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu Lifebook S7110", ALC262_FIXUP_FSC_S7110), |
2466 | SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), | 2464 | SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FIXUP_BENQ), |
2467 | SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN), | 2465 | SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_FIXUP_TYAN), |
2468 | SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270), | 2466 | SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", ALC262_FIXUP_FSC_H270), |
2469 | SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), | 2467 | SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000", ALC262_FIXUP_LENOVO_3000), |
2470 | SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), | 2468 | SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_FIXUP_BENQ), |
2471 | SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31), | 2469 | SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_FIXUP_BENQ_T31), |
2472 | SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY), | 2470 | SND_PCI_QUIRK(0x8086, 0x7270, "BayleyBay", ALC262_FIXUP_INTEL_BAYLEYBAY), |
2473 | {} | 2471 | {} |
2474 | }; | 2472 | }; |
2475 | 2473 | ||
2476 | static const struct hda_model_fixup alc262_fixup_models[] = { | 2474 | static const struct hda_model_fixup alc262_fixup_models[] = { |
2477 | {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"}, | 2475 | {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"}, |
2478 | {} | 2476 | {} |
2479 | }; | 2477 | }; |
2480 | 2478 | ||
2481 | /* | 2479 | /* |
2482 | */ | 2480 | */ |
2483 | static int patch_alc262(struct hda_codec *codec) | 2481 | static int patch_alc262(struct hda_codec *codec) |
2484 | { | 2482 | { |
2485 | struct alc_spec *spec; | 2483 | struct alc_spec *spec; |
2486 | int err; | 2484 | int err; |
2487 | 2485 | ||
2488 | err = alc_alloc_spec(codec, 0x0b); | 2486 | err = alc_alloc_spec(codec, 0x0b); |
2489 | if (err < 0) | 2487 | if (err < 0) |
2490 | return err; | 2488 | return err; |
2491 | 2489 | ||
2492 | spec = codec->spec; | 2490 | spec = codec->spec; |
2493 | spec->gen.shared_mic_vref_pin = 0x18; | 2491 | spec->gen.shared_mic_vref_pin = 0x18; |
2494 | 2492 | ||
2495 | #if 0 | 2493 | #if 0 |
2496 | /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is | 2494 | /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is |
2497 | * under-run | 2495 | * under-run |
2498 | */ | 2496 | */ |
2499 | { | 2497 | { |
2500 | int tmp; | 2498 | int tmp; |
2501 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); | 2499 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); |
2502 | tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); | 2500 | tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); |
2503 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); | 2501 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); |
2504 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); | 2502 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80); |
2505 | } | 2503 | } |
2506 | #endif | 2504 | #endif |
2507 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); | 2505 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); |
2508 | 2506 | ||
2509 | snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl, | 2507 | snd_hda_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl, |
2510 | alc262_fixups); | 2508 | alc262_fixups); |
2511 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 2509 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
2512 | 2510 | ||
2513 | alc_auto_parse_customize_define(codec); | 2511 | alc_auto_parse_customize_define(codec); |
2514 | 2512 | ||
2515 | if (has_cdefine_beep(codec)) | 2513 | if (has_cdefine_beep(codec)) |
2516 | spec->gen.beep_nid = 0x01; | 2514 | spec->gen.beep_nid = 0x01; |
2517 | 2515 | ||
2518 | /* automatic parse from the BIOS config */ | 2516 | /* automatic parse from the BIOS config */ |
2519 | err = alc262_parse_auto_config(codec); | 2517 | err = alc262_parse_auto_config(codec); |
2520 | if (err < 0) | 2518 | if (err < 0) |
2521 | goto error; | 2519 | goto error; |
2522 | 2520 | ||
2523 | if (!spec->gen.no_analog && spec->gen.beep_nid) | 2521 | if (!spec->gen.no_analog && spec->gen.beep_nid) |
2524 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 2522 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
2525 | 2523 | ||
2526 | codec->patch_ops = alc_patch_ops; | 2524 | codec->patch_ops = alc_patch_ops; |
2527 | spec->shutup = alc_eapd_shutup; | 2525 | spec->shutup = alc_eapd_shutup; |
2528 | 2526 | ||
2529 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 2527 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
2530 | 2528 | ||
2531 | return 0; | 2529 | return 0; |
2532 | 2530 | ||
2533 | error: | 2531 | error: |
2534 | alc_free(codec); | 2532 | alc_free(codec); |
2535 | return err; | 2533 | return err; |
2536 | } | 2534 | } |
2537 | 2535 | ||
2538 | /* | 2536 | /* |
2539 | * ALC268 | 2537 | * ALC268 |
2540 | */ | 2538 | */ |
2541 | /* bind Beep switches of both NID 0x0f and 0x10 */ | 2539 | /* bind Beep switches of both NID 0x0f and 0x10 */ |
2542 | static const struct hda_bind_ctls alc268_bind_beep_sw = { | 2540 | static const struct hda_bind_ctls alc268_bind_beep_sw = { |
2543 | .ops = &snd_hda_bind_sw, | 2541 | .ops = &snd_hda_bind_sw, |
2544 | .values = { | 2542 | .values = { |
2545 | HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), | 2543 | HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), |
2546 | HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT), | 2544 | HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT), |
2547 | 0 | 2545 | 0 |
2548 | }, | 2546 | }, |
2549 | }; | 2547 | }; |
2550 | 2548 | ||
2551 | static const struct snd_kcontrol_new alc268_beep_mixer[] = { | 2549 | static const struct snd_kcontrol_new alc268_beep_mixer[] = { |
2552 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), | 2550 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), |
2553 | HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), | 2551 | HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), |
2554 | { } | 2552 | { } |
2555 | }; | 2553 | }; |
2556 | 2554 | ||
2557 | /* set PCBEEP vol = 0, mute connections */ | 2555 | /* set PCBEEP vol = 0, mute connections */ |
2558 | static const struct hda_verb alc268_beep_init_verbs[] = { | 2556 | static const struct hda_verb alc268_beep_init_verbs[] = { |
2559 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 2557 | {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
2560 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 2558 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
2561 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 2559 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
2562 | { } | 2560 | { } |
2563 | }; | 2561 | }; |
2564 | 2562 | ||
2565 | enum { | 2563 | enum { |
2566 | ALC268_FIXUP_INV_DMIC, | 2564 | ALC268_FIXUP_INV_DMIC, |
2567 | ALC268_FIXUP_HP_EAPD, | 2565 | ALC268_FIXUP_HP_EAPD, |
2568 | ALC268_FIXUP_SPDIF, | 2566 | ALC268_FIXUP_SPDIF, |
2569 | }; | 2567 | }; |
2570 | 2568 | ||
2571 | static const struct hda_fixup alc268_fixups[] = { | 2569 | static const struct hda_fixup alc268_fixups[] = { |
2572 | [ALC268_FIXUP_INV_DMIC] = { | 2570 | [ALC268_FIXUP_INV_DMIC] = { |
2573 | .type = HDA_FIXUP_FUNC, | 2571 | .type = HDA_FIXUP_FUNC, |
2574 | .v.func = alc_fixup_inv_dmic_0x12, | 2572 | .v.func = alc_fixup_inv_dmic_0x12, |
2575 | }, | 2573 | }, |
2576 | [ALC268_FIXUP_HP_EAPD] = { | 2574 | [ALC268_FIXUP_HP_EAPD] = { |
2577 | .type = HDA_FIXUP_VERBS, | 2575 | .type = HDA_FIXUP_VERBS, |
2578 | .v.verbs = (const struct hda_verb[]) { | 2576 | .v.verbs = (const struct hda_verb[]) { |
2579 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0}, | 2577 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 0}, |
2580 | {} | 2578 | {} |
2581 | } | 2579 | } |
2582 | }, | 2580 | }, |
2583 | [ALC268_FIXUP_SPDIF] = { | 2581 | [ALC268_FIXUP_SPDIF] = { |
2584 | .type = HDA_FIXUP_PINS, | 2582 | .type = HDA_FIXUP_PINS, |
2585 | .v.pins = (const struct hda_pintbl[]) { | 2583 | .v.pins = (const struct hda_pintbl[]) { |
2586 | { 0x1e, 0x014b1180 }, /* enable SPDIF out */ | 2584 | { 0x1e, 0x014b1180 }, /* enable SPDIF out */ |
2587 | {} | 2585 | {} |
2588 | } | 2586 | } |
2589 | }, | 2587 | }, |
2590 | }; | 2588 | }; |
2591 | 2589 | ||
2592 | static const struct hda_model_fixup alc268_fixup_models[] = { | 2590 | static const struct hda_model_fixup alc268_fixup_models[] = { |
2593 | {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"}, | 2591 | {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"}, |
2594 | {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"}, | 2592 | {.id = ALC268_FIXUP_HP_EAPD, .name = "hp-eapd"}, |
2595 | {} | 2593 | {} |
2596 | }; | 2594 | }; |
2597 | 2595 | ||
2598 | static const struct snd_pci_quirk alc268_fixup_tbl[] = { | 2596 | static const struct snd_pci_quirk alc268_fixup_tbl[] = { |
2599 | SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF), | 2597 | SND_PCI_QUIRK(0x1025, 0x0139, "Acer TravelMate 6293", ALC268_FIXUP_SPDIF), |
2600 | SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC), | 2598 | SND_PCI_QUIRK(0x1025, 0x015b, "Acer AOA 150 (ZG5)", ALC268_FIXUP_INV_DMIC), |
2601 | /* below is codec SSID since multiple Toshiba laptops have the | 2599 | /* below is codec SSID since multiple Toshiba laptops have the |
2602 | * same PCI SSID 1179:ff00 | 2600 | * same PCI SSID 1179:ff00 |
2603 | */ | 2601 | */ |
2604 | SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD), | 2602 | SND_PCI_QUIRK(0x1179, 0xff06, "Toshiba P200", ALC268_FIXUP_HP_EAPD), |
2605 | {} | 2603 | {} |
2606 | }; | 2604 | }; |
2607 | 2605 | ||
2608 | /* | 2606 | /* |
2609 | * BIOS auto configuration | 2607 | * BIOS auto configuration |
2610 | */ | 2608 | */ |
2611 | static int alc268_parse_auto_config(struct hda_codec *codec) | 2609 | static int alc268_parse_auto_config(struct hda_codec *codec) |
2612 | { | 2610 | { |
2613 | static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 }; | 2611 | static const hda_nid_t alc268_ssids[] = { 0x15, 0x1b, 0x14, 0 }; |
2614 | return alc_parse_auto_config(codec, NULL, alc268_ssids); | 2612 | return alc_parse_auto_config(codec, NULL, alc268_ssids); |
2615 | } | 2613 | } |
2616 | 2614 | ||
2617 | /* | 2615 | /* |
2618 | */ | 2616 | */ |
2619 | static int patch_alc268(struct hda_codec *codec) | 2617 | static int patch_alc268(struct hda_codec *codec) |
2620 | { | 2618 | { |
2621 | struct alc_spec *spec; | 2619 | struct alc_spec *spec; |
2622 | int err; | 2620 | int err; |
2623 | 2621 | ||
2624 | /* ALC268 has no aa-loopback mixer */ | 2622 | /* ALC268 has no aa-loopback mixer */ |
2625 | err = alc_alloc_spec(codec, 0); | 2623 | err = alc_alloc_spec(codec, 0); |
2626 | if (err < 0) | 2624 | if (err < 0) |
2627 | return err; | 2625 | return err; |
2628 | 2626 | ||
2629 | spec = codec->spec; | 2627 | spec = codec->spec; |
2630 | spec->gen.beep_nid = 0x01; | 2628 | spec->gen.beep_nid = 0x01; |
2631 | 2629 | ||
2632 | snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups); | 2630 | snd_hda_pick_fixup(codec, alc268_fixup_models, alc268_fixup_tbl, alc268_fixups); |
2633 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 2631 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
2634 | 2632 | ||
2635 | /* automatic parse from the BIOS config */ | 2633 | /* automatic parse from the BIOS config */ |
2636 | err = alc268_parse_auto_config(codec); | 2634 | err = alc268_parse_auto_config(codec); |
2637 | if (err < 0) | 2635 | if (err < 0) |
2638 | goto error; | 2636 | goto error; |
2639 | 2637 | ||
2640 | if (err > 0 && !spec->gen.no_analog && | 2638 | if (err > 0 && !spec->gen.no_analog && |
2641 | spec->gen.autocfg.speaker_pins[0] != 0x1d) { | 2639 | spec->gen.autocfg.speaker_pins[0] != 0x1d) { |
2642 | add_mixer(spec, alc268_beep_mixer); | 2640 | add_mixer(spec, alc268_beep_mixer); |
2643 | snd_hda_add_verbs(codec, alc268_beep_init_verbs); | 2641 | snd_hda_add_verbs(codec, alc268_beep_init_verbs); |
2644 | if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) | 2642 | if (!query_amp_caps(codec, 0x1d, HDA_INPUT)) |
2645 | /* override the amp caps for beep generator */ | 2643 | /* override the amp caps for beep generator */ |
2646 | snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, | 2644 | snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT, |
2647 | (0x0c << AC_AMPCAP_OFFSET_SHIFT) | | 2645 | (0x0c << AC_AMPCAP_OFFSET_SHIFT) | |
2648 | (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) | | 2646 | (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) | |
2649 | (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) | | 2647 | (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) | |
2650 | (0 << AC_AMPCAP_MUTE_SHIFT)); | 2648 | (0 << AC_AMPCAP_MUTE_SHIFT)); |
2651 | } | 2649 | } |
2652 | 2650 | ||
2653 | codec->patch_ops = alc_patch_ops; | 2651 | codec->patch_ops = alc_patch_ops; |
2654 | spec->shutup = alc_eapd_shutup; | 2652 | spec->shutup = alc_eapd_shutup; |
2655 | 2653 | ||
2656 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 2654 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
2657 | 2655 | ||
2658 | return 0; | 2656 | return 0; |
2659 | 2657 | ||
2660 | error: | 2658 | error: |
2661 | alc_free(codec); | 2659 | alc_free(codec); |
2662 | return err; | 2660 | return err; |
2663 | } | 2661 | } |
2664 | 2662 | ||
2665 | /* | 2663 | /* |
2666 | * ALC269 | 2664 | * ALC269 |
2667 | */ | 2665 | */ |
2668 | 2666 | ||
2669 | static int playback_pcm_open(struct hda_pcm_stream *hinfo, | 2667 | static int playback_pcm_open(struct hda_pcm_stream *hinfo, |
2670 | struct hda_codec *codec, | 2668 | struct hda_codec *codec, |
2671 | struct snd_pcm_substream *substream) | 2669 | struct snd_pcm_substream *substream) |
2672 | { | 2670 | { |
2673 | struct hda_gen_spec *spec = codec->spec; | 2671 | struct hda_gen_spec *spec = codec->spec; |
2674 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, | 2672 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, |
2675 | hinfo); | 2673 | hinfo); |
2676 | } | 2674 | } |
2677 | 2675 | ||
2678 | static int playback_pcm_prepare(struct hda_pcm_stream *hinfo, | 2676 | static int playback_pcm_prepare(struct hda_pcm_stream *hinfo, |
2679 | struct hda_codec *codec, | 2677 | struct hda_codec *codec, |
2680 | unsigned int stream_tag, | 2678 | unsigned int stream_tag, |
2681 | unsigned int format, | 2679 | unsigned int format, |
2682 | struct snd_pcm_substream *substream) | 2680 | struct snd_pcm_substream *substream) |
2683 | { | 2681 | { |
2684 | struct hda_gen_spec *spec = codec->spec; | 2682 | struct hda_gen_spec *spec = codec->spec; |
2685 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, | 2683 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, |
2686 | stream_tag, format, substream); | 2684 | stream_tag, format, substream); |
2687 | } | 2685 | } |
2688 | 2686 | ||
2689 | static int playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | 2687 | static int playback_pcm_cleanup(struct hda_pcm_stream *hinfo, |
2690 | struct hda_codec *codec, | 2688 | struct hda_codec *codec, |
2691 | struct snd_pcm_substream *substream) | 2689 | struct snd_pcm_substream *substream) |
2692 | { | 2690 | { |
2693 | struct hda_gen_spec *spec = codec->spec; | 2691 | struct hda_gen_spec *spec = codec->spec; |
2694 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | 2692 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); |
2695 | } | 2693 | } |
2696 | 2694 | ||
2697 | static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = { | 2695 | static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = { |
2698 | .substreams = 1, | 2696 | .substreams = 1, |
2699 | .channels_min = 2, | 2697 | .channels_min = 2, |
2700 | .channels_max = 8, | 2698 | .channels_max = 8, |
2701 | .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ | 2699 | .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ |
2702 | /* NID is set in alc_build_pcms */ | 2700 | /* NID is set in alc_build_pcms */ |
2703 | .ops = { | 2701 | .ops = { |
2704 | .open = playback_pcm_open, | 2702 | .open = playback_pcm_open, |
2705 | .prepare = playback_pcm_prepare, | 2703 | .prepare = playback_pcm_prepare, |
2706 | .cleanup = playback_pcm_cleanup | 2704 | .cleanup = playback_pcm_cleanup |
2707 | }, | 2705 | }, |
2708 | }; | 2706 | }; |
2709 | 2707 | ||
2710 | static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = { | 2708 | static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = { |
2711 | .substreams = 1, | 2709 | .substreams = 1, |
2712 | .channels_min = 2, | 2710 | .channels_min = 2, |
2713 | .channels_max = 2, | 2711 | .channels_max = 2, |
2714 | .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ | 2712 | .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ |
2715 | /* NID is set in alc_build_pcms */ | 2713 | /* NID is set in alc_build_pcms */ |
2716 | }; | 2714 | }; |
2717 | 2715 | ||
2718 | /* different alc269-variants */ | 2716 | /* different alc269-variants */ |
2719 | enum { | 2717 | enum { |
2720 | ALC269_TYPE_ALC269VA, | 2718 | ALC269_TYPE_ALC269VA, |
2721 | ALC269_TYPE_ALC269VB, | 2719 | ALC269_TYPE_ALC269VB, |
2722 | ALC269_TYPE_ALC269VC, | 2720 | ALC269_TYPE_ALC269VC, |
2723 | ALC269_TYPE_ALC269VD, | 2721 | ALC269_TYPE_ALC269VD, |
2724 | ALC269_TYPE_ALC280, | 2722 | ALC269_TYPE_ALC280, |
2725 | ALC269_TYPE_ALC282, | 2723 | ALC269_TYPE_ALC282, |
2726 | ALC269_TYPE_ALC283, | 2724 | ALC269_TYPE_ALC283, |
2727 | ALC269_TYPE_ALC284, | 2725 | ALC269_TYPE_ALC284, |
2728 | ALC269_TYPE_ALC285, | 2726 | ALC269_TYPE_ALC285, |
2729 | ALC269_TYPE_ALC286, | 2727 | ALC269_TYPE_ALC286, |
2730 | ALC269_TYPE_ALC255, | 2728 | ALC269_TYPE_ALC255, |
2731 | }; | 2729 | }; |
2732 | 2730 | ||
2733 | /* | 2731 | /* |
2734 | * BIOS auto configuration | 2732 | * BIOS auto configuration |
2735 | */ | 2733 | */ |
2736 | static int alc269_parse_auto_config(struct hda_codec *codec) | 2734 | static int alc269_parse_auto_config(struct hda_codec *codec) |
2737 | { | 2735 | { |
2738 | static const hda_nid_t alc269_ignore[] = { 0x1d, 0 }; | 2736 | static const hda_nid_t alc269_ignore[] = { 0x1d, 0 }; |
2739 | static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 }; | 2737 | static const hda_nid_t alc269_ssids[] = { 0, 0x1b, 0x14, 0x21 }; |
2740 | static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 }; | 2738 | static const hda_nid_t alc269va_ssids[] = { 0x15, 0x1b, 0x14, 0 }; |
2741 | struct alc_spec *spec = codec->spec; | 2739 | struct alc_spec *spec = codec->spec; |
2742 | const hda_nid_t *ssids; | 2740 | const hda_nid_t *ssids; |
2743 | 2741 | ||
2744 | switch (spec->codec_variant) { | 2742 | switch (spec->codec_variant) { |
2745 | case ALC269_TYPE_ALC269VA: | 2743 | case ALC269_TYPE_ALC269VA: |
2746 | case ALC269_TYPE_ALC269VC: | 2744 | case ALC269_TYPE_ALC269VC: |
2747 | case ALC269_TYPE_ALC280: | 2745 | case ALC269_TYPE_ALC280: |
2748 | case ALC269_TYPE_ALC284: | 2746 | case ALC269_TYPE_ALC284: |
2749 | case ALC269_TYPE_ALC285: | 2747 | case ALC269_TYPE_ALC285: |
2750 | ssids = alc269va_ssids; | 2748 | ssids = alc269va_ssids; |
2751 | break; | 2749 | break; |
2752 | case ALC269_TYPE_ALC269VB: | 2750 | case ALC269_TYPE_ALC269VB: |
2753 | case ALC269_TYPE_ALC269VD: | 2751 | case ALC269_TYPE_ALC269VD: |
2754 | case ALC269_TYPE_ALC282: | 2752 | case ALC269_TYPE_ALC282: |
2755 | case ALC269_TYPE_ALC283: | 2753 | case ALC269_TYPE_ALC283: |
2756 | case ALC269_TYPE_ALC286: | 2754 | case ALC269_TYPE_ALC286: |
2757 | case ALC269_TYPE_ALC255: | 2755 | case ALC269_TYPE_ALC255: |
2758 | ssids = alc269_ssids; | 2756 | ssids = alc269_ssids; |
2759 | break; | 2757 | break; |
2760 | default: | 2758 | default: |
2761 | ssids = alc269_ssids; | 2759 | ssids = alc269_ssids; |
2762 | break; | 2760 | break; |
2763 | } | 2761 | } |
2764 | 2762 | ||
2765 | return alc_parse_auto_config(codec, alc269_ignore, ssids); | 2763 | return alc_parse_auto_config(codec, alc269_ignore, ssids); |
2766 | } | 2764 | } |
2767 | 2765 | ||
2768 | static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up) | 2766 | static void alc269vb_toggle_power_output(struct hda_codec *codec, int power_up) |
2769 | { | 2767 | { |
2770 | int val = alc_read_coef_idx(codec, 0x04); | 2768 | int val = alc_read_coef_idx(codec, 0x04); |
2771 | if (power_up) | 2769 | if (power_up) |
2772 | val |= 1 << 11; | 2770 | val |= 1 << 11; |
2773 | else | 2771 | else |
2774 | val &= ~(1 << 11); | 2772 | val &= ~(1 << 11); |
2775 | alc_write_coef_idx(codec, 0x04, val); | 2773 | alc_write_coef_idx(codec, 0x04, val); |
2776 | } | 2774 | } |
2777 | 2775 | ||
2778 | static void alc269_shutup(struct hda_codec *codec) | 2776 | static void alc269_shutup(struct hda_codec *codec) |
2779 | { | 2777 | { |
2780 | struct alc_spec *spec = codec->spec; | 2778 | struct alc_spec *spec = codec->spec; |
2781 | 2779 | ||
2782 | if (spec->codec_variant == ALC269_TYPE_ALC269VB) | 2780 | if (spec->codec_variant == ALC269_TYPE_ALC269VB) |
2783 | alc269vb_toggle_power_output(codec, 0); | 2781 | alc269vb_toggle_power_output(codec, 0); |
2784 | if (spec->codec_variant == ALC269_TYPE_ALC269VB && | 2782 | if (spec->codec_variant == ALC269_TYPE_ALC269VB && |
2785 | (alc_get_coef0(codec) & 0x00ff) == 0x018) { | 2783 | (alc_get_coef0(codec) & 0x00ff) == 0x018) { |
2786 | msleep(150); | 2784 | msleep(150); |
2787 | } | 2785 | } |
2788 | snd_hda_shutup_pins(codec); | 2786 | snd_hda_shutup_pins(codec); |
2789 | } | 2787 | } |
2790 | 2788 | ||
2791 | static void alc282_restore_default_value(struct hda_codec *codec) | 2789 | static void alc282_restore_default_value(struct hda_codec *codec) |
2792 | { | 2790 | { |
2793 | int val; | 2791 | int val; |
2794 | 2792 | ||
2795 | /* Power Down Control */ | 2793 | /* Power Down Control */ |
2796 | alc_write_coef_idx(codec, 0x03, 0x0002); | 2794 | alc_write_coef_idx(codec, 0x03, 0x0002); |
2797 | /* FIFO and filter clock */ | 2795 | /* FIFO and filter clock */ |
2798 | alc_write_coef_idx(codec, 0x05, 0x0700); | 2796 | alc_write_coef_idx(codec, 0x05, 0x0700); |
2799 | /* DMIC control */ | 2797 | /* DMIC control */ |
2800 | alc_write_coef_idx(codec, 0x07, 0x0200); | 2798 | alc_write_coef_idx(codec, 0x07, 0x0200); |
2801 | /* Analog clock */ | 2799 | /* Analog clock */ |
2802 | val = alc_read_coef_idx(codec, 0x06); | 2800 | val = alc_read_coef_idx(codec, 0x06); |
2803 | alc_write_coef_idx(codec, 0x06, (val & ~0x00f0) | 0x0); | 2801 | alc_write_coef_idx(codec, 0x06, (val & ~0x00f0) | 0x0); |
2804 | /* JD */ | 2802 | /* JD */ |
2805 | val = alc_read_coef_idx(codec, 0x08); | 2803 | val = alc_read_coef_idx(codec, 0x08); |
2806 | alc_write_coef_idx(codec, 0x08, (val & ~0xfffc) | 0x0c2c); | 2804 | alc_write_coef_idx(codec, 0x08, (val & ~0xfffc) | 0x0c2c); |
2807 | /* JD offset1 */ | 2805 | /* JD offset1 */ |
2808 | alc_write_coef_idx(codec, 0x0a, 0xcccc); | 2806 | alc_write_coef_idx(codec, 0x0a, 0xcccc); |
2809 | /* JD offset2 */ | 2807 | /* JD offset2 */ |
2810 | alc_write_coef_idx(codec, 0x0b, 0xcccc); | 2808 | alc_write_coef_idx(codec, 0x0b, 0xcccc); |
2811 | /* LDO1/2/3, DAC/ADC */ | 2809 | /* LDO1/2/3, DAC/ADC */ |
2812 | alc_write_coef_idx(codec, 0x0e, 0x6e00); | 2810 | alc_write_coef_idx(codec, 0x0e, 0x6e00); |
2813 | /* JD */ | 2811 | /* JD */ |
2814 | val = alc_read_coef_idx(codec, 0x0f); | 2812 | val = alc_read_coef_idx(codec, 0x0f); |
2815 | alc_write_coef_idx(codec, 0x0f, (val & ~0xf800) | 0x1000); | 2813 | alc_write_coef_idx(codec, 0x0f, (val & ~0xf800) | 0x1000); |
2816 | /* Capless */ | 2814 | /* Capless */ |
2817 | val = alc_read_coef_idx(codec, 0x10); | 2815 | val = alc_read_coef_idx(codec, 0x10); |
2818 | alc_write_coef_idx(codec, 0x10, (val & ~0xfc00) | 0x0c00); | 2816 | alc_write_coef_idx(codec, 0x10, (val & ~0xfc00) | 0x0c00); |
2819 | /* Class D test 4 */ | 2817 | /* Class D test 4 */ |
2820 | alc_write_coef_idx(codec, 0x6f, 0x0); | 2818 | alc_write_coef_idx(codec, 0x6f, 0x0); |
2821 | /* IO power down directly */ | 2819 | /* IO power down directly */ |
2822 | val = alc_read_coef_idx(codec, 0x0c); | 2820 | val = alc_read_coef_idx(codec, 0x0c); |
2823 | alc_write_coef_idx(codec, 0x0c, (val & ~0xfe00) | 0x0); | 2821 | alc_write_coef_idx(codec, 0x0c, (val & ~0xfe00) | 0x0); |
2824 | /* ANC */ | 2822 | /* ANC */ |
2825 | alc_write_coef_idx(codec, 0x34, 0xa0c0); | 2823 | alc_write_coef_idx(codec, 0x34, 0xa0c0); |
2826 | /* AGC MUX */ | 2824 | /* AGC MUX */ |
2827 | val = alc_read_coef_idx(codec, 0x16); | 2825 | val = alc_read_coef_idx(codec, 0x16); |
2828 | alc_write_coef_idx(codec, 0x16, (val & ~0x0008) | 0x0); | 2826 | alc_write_coef_idx(codec, 0x16, (val & ~0x0008) | 0x0); |
2829 | /* DAC simple content protection */ | 2827 | /* DAC simple content protection */ |
2830 | val = alc_read_coef_idx(codec, 0x1d); | 2828 | val = alc_read_coef_idx(codec, 0x1d); |
2831 | alc_write_coef_idx(codec, 0x1d, (val & ~0x00e0) | 0x0); | 2829 | alc_write_coef_idx(codec, 0x1d, (val & ~0x00e0) | 0x0); |
2832 | /* ADC simple content protection */ | 2830 | /* ADC simple content protection */ |
2833 | val = alc_read_coef_idx(codec, 0x1f); | 2831 | val = alc_read_coef_idx(codec, 0x1f); |
2834 | alc_write_coef_idx(codec, 0x1f, (val & ~0x00e0) | 0x0); | 2832 | alc_write_coef_idx(codec, 0x1f, (val & ~0x00e0) | 0x0); |
2835 | /* DAC ADC Zero Detection */ | 2833 | /* DAC ADC Zero Detection */ |
2836 | alc_write_coef_idx(codec, 0x21, 0x8804); | 2834 | alc_write_coef_idx(codec, 0x21, 0x8804); |
2837 | /* PLL */ | 2835 | /* PLL */ |
2838 | alc_write_coef_idx(codec, 0x63, 0x2902); | 2836 | alc_write_coef_idx(codec, 0x63, 0x2902); |
2839 | /* capless control 2 */ | 2837 | /* capless control 2 */ |
2840 | alc_write_coef_idx(codec, 0x68, 0xa080); | 2838 | alc_write_coef_idx(codec, 0x68, 0xa080); |
2841 | /* capless control 3 */ | 2839 | /* capless control 3 */ |
2842 | alc_write_coef_idx(codec, 0x69, 0x3400); | 2840 | alc_write_coef_idx(codec, 0x69, 0x3400); |
2843 | /* capless control 4 */ | 2841 | /* capless control 4 */ |
2844 | alc_write_coef_idx(codec, 0x6a, 0x2f3e); | 2842 | alc_write_coef_idx(codec, 0x6a, 0x2f3e); |
2845 | /* capless control 5 */ | 2843 | /* capless control 5 */ |
2846 | alc_write_coef_idx(codec, 0x6b, 0x0); | 2844 | alc_write_coef_idx(codec, 0x6b, 0x0); |
2847 | /* class D test 2 */ | 2845 | /* class D test 2 */ |
2848 | val = alc_read_coef_idx(codec, 0x6d); | 2846 | val = alc_read_coef_idx(codec, 0x6d); |
2849 | alc_write_coef_idx(codec, 0x6d, (val & ~0x0fff) | 0x0900); | 2847 | alc_write_coef_idx(codec, 0x6d, (val & ~0x0fff) | 0x0900); |
2850 | /* class D test 3 */ | 2848 | /* class D test 3 */ |
2851 | alc_write_coef_idx(codec, 0x6e, 0x110a); | 2849 | alc_write_coef_idx(codec, 0x6e, 0x110a); |
2852 | /* class D test 5 */ | 2850 | /* class D test 5 */ |
2853 | val = alc_read_coef_idx(codec, 0x70); | 2851 | val = alc_read_coef_idx(codec, 0x70); |
2854 | alc_write_coef_idx(codec, 0x70, (val & ~0x00f8) | 0x00d8); | 2852 | alc_write_coef_idx(codec, 0x70, (val & ~0x00f8) | 0x00d8); |
2855 | /* class D test 6 */ | 2853 | /* class D test 6 */ |
2856 | alc_write_coef_idx(codec, 0x71, 0x0014); | 2854 | alc_write_coef_idx(codec, 0x71, 0x0014); |
2857 | /* classD OCP */ | 2855 | /* classD OCP */ |
2858 | alc_write_coef_idx(codec, 0x72, 0xc2ba); | 2856 | alc_write_coef_idx(codec, 0x72, 0xc2ba); |
2859 | /* classD pure DC test */ | 2857 | /* classD pure DC test */ |
2860 | val = alc_read_coef_idx(codec, 0x77); | 2858 | val = alc_read_coef_idx(codec, 0x77); |
2861 | alc_write_coef_idx(codec, 0x77, (val & ~0x0f80) | 0x0); | 2859 | alc_write_coef_idx(codec, 0x77, (val & ~0x0f80) | 0x0); |
2862 | /* Class D amp control */ | 2860 | /* Class D amp control */ |
2863 | alc_write_coef_idx(codec, 0x6c, 0xfc06); | 2861 | alc_write_coef_idx(codec, 0x6c, 0xfc06); |
2864 | } | 2862 | } |
2865 | 2863 | ||
2866 | static void alc282_init(struct hda_codec *codec) | 2864 | static void alc282_init(struct hda_codec *codec) |
2867 | { | 2865 | { |
2868 | struct alc_spec *spec = codec->spec; | 2866 | struct alc_spec *spec = codec->spec; |
2869 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 2867 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; |
2870 | bool hp_pin_sense; | 2868 | bool hp_pin_sense; |
2871 | int coef78; | 2869 | int coef78; |
2872 | 2870 | ||
2873 | alc282_restore_default_value(codec); | 2871 | alc282_restore_default_value(codec); |
2874 | 2872 | ||
2875 | if (!hp_pin) | 2873 | if (!hp_pin) |
2876 | return; | 2874 | return; |
2877 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); | 2875 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); |
2878 | coef78 = alc_read_coef_idx(codec, 0x78); | 2876 | coef78 = alc_read_coef_idx(codec, 0x78); |
2879 | 2877 | ||
2880 | /* Index 0x78 Direct Drive HP AMP LPM Control 1 */ | 2878 | /* Index 0x78 Direct Drive HP AMP LPM Control 1 */ |
2881 | /* Headphone capless set to high power mode */ | 2879 | /* Headphone capless set to high power mode */ |
2882 | alc_write_coef_idx(codec, 0x78, 0x9004); | 2880 | alc_write_coef_idx(codec, 0x78, 0x9004); |
2883 | 2881 | ||
2884 | if (hp_pin_sense) | 2882 | if (hp_pin_sense) |
2885 | msleep(2); | 2883 | msleep(2); |
2886 | 2884 | ||
2887 | snd_hda_codec_write(codec, hp_pin, 0, | 2885 | snd_hda_codec_write(codec, hp_pin, 0, |
2888 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | 2886 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); |
2889 | 2887 | ||
2890 | if (hp_pin_sense) | 2888 | if (hp_pin_sense) |
2891 | msleep(85); | 2889 | msleep(85); |
2892 | 2890 | ||
2893 | snd_hda_codec_write(codec, hp_pin, 0, | 2891 | snd_hda_codec_write(codec, hp_pin, 0, |
2894 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | 2892 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); |
2895 | 2893 | ||
2896 | if (hp_pin_sense) | 2894 | if (hp_pin_sense) |
2897 | msleep(100); | 2895 | msleep(100); |
2898 | 2896 | ||
2899 | /* Headphone capless set to normal mode */ | 2897 | /* Headphone capless set to normal mode */ |
2900 | alc_write_coef_idx(codec, 0x78, coef78); | 2898 | alc_write_coef_idx(codec, 0x78, coef78); |
2901 | } | 2899 | } |
2902 | 2900 | ||
2903 | static void alc282_shutup(struct hda_codec *codec) | 2901 | static void alc282_shutup(struct hda_codec *codec) |
2904 | { | 2902 | { |
2905 | struct alc_spec *spec = codec->spec; | 2903 | struct alc_spec *spec = codec->spec; |
2906 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 2904 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; |
2907 | bool hp_pin_sense; | 2905 | bool hp_pin_sense; |
2908 | int coef78; | 2906 | int coef78; |
2909 | 2907 | ||
2910 | if (!hp_pin) { | 2908 | if (!hp_pin) { |
2911 | alc269_shutup(codec); | 2909 | alc269_shutup(codec); |
2912 | return; | 2910 | return; |
2913 | } | 2911 | } |
2914 | 2912 | ||
2915 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); | 2913 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); |
2916 | coef78 = alc_read_coef_idx(codec, 0x78); | 2914 | coef78 = alc_read_coef_idx(codec, 0x78); |
2917 | alc_write_coef_idx(codec, 0x78, 0x9004); | 2915 | alc_write_coef_idx(codec, 0x78, 0x9004); |
2918 | 2916 | ||
2919 | if (hp_pin_sense) | 2917 | if (hp_pin_sense) |
2920 | msleep(2); | 2918 | msleep(2); |
2921 | 2919 | ||
2922 | snd_hda_codec_write(codec, hp_pin, 0, | 2920 | snd_hda_codec_write(codec, hp_pin, 0, |
2923 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | 2921 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); |
2924 | 2922 | ||
2925 | if (hp_pin_sense) | 2923 | if (hp_pin_sense) |
2926 | msleep(85); | 2924 | msleep(85); |
2927 | 2925 | ||
2928 | snd_hda_codec_write(codec, hp_pin, 0, | 2926 | snd_hda_codec_write(codec, hp_pin, 0, |
2929 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); | 2927 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); |
2930 | 2928 | ||
2931 | if (hp_pin_sense) | 2929 | if (hp_pin_sense) |
2932 | msleep(100); | 2930 | msleep(100); |
2933 | 2931 | ||
2934 | alc_auto_setup_eapd(codec, false); | 2932 | alc_auto_setup_eapd(codec, false); |
2935 | snd_hda_shutup_pins(codec); | 2933 | snd_hda_shutup_pins(codec); |
2936 | alc_write_coef_idx(codec, 0x78, coef78); | 2934 | alc_write_coef_idx(codec, 0x78, coef78); |
2937 | } | 2935 | } |
2938 | 2936 | ||
2939 | static void alc283_restore_default_value(struct hda_codec *codec) | 2937 | static void alc283_restore_default_value(struct hda_codec *codec) |
2940 | { | 2938 | { |
2941 | int val; | 2939 | int val; |
2942 | 2940 | ||
2943 | /* Power Down Control */ | 2941 | /* Power Down Control */ |
2944 | alc_write_coef_idx(codec, 0x03, 0x0002); | 2942 | alc_write_coef_idx(codec, 0x03, 0x0002); |
2945 | /* FIFO and filter clock */ | 2943 | /* FIFO and filter clock */ |
2946 | alc_write_coef_idx(codec, 0x05, 0x0700); | 2944 | alc_write_coef_idx(codec, 0x05, 0x0700); |
2947 | /* DMIC control */ | 2945 | /* DMIC control */ |
2948 | alc_write_coef_idx(codec, 0x07, 0x0200); | 2946 | alc_write_coef_idx(codec, 0x07, 0x0200); |
2949 | /* Analog clock */ | 2947 | /* Analog clock */ |
2950 | val = alc_read_coef_idx(codec, 0x06); | 2948 | val = alc_read_coef_idx(codec, 0x06); |
2951 | alc_write_coef_idx(codec, 0x06, (val & ~0x00f0) | 0x0); | 2949 | alc_write_coef_idx(codec, 0x06, (val & ~0x00f0) | 0x0); |
2952 | /* JD */ | 2950 | /* JD */ |
2953 | val = alc_read_coef_idx(codec, 0x08); | 2951 | val = alc_read_coef_idx(codec, 0x08); |
2954 | alc_write_coef_idx(codec, 0x08, (val & ~0xfffc) | 0x0c2c); | 2952 | alc_write_coef_idx(codec, 0x08, (val & ~0xfffc) | 0x0c2c); |
2955 | /* JD offset1 */ | 2953 | /* JD offset1 */ |
2956 | alc_write_coef_idx(codec, 0x0a, 0xcccc); | 2954 | alc_write_coef_idx(codec, 0x0a, 0xcccc); |
2957 | /* JD offset2 */ | 2955 | /* JD offset2 */ |
2958 | alc_write_coef_idx(codec, 0x0b, 0xcccc); | 2956 | alc_write_coef_idx(codec, 0x0b, 0xcccc); |
2959 | /* LDO1/2/3, DAC/ADC */ | 2957 | /* LDO1/2/3, DAC/ADC */ |
2960 | alc_write_coef_idx(codec, 0x0e, 0x6fc0); | 2958 | alc_write_coef_idx(codec, 0x0e, 0x6fc0); |
2961 | /* JD */ | 2959 | /* JD */ |
2962 | val = alc_read_coef_idx(codec, 0x0f); | 2960 | val = alc_read_coef_idx(codec, 0x0f); |
2963 | alc_write_coef_idx(codec, 0x0f, (val & ~0xf800) | 0x1000); | 2961 | alc_write_coef_idx(codec, 0x0f, (val & ~0xf800) | 0x1000); |
2964 | /* Capless */ | 2962 | /* Capless */ |
2965 | val = alc_read_coef_idx(codec, 0x10); | 2963 | val = alc_read_coef_idx(codec, 0x10); |
2966 | alc_write_coef_idx(codec, 0x10, (val & ~0xfc00) | 0x0c00); | 2964 | alc_write_coef_idx(codec, 0x10, (val & ~0xfc00) | 0x0c00); |
2967 | /* Class D test 4 */ | 2965 | /* Class D test 4 */ |
2968 | alc_write_coef_idx(codec, 0x3a, 0x0); | 2966 | alc_write_coef_idx(codec, 0x3a, 0x0); |
2969 | /* IO power down directly */ | 2967 | /* IO power down directly */ |
2970 | val = alc_read_coef_idx(codec, 0x0c); | 2968 | val = alc_read_coef_idx(codec, 0x0c); |
2971 | alc_write_coef_idx(codec, 0x0c, (val & ~0xfe00) | 0x0); | 2969 | alc_write_coef_idx(codec, 0x0c, (val & ~0xfe00) | 0x0); |
2972 | /* ANC */ | 2970 | /* ANC */ |
2973 | alc_write_coef_idx(codec, 0x22, 0xa0c0); | 2971 | alc_write_coef_idx(codec, 0x22, 0xa0c0); |
2974 | /* AGC MUX */ | 2972 | /* AGC MUX */ |
2975 | val = alc_read_coefex_idx(codec, 0x53, 0x01); | 2973 | val = alc_read_coefex_idx(codec, 0x53, 0x01); |
2976 | alc_write_coefex_idx(codec, 0x53, 0x01, (val & ~0x000f) | 0x0008); | 2974 | alc_write_coefex_idx(codec, 0x53, 0x01, (val & ~0x000f) | 0x0008); |
2977 | /* DAC simple content protection */ | 2975 | /* DAC simple content protection */ |
2978 | val = alc_read_coef_idx(codec, 0x1d); | 2976 | val = alc_read_coef_idx(codec, 0x1d); |
2979 | alc_write_coef_idx(codec, 0x1d, (val & ~0x00e0) | 0x0); | 2977 | alc_write_coef_idx(codec, 0x1d, (val & ~0x00e0) | 0x0); |
2980 | /* ADC simple content protection */ | 2978 | /* ADC simple content protection */ |
2981 | val = alc_read_coef_idx(codec, 0x1f); | 2979 | val = alc_read_coef_idx(codec, 0x1f); |
2982 | alc_write_coef_idx(codec, 0x1f, (val & ~0x00e0) | 0x0); | 2980 | alc_write_coef_idx(codec, 0x1f, (val & ~0x00e0) | 0x0); |
2983 | /* DAC ADC Zero Detection */ | 2981 | /* DAC ADC Zero Detection */ |
2984 | alc_write_coef_idx(codec, 0x21, 0x8804); | 2982 | alc_write_coef_idx(codec, 0x21, 0x8804); |
2985 | /* PLL */ | 2983 | /* PLL */ |
2986 | alc_write_coef_idx(codec, 0x2e, 0x2902); | 2984 | alc_write_coef_idx(codec, 0x2e, 0x2902); |
2987 | /* capless control 2 */ | 2985 | /* capless control 2 */ |
2988 | alc_write_coef_idx(codec, 0x33, 0xa080); | 2986 | alc_write_coef_idx(codec, 0x33, 0xa080); |
2989 | /* capless control 3 */ | 2987 | /* capless control 3 */ |
2990 | alc_write_coef_idx(codec, 0x34, 0x3400); | 2988 | alc_write_coef_idx(codec, 0x34, 0x3400); |
2991 | /* capless control 4 */ | 2989 | /* capless control 4 */ |
2992 | alc_write_coef_idx(codec, 0x35, 0x2f3e); | 2990 | alc_write_coef_idx(codec, 0x35, 0x2f3e); |
2993 | /* capless control 5 */ | 2991 | /* capless control 5 */ |
2994 | alc_write_coef_idx(codec, 0x36, 0x0); | 2992 | alc_write_coef_idx(codec, 0x36, 0x0); |
2995 | /* class D test 2 */ | 2993 | /* class D test 2 */ |
2996 | val = alc_read_coef_idx(codec, 0x38); | 2994 | val = alc_read_coef_idx(codec, 0x38); |
2997 | alc_write_coef_idx(codec, 0x38, (val & ~0x0fff) | 0x0900); | 2995 | alc_write_coef_idx(codec, 0x38, (val & ~0x0fff) | 0x0900); |
2998 | /* class D test 3 */ | 2996 | /* class D test 3 */ |
2999 | alc_write_coef_idx(codec, 0x39, 0x110a); | 2997 | alc_write_coef_idx(codec, 0x39, 0x110a); |
3000 | /* class D test 5 */ | 2998 | /* class D test 5 */ |
3001 | val = alc_read_coef_idx(codec, 0x3b); | 2999 | val = alc_read_coef_idx(codec, 0x3b); |
3002 | alc_write_coef_idx(codec, 0x3b, (val & ~0x00f8) | 0x00d8); | 3000 | alc_write_coef_idx(codec, 0x3b, (val & ~0x00f8) | 0x00d8); |
3003 | /* class D test 6 */ | 3001 | /* class D test 6 */ |
3004 | alc_write_coef_idx(codec, 0x3c, 0x0014); | 3002 | alc_write_coef_idx(codec, 0x3c, 0x0014); |
3005 | /* classD OCP */ | 3003 | /* classD OCP */ |
3006 | alc_write_coef_idx(codec, 0x3d, 0xc2ba); | 3004 | alc_write_coef_idx(codec, 0x3d, 0xc2ba); |
3007 | /* classD pure DC test */ | 3005 | /* classD pure DC test */ |
3008 | val = alc_read_coef_idx(codec, 0x42); | 3006 | val = alc_read_coef_idx(codec, 0x42); |
3009 | alc_write_coef_idx(codec, 0x42, (val & ~0x0f80) | 0x0); | 3007 | alc_write_coef_idx(codec, 0x42, (val & ~0x0f80) | 0x0); |
3010 | /* test mode */ | 3008 | /* test mode */ |
3011 | alc_write_coef_idx(codec, 0x49, 0x0); | 3009 | alc_write_coef_idx(codec, 0x49, 0x0); |
3012 | /* Class D DC enable */ | 3010 | /* Class D DC enable */ |
3013 | val = alc_read_coef_idx(codec, 0x40); | 3011 | val = alc_read_coef_idx(codec, 0x40); |
3014 | alc_write_coef_idx(codec, 0x40, (val & ~0xf800) | 0x9800); | 3012 | alc_write_coef_idx(codec, 0x40, (val & ~0xf800) | 0x9800); |
3015 | /* DC offset */ | 3013 | /* DC offset */ |
3016 | val = alc_read_coef_idx(codec, 0x42); | 3014 | val = alc_read_coef_idx(codec, 0x42); |
3017 | alc_write_coef_idx(codec, 0x42, (val & ~0xf000) | 0x2000); | 3015 | alc_write_coef_idx(codec, 0x42, (val & ~0xf000) | 0x2000); |
3018 | /* Class D amp control */ | 3016 | /* Class D amp control */ |
3019 | alc_write_coef_idx(codec, 0x37, 0xfc06); | 3017 | alc_write_coef_idx(codec, 0x37, 0xfc06); |
3020 | } | 3018 | } |
3021 | 3019 | ||
3022 | static void alc283_init(struct hda_codec *codec) | 3020 | static void alc283_init(struct hda_codec *codec) |
3023 | { | 3021 | { |
3024 | struct alc_spec *spec = codec->spec; | 3022 | struct alc_spec *spec = codec->spec; |
3025 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 3023 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; |
3026 | bool hp_pin_sense; | 3024 | bool hp_pin_sense; |
3027 | int val; | 3025 | int val; |
3028 | 3026 | ||
3029 | if (!spec->gen.autocfg.hp_outs) { | 3027 | if (!spec->gen.autocfg.hp_outs) { |
3030 | if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) | 3028 | if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) |
3031 | hp_pin = spec->gen.autocfg.line_out_pins[0]; | 3029 | hp_pin = spec->gen.autocfg.line_out_pins[0]; |
3032 | } | 3030 | } |
3033 | 3031 | ||
3034 | alc283_restore_default_value(codec); | 3032 | alc283_restore_default_value(codec); |
3035 | 3033 | ||
3036 | if (!hp_pin) | 3034 | if (!hp_pin) |
3037 | return; | 3035 | return; |
3038 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); | 3036 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); |
3039 | 3037 | ||
3040 | /* Index 0x43 Direct Drive HP AMP LPM Control 1 */ | 3038 | /* Index 0x43 Direct Drive HP AMP LPM Control 1 */ |
3041 | /* Headphone capless set to high power mode */ | 3039 | /* Headphone capless set to high power mode */ |
3042 | alc_write_coef_idx(codec, 0x43, 0x9004); | 3040 | alc_write_coef_idx(codec, 0x43, 0x9004); |
3043 | 3041 | ||
3044 | snd_hda_codec_write(codec, hp_pin, 0, | 3042 | snd_hda_codec_write(codec, hp_pin, 0, |
3045 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | 3043 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); |
3046 | 3044 | ||
3047 | if (hp_pin_sense) | 3045 | if (hp_pin_sense) |
3048 | msleep(85); | 3046 | msleep(85); |
3049 | 3047 | ||
3050 | snd_hda_codec_write(codec, hp_pin, 0, | 3048 | snd_hda_codec_write(codec, hp_pin, 0, |
3051 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | 3049 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); |
3052 | 3050 | ||
3053 | if (hp_pin_sense) | 3051 | if (hp_pin_sense) |
3054 | msleep(85); | 3052 | msleep(85); |
3055 | /* Index 0x46 Combo jack auto switch control 2 */ | 3053 | /* Index 0x46 Combo jack auto switch control 2 */ |
3056 | /* 3k pull low control for Headset jack. */ | 3054 | /* 3k pull low control for Headset jack. */ |
3057 | val = alc_read_coef_idx(codec, 0x46); | 3055 | val = alc_read_coef_idx(codec, 0x46); |
3058 | alc_write_coef_idx(codec, 0x46, val & ~(3 << 12)); | 3056 | alc_write_coef_idx(codec, 0x46, val & ~(3 << 12)); |
3059 | /* Headphone capless set to normal mode */ | 3057 | /* Headphone capless set to normal mode */ |
3060 | alc_write_coef_idx(codec, 0x43, 0x9614); | 3058 | alc_write_coef_idx(codec, 0x43, 0x9614); |
3061 | } | 3059 | } |
3062 | 3060 | ||
3063 | static void alc283_shutup(struct hda_codec *codec) | 3061 | static void alc283_shutup(struct hda_codec *codec) |
3064 | { | 3062 | { |
3065 | struct alc_spec *spec = codec->spec; | 3063 | struct alc_spec *spec = codec->spec; |
3066 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 3064 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; |
3067 | bool hp_pin_sense; | 3065 | bool hp_pin_sense; |
3068 | int val; | 3066 | int val; |
3069 | 3067 | ||
3070 | if (!spec->gen.autocfg.hp_outs) { | 3068 | if (!spec->gen.autocfg.hp_outs) { |
3071 | if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) | 3069 | if (spec->gen.autocfg.line_out_type == AC_JACK_HP_OUT) |
3072 | hp_pin = spec->gen.autocfg.line_out_pins[0]; | 3070 | hp_pin = spec->gen.autocfg.line_out_pins[0]; |
3073 | } | 3071 | } |
3074 | 3072 | ||
3075 | if (!hp_pin) { | 3073 | if (!hp_pin) { |
3076 | alc269_shutup(codec); | 3074 | alc269_shutup(codec); |
3077 | return; | 3075 | return; |
3078 | } | 3076 | } |
3079 | 3077 | ||
3080 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); | 3078 | hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); |
3081 | 3079 | ||
3082 | alc_write_coef_idx(codec, 0x43, 0x9004); | 3080 | alc_write_coef_idx(codec, 0x43, 0x9004); |
3083 | 3081 | ||
3084 | snd_hda_codec_write(codec, hp_pin, 0, | 3082 | snd_hda_codec_write(codec, hp_pin, 0, |
3085 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | 3083 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); |
3086 | 3084 | ||
3087 | if (hp_pin_sense) | 3085 | if (hp_pin_sense) |
3088 | msleep(100); | 3086 | msleep(100); |
3089 | 3087 | ||
3090 | snd_hda_codec_write(codec, hp_pin, 0, | 3088 | snd_hda_codec_write(codec, hp_pin, 0, |
3091 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); | 3089 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); |
3092 | 3090 | ||
3093 | val = alc_read_coef_idx(codec, 0x46); | 3091 | val = alc_read_coef_idx(codec, 0x46); |
3094 | alc_write_coef_idx(codec, 0x46, val | (3 << 12)); | 3092 | alc_write_coef_idx(codec, 0x46, val | (3 << 12)); |
3095 | 3093 | ||
3096 | if (hp_pin_sense) | 3094 | if (hp_pin_sense) |
3097 | msleep(100); | 3095 | msleep(100); |
3098 | alc_auto_setup_eapd(codec, false); | 3096 | alc_auto_setup_eapd(codec, false); |
3099 | snd_hda_shutup_pins(codec); | 3097 | snd_hda_shutup_pins(codec); |
3100 | alc_write_coef_idx(codec, 0x43, 0x9614); | 3098 | alc_write_coef_idx(codec, 0x43, 0x9614); |
3101 | } | 3099 | } |
3102 | 3100 | ||
3103 | static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg, | 3101 | static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg, |
3104 | unsigned int val) | 3102 | unsigned int val) |
3105 | { | 3103 | { |
3106 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1); | 3104 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1); |
3107 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */ | 3105 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val & 0xffff); /* LSB */ |
3108 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */ | 3106 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_PROC_COEF, val >> 16); /* MSB */ |
3109 | } | 3107 | } |
3110 | 3108 | ||
3111 | static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg) | 3109 | static int alc5505_coef_get(struct hda_codec *codec, unsigned int index_reg) |
3112 | { | 3110 | { |
3113 | unsigned int val; | 3111 | unsigned int val; |
3114 | 3112 | ||
3115 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1); | 3113 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_COEF_INDEX, index_reg >> 1); |
3116 | val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0) | 3114 | val = snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0) |
3117 | & 0xffff; | 3115 | & 0xffff; |
3118 | val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0) | 3116 | val |= snd_hda_codec_read(codec, 0x51, 0, AC_VERB_GET_PROC_COEF, 0) |
3119 | << 16; | 3117 | << 16; |
3120 | return val; | 3118 | return val; |
3121 | } | 3119 | } |
3122 | 3120 | ||
3123 | static void alc5505_dsp_halt(struct hda_codec *codec) | 3121 | static void alc5505_dsp_halt(struct hda_codec *codec) |
3124 | { | 3122 | { |
3125 | unsigned int val; | 3123 | unsigned int val; |
3126 | 3124 | ||
3127 | alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */ | 3125 | alc5505_coef_set(codec, 0x3000, 0x000c); /* DSP CPU stop */ |
3128 | alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */ | 3126 | alc5505_coef_set(codec, 0x880c, 0x0008); /* DDR enter self refresh */ |
3129 | alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */ | 3127 | alc5505_coef_set(codec, 0x61c0, 0x11110080); /* Clock control for PLL and CPU */ |
3130 | alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */ | 3128 | alc5505_coef_set(codec, 0x6230, 0xfc0d4011); /* Disable Input OP */ |
3131 | alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */ | 3129 | alc5505_coef_set(codec, 0x61b4, 0x040a2b03); /* Stop PLL2 */ |
3132 | alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */ | 3130 | alc5505_coef_set(codec, 0x61b0, 0x00005b17); /* Stop PLL1 */ |
3133 | alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */ | 3131 | alc5505_coef_set(codec, 0x61b8, 0x04133303); /* Stop PLL3 */ |
3134 | val = alc5505_coef_get(codec, 0x6220); | 3132 | val = alc5505_coef_get(codec, 0x6220); |
3135 | alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */ | 3133 | alc5505_coef_set(codec, 0x6220, (val | 0x3000)); /* switch Ringbuffer clock to DBUS clock */ |
3136 | } | 3134 | } |
3137 | 3135 | ||
3138 | static void alc5505_dsp_back_from_halt(struct hda_codec *codec) | 3136 | static void alc5505_dsp_back_from_halt(struct hda_codec *codec) |
3139 | { | 3137 | { |
3140 | alc5505_coef_set(codec, 0x61b8, 0x04133302); | 3138 | alc5505_coef_set(codec, 0x61b8, 0x04133302); |
3141 | alc5505_coef_set(codec, 0x61b0, 0x00005b16); | 3139 | alc5505_coef_set(codec, 0x61b0, 0x00005b16); |
3142 | alc5505_coef_set(codec, 0x61b4, 0x040a2b02); | 3140 | alc5505_coef_set(codec, 0x61b4, 0x040a2b02); |
3143 | alc5505_coef_set(codec, 0x6230, 0xf80d4011); | 3141 | alc5505_coef_set(codec, 0x6230, 0xf80d4011); |
3144 | alc5505_coef_set(codec, 0x6220, 0x2002010f); | 3142 | alc5505_coef_set(codec, 0x6220, 0x2002010f); |
3145 | alc5505_coef_set(codec, 0x880c, 0x00000004); | 3143 | alc5505_coef_set(codec, 0x880c, 0x00000004); |
3146 | } | 3144 | } |
3147 | 3145 | ||
3148 | static void alc5505_dsp_init(struct hda_codec *codec) | 3146 | static void alc5505_dsp_init(struct hda_codec *codec) |
3149 | { | 3147 | { |
3150 | unsigned int val; | 3148 | unsigned int val; |
3151 | 3149 | ||
3152 | alc5505_dsp_halt(codec); | 3150 | alc5505_dsp_halt(codec); |
3153 | alc5505_dsp_back_from_halt(codec); | 3151 | alc5505_dsp_back_from_halt(codec); |
3154 | alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */ | 3152 | alc5505_coef_set(codec, 0x61b0, 0x5b14); /* PLL1 control */ |
3155 | alc5505_coef_set(codec, 0x61b0, 0x5b16); | 3153 | alc5505_coef_set(codec, 0x61b0, 0x5b16); |
3156 | alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */ | 3154 | alc5505_coef_set(codec, 0x61b4, 0x04132b00); /* PLL2 control */ |
3157 | alc5505_coef_set(codec, 0x61b4, 0x04132b02); | 3155 | alc5505_coef_set(codec, 0x61b4, 0x04132b02); |
3158 | alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/ | 3156 | alc5505_coef_set(codec, 0x61b8, 0x041f3300); /* PLL3 control*/ |
3159 | alc5505_coef_set(codec, 0x61b8, 0x041f3302); | 3157 | alc5505_coef_set(codec, 0x61b8, 0x041f3302); |
3160 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */ | 3158 | snd_hda_codec_write(codec, 0x51, 0, AC_VERB_SET_CODEC_RESET, 0); /* Function reset */ |
3161 | alc5505_coef_set(codec, 0x61b8, 0x041b3302); | 3159 | alc5505_coef_set(codec, 0x61b8, 0x041b3302); |
3162 | alc5505_coef_set(codec, 0x61b8, 0x04173302); | 3160 | alc5505_coef_set(codec, 0x61b8, 0x04173302); |
3163 | alc5505_coef_set(codec, 0x61b8, 0x04163302); | 3161 | alc5505_coef_set(codec, 0x61b8, 0x04163302); |
3164 | alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */ | 3162 | alc5505_coef_set(codec, 0x8800, 0x348b328b); /* DRAM control */ |
3165 | alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */ | 3163 | alc5505_coef_set(codec, 0x8808, 0x00020022); /* DRAM control */ |
3166 | alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */ | 3164 | alc5505_coef_set(codec, 0x8818, 0x00000400); /* DRAM control */ |
3167 | 3165 | ||
3168 | val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */ | 3166 | val = alc5505_coef_get(codec, 0x6200) >> 16; /* Read revision ID */ |
3169 | if (val <= 3) | 3167 | if (val <= 3) |
3170 | alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */ | 3168 | alc5505_coef_set(codec, 0x6220, 0x2002010f); /* I/O PAD Configuration */ |
3171 | else | 3169 | else |
3172 | alc5505_coef_set(codec, 0x6220, 0x6002018f); | 3170 | alc5505_coef_set(codec, 0x6220, 0x6002018f); |
3173 | 3171 | ||
3174 | alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/ | 3172 | alc5505_coef_set(codec, 0x61ac, 0x055525f0); /**/ |
3175 | alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */ | 3173 | alc5505_coef_set(codec, 0x61c0, 0x12230080); /* Clock control */ |
3176 | alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */ | 3174 | alc5505_coef_set(codec, 0x61b4, 0x040e2b02); /* PLL2 control */ |
3177 | alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */ | 3175 | alc5505_coef_set(codec, 0x61bc, 0x010234f8); /* OSC Control */ |
3178 | alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */ | 3176 | alc5505_coef_set(codec, 0x880c, 0x00000004); /* DRAM Function control */ |
3179 | alc5505_coef_set(codec, 0x880c, 0x00000003); | 3177 | alc5505_coef_set(codec, 0x880c, 0x00000003); |
3180 | alc5505_coef_set(codec, 0x880c, 0x00000010); | 3178 | alc5505_coef_set(codec, 0x880c, 0x00000010); |
3181 | 3179 | ||
3182 | #ifdef HALT_REALTEK_ALC5505 | 3180 | #ifdef HALT_REALTEK_ALC5505 |
3183 | alc5505_dsp_halt(codec); | 3181 | alc5505_dsp_halt(codec); |
3184 | #endif | 3182 | #endif |
3185 | } | 3183 | } |
3186 | 3184 | ||
3187 | #ifdef HALT_REALTEK_ALC5505 | 3185 | #ifdef HALT_REALTEK_ALC5505 |
3188 | #define alc5505_dsp_suspend(codec) /* NOP */ | 3186 | #define alc5505_dsp_suspend(codec) /* NOP */ |
3189 | #define alc5505_dsp_resume(codec) /* NOP */ | 3187 | #define alc5505_dsp_resume(codec) /* NOP */ |
3190 | #else | 3188 | #else |
3191 | #define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec) | 3189 | #define alc5505_dsp_suspend(codec) alc5505_dsp_halt(codec) |
3192 | #define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec) | 3190 | #define alc5505_dsp_resume(codec) alc5505_dsp_back_from_halt(codec) |
3193 | #endif | 3191 | #endif |
3194 | 3192 | ||
3195 | #ifdef CONFIG_PM | 3193 | #ifdef CONFIG_PM |
3196 | static int alc269_suspend(struct hda_codec *codec) | 3194 | static int alc269_suspend(struct hda_codec *codec) |
3197 | { | 3195 | { |
3198 | struct alc_spec *spec = codec->spec; | 3196 | struct alc_spec *spec = codec->spec; |
3199 | 3197 | ||
3200 | if (spec->has_alc5505_dsp) | 3198 | if (spec->has_alc5505_dsp) |
3201 | alc5505_dsp_suspend(codec); | 3199 | alc5505_dsp_suspend(codec); |
3202 | return alc_suspend(codec); | 3200 | return alc_suspend(codec); |
3203 | } | 3201 | } |
3204 | 3202 | ||
3205 | static int alc269_resume(struct hda_codec *codec) | 3203 | static int alc269_resume(struct hda_codec *codec) |
3206 | { | 3204 | { |
3207 | struct alc_spec *spec = codec->spec; | 3205 | struct alc_spec *spec = codec->spec; |
3208 | 3206 | ||
3209 | if (spec->codec_variant == ALC269_TYPE_ALC269VB) | 3207 | if (spec->codec_variant == ALC269_TYPE_ALC269VB) |
3210 | alc269vb_toggle_power_output(codec, 0); | 3208 | alc269vb_toggle_power_output(codec, 0); |
3211 | if (spec->codec_variant == ALC269_TYPE_ALC269VB && | 3209 | if (spec->codec_variant == ALC269_TYPE_ALC269VB && |
3212 | (alc_get_coef0(codec) & 0x00ff) == 0x018) { | 3210 | (alc_get_coef0(codec) & 0x00ff) == 0x018) { |
3213 | msleep(150); | 3211 | msleep(150); |
3214 | } | 3212 | } |
3215 | 3213 | ||
3216 | codec->patch_ops.init(codec); | 3214 | codec->patch_ops.init(codec); |
3217 | 3215 | ||
3218 | if (spec->codec_variant == ALC269_TYPE_ALC269VB) | 3216 | if (spec->codec_variant == ALC269_TYPE_ALC269VB) |
3219 | alc269vb_toggle_power_output(codec, 1); | 3217 | alc269vb_toggle_power_output(codec, 1); |
3220 | if (spec->codec_variant == ALC269_TYPE_ALC269VB && | 3218 | if (spec->codec_variant == ALC269_TYPE_ALC269VB && |
3221 | (alc_get_coef0(codec) & 0x00ff) == 0x017) { | 3219 | (alc_get_coef0(codec) & 0x00ff) == 0x017) { |
3222 | msleep(200); | 3220 | msleep(200); |
3223 | } | 3221 | } |
3224 | 3222 | ||
3225 | snd_hda_codec_resume_amp(codec); | 3223 | snd_hda_codec_resume_amp(codec); |
3226 | snd_hda_codec_resume_cache(codec); | 3224 | snd_hda_codec_resume_cache(codec); |
3227 | alc_inv_dmic_sync(codec, true); | 3225 | alc_inv_dmic_sync(codec, true); |
3228 | hda_call_check_power_status(codec, 0x01); | 3226 | hda_call_check_power_status(codec, 0x01); |
3229 | if (spec->has_alc5505_dsp) | 3227 | if (spec->has_alc5505_dsp) |
3230 | alc5505_dsp_resume(codec); | 3228 | alc5505_dsp_resume(codec); |
3231 | 3229 | ||
3232 | return 0; | 3230 | return 0; |
3233 | } | 3231 | } |
3234 | #endif /* CONFIG_PM */ | 3232 | #endif /* CONFIG_PM */ |
3235 | 3233 | ||
3236 | static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec, | 3234 | static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec, |
3237 | const struct hda_fixup *fix, int action) | 3235 | const struct hda_fixup *fix, int action) |
3238 | { | 3236 | { |
3239 | struct alc_spec *spec = codec->spec; | 3237 | struct alc_spec *spec = codec->spec; |
3240 | 3238 | ||
3241 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | 3239 | if (action == HDA_FIXUP_ACT_PRE_PROBE) |
3242 | spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; | 3240 | spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; |
3243 | } | 3241 | } |
3244 | 3242 | ||
3245 | static void alc269_fixup_hweq(struct hda_codec *codec, | 3243 | static void alc269_fixup_hweq(struct hda_codec *codec, |
3246 | const struct hda_fixup *fix, int action) | 3244 | const struct hda_fixup *fix, int action) |
3247 | { | 3245 | { |
3248 | int coef; | 3246 | int coef; |
3249 | 3247 | ||
3250 | if (action != HDA_FIXUP_ACT_INIT) | 3248 | if (action != HDA_FIXUP_ACT_INIT) |
3251 | return; | 3249 | return; |
3252 | coef = alc_read_coef_idx(codec, 0x1e); | 3250 | coef = alc_read_coef_idx(codec, 0x1e); |
3253 | alc_write_coef_idx(codec, 0x1e, coef | 0x80); | 3251 | alc_write_coef_idx(codec, 0x1e, coef | 0x80); |
3254 | } | 3252 | } |
3255 | 3253 | ||
3256 | static void alc269_fixup_headset_mic(struct hda_codec *codec, | 3254 | static void alc269_fixup_headset_mic(struct hda_codec *codec, |
3257 | const struct hda_fixup *fix, int action) | 3255 | const struct hda_fixup *fix, int action) |
3258 | { | 3256 | { |
3259 | struct alc_spec *spec = codec->spec; | 3257 | struct alc_spec *spec = codec->spec; |
3260 | 3258 | ||
3261 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | 3259 | if (action == HDA_FIXUP_ACT_PRE_PROBE) |
3262 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; | 3260 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; |
3263 | } | 3261 | } |
3264 | 3262 | ||
3265 | static void alc271_fixup_dmic(struct hda_codec *codec, | 3263 | static void alc271_fixup_dmic(struct hda_codec *codec, |
3266 | const struct hda_fixup *fix, int action) | 3264 | const struct hda_fixup *fix, int action) |
3267 | { | 3265 | { |
3268 | static const struct hda_verb verbs[] = { | 3266 | static const struct hda_verb verbs[] = { |
3269 | {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, | 3267 | {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, |
3270 | {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, | 3268 | {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, |
3271 | {} | 3269 | {} |
3272 | }; | 3270 | }; |
3273 | unsigned int cfg; | 3271 | unsigned int cfg; |
3274 | 3272 | ||
3275 | if (strcmp(codec->chip_name, "ALC271X") && | 3273 | if (strcmp(codec->chip_name, "ALC271X") && |
3276 | strcmp(codec->chip_name, "ALC269VB")) | 3274 | strcmp(codec->chip_name, "ALC269VB")) |
3277 | return; | 3275 | return; |
3278 | cfg = snd_hda_codec_get_pincfg(codec, 0x12); | 3276 | cfg = snd_hda_codec_get_pincfg(codec, 0x12); |
3279 | if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED) | 3277 | if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED) |
3280 | snd_hda_sequence_write(codec, verbs); | 3278 | snd_hda_sequence_write(codec, verbs); |
3281 | } | 3279 | } |
3282 | 3280 | ||
3283 | static void alc269_fixup_pcm_44k(struct hda_codec *codec, | 3281 | static void alc269_fixup_pcm_44k(struct hda_codec *codec, |
3284 | const struct hda_fixup *fix, int action) | 3282 | const struct hda_fixup *fix, int action) |
3285 | { | 3283 | { |
3286 | struct alc_spec *spec = codec->spec; | 3284 | struct alc_spec *spec = codec->spec; |
3287 | 3285 | ||
3288 | if (action != HDA_FIXUP_ACT_PROBE) | 3286 | if (action != HDA_FIXUP_ACT_PROBE) |
3289 | return; | 3287 | return; |
3290 | 3288 | ||
3291 | /* Due to a hardware problem on Lenovo Ideadpad, we need to | 3289 | /* Due to a hardware problem on Lenovo Ideadpad, we need to |
3292 | * fix the sample rate of analog I/O to 44.1kHz | 3290 | * fix the sample rate of analog I/O to 44.1kHz |
3293 | */ | 3291 | */ |
3294 | spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback; | 3292 | spec->gen.stream_analog_playback = &alc269_44k_pcm_analog_playback; |
3295 | spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture; | 3293 | spec->gen.stream_analog_capture = &alc269_44k_pcm_analog_capture; |
3296 | } | 3294 | } |
3297 | 3295 | ||
3298 | static void alc269_fixup_stereo_dmic(struct hda_codec *codec, | 3296 | static void alc269_fixup_stereo_dmic(struct hda_codec *codec, |
3299 | const struct hda_fixup *fix, int action) | 3297 | const struct hda_fixup *fix, int action) |
3300 | { | 3298 | { |
3301 | int coef; | 3299 | int coef; |
3302 | 3300 | ||
3303 | if (action != HDA_FIXUP_ACT_INIT) | 3301 | if (action != HDA_FIXUP_ACT_INIT) |
3304 | return; | 3302 | return; |
3305 | /* The digital-mic unit sends PDM (differential signal) instead of | 3303 | /* The digital-mic unit sends PDM (differential signal) instead of |
3306 | * the standard PCM, thus you can't record a valid mono stream as is. | 3304 | * the standard PCM, thus you can't record a valid mono stream as is. |
3307 | * Below is a workaround specific to ALC269 to control the dmic | 3305 | * Below is a workaround specific to ALC269 to control the dmic |
3308 | * signal source as mono. | 3306 | * signal source as mono. |
3309 | */ | 3307 | */ |
3310 | coef = alc_read_coef_idx(codec, 0x07); | 3308 | coef = alc_read_coef_idx(codec, 0x07); |
3311 | alc_write_coef_idx(codec, 0x07, coef | 0x80); | 3309 | alc_write_coef_idx(codec, 0x07, coef | 0x80); |
3312 | } | 3310 | } |
3313 | 3311 | ||
3314 | static void alc269_quanta_automute(struct hda_codec *codec) | 3312 | static void alc269_quanta_automute(struct hda_codec *codec) |
3315 | { | 3313 | { |
3316 | snd_hda_gen_update_outputs(codec); | 3314 | snd_hda_gen_update_outputs(codec); |
3317 | 3315 | ||
3318 | snd_hda_codec_write(codec, 0x20, 0, | 3316 | snd_hda_codec_write(codec, 0x20, 0, |
3319 | AC_VERB_SET_COEF_INDEX, 0x0c); | 3317 | AC_VERB_SET_COEF_INDEX, 0x0c); |
3320 | snd_hda_codec_write(codec, 0x20, 0, | 3318 | snd_hda_codec_write(codec, 0x20, 0, |
3321 | AC_VERB_SET_PROC_COEF, 0x680); | 3319 | AC_VERB_SET_PROC_COEF, 0x680); |
3322 | 3320 | ||
3323 | snd_hda_codec_write(codec, 0x20, 0, | 3321 | snd_hda_codec_write(codec, 0x20, 0, |
3324 | AC_VERB_SET_COEF_INDEX, 0x0c); | 3322 | AC_VERB_SET_COEF_INDEX, 0x0c); |
3325 | snd_hda_codec_write(codec, 0x20, 0, | 3323 | snd_hda_codec_write(codec, 0x20, 0, |
3326 | AC_VERB_SET_PROC_COEF, 0x480); | 3324 | AC_VERB_SET_PROC_COEF, 0x480); |
3327 | } | 3325 | } |
3328 | 3326 | ||
3329 | static void alc269_fixup_quanta_mute(struct hda_codec *codec, | 3327 | static void alc269_fixup_quanta_mute(struct hda_codec *codec, |
3330 | const struct hda_fixup *fix, int action) | 3328 | const struct hda_fixup *fix, int action) |
3331 | { | 3329 | { |
3332 | struct alc_spec *spec = codec->spec; | 3330 | struct alc_spec *spec = codec->spec; |
3333 | if (action != HDA_FIXUP_ACT_PROBE) | 3331 | if (action != HDA_FIXUP_ACT_PROBE) |
3334 | return; | 3332 | return; |
3335 | spec->gen.automute_hook = alc269_quanta_automute; | 3333 | spec->gen.automute_hook = alc269_quanta_automute; |
3336 | } | 3334 | } |
3337 | 3335 | ||
3338 | static void alc269_x101_hp_automute_hook(struct hda_codec *codec, | 3336 | static void alc269_x101_hp_automute_hook(struct hda_codec *codec, |
3339 | struct hda_jack_tbl *jack) | 3337 | struct hda_jack_tbl *jack) |
3340 | { | 3338 | { |
3341 | struct alc_spec *spec = codec->spec; | 3339 | struct alc_spec *spec = codec->spec; |
3342 | int vref; | 3340 | int vref; |
3343 | msleep(200); | 3341 | msleep(200); |
3344 | snd_hda_gen_hp_automute(codec, jack); | 3342 | snd_hda_gen_hp_automute(codec, jack); |
3345 | 3343 | ||
3346 | vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0; | 3344 | vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0; |
3347 | msleep(100); | 3345 | msleep(100); |
3348 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 3346 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
3349 | vref); | 3347 | vref); |
3350 | msleep(500); | 3348 | msleep(500); |
3351 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 3349 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
3352 | vref); | 3350 | vref); |
3353 | } | 3351 | } |
3354 | 3352 | ||
3355 | static void alc269_fixup_x101_headset_mic(struct hda_codec *codec, | 3353 | static void alc269_fixup_x101_headset_mic(struct hda_codec *codec, |
3356 | const struct hda_fixup *fix, int action) | 3354 | const struct hda_fixup *fix, int action) |
3357 | { | 3355 | { |
3358 | struct alc_spec *spec = codec->spec; | 3356 | struct alc_spec *spec = codec->spec; |
3359 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3357 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3360 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; | 3358 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; |
3361 | spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook; | 3359 | spec->gen.hp_automute_hook = alc269_x101_hp_automute_hook; |
3362 | } | 3360 | } |
3363 | } | 3361 | } |
3364 | 3362 | ||
3365 | 3363 | ||
3366 | /* update mute-LED according to the speaker mute state via mic VREF pin */ | 3364 | /* update mute-LED according to the speaker mute state via mic VREF pin */ |
3367 | static void alc269_fixup_mic_mute_hook(void *private_data, int enabled) | 3365 | static void alc269_fixup_mic_mute_hook(void *private_data, int enabled) |
3368 | { | 3366 | { |
3369 | struct hda_codec *codec = private_data; | 3367 | struct hda_codec *codec = private_data; |
3370 | struct alc_spec *spec = codec->spec; | 3368 | struct alc_spec *spec = codec->spec; |
3371 | unsigned int pinval; | 3369 | unsigned int pinval; |
3372 | 3370 | ||
3373 | if (spec->mute_led_polarity) | 3371 | if (spec->mute_led_polarity) |
3374 | enabled = !enabled; | 3372 | enabled = !enabled; |
3375 | pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid); | 3373 | pinval = snd_hda_codec_get_pin_target(codec, spec->mute_led_nid); |
3376 | pinval &= ~AC_PINCTL_VREFEN; | 3374 | pinval &= ~AC_PINCTL_VREFEN; |
3377 | pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80; | 3375 | pinval |= enabled ? AC_PINCTL_VREF_HIZ : AC_PINCTL_VREF_80; |
3378 | if (spec->mute_led_nid) | 3376 | if (spec->mute_led_nid) |
3379 | snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval); | 3377 | snd_hda_set_pin_ctl_cache(codec, spec->mute_led_nid, pinval); |
3380 | } | 3378 | } |
3381 | 3379 | ||
3382 | /* Make sure the led works even in runtime suspend */ | 3380 | /* Make sure the led works even in runtime suspend */ |
3383 | static unsigned int led_power_filter(struct hda_codec *codec, | 3381 | static unsigned int led_power_filter(struct hda_codec *codec, |
3384 | hda_nid_t nid, | 3382 | hda_nid_t nid, |
3385 | unsigned int power_state) | 3383 | unsigned int power_state) |
3386 | { | 3384 | { |
3387 | struct alc_spec *spec = codec->spec; | 3385 | struct alc_spec *spec = codec->spec; |
3388 | 3386 | ||
3389 | if (power_state != AC_PWRST_D3 || nid != spec->mute_led_nid) | 3387 | if (power_state != AC_PWRST_D3 || nid != spec->mute_led_nid) |
3390 | return power_state; | 3388 | return power_state; |
3391 | 3389 | ||
3392 | /* Set pin ctl again, it might have just been set to 0 */ | 3390 | /* Set pin ctl again, it might have just been set to 0 */ |
3393 | snd_hda_set_pin_ctl(codec, nid, | 3391 | snd_hda_set_pin_ctl(codec, nid, |
3394 | snd_hda_codec_get_pin_target(codec, nid)); | 3392 | snd_hda_codec_get_pin_target(codec, nid)); |
3395 | 3393 | ||
3396 | return AC_PWRST_D0; | 3394 | return AC_PWRST_D0; |
3397 | } | 3395 | } |
3398 | 3396 | ||
3399 | static void alc269_fixup_hp_mute_led(struct hda_codec *codec, | 3397 | static void alc269_fixup_hp_mute_led(struct hda_codec *codec, |
3400 | const struct hda_fixup *fix, int action) | 3398 | const struct hda_fixup *fix, int action) |
3401 | { | 3399 | { |
3402 | struct alc_spec *spec = codec->spec; | 3400 | struct alc_spec *spec = codec->spec; |
3403 | const struct dmi_device *dev = NULL; | 3401 | const struct dmi_device *dev = NULL; |
3404 | 3402 | ||
3405 | if (action != HDA_FIXUP_ACT_PRE_PROBE) | 3403 | if (action != HDA_FIXUP_ACT_PRE_PROBE) |
3406 | return; | 3404 | return; |
3407 | 3405 | ||
3408 | while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { | 3406 | while ((dev = dmi_find_device(DMI_DEV_TYPE_OEM_STRING, NULL, dev))) { |
3409 | int pol, pin; | 3407 | int pol, pin; |
3410 | if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2) | 3408 | if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &pol, &pin) != 2) |
3411 | continue; | 3409 | continue; |
3412 | if (pin < 0x0a || pin >= 0x10) | 3410 | if (pin < 0x0a || pin >= 0x10) |
3413 | break; | 3411 | break; |
3414 | spec->mute_led_polarity = pol; | 3412 | spec->mute_led_polarity = pol; |
3415 | spec->mute_led_nid = pin - 0x0a + 0x18; | 3413 | spec->mute_led_nid = pin - 0x0a + 0x18; |
3416 | spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; | 3414 | spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; |
3417 | spec->gen.vmaster_mute_enum = 1; | 3415 | spec->gen.vmaster_mute_enum = 1; |
3418 | codec->power_filter = led_power_filter; | 3416 | codec->power_filter = led_power_filter; |
3419 | codec_dbg(codec, | 3417 | codec_dbg(codec, |
3420 | "Detected mute LED for %x:%d\n", spec->mute_led_nid, | 3418 | "Detected mute LED for %x:%d\n", spec->mute_led_nid, |
3421 | spec->mute_led_polarity); | 3419 | spec->mute_led_polarity); |
3422 | break; | 3420 | break; |
3423 | } | 3421 | } |
3424 | } | 3422 | } |
3425 | 3423 | ||
3426 | static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec, | 3424 | static void alc269_fixup_hp_mute_led_mic1(struct hda_codec *codec, |
3427 | const struct hda_fixup *fix, int action) | 3425 | const struct hda_fixup *fix, int action) |
3428 | { | 3426 | { |
3429 | struct alc_spec *spec = codec->spec; | 3427 | struct alc_spec *spec = codec->spec; |
3430 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3428 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3431 | spec->mute_led_polarity = 0; | 3429 | spec->mute_led_polarity = 0; |
3432 | spec->mute_led_nid = 0x18; | 3430 | spec->mute_led_nid = 0x18; |
3433 | spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; | 3431 | spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; |
3434 | spec->gen.vmaster_mute_enum = 1; | 3432 | spec->gen.vmaster_mute_enum = 1; |
3435 | codec->power_filter = led_power_filter; | 3433 | codec->power_filter = led_power_filter; |
3436 | } | 3434 | } |
3437 | } | 3435 | } |
3438 | 3436 | ||
3439 | static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec, | 3437 | static void alc269_fixup_hp_mute_led_mic2(struct hda_codec *codec, |
3440 | const struct hda_fixup *fix, int action) | 3438 | const struct hda_fixup *fix, int action) |
3441 | { | 3439 | { |
3442 | struct alc_spec *spec = codec->spec; | 3440 | struct alc_spec *spec = codec->spec; |
3443 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3441 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3444 | spec->mute_led_polarity = 0; | 3442 | spec->mute_led_polarity = 0; |
3445 | spec->mute_led_nid = 0x19; | 3443 | spec->mute_led_nid = 0x19; |
3446 | spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; | 3444 | spec->gen.vmaster_mute.hook = alc269_fixup_mic_mute_hook; |
3447 | spec->gen.vmaster_mute_enum = 1; | 3445 | spec->gen.vmaster_mute_enum = 1; |
3448 | codec->power_filter = led_power_filter; | 3446 | codec->power_filter = led_power_filter; |
3449 | } | 3447 | } |
3450 | } | 3448 | } |
3451 | 3449 | ||
3452 | /* turn on/off mute LED per vmaster hook */ | 3450 | /* turn on/off mute LED per vmaster hook */ |
3453 | static void alc269_fixup_hp_gpio_mute_hook(void *private_data, int enabled) | 3451 | static void alc269_fixup_hp_gpio_mute_hook(void *private_data, int enabled) |
3454 | { | 3452 | { |
3455 | struct hda_codec *codec = private_data; | 3453 | struct hda_codec *codec = private_data; |
3456 | struct alc_spec *spec = codec->spec; | 3454 | struct alc_spec *spec = codec->spec; |
3457 | unsigned int oldval = spec->gpio_led; | 3455 | unsigned int oldval = spec->gpio_led; |
3458 | 3456 | ||
3459 | if (enabled) | 3457 | if (enabled) |
3460 | spec->gpio_led &= ~0x08; | 3458 | spec->gpio_led &= ~0x08; |
3461 | else | 3459 | else |
3462 | spec->gpio_led |= 0x08; | 3460 | spec->gpio_led |= 0x08; |
3463 | if (spec->gpio_led != oldval) | 3461 | if (spec->gpio_led != oldval) |
3464 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | 3462 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, |
3465 | spec->gpio_led); | 3463 | spec->gpio_led); |
3466 | } | 3464 | } |
3467 | 3465 | ||
3468 | /* turn on/off mic-mute LED per capture hook */ | 3466 | /* turn on/off mic-mute LED per capture hook */ |
3469 | static void alc269_fixup_hp_gpio_mic_mute_hook(struct hda_codec *codec, | 3467 | static void alc269_fixup_hp_gpio_mic_mute_hook(struct hda_codec *codec, |
3470 | struct snd_kcontrol *kcontrol, | 3468 | struct snd_kcontrol *kcontrol, |
3471 | struct snd_ctl_elem_value *ucontrol) | 3469 | struct snd_ctl_elem_value *ucontrol) |
3472 | { | 3470 | { |
3473 | struct alc_spec *spec = codec->spec; | 3471 | struct alc_spec *spec = codec->spec; |
3474 | unsigned int oldval = spec->gpio_led; | 3472 | unsigned int oldval = spec->gpio_led; |
3475 | 3473 | ||
3476 | if (!ucontrol) | 3474 | if (!ucontrol) |
3477 | return; | 3475 | return; |
3478 | 3476 | ||
3479 | if (ucontrol->value.integer.value[0] || | 3477 | if (ucontrol->value.integer.value[0] || |
3480 | ucontrol->value.integer.value[1]) | 3478 | ucontrol->value.integer.value[1]) |
3481 | spec->gpio_led &= ~0x10; | 3479 | spec->gpio_led &= ~0x10; |
3482 | else | 3480 | else |
3483 | spec->gpio_led |= 0x10; | 3481 | spec->gpio_led |= 0x10; |
3484 | if (spec->gpio_led != oldval) | 3482 | if (spec->gpio_led != oldval) |
3485 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | 3483 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, |
3486 | spec->gpio_led); | 3484 | spec->gpio_led); |
3487 | } | 3485 | } |
3488 | 3486 | ||
3489 | static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, | 3487 | static void alc269_fixup_hp_gpio_led(struct hda_codec *codec, |
3490 | const struct hda_fixup *fix, int action) | 3488 | const struct hda_fixup *fix, int action) |
3491 | { | 3489 | { |
3492 | struct alc_spec *spec = codec->spec; | 3490 | struct alc_spec *spec = codec->spec; |
3493 | static const struct hda_verb gpio_init[] = { | 3491 | static const struct hda_verb gpio_init[] = { |
3494 | { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 }, | 3492 | { 0x01, AC_VERB_SET_GPIO_MASK, 0x18 }, |
3495 | { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 }, | 3493 | { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x18 }, |
3496 | {} | 3494 | {} |
3497 | }; | 3495 | }; |
3498 | 3496 | ||
3499 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3497 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3500 | spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook; | 3498 | spec->gen.vmaster_mute.hook = alc269_fixup_hp_gpio_mute_hook; |
3501 | spec->gen.cap_sync_hook = alc269_fixup_hp_gpio_mic_mute_hook; | 3499 | spec->gen.cap_sync_hook = alc269_fixup_hp_gpio_mic_mute_hook; |
3502 | spec->gpio_led = 0; | 3500 | spec->gpio_led = 0; |
3503 | snd_hda_add_verbs(codec, gpio_init); | 3501 | snd_hda_add_verbs(codec, gpio_init); |
3504 | } | 3502 | } |
3505 | } | 3503 | } |
3506 | 3504 | ||
3507 | static void alc_headset_mode_unplugged(struct hda_codec *codec) | 3505 | static void alc_headset_mode_unplugged(struct hda_codec *codec) |
3508 | { | 3506 | { |
3509 | int val; | 3507 | int val; |
3510 | 3508 | ||
3511 | switch (codec->vendor_id) { | 3509 | switch (codec->vendor_id) { |
3512 | case 0x10ec0255: | 3510 | case 0x10ec0255: |
3513 | /* LDO and MISC control */ | 3511 | /* LDO and MISC control */ |
3514 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); | 3512 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); |
3515 | /* UAJ function set to menual mode */ | 3513 | /* UAJ function set to menual mode */ |
3516 | alc_write_coef_idx(codec, 0x45, 0xd089); | 3514 | alc_write_coef_idx(codec, 0x45, 0xd089); |
3517 | /* Direct Drive HP Amp control(Set to verb control)*/ | 3515 | /* Direct Drive HP Amp control(Set to verb control)*/ |
3518 | val = alc_read_coefex_idx(codec, 0x57, 0x05); | 3516 | val = alc_read_coefex_idx(codec, 0x57, 0x05); |
3519 | alc_write_coefex_idx(codec, 0x57, 0x05, val & ~(1<<14)); | 3517 | alc_write_coefex_idx(codec, 0x57, 0x05, val & ~(1<<14)); |
3520 | /* Set MIC2 Vref gate with HP */ | 3518 | /* Set MIC2 Vref gate with HP */ |
3521 | alc_write_coef_idx(codec, 0x06, 0x6104); | 3519 | alc_write_coef_idx(codec, 0x06, 0x6104); |
3522 | /* Direct Drive HP Amp control */ | 3520 | /* Direct Drive HP Amp control */ |
3523 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6); | 3521 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6); |
3524 | break; | 3522 | break; |
3525 | case 0x10ec0283: | 3523 | case 0x10ec0283: |
3526 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); | 3524 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); |
3527 | alc_write_coef_idx(codec, 0x45, 0xc429); | 3525 | alc_write_coef_idx(codec, 0x45, 0xc429); |
3528 | val = alc_read_coef_idx(codec, 0x35); | 3526 | val = alc_read_coef_idx(codec, 0x35); |
3529 | alc_write_coef_idx(codec, 0x35, val & 0xbfff); | 3527 | alc_write_coef_idx(codec, 0x35, val & 0xbfff); |
3530 | alc_write_coef_idx(codec, 0x06, 0x2104); | 3528 | alc_write_coef_idx(codec, 0x06, 0x2104); |
3531 | alc_write_coef_idx(codec, 0x1a, 0x0001); | 3529 | alc_write_coef_idx(codec, 0x1a, 0x0001); |
3532 | alc_write_coef_idx(codec, 0x26, 0x0004); | 3530 | alc_write_coef_idx(codec, 0x26, 0x0004); |
3533 | alc_write_coef_idx(codec, 0x32, 0x42a3); | 3531 | alc_write_coef_idx(codec, 0x32, 0x42a3); |
3534 | break; | 3532 | break; |
3535 | case 0x10ec0292: | 3533 | case 0x10ec0292: |
3536 | alc_write_coef_idx(codec, 0x76, 0x000e); | 3534 | alc_write_coef_idx(codec, 0x76, 0x000e); |
3537 | alc_write_coef_idx(codec, 0x6c, 0x2400); | 3535 | alc_write_coef_idx(codec, 0x6c, 0x2400); |
3538 | alc_write_coef_idx(codec, 0x18, 0x7308); | 3536 | alc_write_coef_idx(codec, 0x18, 0x7308); |
3539 | alc_write_coef_idx(codec, 0x6b, 0xc429); | 3537 | alc_write_coef_idx(codec, 0x6b, 0xc429); |
3540 | break; | 3538 | break; |
3541 | case 0x10ec0668: | 3539 | case 0x10ec0668: |
3542 | alc_write_coef_idx(codec, 0x15, 0x0d40); | 3540 | alc_write_coef_idx(codec, 0x15, 0x0d40); |
3543 | alc_write_coef_idx(codec, 0xb7, 0x802b); | 3541 | alc_write_coef_idx(codec, 0xb7, 0x802b); |
3544 | break; | 3542 | break; |
3545 | } | 3543 | } |
3546 | codec_dbg(codec, "Headset jack set to unplugged mode.\n"); | 3544 | codec_dbg(codec, "Headset jack set to unplugged mode.\n"); |
3547 | } | 3545 | } |
3548 | 3546 | ||
3549 | 3547 | ||
3550 | static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, | 3548 | static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin, |
3551 | hda_nid_t mic_pin) | 3549 | hda_nid_t mic_pin) |
3552 | { | 3550 | { |
3553 | int val; | 3551 | int val; |
3554 | 3552 | ||
3555 | switch (codec->vendor_id) { | 3553 | switch (codec->vendor_id) { |
3556 | case 0x10ec0255: | 3554 | case 0x10ec0255: |
3557 | alc_write_coef_idx(codec, 0x45, 0xc489); | 3555 | alc_write_coef_idx(codec, 0x45, 0xc489); |
3558 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); | 3556 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); |
3559 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6); | 3557 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8aa6); |
3560 | /* Set MIC2 Vref gate to normal */ | 3558 | /* Set MIC2 Vref gate to normal */ |
3561 | alc_write_coef_idx(codec, 0x06, 0x6100); | 3559 | alc_write_coef_idx(codec, 0x06, 0x6100); |
3562 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); | 3560 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); |
3563 | break; | 3561 | break; |
3564 | case 0x10ec0283: | 3562 | case 0x10ec0283: |
3565 | alc_write_coef_idx(codec, 0x45, 0xc429); | 3563 | alc_write_coef_idx(codec, 0x45, 0xc429); |
3566 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); | 3564 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); |
3567 | val = alc_read_coef_idx(codec, 0x35); | 3565 | val = alc_read_coef_idx(codec, 0x35); |
3568 | alc_write_coef_idx(codec, 0x35, val | 1<<14); | 3566 | alc_write_coef_idx(codec, 0x35, val | 1<<14); |
3569 | alc_write_coef_idx(codec, 0x06, 0x2100); | 3567 | alc_write_coef_idx(codec, 0x06, 0x2100); |
3570 | alc_write_coef_idx(codec, 0x1a, 0x0021); | 3568 | alc_write_coef_idx(codec, 0x1a, 0x0021); |
3571 | alc_write_coef_idx(codec, 0x26, 0x008c); | 3569 | alc_write_coef_idx(codec, 0x26, 0x008c); |
3572 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); | 3570 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); |
3573 | break; | 3571 | break; |
3574 | case 0x10ec0292: | 3572 | case 0x10ec0292: |
3575 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); | 3573 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); |
3576 | alc_write_coef_idx(codec, 0x19, 0xa208); | 3574 | alc_write_coef_idx(codec, 0x19, 0xa208); |
3577 | alc_write_coef_idx(codec, 0x2e, 0xacf0); | 3575 | alc_write_coef_idx(codec, 0x2e, 0xacf0); |
3578 | break; | 3576 | break; |
3579 | case 0x10ec0668: | 3577 | case 0x10ec0668: |
3580 | alc_write_coef_idx(codec, 0x11, 0x0001); | 3578 | alc_write_coef_idx(codec, 0x11, 0x0001); |
3581 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); | 3579 | snd_hda_set_pin_ctl_cache(codec, hp_pin, 0); |
3582 | alc_write_coef_idx(codec, 0xb7, 0x802b); | 3580 | alc_write_coef_idx(codec, 0xb7, 0x802b); |
3583 | alc_write_coef_idx(codec, 0xb5, 0x1040); | 3581 | alc_write_coef_idx(codec, 0xb5, 0x1040); |
3584 | val = alc_read_coef_idx(codec, 0xc3); | 3582 | val = alc_read_coef_idx(codec, 0xc3); |
3585 | alc_write_coef_idx(codec, 0xc3, val | 1<<12); | 3583 | alc_write_coef_idx(codec, 0xc3, val | 1<<12); |
3586 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); | 3584 | snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50); |
3587 | break; | 3585 | break; |
3588 | } | 3586 | } |
3589 | codec_dbg(codec, "Headset jack set to mic-in mode.\n"); | 3587 | codec_dbg(codec, "Headset jack set to mic-in mode.\n"); |
3590 | } | 3588 | } |
3591 | 3589 | ||
3592 | static void alc_headset_mode_default(struct hda_codec *codec) | 3590 | static void alc_headset_mode_default(struct hda_codec *codec) |
3593 | { | 3591 | { |
3594 | switch (codec->vendor_id) { | 3592 | switch (codec->vendor_id) { |
3595 | case 0x10ec0255: | 3593 | case 0x10ec0255: |
3596 | alc_write_coef_idx(codec, 0x45, 0xc089); | 3594 | alc_write_coef_idx(codec, 0x45, 0xc089); |
3597 | alc_write_coef_idx(codec, 0x45, 0xc489); | 3595 | alc_write_coef_idx(codec, 0x45, 0xc489); |
3598 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); | 3596 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); |
3599 | alc_write_coef_idx(codec, 0x49, 0x0049); | 3597 | alc_write_coef_idx(codec, 0x49, 0x0049); |
3600 | break; | 3598 | break; |
3601 | case 0x10ec0283: | 3599 | case 0x10ec0283: |
3602 | alc_write_coef_idx(codec, 0x06, 0x2100); | 3600 | alc_write_coef_idx(codec, 0x06, 0x2100); |
3603 | alc_write_coef_idx(codec, 0x32, 0x4ea3); | 3601 | alc_write_coef_idx(codec, 0x32, 0x4ea3); |
3604 | break; | 3602 | break; |
3605 | case 0x10ec0292: | 3603 | case 0x10ec0292: |
3606 | alc_write_coef_idx(codec, 0x76, 0x000e); | 3604 | alc_write_coef_idx(codec, 0x76, 0x000e); |
3607 | alc_write_coef_idx(codec, 0x6c, 0x2400); | 3605 | alc_write_coef_idx(codec, 0x6c, 0x2400); |
3608 | alc_write_coef_idx(codec, 0x6b, 0xc429); | 3606 | alc_write_coef_idx(codec, 0x6b, 0xc429); |
3609 | alc_write_coef_idx(codec, 0x18, 0x7308); | 3607 | alc_write_coef_idx(codec, 0x18, 0x7308); |
3610 | break; | 3608 | break; |
3611 | case 0x10ec0668: | 3609 | case 0x10ec0668: |
3612 | alc_write_coef_idx(codec, 0x11, 0x0041); | 3610 | alc_write_coef_idx(codec, 0x11, 0x0041); |
3613 | alc_write_coef_idx(codec, 0x15, 0x0d40); | 3611 | alc_write_coef_idx(codec, 0x15, 0x0d40); |
3614 | alc_write_coef_idx(codec, 0xb7, 0x802b); | 3612 | alc_write_coef_idx(codec, 0xb7, 0x802b); |
3615 | break; | 3613 | break; |
3616 | } | 3614 | } |
3617 | codec_dbg(codec, "Headset jack set to headphone (default) mode.\n"); | 3615 | codec_dbg(codec, "Headset jack set to headphone (default) mode.\n"); |
3618 | } | 3616 | } |
3619 | 3617 | ||
3620 | /* Iphone type */ | 3618 | /* Iphone type */ |
3621 | static void alc_headset_mode_ctia(struct hda_codec *codec) | 3619 | static void alc_headset_mode_ctia(struct hda_codec *codec) |
3622 | { | 3620 | { |
3623 | switch (codec->vendor_id) { | 3621 | switch (codec->vendor_id) { |
3624 | case 0x10ec0255: | 3622 | case 0x10ec0255: |
3625 | /* Set to CTIA type */ | 3623 | /* Set to CTIA type */ |
3626 | alc_write_coef_idx(codec, 0x45, 0xd489); | 3624 | alc_write_coef_idx(codec, 0x45, 0xd489); |
3627 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | 3625 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); |
3628 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); | 3626 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); |
3629 | break; | 3627 | break; |
3630 | case 0x10ec0283: | 3628 | case 0x10ec0283: |
3631 | alc_write_coef_idx(codec, 0x45, 0xd429); | 3629 | alc_write_coef_idx(codec, 0x45, 0xd429); |
3632 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | 3630 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); |
3633 | alc_write_coef_idx(codec, 0x32, 0x4ea3); | 3631 | alc_write_coef_idx(codec, 0x32, 0x4ea3); |
3634 | break; | 3632 | break; |
3635 | case 0x10ec0292: | 3633 | case 0x10ec0292: |
3636 | alc_write_coef_idx(codec, 0x6b, 0xd429); | 3634 | alc_write_coef_idx(codec, 0x6b, 0xd429); |
3637 | alc_write_coef_idx(codec, 0x76, 0x0008); | 3635 | alc_write_coef_idx(codec, 0x76, 0x0008); |
3638 | alc_write_coef_idx(codec, 0x18, 0x7388); | 3636 | alc_write_coef_idx(codec, 0x18, 0x7388); |
3639 | break; | 3637 | break; |
3640 | case 0x10ec0668: | 3638 | case 0x10ec0668: |
3641 | alc_write_coef_idx(codec, 0x11, 0x0001); | 3639 | alc_write_coef_idx(codec, 0x11, 0x0001); |
3642 | alc_write_coef_idx(codec, 0x15, 0x0d60); | 3640 | alc_write_coef_idx(codec, 0x15, 0x0d60); |
3643 | alc_write_coef_idx(codec, 0xc3, 0x0000); | 3641 | alc_write_coef_idx(codec, 0xc3, 0x0000); |
3644 | break; | 3642 | break; |
3645 | } | 3643 | } |
3646 | codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n"); | 3644 | codec_dbg(codec, "Headset jack set to iPhone-style headset mode.\n"); |
3647 | } | 3645 | } |
3648 | 3646 | ||
3649 | /* Nokia type */ | 3647 | /* Nokia type */ |
3650 | static void alc_headset_mode_omtp(struct hda_codec *codec) | 3648 | static void alc_headset_mode_omtp(struct hda_codec *codec) |
3651 | { | 3649 | { |
3652 | switch (codec->vendor_id) { | 3650 | switch (codec->vendor_id) { |
3653 | case 0x10ec0255: | 3651 | case 0x10ec0255: |
3654 | /* Set to OMTP Type */ | 3652 | /* Set to OMTP Type */ |
3655 | alc_write_coef_idx(codec, 0x45, 0xe489); | 3653 | alc_write_coef_idx(codec, 0x45, 0xe489); |
3656 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | 3654 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); |
3657 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); | 3655 | alc_write_coefex_idx(codec, 0x57, 0x03, 0x8ea6); |
3658 | break; | 3656 | break; |
3659 | case 0x10ec0283: | 3657 | case 0x10ec0283: |
3660 | alc_write_coef_idx(codec, 0x45, 0xe429); | 3658 | alc_write_coef_idx(codec, 0x45, 0xe429); |
3661 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); | 3659 | alc_write_coef_idx(codec, 0x1b, 0x0c2b); |
3662 | alc_write_coef_idx(codec, 0x32, 0x4ea3); | 3660 | alc_write_coef_idx(codec, 0x32, 0x4ea3); |
3663 | break; | 3661 | break; |
3664 | case 0x10ec0292: | 3662 | case 0x10ec0292: |
3665 | alc_write_coef_idx(codec, 0x6b, 0xe429); | 3663 | alc_write_coef_idx(codec, 0x6b, 0xe429); |
3666 | alc_write_coef_idx(codec, 0x76, 0x0008); | 3664 | alc_write_coef_idx(codec, 0x76, 0x0008); |
3667 | alc_write_coef_idx(codec, 0x18, 0x7388); | 3665 | alc_write_coef_idx(codec, 0x18, 0x7388); |
3668 | break; | 3666 | break; |
3669 | case 0x10ec0668: | 3667 | case 0x10ec0668: |
3670 | alc_write_coef_idx(codec, 0x11, 0x0001); | 3668 | alc_write_coef_idx(codec, 0x11, 0x0001); |
3671 | alc_write_coef_idx(codec, 0x15, 0x0d50); | 3669 | alc_write_coef_idx(codec, 0x15, 0x0d50); |
3672 | alc_write_coef_idx(codec, 0xc3, 0x0000); | 3670 | alc_write_coef_idx(codec, 0xc3, 0x0000); |
3673 | break; | 3671 | break; |
3674 | } | 3672 | } |
3675 | codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n"); | 3673 | codec_dbg(codec, "Headset jack set to Nokia-style headset mode.\n"); |
3676 | } | 3674 | } |
3677 | 3675 | ||
3678 | static void alc_determine_headset_type(struct hda_codec *codec) | 3676 | static void alc_determine_headset_type(struct hda_codec *codec) |
3679 | { | 3677 | { |
3680 | int val; | 3678 | int val; |
3681 | bool is_ctia = false; | 3679 | bool is_ctia = false; |
3682 | struct alc_spec *spec = codec->spec; | 3680 | struct alc_spec *spec = codec->spec; |
3683 | 3681 | ||
3684 | switch (codec->vendor_id) { | 3682 | switch (codec->vendor_id) { |
3685 | case 0x10ec0255: | 3683 | case 0x10ec0255: |
3686 | /* combo jack auto switch control(Check type)*/ | 3684 | /* combo jack auto switch control(Check type)*/ |
3687 | alc_write_coef_idx(codec, 0x45, 0xd089); | 3685 | alc_write_coef_idx(codec, 0x45, 0xd089); |
3688 | /* combo jack auto switch control(Vref conteol) */ | 3686 | /* combo jack auto switch control(Vref conteol) */ |
3689 | alc_write_coef_idx(codec, 0x49, 0x0149); | 3687 | alc_write_coef_idx(codec, 0x49, 0x0149); |
3690 | msleep(300); | 3688 | msleep(300); |
3691 | val = alc_read_coef_idx(codec, 0x46); | 3689 | val = alc_read_coef_idx(codec, 0x46); |
3692 | is_ctia = (val & 0x0070) == 0x0070; | 3690 | is_ctia = (val & 0x0070) == 0x0070; |
3693 | break; | 3691 | break; |
3694 | case 0x10ec0283: | 3692 | case 0x10ec0283: |
3695 | alc_write_coef_idx(codec, 0x45, 0xd029); | 3693 | alc_write_coef_idx(codec, 0x45, 0xd029); |
3696 | msleep(300); | 3694 | msleep(300); |
3697 | val = alc_read_coef_idx(codec, 0x46); | 3695 | val = alc_read_coef_idx(codec, 0x46); |
3698 | is_ctia = (val & 0x0070) == 0x0070; | 3696 | is_ctia = (val & 0x0070) == 0x0070; |
3699 | break; | 3697 | break; |
3700 | case 0x10ec0292: | 3698 | case 0x10ec0292: |
3701 | alc_write_coef_idx(codec, 0x6b, 0xd429); | 3699 | alc_write_coef_idx(codec, 0x6b, 0xd429); |
3702 | msleep(300); | 3700 | msleep(300); |
3703 | val = alc_read_coef_idx(codec, 0x6c); | 3701 | val = alc_read_coef_idx(codec, 0x6c); |
3704 | is_ctia = (val & 0x001c) == 0x001c; | 3702 | is_ctia = (val & 0x001c) == 0x001c; |
3705 | break; | 3703 | break; |
3706 | case 0x10ec0668: | 3704 | case 0x10ec0668: |
3707 | alc_write_coef_idx(codec, 0x11, 0x0001); | 3705 | alc_write_coef_idx(codec, 0x11, 0x0001); |
3708 | alc_write_coef_idx(codec, 0xb7, 0x802b); | 3706 | alc_write_coef_idx(codec, 0xb7, 0x802b); |
3709 | alc_write_coef_idx(codec, 0x15, 0x0d60); | 3707 | alc_write_coef_idx(codec, 0x15, 0x0d60); |
3710 | alc_write_coef_idx(codec, 0xc3, 0x0c00); | 3708 | alc_write_coef_idx(codec, 0xc3, 0x0c00); |
3711 | msleep(300); | 3709 | msleep(300); |
3712 | val = alc_read_coef_idx(codec, 0xbe); | 3710 | val = alc_read_coef_idx(codec, 0xbe); |
3713 | is_ctia = (val & 0x1c02) == 0x1c02; | 3711 | is_ctia = (val & 0x1c02) == 0x1c02; |
3714 | break; | 3712 | break; |
3715 | } | 3713 | } |
3716 | 3714 | ||
3717 | codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n", | 3715 | codec_dbg(codec, "Headset jack detected iPhone-style headset: %s\n", |
3718 | is_ctia ? "yes" : "no"); | 3716 | is_ctia ? "yes" : "no"); |
3719 | spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP; | 3717 | spec->current_headset_type = is_ctia ? ALC_HEADSET_TYPE_CTIA : ALC_HEADSET_TYPE_OMTP; |
3720 | } | 3718 | } |
3721 | 3719 | ||
3722 | static void alc_update_headset_mode(struct hda_codec *codec) | 3720 | static void alc_update_headset_mode(struct hda_codec *codec) |
3723 | { | 3721 | { |
3724 | struct alc_spec *spec = codec->spec; | 3722 | struct alc_spec *spec = codec->spec; |
3725 | 3723 | ||
3726 | hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]]; | 3724 | hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]]; |
3727 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; | 3725 | hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; |
3728 | 3726 | ||
3729 | int new_headset_mode; | 3727 | int new_headset_mode; |
3730 | 3728 | ||
3731 | if (!snd_hda_jack_detect(codec, hp_pin)) | 3729 | if (!snd_hda_jack_detect(codec, hp_pin)) |
3732 | new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED; | 3730 | new_headset_mode = ALC_HEADSET_MODE_UNPLUGGED; |
3733 | else if (mux_pin == spec->headset_mic_pin) | 3731 | else if (mux_pin == spec->headset_mic_pin) |
3734 | new_headset_mode = ALC_HEADSET_MODE_HEADSET; | 3732 | new_headset_mode = ALC_HEADSET_MODE_HEADSET; |
3735 | else if (mux_pin == spec->headphone_mic_pin) | 3733 | else if (mux_pin == spec->headphone_mic_pin) |
3736 | new_headset_mode = ALC_HEADSET_MODE_MIC; | 3734 | new_headset_mode = ALC_HEADSET_MODE_MIC; |
3737 | else | 3735 | else |
3738 | new_headset_mode = ALC_HEADSET_MODE_HEADPHONE; | 3736 | new_headset_mode = ALC_HEADSET_MODE_HEADPHONE; |
3739 | 3737 | ||
3740 | if (new_headset_mode == spec->current_headset_mode) { | 3738 | if (new_headset_mode == spec->current_headset_mode) { |
3741 | snd_hda_gen_update_outputs(codec); | 3739 | snd_hda_gen_update_outputs(codec); |
3742 | return; | 3740 | return; |
3743 | } | 3741 | } |
3744 | 3742 | ||
3745 | switch (new_headset_mode) { | 3743 | switch (new_headset_mode) { |
3746 | case ALC_HEADSET_MODE_UNPLUGGED: | 3744 | case ALC_HEADSET_MODE_UNPLUGGED: |
3747 | alc_headset_mode_unplugged(codec); | 3745 | alc_headset_mode_unplugged(codec); |
3748 | spec->gen.hp_jack_present = false; | 3746 | spec->gen.hp_jack_present = false; |
3749 | break; | 3747 | break; |
3750 | case ALC_HEADSET_MODE_HEADSET: | 3748 | case ALC_HEADSET_MODE_HEADSET: |
3751 | if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN) | 3749 | if (spec->current_headset_type == ALC_HEADSET_TYPE_UNKNOWN) |
3752 | alc_determine_headset_type(codec); | 3750 | alc_determine_headset_type(codec); |
3753 | if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA) | 3751 | if (spec->current_headset_type == ALC_HEADSET_TYPE_CTIA) |
3754 | alc_headset_mode_ctia(codec); | 3752 | alc_headset_mode_ctia(codec); |
3755 | else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP) | 3753 | else if (spec->current_headset_type == ALC_HEADSET_TYPE_OMTP) |
3756 | alc_headset_mode_omtp(codec); | 3754 | alc_headset_mode_omtp(codec); |
3757 | spec->gen.hp_jack_present = true; | 3755 | spec->gen.hp_jack_present = true; |
3758 | break; | 3756 | break; |
3759 | case ALC_HEADSET_MODE_MIC: | 3757 | case ALC_HEADSET_MODE_MIC: |
3760 | alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin); | 3758 | alc_headset_mode_mic_in(codec, hp_pin, spec->headphone_mic_pin); |
3761 | spec->gen.hp_jack_present = false; | 3759 | spec->gen.hp_jack_present = false; |
3762 | break; | 3760 | break; |
3763 | case ALC_HEADSET_MODE_HEADPHONE: | 3761 | case ALC_HEADSET_MODE_HEADPHONE: |
3764 | alc_headset_mode_default(codec); | 3762 | alc_headset_mode_default(codec); |
3765 | spec->gen.hp_jack_present = true; | 3763 | spec->gen.hp_jack_present = true; |
3766 | break; | 3764 | break; |
3767 | } | 3765 | } |
3768 | if (new_headset_mode != ALC_HEADSET_MODE_MIC) { | 3766 | if (new_headset_mode != ALC_HEADSET_MODE_MIC) { |
3769 | snd_hda_set_pin_ctl_cache(codec, hp_pin, | 3767 | snd_hda_set_pin_ctl_cache(codec, hp_pin, |
3770 | AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); | 3768 | AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN); |
3771 | if (spec->headphone_mic_pin) | 3769 | if (spec->headphone_mic_pin) |
3772 | snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin, | 3770 | snd_hda_set_pin_ctl_cache(codec, spec->headphone_mic_pin, |
3773 | PIN_VREFHIZ); | 3771 | PIN_VREFHIZ); |
3774 | } | 3772 | } |
3775 | spec->current_headset_mode = new_headset_mode; | 3773 | spec->current_headset_mode = new_headset_mode; |
3776 | 3774 | ||
3777 | snd_hda_gen_update_outputs(codec); | 3775 | snd_hda_gen_update_outputs(codec); |
3778 | } | 3776 | } |
3779 | 3777 | ||
3780 | static void alc_update_headset_mode_hook(struct hda_codec *codec, | 3778 | static void alc_update_headset_mode_hook(struct hda_codec *codec, |
3781 | struct snd_kcontrol *kcontrol, | 3779 | struct snd_kcontrol *kcontrol, |
3782 | struct snd_ctl_elem_value *ucontrol) | 3780 | struct snd_ctl_elem_value *ucontrol) |
3783 | { | 3781 | { |
3784 | alc_update_headset_mode(codec); | 3782 | alc_update_headset_mode(codec); |
3785 | } | 3783 | } |
3786 | 3784 | ||
3787 | static void alc_update_headset_jack_cb(struct hda_codec *codec, struct hda_jack_tbl *jack) | 3785 | static void alc_update_headset_jack_cb(struct hda_codec *codec, struct hda_jack_tbl *jack) |
3788 | { | 3786 | { |
3789 | struct alc_spec *spec = codec->spec; | 3787 | struct alc_spec *spec = codec->spec; |
3790 | spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN; | 3788 | spec->current_headset_type = ALC_HEADSET_TYPE_UNKNOWN; |
3791 | snd_hda_gen_hp_automute(codec, jack); | 3789 | snd_hda_gen_hp_automute(codec, jack); |
3792 | } | 3790 | } |
3793 | 3791 | ||
3794 | static void alc_probe_headset_mode(struct hda_codec *codec) | 3792 | static void alc_probe_headset_mode(struct hda_codec *codec) |
3795 | { | 3793 | { |
3796 | int i; | 3794 | int i; |
3797 | struct alc_spec *spec = codec->spec; | 3795 | struct alc_spec *spec = codec->spec; |
3798 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; | 3796 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; |
3799 | 3797 | ||
3800 | /* Find mic pins */ | 3798 | /* Find mic pins */ |
3801 | for (i = 0; i < cfg->num_inputs; i++) { | 3799 | for (i = 0; i < cfg->num_inputs; i++) { |
3802 | if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin) | 3800 | if (cfg->inputs[i].is_headset_mic && !spec->headset_mic_pin) |
3803 | spec->headset_mic_pin = cfg->inputs[i].pin; | 3801 | spec->headset_mic_pin = cfg->inputs[i].pin; |
3804 | if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin) | 3802 | if (cfg->inputs[i].is_headphone_mic && !spec->headphone_mic_pin) |
3805 | spec->headphone_mic_pin = cfg->inputs[i].pin; | 3803 | spec->headphone_mic_pin = cfg->inputs[i].pin; |
3806 | } | 3804 | } |
3807 | 3805 | ||
3808 | spec->gen.cap_sync_hook = alc_update_headset_mode_hook; | 3806 | spec->gen.cap_sync_hook = alc_update_headset_mode_hook; |
3809 | spec->gen.automute_hook = alc_update_headset_mode; | 3807 | spec->gen.automute_hook = alc_update_headset_mode; |
3810 | spec->gen.hp_automute_hook = alc_update_headset_jack_cb; | 3808 | spec->gen.hp_automute_hook = alc_update_headset_jack_cb; |
3811 | } | 3809 | } |
3812 | 3810 | ||
3813 | static void alc_fixup_headset_mode(struct hda_codec *codec, | 3811 | static void alc_fixup_headset_mode(struct hda_codec *codec, |
3814 | const struct hda_fixup *fix, int action) | 3812 | const struct hda_fixup *fix, int action) |
3815 | { | 3813 | { |
3816 | struct alc_spec *spec = codec->spec; | 3814 | struct alc_spec *spec = codec->spec; |
3817 | 3815 | ||
3818 | switch (action) { | 3816 | switch (action) { |
3819 | case HDA_FIXUP_ACT_PRE_PROBE: | 3817 | case HDA_FIXUP_ACT_PRE_PROBE: |
3820 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC; | 3818 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC | HDA_PINCFG_HEADPHONE_MIC; |
3821 | break; | 3819 | break; |
3822 | case HDA_FIXUP_ACT_PROBE: | 3820 | case HDA_FIXUP_ACT_PROBE: |
3823 | alc_probe_headset_mode(codec); | 3821 | alc_probe_headset_mode(codec); |
3824 | break; | 3822 | break; |
3825 | case HDA_FIXUP_ACT_INIT: | 3823 | case HDA_FIXUP_ACT_INIT: |
3826 | spec->current_headset_mode = 0; | 3824 | spec->current_headset_mode = 0; |
3827 | alc_update_headset_mode(codec); | 3825 | alc_update_headset_mode(codec); |
3828 | break; | 3826 | break; |
3829 | } | 3827 | } |
3830 | } | 3828 | } |
3831 | 3829 | ||
3832 | static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec, | 3830 | static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec, |
3833 | const struct hda_fixup *fix, int action) | 3831 | const struct hda_fixup *fix, int action) |
3834 | { | 3832 | { |
3835 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3833 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3836 | struct alc_spec *spec = codec->spec; | 3834 | struct alc_spec *spec = codec->spec; |
3837 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; | 3835 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; |
3838 | } | 3836 | } |
3839 | else | 3837 | else |
3840 | alc_fixup_headset_mode(codec, fix, action); | 3838 | alc_fixup_headset_mode(codec, fix, action); |
3841 | } | 3839 | } |
3842 | 3840 | ||
3843 | static void alc255_set_default_jack_type(struct hda_codec *codec) | 3841 | static void alc255_set_default_jack_type(struct hda_codec *codec) |
3844 | { | 3842 | { |
3845 | /* Set to iphone type */ | 3843 | /* Set to iphone type */ |
3846 | alc_write_coef_idx(codec, 0x1b, 0x880b); | 3844 | alc_write_coef_idx(codec, 0x1b, 0x880b); |
3847 | alc_write_coef_idx(codec, 0x45, 0xd089); | 3845 | alc_write_coef_idx(codec, 0x45, 0xd089); |
3848 | alc_write_coef_idx(codec, 0x1b, 0x080b); | 3846 | alc_write_coef_idx(codec, 0x1b, 0x080b); |
3849 | alc_write_coef_idx(codec, 0x46, 0x0004); | 3847 | alc_write_coef_idx(codec, 0x46, 0x0004); |
3850 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); | 3848 | alc_write_coef_idx(codec, 0x1b, 0x0c0b); |
3851 | msleep(30); | 3849 | msleep(30); |
3852 | } | 3850 | } |
3853 | 3851 | ||
3854 | static void alc_fixup_headset_mode_alc255(struct hda_codec *codec, | 3852 | static void alc_fixup_headset_mode_alc255(struct hda_codec *codec, |
3855 | const struct hda_fixup *fix, int action) | 3853 | const struct hda_fixup *fix, int action) |
3856 | { | 3854 | { |
3857 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3855 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3858 | alc255_set_default_jack_type(codec); | 3856 | alc255_set_default_jack_type(codec); |
3859 | } | 3857 | } |
3860 | alc_fixup_headset_mode(codec, fix, action); | 3858 | alc_fixup_headset_mode(codec, fix, action); |
3861 | } | 3859 | } |
3862 | 3860 | ||
3863 | static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec, | 3861 | static void alc_fixup_headset_mode_alc255_no_hp_mic(struct hda_codec *codec, |
3864 | const struct hda_fixup *fix, int action) | 3862 | const struct hda_fixup *fix, int action) |
3865 | { | 3863 | { |
3866 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3864 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3867 | struct alc_spec *spec = codec->spec; | 3865 | struct alc_spec *spec = codec->spec; |
3868 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; | 3866 | spec->parse_flags |= HDA_PINCFG_HEADSET_MIC; |
3869 | alc255_set_default_jack_type(codec); | 3867 | alc255_set_default_jack_type(codec); |
3870 | } | 3868 | } |
3871 | else | 3869 | else |
3872 | alc_fixup_headset_mode(codec, fix, action); | 3870 | alc_fixup_headset_mode(codec, fix, action); |
3873 | } | 3871 | } |
3874 | 3872 | ||
3875 | static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec, | 3873 | static void alc_fixup_auto_mute_via_amp(struct hda_codec *codec, |
3876 | const struct hda_fixup *fix, int action) | 3874 | const struct hda_fixup *fix, int action) |
3877 | { | 3875 | { |
3878 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3876 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3879 | struct alc_spec *spec = codec->spec; | 3877 | struct alc_spec *spec = codec->spec; |
3880 | spec->gen.auto_mute_via_amp = 1; | 3878 | spec->gen.auto_mute_via_amp = 1; |
3881 | } | 3879 | } |
3882 | } | 3880 | } |
3883 | 3881 | ||
3884 | static void alc_no_shutup(struct hda_codec *codec) | 3882 | static void alc_no_shutup(struct hda_codec *codec) |
3885 | { | 3883 | { |
3886 | } | 3884 | } |
3887 | 3885 | ||
3888 | static void alc_fixup_no_shutup(struct hda_codec *codec, | 3886 | static void alc_fixup_no_shutup(struct hda_codec *codec, |
3889 | const struct hda_fixup *fix, int action) | 3887 | const struct hda_fixup *fix, int action) |
3890 | { | 3888 | { |
3891 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3889 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3892 | struct alc_spec *spec = codec->spec; | 3890 | struct alc_spec *spec = codec->spec; |
3893 | spec->shutup = alc_no_shutup; | 3891 | spec->shutup = alc_no_shutup; |
3894 | } | 3892 | } |
3895 | } | 3893 | } |
3896 | 3894 | ||
3897 | static void alc_fixup_headset_mode_alc668(struct hda_codec *codec, | 3895 | static void alc_fixup_headset_mode_alc668(struct hda_codec *codec, |
3898 | const struct hda_fixup *fix, int action) | 3896 | const struct hda_fixup *fix, int action) |
3899 | { | 3897 | { |
3900 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 3898 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
3901 | int val; | 3899 | int val; |
3902 | alc_write_coef_idx(codec, 0xc4, 0x8000); | 3900 | alc_write_coef_idx(codec, 0xc4, 0x8000); |
3903 | val = alc_read_coef_idx(codec, 0xc2); | 3901 | val = alc_read_coef_idx(codec, 0xc2); |
3904 | alc_write_coef_idx(codec, 0xc2, val & 0xfe); | 3902 | alc_write_coef_idx(codec, 0xc2, val & 0xfe); |
3905 | snd_hda_set_pin_ctl_cache(codec, 0x18, 0); | 3903 | snd_hda_set_pin_ctl_cache(codec, 0x18, 0); |
3906 | } | 3904 | } |
3907 | alc_fixup_headset_mode(codec, fix, action); | 3905 | alc_fixup_headset_mode(codec, fix, action); |
3908 | } | 3906 | } |
3909 | 3907 | ||
3910 | /* Returns the nid of the external mic input pin, or 0 if it cannot be found. */ | 3908 | /* Returns the nid of the external mic input pin, or 0 if it cannot be found. */ |
3911 | static int find_ext_mic_pin(struct hda_codec *codec) | 3909 | static int find_ext_mic_pin(struct hda_codec *codec) |
3912 | { | 3910 | { |
3913 | struct alc_spec *spec = codec->spec; | 3911 | struct alc_spec *spec = codec->spec; |
3914 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; | 3912 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; |
3915 | hda_nid_t nid; | 3913 | hda_nid_t nid; |
3916 | unsigned int defcfg; | 3914 | unsigned int defcfg; |
3917 | int i; | 3915 | int i; |
3918 | 3916 | ||
3919 | for (i = 0; i < cfg->num_inputs; i++) { | 3917 | for (i = 0; i < cfg->num_inputs; i++) { |
3920 | if (cfg->inputs[i].type != AUTO_PIN_MIC) | 3918 | if (cfg->inputs[i].type != AUTO_PIN_MIC) |
3921 | continue; | 3919 | continue; |
3922 | nid = cfg->inputs[i].pin; | 3920 | nid = cfg->inputs[i].pin; |
3923 | defcfg = snd_hda_codec_get_pincfg(codec, nid); | 3921 | defcfg = snd_hda_codec_get_pincfg(codec, nid); |
3924 | if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT) | 3922 | if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT) |
3925 | continue; | 3923 | continue; |
3926 | return nid; | 3924 | return nid; |
3927 | } | 3925 | } |
3928 | 3926 | ||
3929 | return 0; | 3927 | return 0; |
3930 | } | 3928 | } |
3931 | 3929 | ||
3932 | static void alc271_hp_gate_mic_jack(struct hda_codec *codec, | 3930 | static void alc271_hp_gate_mic_jack(struct hda_codec *codec, |
3933 | const struct hda_fixup *fix, | 3931 | const struct hda_fixup *fix, |
3934 | int action) | 3932 | int action) |
3935 | { | 3933 | { |
3936 | struct alc_spec *spec = codec->spec; | 3934 | struct alc_spec *spec = codec->spec; |
3937 | 3935 | ||
3938 | if (action == HDA_FIXUP_ACT_PROBE) { | 3936 | if (action == HDA_FIXUP_ACT_PROBE) { |
3939 | int mic_pin = find_ext_mic_pin(codec); | 3937 | int mic_pin = find_ext_mic_pin(codec); |
3940 | int hp_pin = spec->gen.autocfg.hp_pins[0]; | 3938 | int hp_pin = spec->gen.autocfg.hp_pins[0]; |
3941 | 3939 | ||
3942 | if (snd_BUG_ON(!mic_pin || !hp_pin)) | 3940 | if (snd_BUG_ON(!mic_pin || !hp_pin)) |
3943 | return; | 3941 | return; |
3944 | snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin); | 3942 | snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin); |
3945 | } | 3943 | } |
3946 | } | 3944 | } |
3947 | 3945 | ||
3948 | static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec, | 3946 | static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec, |
3949 | const struct hda_fixup *fix, | 3947 | const struct hda_fixup *fix, |
3950 | int action) | 3948 | int action) |
3951 | { | 3949 | { |
3952 | struct alc_spec *spec = codec->spec; | 3950 | struct alc_spec *spec = codec->spec; |
3953 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; | 3951 | struct auto_pin_cfg *cfg = &spec->gen.autocfg; |
3954 | int i; | 3952 | int i; |
3955 | 3953 | ||
3956 | /* The mic boosts on level 2 and 3 are too noisy | 3954 | /* The mic boosts on level 2 and 3 are too noisy |
3957 | on the internal mic input. | 3955 | on the internal mic input. |
3958 | Therefore limit the boost to 0 or 1. */ | 3956 | Therefore limit the boost to 0 or 1. */ |
3959 | 3957 | ||
3960 | if (action != HDA_FIXUP_ACT_PROBE) | 3958 | if (action != HDA_FIXUP_ACT_PROBE) |
3961 | return; | 3959 | return; |
3962 | 3960 | ||
3963 | for (i = 0; i < cfg->num_inputs; i++) { | 3961 | for (i = 0; i < cfg->num_inputs; i++) { |
3964 | hda_nid_t nid = cfg->inputs[i].pin; | 3962 | hda_nid_t nid = cfg->inputs[i].pin; |
3965 | unsigned int defcfg; | 3963 | unsigned int defcfg; |
3966 | if (cfg->inputs[i].type != AUTO_PIN_MIC) | 3964 | if (cfg->inputs[i].type != AUTO_PIN_MIC) |
3967 | continue; | 3965 | continue; |
3968 | defcfg = snd_hda_codec_get_pincfg(codec, nid); | 3966 | defcfg = snd_hda_codec_get_pincfg(codec, nid); |
3969 | if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT) | 3967 | if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT) |
3970 | continue; | 3968 | continue; |
3971 | 3969 | ||
3972 | snd_hda_override_amp_caps(codec, nid, HDA_INPUT, | 3970 | snd_hda_override_amp_caps(codec, nid, HDA_INPUT, |
3973 | (0x00 << AC_AMPCAP_OFFSET_SHIFT) | | 3971 | (0x00 << AC_AMPCAP_OFFSET_SHIFT) | |
3974 | (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) | | 3972 | (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) | |
3975 | (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) | | 3973 | (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) | |
3976 | (0 << AC_AMPCAP_MUTE_SHIFT)); | 3974 | (0 << AC_AMPCAP_MUTE_SHIFT)); |
3977 | } | 3975 | } |
3978 | } | 3976 | } |
3979 | 3977 | ||
3980 | static void alc283_hp_automute_hook(struct hda_codec *codec, | 3978 | static void alc283_hp_automute_hook(struct hda_codec *codec, |
3981 | struct hda_jack_tbl *jack) | 3979 | struct hda_jack_tbl *jack) |
3982 | { | 3980 | { |
3983 | struct alc_spec *spec = codec->spec; | 3981 | struct alc_spec *spec = codec->spec; |
3984 | int vref; | 3982 | int vref; |
3985 | 3983 | ||
3986 | msleep(200); | 3984 | msleep(200); |
3987 | snd_hda_gen_hp_automute(codec, jack); | 3985 | snd_hda_gen_hp_automute(codec, jack); |
3988 | 3986 | ||
3989 | vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0; | 3987 | vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0; |
3990 | 3988 | ||
3991 | msleep(600); | 3989 | msleep(600); |
3992 | snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 3990 | snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
3993 | vref); | 3991 | vref); |
3994 | } | 3992 | } |
3995 | 3993 | ||
3996 | static void alc283_fixup_chromebook(struct hda_codec *codec, | 3994 | static void alc283_fixup_chromebook(struct hda_codec *codec, |
3997 | const struct hda_fixup *fix, int action) | 3995 | const struct hda_fixup *fix, int action) |
3998 | { | 3996 | { |
3999 | struct alc_spec *spec = codec->spec; | 3997 | struct alc_spec *spec = codec->spec; |
4000 | int val; | 3998 | int val; |
4001 | 3999 | ||
4002 | switch (action) { | 4000 | switch (action) { |
4003 | case HDA_FIXUP_ACT_PRE_PROBE: | 4001 | case HDA_FIXUP_ACT_PRE_PROBE: |
4004 | snd_hda_override_wcaps(codec, 0x03, 0); | 4002 | snd_hda_override_wcaps(codec, 0x03, 0); |
4005 | /* Disable AA-loopback as it causes white noise */ | 4003 | /* Disable AA-loopback as it causes white noise */ |
4006 | spec->gen.mixer_nid = 0; | 4004 | spec->gen.mixer_nid = 0; |
4007 | break; | 4005 | break; |
4008 | case HDA_FIXUP_ACT_INIT: | 4006 | case HDA_FIXUP_ACT_INIT: |
4009 | /* MIC2-VREF control */ | 4007 | /* MIC2-VREF control */ |
4010 | /* Set to manual mode */ | 4008 | /* Set to manual mode */ |
4011 | val = alc_read_coef_idx(codec, 0x06); | 4009 | val = alc_read_coef_idx(codec, 0x06); |
4012 | alc_write_coef_idx(codec, 0x06, val & ~0x000c); | 4010 | alc_write_coef_idx(codec, 0x06, val & ~0x000c); |
4013 | /* Enable Line1 input control by verb */ | 4011 | /* Enable Line1 input control by verb */ |
4014 | val = alc_read_coef_idx(codec, 0x1a); | 4012 | val = alc_read_coef_idx(codec, 0x1a); |
4015 | alc_write_coef_idx(codec, 0x1a, val | (1 << 4)); | 4013 | alc_write_coef_idx(codec, 0x1a, val | (1 << 4)); |
4016 | break; | 4014 | break; |
4017 | } | 4015 | } |
4018 | } | 4016 | } |
4019 | 4017 | ||
4020 | static void alc283_fixup_sense_combo_jack(struct hda_codec *codec, | 4018 | static void alc283_fixup_sense_combo_jack(struct hda_codec *codec, |
4021 | const struct hda_fixup *fix, int action) | 4019 | const struct hda_fixup *fix, int action) |
4022 | { | 4020 | { |
4023 | struct alc_spec *spec = codec->spec; | 4021 | struct alc_spec *spec = codec->spec; |
4024 | int val; | 4022 | int val; |
4025 | 4023 | ||
4026 | switch (action) { | 4024 | switch (action) { |
4027 | case HDA_FIXUP_ACT_PRE_PROBE: | 4025 | case HDA_FIXUP_ACT_PRE_PROBE: |
4028 | spec->gen.hp_automute_hook = alc283_hp_automute_hook; | 4026 | spec->gen.hp_automute_hook = alc283_hp_automute_hook; |
4029 | break; | 4027 | break; |
4030 | case HDA_FIXUP_ACT_INIT: | 4028 | case HDA_FIXUP_ACT_INIT: |
4031 | /* MIC2-VREF control */ | 4029 | /* MIC2-VREF control */ |
4032 | /* Set to manual mode */ | 4030 | /* Set to manual mode */ |
4033 | val = alc_read_coef_idx(codec, 0x06); | 4031 | val = alc_read_coef_idx(codec, 0x06); |
4034 | alc_write_coef_idx(codec, 0x06, val & ~0x000c); | 4032 | alc_write_coef_idx(codec, 0x06, val & ~0x000c); |
4035 | break; | 4033 | break; |
4036 | } | 4034 | } |
4037 | } | 4035 | } |
4038 | 4036 | ||
4039 | /* mute tablet speaker pin (0x14) via dock plugging in addition */ | 4037 | /* mute tablet speaker pin (0x14) via dock plugging in addition */ |
4040 | static void asus_tx300_automute(struct hda_codec *codec) | 4038 | static void asus_tx300_automute(struct hda_codec *codec) |
4041 | { | 4039 | { |
4042 | struct alc_spec *spec = codec->spec; | 4040 | struct alc_spec *spec = codec->spec; |
4043 | snd_hda_gen_update_outputs(codec); | 4041 | snd_hda_gen_update_outputs(codec); |
4044 | if (snd_hda_jack_detect(codec, 0x1b)) | 4042 | if (snd_hda_jack_detect(codec, 0x1b)) |
4045 | spec->gen.mute_bits |= (1ULL << 0x14); | 4043 | spec->gen.mute_bits |= (1ULL << 0x14); |
4046 | } | 4044 | } |
4047 | 4045 | ||
4048 | static void alc282_fixup_asus_tx300(struct hda_codec *codec, | 4046 | static void alc282_fixup_asus_tx300(struct hda_codec *codec, |
4049 | const struct hda_fixup *fix, int action) | 4047 | const struct hda_fixup *fix, int action) |
4050 | { | 4048 | { |
4051 | struct alc_spec *spec = codec->spec; | 4049 | struct alc_spec *spec = codec->spec; |
4052 | /* TX300 needs to set up GPIO2 for the speaker amp */ | 4050 | /* TX300 needs to set up GPIO2 for the speaker amp */ |
4053 | static const struct hda_verb gpio2_verbs[] = { | 4051 | static const struct hda_verb gpio2_verbs[] = { |
4054 | { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 }, | 4052 | { 0x01, AC_VERB_SET_GPIO_MASK, 0x04 }, |
4055 | { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 }, | 4053 | { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04 }, |
4056 | { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 }, | 4054 | { 0x01, AC_VERB_SET_GPIO_DATA, 0x04 }, |
4057 | {} | 4055 | {} |
4058 | }; | 4056 | }; |
4059 | static const struct hda_pintbl dock_pins[] = { | 4057 | static const struct hda_pintbl dock_pins[] = { |
4060 | { 0x1b, 0x21114000 }, /* dock speaker pin */ | 4058 | { 0x1b, 0x21114000 }, /* dock speaker pin */ |
4061 | {} | 4059 | {} |
4062 | }; | 4060 | }; |
4063 | struct snd_kcontrol *kctl; | 4061 | struct snd_kcontrol *kctl; |
4064 | 4062 | ||
4065 | switch (action) { | 4063 | switch (action) { |
4066 | case HDA_FIXUP_ACT_PRE_PROBE: | 4064 | case HDA_FIXUP_ACT_PRE_PROBE: |
4067 | snd_hda_add_verbs(codec, gpio2_verbs); | 4065 | snd_hda_add_verbs(codec, gpio2_verbs); |
4068 | snd_hda_apply_pincfgs(codec, dock_pins); | 4066 | snd_hda_apply_pincfgs(codec, dock_pins); |
4069 | spec->gen.auto_mute_via_amp = 1; | 4067 | spec->gen.auto_mute_via_amp = 1; |
4070 | spec->gen.automute_hook = asus_tx300_automute; | 4068 | spec->gen.automute_hook = asus_tx300_automute; |
4071 | snd_hda_jack_detect_enable_callback(codec, 0x1b, | 4069 | snd_hda_jack_detect_enable_callback(codec, 0x1b, |
4072 | HDA_GEN_HP_EVENT, | 4070 | HDA_GEN_HP_EVENT, |
4073 | snd_hda_gen_hp_automute); | 4071 | snd_hda_gen_hp_automute); |
4074 | break; | 4072 | break; |
4075 | case HDA_FIXUP_ACT_BUILD: | 4073 | case HDA_FIXUP_ACT_BUILD: |
4076 | /* this is a bit tricky; give more sane names for the main | 4074 | /* this is a bit tricky; give more sane names for the main |
4077 | * (tablet) speaker and the dock speaker, respectively | 4075 | * (tablet) speaker and the dock speaker, respectively |
4078 | */ | 4076 | */ |
4079 | kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch"); | 4077 | kctl = snd_hda_find_mixer_ctl(codec, "Speaker Playback Switch"); |
4080 | if (kctl) | 4078 | if (kctl) |
4081 | strcpy(kctl->id.name, "Dock Speaker Playback Switch"); | 4079 | strcpy(kctl->id.name, "Dock Speaker Playback Switch"); |
4082 | kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch"); | 4080 | kctl = snd_hda_find_mixer_ctl(codec, "Bass Speaker Playback Switch"); |
4083 | if (kctl) | 4081 | if (kctl) |
4084 | strcpy(kctl->id.name, "Speaker Playback Switch"); | 4082 | strcpy(kctl->id.name, "Speaker Playback Switch"); |
4085 | break; | 4083 | break; |
4086 | } | 4084 | } |
4087 | } | 4085 | } |
4088 | 4086 | ||
4089 | static void alc290_fixup_mono_speakers(struct hda_codec *codec, | 4087 | static void alc290_fixup_mono_speakers(struct hda_codec *codec, |
4090 | const struct hda_fixup *fix, int action) | 4088 | const struct hda_fixup *fix, int action) |
4091 | { | 4089 | { |
4092 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 4090 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
4093 | /* DAC node 0x03 is giving mono output. We therefore want to | 4091 | /* DAC node 0x03 is giving mono output. We therefore want to |
4094 | make sure 0x14 (front speaker) and 0x15 (headphones) use the | 4092 | make sure 0x14 (front speaker) and 0x15 (headphones) use the |
4095 | stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */ | 4093 | stereo DAC, while leaving 0x17 (bass speaker) for node 0x03. */ |
4096 | hda_nid_t conn1[2] = { 0x0c }; | 4094 | hda_nid_t conn1[2] = { 0x0c }; |
4097 | snd_hda_override_conn_list(codec, 0x14, 1, conn1); | 4095 | snd_hda_override_conn_list(codec, 0x14, 1, conn1); |
4098 | snd_hda_override_conn_list(codec, 0x15, 1, conn1); | 4096 | snd_hda_override_conn_list(codec, 0x15, 1, conn1); |
4099 | } | 4097 | } |
4100 | } | 4098 | } |
4101 | 4099 | ||
4102 | /* for hda_fixup_thinkpad_acpi() */ | 4100 | /* for hda_fixup_thinkpad_acpi() */ |
4103 | #include "thinkpad_helper.c" | 4101 | #include "thinkpad_helper.c" |
4104 | 4102 | ||
4105 | enum { | 4103 | enum { |
4106 | ALC269_FIXUP_SONY_VAIO, | 4104 | ALC269_FIXUP_SONY_VAIO, |
4107 | ALC275_FIXUP_SONY_VAIO_GPIO2, | 4105 | ALC275_FIXUP_SONY_VAIO_GPIO2, |
4108 | ALC269_FIXUP_DELL_M101Z, | 4106 | ALC269_FIXUP_DELL_M101Z, |
4109 | ALC269_FIXUP_SKU_IGNORE, | 4107 | ALC269_FIXUP_SKU_IGNORE, |
4110 | ALC269_FIXUP_ASUS_G73JW, | 4108 | ALC269_FIXUP_ASUS_G73JW, |
4111 | ALC269_FIXUP_LENOVO_EAPD, | 4109 | ALC269_FIXUP_LENOVO_EAPD, |
4112 | ALC275_FIXUP_SONY_HWEQ, | 4110 | ALC275_FIXUP_SONY_HWEQ, |
4113 | ALC271_FIXUP_DMIC, | 4111 | ALC271_FIXUP_DMIC, |
4114 | ALC269_FIXUP_PCM_44K, | 4112 | ALC269_FIXUP_PCM_44K, |
4115 | ALC269_FIXUP_STEREO_DMIC, | 4113 | ALC269_FIXUP_STEREO_DMIC, |
4116 | ALC269_FIXUP_HEADSET_MIC, | 4114 | ALC269_FIXUP_HEADSET_MIC, |
4117 | ALC269_FIXUP_QUANTA_MUTE, | 4115 | ALC269_FIXUP_QUANTA_MUTE, |
4118 | ALC269_FIXUP_LIFEBOOK, | 4116 | ALC269_FIXUP_LIFEBOOK, |
4119 | ALC269_FIXUP_AMIC, | 4117 | ALC269_FIXUP_AMIC, |
4120 | ALC269_FIXUP_DMIC, | 4118 | ALC269_FIXUP_DMIC, |
4121 | ALC269VB_FIXUP_AMIC, | 4119 | ALC269VB_FIXUP_AMIC, |
4122 | ALC269VB_FIXUP_DMIC, | 4120 | ALC269VB_FIXUP_DMIC, |
4123 | ALC269_FIXUP_HP_MUTE_LED, | 4121 | ALC269_FIXUP_HP_MUTE_LED, |
4124 | ALC269_FIXUP_HP_MUTE_LED_MIC1, | 4122 | ALC269_FIXUP_HP_MUTE_LED_MIC1, |
4125 | ALC269_FIXUP_HP_MUTE_LED_MIC2, | 4123 | ALC269_FIXUP_HP_MUTE_LED_MIC2, |
4126 | ALC269_FIXUP_HP_GPIO_LED, | 4124 | ALC269_FIXUP_HP_GPIO_LED, |
4127 | ALC269_FIXUP_INV_DMIC, | 4125 | ALC269_FIXUP_INV_DMIC, |
4128 | ALC269_FIXUP_LENOVO_DOCK, | 4126 | ALC269_FIXUP_LENOVO_DOCK, |
4129 | ALC269_FIXUP_NO_SHUTUP, | 4127 | ALC269_FIXUP_NO_SHUTUP, |
4130 | ALC286_FIXUP_SONY_MIC_NO_PRESENCE, | 4128 | ALC286_FIXUP_SONY_MIC_NO_PRESENCE, |
4131 | ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, | 4129 | ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT, |
4132 | ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, | 4130 | ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, |
4133 | ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, | 4131 | ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, |
4134 | ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, | 4132 | ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, |
4135 | ALC269_FIXUP_HEADSET_MODE, | 4133 | ALC269_FIXUP_HEADSET_MODE, |
4136 | ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, | 4134 | ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC, |
4137 | ALC269_FIXUP_ASUS_X101_FUNC, | 4135 | ALC269_FIXUP_ASUS_X101_FUNC, |
4138 | ALC269_FIXUP_ASUS_X101_VERB, | 4136 | ALC269_FIXUP_ASUS_X101_VERB, |
4139 | ALC269_FIXUP_ASUS_X101, | 4137 | ALC269_FIXUP_ASUS_X101, |
4140 | ALC271_FIXUP_AMIC_MIC2, | 4138 | ALC271_FIXUP_AMIC_MIC2, |
4141 | ALC271_FIXUP_HP_GATE_MIC_JACK, | 4139 | ALC271_FIXUP_HP_GATE_MIC_JACK, |
4142 | ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572, | 4140 | ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572, |
4143 | ALC269_FIXUP_ACER_AC700, | 4141 | ALC269_FIXUP_ACER_AC700, |
4144 | ALC269_FIXUP_LIMIT_INT_MIC_BOOST, | 4142 | ALC269_FIXUP_LIMIT_INT_MIC_BOOST, |
4145 | ALC269VB_FIXUP_ASUS_ZENBOOK, | 4143 | ALC269VB_FIXUP_ASUS_ZENBOOK, |
4146 | ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A, | 4144 | ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A, |
4147 | ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED, | 4145 | ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED, |
4148 | ALC269VB_FIXUP_ORDISSIMO_EVE2, | 4146 | ALC269VB_FIXUP_ORDISSIMO_EVE2, |
4149 | ALC283_FIXUP_CHROME_BOOK, | 4147 | ALC283_FIXUP_CHROME_BOOK, |
4150 | ALC283_FIXUP_SENSE_COMBO_JACK, | 4148 | ALC283_FIXUP_SENSE_COMBO_JACK, |
4151 | ALC282_FIXUP_ASUS_TX300, | 4149 | ALC282_FIXUP_ASUS_TX300, |
4152 | ALC283_FIXUP_INT_MIC, | 4150 | ALC283_FIXUP_INT_MIC, |
4153 | ALC290_FIXUP_MONO_SPEAKERS, | 4151 | ALC290_FIXUP_MONO_SPEAKERS, |
4154 | ALC290_FIXUP_MONO_SPEAKERS_HSJACK, | 4152 | ALC290_FIXUP_MONO_SPEAKERS_HSJACK, |
4155 | ALC290_FIXUP_SUBWOOFER, | 4153 | ALC290_FIXUP_SUBWOOFER, |
4156 | ALC290_FIXUP_SUBWOOFER_HSJACK, | 4154 | ALC290_FIXUP_SUBWOOFER_HSJACK, |
4157 | ALC269_FIXUP_THINKPAD_ACPI, | 4155 | ALC269_FIXUP_THINKPAD_ACPI, |
4158 | ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, | 4156 | ALC255_FIXUP_DELL1_MIC_NO_PRESENCE, |
4159 | ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, | 4157 | ALC255_FIXUP_DELL2_MIC_NO_PRESENCE, |
4160 | ALC255_FIXUP_HEADSET_MODE, | 4158 | ALC255_FIXUP_HEADSET_MODE, |
4161 | ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC, | 4159 | ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC, |
4162 | }; | 4160 | }; |
4163 | 4161 | ||
4164 | static const struct hda_fixup alc269_fixups[] = { | 4162 | static const struct hda_fixup alc269_fixups[] = { |
4165 | [ALC269_FIXUP_SONY_VAIO] = { | 4163 | [ALC269_FIXUP_SONY_VAIO] = { |
4166 | .type = HDA_FIXUP_PINCTLS, | 4164 | .type = HDA_FIXUP_PINCTLS, |
4167 | .v.pins = (const struct hda_pintbl[]) { | 4165 | .v.pins = (const struct hda_pintbl[]) { |
4168 | {0x19, PIN_VREFGRD}, | 4166 | {0x19, PIN_VREFGRD}, |
4169 | {} | 4167 | {} |
4170 | } | 4168 | } |
4171 | }, | 4169 | }, |
4172 | [ALC275_FIXUP_SONY_VAIO_GPIO2] = { | 4170 | [ALC275_FIXUP_SONY_VAIO_GPIO2] = { |
4173 | .type = HDA_FIXUP_VERBS, | 4171 | .type = HDA_FIXUP_VERBS, |
4174 | .v.verbs = (const struct hda_verb[]) { | 4172 | .v.verbs = (const struct hda_verb[]) { |
4175 | {0x01, AC_VERB_SET_GPIO_MASK, 0x04}, | 4173 | {0x01, AC_VERB_SET_GPIO_MASK, 0x04}, |
4176 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04}, | 4174 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04}, |
4177 | {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, | 4175 | {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, |
4178 | { } | 4176 | { } |
4179 | }, | 4177 | }, |
4180 | .chained = true, | 4178 | .chained = true, |
4181 | .chain_id = ALC269_FIXUP_SONY_VAIO | 4179 | .chain_id = ALC269_FIXUP_SONY_VAIO |
4182 | }, | 4180 | }, |
4183 | [ALC269_FIXUP_DELL_M101Z] = { | 4181 | [ALC269_FIXUP_DELL_M101Z] = { |
4184 | .type = HDA_FIXUP_VERBS, | 4182 | .type = HDA_FIXUP_VERBS, |
4185 | .v.verbs = (const struct hda_verb[]) { | 4183 | .v.verbs = (const struct hda_verb[]) { |
4186 | /* Enables internal speaker */ | 4184 | /* Enables internal speaker */ |
4187 | {0x20, AC_VERB_SET_COEF_INDEX, 13}, | 4185 | {0x20, AC_VERB_SET_COEF_INDEX, 13}, |
4188 | {0x20, AC_VERB_SET_PROC_COEF, 0x4040}, | 4186 | {0x20, AC_VERB_SET_PROC_COEF, 0x4040}, |
4189 | {} | 4187 | {} |
4190 | } | 4188 | } |
4191 | }, | 4189 | }, |
4192 | [ALC269_FIXUP_SKU_IGNORE] = { | 4190 | [ALC269_FIXUP_SKU_IGNORE] = { |
4193 | .type = HDA_FIXUP_FUNC, | 4191 | .type = HDA_FIXUP_FUNC, |
4194 | .v.func = alc_fixup_sku_ignore, | 4192 | .v.func = alc_fixup_sku_ignore, |
4195 | }, | 4193 | }, |
4196 | [ALC269_FIXUP_ASUS_G73JW] = { | 4194 | [ALC269_FIXUP_ASUS_G73JW] = { |
4197 | .type = HDA_FIXUP_PINS, | 4195 | .type = HDA_FIXUP_PINS, |
4198 | .v.pins = (const struct hda_pintbl[]) { | 4196 | .v.pins = (const struct hda_pintbl[]) { |
4199 | { 0x17, 0x99130111 }, /* subwoofer */ | 4197 | { 0x17, 0x99130111 }, /* subwoofer */ |
4200 | { } | 4198 | { } |
4201 | } | 4199 | } |
4202 | }, | 4200 | }, |
4203 | [ALC269_FIXUP_LENOVO_EAPD] = { | 4201 | [ALC269_FIXUP_LENOVO_EAPD] = { |
4204 | .type = HDA_FIXUP_VERBS, | 4202 | .type = HDA_FIXUP_VERBS, |
4205 | .v.verbs = (const struct hda_verb[]) { | 4203 | .v.verbs = (const struct hda_verb[]) { |
4206 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, | 4204 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, |
4207 | {} | 4205 | {} |
4208 | } | 4206 | } |
4209 | }, | 4207 | }, |
4210 | [ALC275_FIXUP_SONY_HWEQ] = { | 4208 | [ALC275_FIXUP_SONY_HWEQ] = { |
4211 | .type = HDA_FIXUP_FUNC, | 4209 | .type = HDA_FIXUP_FUNC, |
4212 | .v.func = alc269_fixup_hweq, | 4210 | .v.func = alc269_fixup_hweq, |
4213 | .chained = true, | 4211 | .chained = true, |
4214 | .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2 | 4212 | .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2 |
4215 | }, | 4213 | }, |
4216 | [ALC271_FIXUP_DMIC] = { | 4214 | [ALC271_FIXUP_DMIC] = { |
4217 | .type = HDA_FIXUP_FUNC, | 4215 | .type = HDA_FIXUP_FUNC, |
4218 | .v.func = alc271_fixup_dmic, | 4216 | .v.func = alc271_fixup_dmic, |
4219 | }, | 4217 | }, |
4220 | [ALC269_FIXUP_PCM_44K] = { | 4218 | [ALC269_FIXUP_PCM_44K] = { |
4221 | .type = HDA_FIXUP_FUNC, | 4219 | .type = HDA_FIXUP_FUNC, |
4222 | .v.func = alc269_fixup_pcm_44k, | 4220 | .v.func = alc269_fixup_pcm_44k, |
4223 | .chained = true, | 4221 | .chained = true, |
4224 | .chain_id = ALC269_FIXUP_QUANTA_MUTE | 4222 | .chain_id = ALC269_FIXUP_QUANTA_MUTE |
4225 | }, | 4223 | }, |
4226 | [ALC269_FIXUP_STEREO_DMIC] = { | 4224 | [ALC269_FIXUP_STEREO_DMIC] = { |
4227 | .type = HDA_FIXUP_FUNC, | 4225 | .type = HDA_FIXUP_FUNC, |
4228 | .v.func = alc269_fixup_stereo_dmic, | 4226 | .v.func = alc269_fixup_stereo_dmic, |
4229 | }, | 4227 | }, |
4230 | [ALC269_FIXUP_HEADSET_MIC] = { | 4228 | [ALC269_FIXUP_HEADSET_MIC] = { |
4231 | .type = HDA_FIXUP_FUNC, | 4229 | .type = HDA_FIXUP_FUNC, |
4232 | .v.func = alc269_fixup_headset_mic, | 4230 | .v.func = alc269_fixup_headset_mic, |
4233 | }, | 4231 | }, |
4234 | [ALC269_FIXUP_QUANTA_MUTE] = { | 4232 | [ALC269_FIXUP_QUANTA_MUTE] = { |
4235 | .type = HDA_FIXUP_FUNC, | 4233 | .type = HDA_FIXUP_FUNC, |
4236 | .v.func = alc269_fixup_quanta_mute, | 4234 | .v.func = alc269_fixup_quanta_mute, |
4237 | }, | 4235 | }, |
4238 | [ALC269_FIXUP_LIFEBOOK] = { | 4236 | [ALC269_FIXUP_LIFEBOOK] = { |
4239 | .type = HDA_FIXUP_PINS, | 4237 | .type = HDA_FIXUP_PINS, |
4240 | .v.pins = (const struct hda_pintbl[]) { | 4238 | .v.pins = (const struct hda_pintbl[]) { |
4241 | { 0x1a, 0x2101103f }, /* dock line-out */ | 4239 | { 0x1a, 0x2101103f }, /* dock line-out */ |
4242 | { 0x1b, 0x23a11040 }, /* dock mic-in */ | 4240 | { 0x1b, 0x23a11040 }, /* dock mic-in */ |
4243 | { } | 4241 | { } |
4244 | }, | 4242 | }, |
4245 | .chained = true, | 4243 | .chained = true, |
4246 | .chain_id = ALC269_FIXUP_QUANTA_MUTE | 4244 | .chain_id = ALC269_FIXUP_QUANTA_MUTE |
4247 | }, | 4245 | }, |
4248 | [ALC269_FIXUP_AMIC] = { | 4246 | [ALC269_FIXUP_AMIC] = { |
4249 | .type = HDA_FIXUP_PINS, | 4247 | .type = HDA_FIXUP_PINS, |
4250 | .v.pins = (const struct hda_pintbl[]) { | 4248 | .v.pins = (const struct hda_pintbl[]) { |
4251 | { 0x14, 0x99130110 }, /* speaker */ | 4249 | { 0x14, 0x99130110 }, /* speaker */ |
4252 | { 0x15, 0x0121401f }, /* HP out */ | 4250 | { 0x15, 0x0121401f }, /* HP out */ |
4253 | { 0x18, 0x01a19c20 }, /* mic */ | 4251 | { 0x18, 0x01a19c20 }, /* mic */ |
4254 | { 0x19, 0x99a3092f }, /* int-mic */ | 4252 | { 0x19, 0x99a3092f }, /* int-mic */ |
4255 | { } | 4253 | { } |
4256 | }, | 4254 | }, |
4257 | }, | 4255 | }, |
4258 | [ALC269_FIXUP_DMIC] = { | 4256 | [ALC269_FIXUP_DMIC] = { |
4259 | .type = HDA_FIXUP_PINS, | 4257 | .type = HDA_FIXUP_PINS, |
4260 | .v.pins = (const struct hda_pintbl[]) { | 4258 | .v.pins = (const struct hda_pintbl[]) { |
4261 | { 0x12, 0x99a3092f }, /* int-mic */ | 4259 | { 0x12, 0x99a3092f }, /* int-mic */ |
4262 | { 0x14, 0x99130110 }, /* speaker */ | 4260 | { 0x14, 0x99130110 }, /* speaker */ |
4263 | { 0x15, 0x0121401f }, /* HP out */ | 4261 | { 0x15, 0x0121401f }, /* HP out */ |
4264 | { 0x18, 0x01a19c20 }, /* mic */ | 4262 | { 0x18, 0x01a19c20 }, /* mic */ |
4265 | { } | 4263 | { } |
4266 | }, | 4264 | }, |
4267 | }, | 4265 | }, |
4268 | [ALC269VB_FIXUP_AMIC] = { | 4266 | [ALC269VB_FIXUP_AMIC] = { |
4269 | .type = HDA_FIXUP_PINS, | 4267 | .type = HDA_FIXUP_PINS, |
4270 | .v.pins = (const struct hda_pintbl[]) { | 4268 | .v.pins = (const struct hda_pintbl[]) { |
4271 | { 0x14, 0x99130110 }, /* speaker */ | 4269 | { 0x14, 0x99130110 }, /* speaker */ |
4272 | { 0x18, 0x01a19c20 }, /* mic */ | 4270 | { 0x18, 0x01a19c20 }, /* mic */ |
4273 | { 0x19, 0x99a3092f }, /* int-mic */ | 4271 | { 0x19, 0x99a3092f }, /* int-mic */ |
4274 | { 0x21, 0x0121401f }, /* HP out */ | 4272 | { 0x21, 0x0121401f }, /* HP out */ |
4275 | { } | 4273 | { } |
4276 | }, | 4274 | }, |
4277 | }, | 4275 | }, |
4278 | [ALC269VB_FIXUP_DMIC] = { | 4276 | [ALC269VB_FIXUP_DMIC] = { |
4279 | .type = HDA_FIXUP_PINS, | 4277 | .type = HDA_FIXUP_PINS, |
4280 | .v.pins = (const struct hda_pintbl[]) { | 4278 | .v.pins = (const struct hda_pintbl[]) { |
4281 | { 0x12, 0x99a3092f }, /* int-mic */ | 4279 | { 0x12, 0x99a3092f }, /* int-mic */ |
4282 | { 0x14, 0x99130110 }, /* speaker */ | 4280 | { 0x14, 0x99130110 }, /* speaker */ |
4283 | { 0x18, 0x01a19c20 }, /* mic */ | 4281 | { 0x18, 0x01a19c20 }, /* mic */ |
4284 | { 0x21, 0x0121401f }, /* HP out */ | 4282 | { 0x21, 0x0121401f }, /* HP out */ |
4285 | { } | 4283 | { } |
4286 | }, | 4284 | }, |
4287 | }, | 4285 | }, |
4288 | [ALC269_FIXUP_HP_MUTE_LED] = { | 4286 | [ALC269_FIXUP_HP_MUTE_LED] = { |
4289 | .type = HDA_FIXUP_FUNC, | 4287 | .type = HDA_FIXUP_FUNC, |
4290 | .v.func = alc269_fixup_hp_mute_led, | 4288 | .v.func = alc269_fixup_hp_mute_led, |
4291 | }, | 4289 | }, |
4292 | [ALC269_FIXUP_HP_MUTE_LED_MIC1] = { | 4290 | [ALC269_FIXUP_HP_MUTE_LED_MIC1] = { |
4293 | .type = HDA_FIXUP_FUNC, | 4291 | .type = HDA_FIXUP_FUNC, |
4294 | .v.func = alc269_fixup_hp_mute_led_mic1, | 4292 | .v.func = alc269_fixup_hp_mute_led_mic1, |
4295 | }, | 4293 | }, |
4296 | [ALC269_FIXUP_HP_MUTE_LED_MIC2] = { | 4294 | [ALC269_FIXUP_HP_MUTE_LED_MIC2] = { |
4297 | .type = HDA_FIXUP_FUNC, | 4295 | .type = HDA_FIXUP_FUNC, |
4298 | .v.func = alc269_fixup_hp_mute_led_mic2, | 4296 | .v.func = alc269_fixup_hp_mute_led_mic2, |
4299 | }, | 4297 | }, |
4300 | [ALC269_FIXUP_HP_GPIO_LED] = { | 4298 | [ALC269_FIXUP_HP_GPIO_LED] = { |
4301 | .type = HDA_FIXUP_FUNC, | 4299 | .type = HDA_FIXUP_FUNC, |
4302 | .v.func = alc269_fixup_hp_gpio_led, | 4300 | .v.func = alc269_fixup_hp_gpio_led, |
4303 | }, | 4301 | }, |
4304 | [ALC269_FIXUP_INV_DMIC] = { | 4302 | [ALC269_FIXUP_INV_DMIC] = { |
4305 | .type = HDA_FIXUP_FUNC, | 4303 | .type = HDA_FIXUP_FUNC, |
4306 | .v.func = alc_fixup_inv_dmic_0x12, | 4304 | .v.func = alc_fixup_inv_dmic_0x12, |
4307 | }, | 4305 | }, |
4308 | [ALC269_FIXUP_NO_SHUTUP] = { | 4306 | [ALC269_FIXUP_NO_SHUTUP] = { |
4309 | .type = HDA_FIXUP_FUNC, | 4307 | .type = HDA_FIXUP_FUNC, |
4310 | .v.func = alc_fixup_no_shutup, | 4308 | .v.func = alc_fixup_no_shutup, |
4311 | }, | 4309 | }, |
4312 | [ALC269_FIXUP_LENOVO_DOCK] = { | 4310 | [ALC269_FIXUP_LENOVO_DOCK] = { |
4313 | .type = HDA_FIXUP_PINS, | 4311 | .type = HDA_FIXUP_PINS, |
4314 | .v.pins = (const struct hda_pintbl[]) { | 4312 | .v.pins = (const struct hda_pintbl[]) { |
4315 | { 0x19, 0x23a11040 }, /* dock mic */ | 4313 | { 0x19, 0x23a11040 }, /* dock mic */ |
4316 | { 0x1b, 0x2121103f }, /* dock headphone */ | 4314 | { 0x1b, 0x2121103f }, /* dock headphone */ |
4317 | { } | 4315 | { } |
4318 | }, | 4316 | }, |
4319 | .chained = true, | 4317 | .chained = true, |
4320 | .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT | 4318 | .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT |
4321 | }, | 4319 | }, |
4322 | [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = { | 4320 | [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = { |
4323 | .type = HDA_FIXUP_FUNC, | 4321 | .type = HDA_FIXUP_FUNC, |
4324 | .v.func = alc269_fixup_pincfg_no_hp_to_lineout, | 4322 | .v.func = alc269_fixup_pincfg_no_hp_to_lineout, |
4325 | .chained = true, | 4323 | .chained = true, |
4326 | .chain_id = ALC269_FIXUP_THINKPAD_ACPI, | 4324 | .chain_id = ALC269_FIXUP_THINKPAD_ACPI, |
4327 | }, | 4325 | }, |
4328 | [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = { | 4326 | [ALC269_FIXUP_DELL1_MIC_NO_PRESENCE] = { |
4329 | .type = HDA_FIXUP_PINS, | 4327 | .type = HDA_FIXUP_PINS, |
4330 | .v.pins = (const struct hda_pintbl[]) { | 4328 | .v.pins = (const struct hda_pintbl[]) { |
4331 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | 4329 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ |
4332 | { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ | 4330 | { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ |
4333 | { } | 4331 | { } |
4334 | }, | 4332 | }, |
4335 | .chained = true, | 4333 | .chained = true, |
4336 | .chain_id = ALC269_FIXUP_HEADSET_MODE | 4334 | .chain_id = ALC269_FIXUP_HEADSET_MODE |
4337 | }, | 4335 | }, |
4338 | [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = { | 4336 | [ALC269_FIXUP_DELL2_MIC_NO_PRESENCE] = { |
4339 | .type = HDA_FIXUP_PINS, | 4337 | .type = HDA_FIXUP_PINS, |
4340 | .v.pins = (const struct hda_pintbl[]) { | 4338 | .v.pins = (const struct hda_pintbl[]) { |
4341 | { 0x16, 0x21014020 }, /* dock line out */ | 4339 | { 0x16, 0x21014020 }, /* dock line out */ |
4342 | { 0x19, 0x21a19030 }, /* dock mic */ | 4340 | { 0x19, 0x21a19030 }, /* dock mic */ |
4343 | { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | 4341 | { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ |
4344 | { } | 4342 | { } |
4345 | }, | 4343 | }, |
4346 | .chained = true, | 4344 | .chained = true, |
4347 | .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC | 4345 | .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC |
4348 | }, | 4346 | }, |
4349 | [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = { | 4347 | [ALC269_FIXUP_DELL3_MIC_NO_PRESENCE] = { |
4350 | .type = HDA_FIXUP_PINS, | 4348 | .type = HDA_FIXUP_PINS, |
4351 | .v.pins = (const struct hda_pintbl[]) { | 4349 | .v.pins = (const struct hda_pintbl[]) { |
4352 | { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | 4350 | { 0x1a, 0x01a1913c }, /* use as headset mic, without its own jack detect */ |
4353 | { } | 4351 | { } |
4354 | }, | 4352 | }, |
4355 | .chained = true, | 4353 | .chained = true, |
4356 | .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC | 4354 | .chain_id = ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC |
4357 | }, | 4355 | }, |
4358 | [ALC269_FIXUP_HEADSET_MODE] = { | 4356 | [ALC269_FIXUP_HEADSET_MODE] = { |
4359 | .type = HDA_FIXUP_FUNC, | 4357 | .type = HDA_FIXUP_FUNC, |
4360 | .v.func = alc_fixup_headset_mode, | 4358 | .v.func = alc_fixup_headset_mode, |
4361 | }, | 4359 | }, |
4362 | [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = { | 4360 | [ALC269_FIXUP_HEADSET_MODE_NO_HP_MIC] = { |
4363 | .type = HDA_FIXUP_FUNC, | 4361 | .type = HDA_FIXUP_FUNC, |
4364 | .v.func = alc_fixup_headset_mode_no_hp_mic, | 4362 | .v.func = alc_fixup_headset_mode_no_hp_mic, |
4365 | }, | 4363 | }, |
4366 | [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = { | 4364 | [ALC286_FIXUP_SONY_MIC_NO_PRESENCE] = { |
4367 | .type = HDA_FIXUP_PINS, | 4365 | .type = HDA_FIXUP_PINS, |
4368 | .v.pins = (const struct hda_pintbl[]) { | 4366 | .v.pins = (const struct hda_pintbl[]) { |
4369 | { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | 4367 | { 0x18, 0x01a1913c }, /* use as headset mic, without its own jack detect */ |
4370 | { } | 4368 | { } |
4371 | }, | 4369 | }, |
4372 | .chained = true, | 4370 | .chained = true, |
4373 | .chain_id = ALC269_FIXUP_HEADSET_MIC | 4371 | .chain_id = ALC269_FIXUP_HEADSET_MIC |
4374 | }, | 4372 | }, |
4375 | [ALC269_FIXUP_ASUS_X101_FUNC] = { | 4373 | [ALC269_FIXUP_ASUS_X101_FUNC] = { |
4376 | .type = HDA_FIXUP_FUNC, | 4374 | .type = HDA_FIXUP_FUNC, |
4377 | .v.func = alc269_fixup_x101_headset_mic, | 4375 | .v.func = alc269_fixup_x101_headset_mic, |
4378 | }, | 4376 | }, |
4379 | [ALC269_FIXUP_ASUS_X101_VERB] = { | 4377 | [ALC269_FIXUP_ASUS_X101_VERB] = { |
4380 | .type = HDA_FIXUP_VERBS, | 4378 | .type = HDA_FIXUP_VERBS, |
4381 | .v.verbs = (const struct hda_verb[]) { | 4379 | .v.verbs = (const struct hda_verb[]) { |
4382 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | 4380 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, |
4383 | {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, | 4381 | {0x20, AC_VERB_SET_COEF_INDEX, 0x08}, |
4384 | {0x20, AC_VERB_SET_PROC_COEF, 0x0310}, | 4382 | {0x20, AC_VERB_SET_PROC_COEF, 0x0310}, |
4385 | { } | 4383 | { } |
4386 | }, | 4384 | }, |
4387 | .chained = true, | 4385 | .chained = true, |
4388 | .chain_id = ALC269_FIXUP_ASUS_X101_FUNC | 4386 | .chain_id = ALC269_FIXUP_ASUS_X101_FUNC |
4389 | }, | 4387 | }, |
4390 | [ALC269_FIXUP_ASUS_X101] = { | 4388 | [ALC269_FIXUP_ASUS_X101] = { |
4391 | .type = HDA_FIXUP_PINS, | 4389 | .type = HDA_FIXUP_PINS, |
4392 | .v.pins = (const struct hda_pintbl[]) { | 4390 | .v.pins = (const struct hda_pintbl[]) { |
4393 | { 0x18, 0x04a1182c }, /* Headset mic */ | 4391 | { 0x18, 0x04a1182c }, /* Headset mic */ |
4394 | { } | 4392 | { } |
4395 | }, | 4393 | }, |
4396 | .chained = true, | 4394 | .chained = true, |
4397 | .chain_id = ALC269_FIXUP_ASUS_X101_VERB | 4395 | .chain_id = ALC269_FIXUP_ASUS_X101_VERB |
4398 | }, | 4396 | }, |
4399 | [ALC271_FIXUP_AMIC_MIC2] = { | 4397 | [ALC271_FIXUP_AMIC_MIC2] = { |
4400 | .type = HDA_FIXUP_PINS, | 4398 | .type = HDA_FIXUP_PINS, |
4401 | .v.pins = (const struct hda_pintbl[]) { | 4399 | .v.pins = (const struct hda_pintbl[]) { |
4402 | { 0x14, 0x99130110 }, /* speaker */ | 4400 | { 0x14, 0x99130110 }, /* speaker */ |
4403 | { 0x19, 0x01a19c20 }, /* mic */ | 4401 | { 0x19, 0x01a19c20 }, /* mic */ |
4404 | { 0x1b, 0x99a7012f }, /* int-mic */ | 4402 | { 0x1b, 0x99a7012f }, /* int-mic */ |
4405 | { 0x21, 0x0121401f }, /* HP out */ | 4403 | { 0x21, 0x0121401f }, /* HP out */ |
4406 | { } | 4404 | { } |
4407 | }, | 4405 | }, |
4408 | }, | 4406 | }, |
4409 | [ALC271_FIXUP_HP_GATE_MIC_JACK] = { | 4407 | [ALC271_FIXUP_HP_GATE_MIC_JACK] = { |
4410 | .type = HDA_FIXUP_FUNC, | 4408 | .type = HDA_FIXUP_FUNC, |
4411 | .v.func = alc271_hp_gate_mic_jack, | 4409 | .v.func = alc271_hp_gate_mic_jack, |
4412 | .chained = true, | 4410 | .chained = true, |
4413 | .chain_id = ALC271_FIXUP_AMIC_MIC2, | 4411 | .chain_id = ALC271_FIXUP_AMIC_MIC2, |
4414 | }, | 4412 | }, |
4415 | [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = { | 4413 | [ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572] = { |
4416 | .type = HDA_FIXUP_FUNC, | 4414 | .type = HDA_FIXUP_FUNC, |
4417 | .v.func = alc269_fixup_limit_int_mic_boost, | 4415 | .v.func = alc269_fixup_limit_int_mic_boost, |
4418 | .chained = true, | 4416 | .chained = true, |
4419 | .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK, | 4417 | .chain_id = ALC271_FIXUP_HP_GATE_MIC_JACK, |
4420 | }, | 4418 | }, |
4421 | [ALC269_FIXUP_ACER_AC700] = { | 4419 | [ALC269_FIXUP_ACER_AC700] = { |
4422 | .type = HDA_FIXUP_PINS, | 4420 | .type = HDA_FIXUP_PINS, |
4423 | .v.pins = (const struct hda_pintbl[]) { | 4421 | .v.pins = (const struct hda_pintbl[]) { |
4424 | { 0x12, 0x99a3092f }, /* int-mic */ | 4422 | { 0x12, 0x99a3092f }, /* int-mic */ |
4425 | { 0x14, 0x99130110 }, /* speaker */ | 4423 | { 0x14, 0x99130110 }, /* speaker */ |
4426 | { 0x18, 0x03a11c20 }, /* mic */ | 4424 | { 0x18, 0x03a11c20 }, /* mic */ |
4427 | { 0x1e, 0x0346101e }, /* SPDIF1 */ | 4425 | { 0x1e, 0x0346101e }, /* SPDIF1 */ |
4428 | { 0x21, 0x0321101f }, /* HP out */ | 4426 | { 0x21, 0x0321101f }, /* HP out */ |
4429 | { } | 4427 | { } |
4430 | }, | 4428 | }, |
4431 | .chained = true, | 4429 | .chained = true, |
4432 | .chain_id = ALC271_FIXUP_DMIC, | 4430 | .chain_id = ALC271_FIXUP_DMIC, |
4433 | }, | 4431 | }, |
4434 | [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = { | 4432 | [ALC269_FIXUP_LIMIT_INT_MIC_BOOST] = { |
4435 | .type = HDA_FIXUP_FUNC, | 4433 | .type = HDA_FIXUP_FUNC, |
4436 | .v.func = alc269_fixup_limit_int_mic_boost, | 4434 | .v.func = alc269_fixup_limit_int_mic_boost, |
4437 | .chained = true, | 4435 | .chained = true, |
4438 | .chain_id = ALC269_FIXUP_THINKPAD_ACPI, | 4436 | .chain_id = ALC269_FIXUP_THINKPAD_ACPI, |
4439 | }, | 4437 | }, |
4440 | [ALC269VB_FIXUP_ASUS_ZENBOOK] = { | 4438 | [ALC269VB_FIXUP_ASUS_ZENBOOK] = { |
4441 | .type = HDA_FIXUP_FUNC, | 4439 | .type = HDA_FIXUP_FUNC, |
4442 | .v.func = alc269_fixup_limit_int_mic_boost, | 4440 | .v.func = alc269_fixup_limit_int_mic_boost, |
4443 | .chained = true, | 4441 | .chained = true, |
4444 | .chain_id = ALC269VB_FIXUP_DMIC, | 4442 | .chain_id = ALC269VB_FIXUP_DMIC, |
4445 | }, | 4443 | }, |
4446 | [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = { | 4444 | [ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A] = { |
4447 | .type = HDA_FIXUP_VERBS, | 4445 | .type = HDA_FIXUP_VERBS, |
4448 | .v.verbs = (const struct hda_verb[]) { | 4446 | .v.verbs = (const struct hda_verb[]) { |
4449 | /* class-D output amp +5dB */ | 4447 | /* class-D output amp +5dB */ |
4450 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 }, | 4448 | { 0x20, AC_VERB_SET_COEF_INDEX, 0x12 }, |
4451 | { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 }, | 4449 | { 0x20, AC_VERB_SET_PROC_COEF, 0x2800 }, |
4452 | {} | 4450 | {} |
4453 | }, | 4451 | }, |
4454 | .chained = true, | 4452 | .chained = true, |
4455 | .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK, | 4453 | .chain_id = ALC269VB_FIXUP_ASUS_ZENBOOK, |
4456 | }, | 4454 | }, |
4457 | [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = { | 4455 | [ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED] = { |
4458 | .type = HDA_FIXUP_FUNC, | 4456 | .type = HDA_FIXUP_FUNC, |
4459 | .v.func = alc269_fixup_limit_int_mic_boost, | 4457 | .v.func = alc269_fixup_limit_int_mic_boost, |
4460 | .chained = true, | 4458 | .chained = true, |
4461 | .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1, | 4459 | .chain_id = ALC269_FIXUP_HP_MUTE_LED_MIC1, |
4462 | }, | 4460 | }, |
4463 | [ALC269VB_FIXUP_ORDISSIMO_EVE2] = { | 4461 | [ALC269VB_FIXUP_ORDISSIMO_EVE2] = { |
4464 | .type = HDA_FIXUP_PINS, | 4462 | .type = HDA_FIXUP_PINS, |
4465 | .v.pins = (const struct hda_pintbl[]) { | 4463 | .v.pins = (const struct hda_pintbl[]) { |
4466 | { 0x12, 0x99a3092f }, /* int-mic */ | 4464 | { 0x12, 0x99a3092f }, /* int-mic */ |
4467 | { 0x18, 0x03a11d20 }, /* mic */ | 4465 | { 0x18, 0x03a11d20 }, /* mic */ |
4468 | { 0x19, 0x411111f0 }, /* Unused bogus pin */ | 4466 | { 0x19, 0x411111f0 }, /* Unused bogus pin */ |
4469 | { } | 4467 | { } |
4470 | }, | 4468 | }, |
4471 | }, | 4469 | }, |
4472 | [ALC283_FIXUP_CHROME_BOOK] = { | 4470 | [ALC283_FIXUP_CHROME_BOOK] = { |
4473 | .type = HDA_FIXUP_FUNC, | 4471 | .type = HDA_FIXUP_FUNC, |
4474 | .v.func = alc283_fixup_chromebook, | 4472 | .v.func = alc283_fixup_chromebook, |
4475 | }, | 4473 | }, |
4476 | [ALC283_FIXUP_SENSE_COMBO_JACK] = { | 4474 | [ALC283_FIXUP_SENSE_COMBO_JACK] = { |
4477 | .type = HDA_FIXUP_FUNC, | 4475 | .type = HDA_FIXUP_FUNC, |
4478 | .v.func = alc283_fixup_sense_combo_jack, | 4476 | .v.func = alc283_fixup_sense_combo_jack, |
4479 | .chained = true, | 4477 | .chained = true, |
4480 | .chain_id = ALC283_FIXUP_CHROME_BOOK, | 4478 | .chain_id = ALC283_FIXUP_CHROME_BOOK, |
4481 | }, | 4479 | }, |
4482 | [ALC282_FIXUP_ASUS_TX300] = { | 4480 | [ALC282_FIXUP_ASUS_TX300] = { |
4483 | .type = HDA_FIXUP_FUNC, | 4481 | .type = HDA_FIXUP_FUNC, |
4484 | .v.func = alc282_fixup_asus_tx300, | 4482 | .v.func = alc282_fixup_asus_tx300, |
4485 | }, | 4483 | }, |
4486 | [ALC283_FIXUP_INT_MIC] = { | 4484 | [ALC283_FIXUP_INT_MIC] = { |
4487 | .type = HDA_FIXUP_VERBS, | 4485 | .type = HDA_FIXUP_VERBS, |
4488 | .v.verbs = (const struct hda_verb[]) { | 4486 | .v.verbs = (const struct hda_verb[]) { |
4489 | {0x20, AC_VERB_SET_COEF_INDEX, 0x1a}, | 4487 | {0x20, AC_VERB_SET_COEF_INDEX, 0x1a}, |
4490 | {0x20, AC_VERB_SET_PROC_COEF, 0x0011}, | 4488 | {0x20, AC_VERB_SET_PROC_COEF, 0x0011}, |
4491 | { } | 4489 | { } |
4492 | }, | 4490 | }, |
4493 | .chained = true, | 4491 | .chained = true, |
4494 | .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST | 4492 | .chain_id = ALC269_FIXUP_LIMIT_INT_MIC_BOOST |
4495 | }, | 4493 | }, |
4496 | [ALC290_FIXUP_SUBWOOFER_HSJACK] = { | 4494 | [ALC290_FIXUP_SUBWOOFER_HSJACK] = { |
4497 | .type = HDA_FIXUP_PINS, | 4495 | .type = HDA_FIXUP_PINS, |
4498 | .v.pins = (const struct hda_pintbl[]) { | 4496 | .v.pins = (const struct hda_pintbl[]) { |
4499 | { 0x17, 0x90170112 }, /* subwoofer */ | 4497 | { 0x17, 0x90170112 }, /* subwoofer */ |
4500 | { } | 4498 | { } |
4501 | }, | 4499 | }, |
4502 | .chained = true, | 4500 | .chained = true, |
4503 | .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK, | 4501 | .chain_id = ALC290_FIXUP_MONO_SPEAKERS_HSJACK, |
4504 | }, | 4502 | }, |
4505 | [ALC290_FIXUP_SUBWOOFER] = { | 4503 | [ALC290_FIXUP_SUBWOOFER] = { |
4506 | .type = HDA_FIXUP_PINS, | 4504 | .type = HDA_FIXUP_PINS, |
4507 | .v.pins = (const struct hda_pintbl[]) { | 4505 | .v.pins = (const struct hda_pintbl[]) { |
4508 | { 0x17, 0x90170112 }, /* subwoofer */ | 4506 | { 0x17, 0x90170112 }, /* subwoofer */ |
4509 | { } | 4507 | { } |
4510 | }, | 4508 | }, |
4511 | .chained = true, | 4509 | .chained = true, |
4512 | .chain_id = ALC290_FIXUP_MONO_SPEAKERS, | 4510 | .chain_id = ALC290_FIXUP_MONO_SPEAKERS, |
4513 | }, | 4511 | }, |
4514 | [ALC290_FIXUP_MONO_SPEAKERS] = { | 4512 | [ALC290_FIXUP_MONO_SPEAKERS] = { |
4515 | .type = HDA_FIXUP_FUNC, | 4513 | .type = HDA_FIXUP_FUNC, |
4516 | .v.func = alc290_fixup_mono_speakers, | 4514 | .v.func = alc290_fixup_mono_speakers, |
4517 | }, | 4515 | }, |
4518 | [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = { | 4516 | [ALC290_FIXUP_MONO_SPEAKERS_HSJACK] = { |
4519 | .type = HDA_FIXUP_FUNC, | 4517 | .type = HDA_FIXUP_FUNC, |
4520 | .v.func = alc290_fixup_mono_speakers, | 4518 | .v.func = alc290_fixup_mono_speakers, |
4521 | .chained = true, | 4519 | .chained = true, |
4522 | .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, | 4520 | .chain_id = ALC269_FIXUP_DELL3_MIC_NO_PRESENCE, |
4523 | }, | 4521 | }, |
4524 | [ALC269_FIXUP_THINKPAD_ACPI] = { | 4522 | [ALC269_FIXUP_THINKPAD_ACPI] = { |
4525 | .type = HDA_FIXUP_FUNC, | 4523 | .type = HDA_FIXUP_FUNC, |
4526 | .v.func = hda_fixup_thinkpad_acpi, | 4524 | .v.func = hda_fixup_thinkpad_acpi, |
4527 | }, | 4525 | }, |
4528 | [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = { | 4526 | [ALC255_FIXUP_DELL1_MIC_NO_PRESENCE] = { |
4529 | .type = HDA_FIXUP_PINS, | 4527 | .type = HDA_FIXUP_PINS, |
4530 | .v.pins = (const struct hda_pintbl[]) { | 4528 | .v.pins = (const struct hda_pintbl[]) { |
4531 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | 4529 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ |
4532 | { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ | 4530 | { 0x1a, 0x01a1913d }, /* use as headphone mic, without its own jack detect */ |
4533 | { } | 4531 | { } |
4534 | }, | 4532 | }, |
4535 | .chained = true, | 4533 | .chained = true, |
4536 | .chain_id = ALC255_FIXUP_HEADSET_MODE | 4534 | .chain_id = ALC255_FIXUP_HEADSET_MODE |
4537 | }, | 4535 | }, |
4538 | [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = { | 4536 | [ALC255_FIXUP_DELL2_MIC_NO_PRESENCE] = { |
4539 | .type = HDA_FIXUP_PINS, | 4537 | .type = HDA_FIXUP_PINS, |
4540 | .v.pins = (const struct hda_pintbl[]) { | 4538 | .v.pins = (const struct hda_pintbl[]) { |
4541 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ | 4539 | { 0x19, 0x01a1913c }, /* use as headset mic, without its own jack detect */ |
4542 | { } | 4540 | { } |
4543 | }, | 4541 | }, |
4544 | .chained = true, | 4542 | .chained = true, |
4545 | .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC | 4543 | .chain_id = ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC |
4546 | }, | 4544 | }, |
4547 | [ALC255_FIXUP_HEADSET_MODE] = { | 4545 | [ALC255_FIXUP_HEADSET_MODE] = { |
4548 | .type = HDA_FIXUP_FUNC, | 4546 | .type = HDA_FIXUP_FUNC, |
4549 | .v.func = alc_fixup_headset_mode_alc255, | 4547 | .v.func = alc_fixup_headset_mode_alc255, |
4550 | }, | 4548 | }, |
4551 | [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = { | 4549 | [ALC255_FIXUP_HEADSET_MODE_NO_HP_MIC] = { |
4552 | .type = HDA_FIXUP_FUNC, | 4550 | .type = HDA_FIXUP_FUNC, |
4553 | .v.func = alc_fixup_headset_mode_alc255_no_hp_mic, | 4551 | .v.func = alc_fixup_headset_mode_alc255_no_hp_mic, |
4554 | }, | 4552 | }, |
4555 | }; | 4553 | }; |
4556 | 4554 | ||
4557 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { | 4555 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
4558 | SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC), | 4556 | SND_PCI_QUIRK(0x1025, 0x0283, "Acer TravelMate 8371", ALC269_FIXUP_INV_DMIC), |
4559 | SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), | 4557 | SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), |
4560 | SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), | 4558 | SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), |
4561 | SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700), | 4559 | SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700), |
4562 | SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK), | 4560 | SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK), |
4563 | SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK), | 4561 | SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK), |
4564 | SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), | 4562 | SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), |
4565 | SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572), | 4563 | SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572), |
4566 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), | 4564 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), |
4567 | SND_PCI_QUIRK(0x1028, 0x05bd, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4565 | SND_PCI_QUIRK(0x1028, 0x05bd, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4568 | SND_PCI_QUIRK(0x1028, 0x05be, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4566 | SND_PCI_QUIRK(0x1028, 0x05be, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4569 | SND_PCI_QUIRK(0x1028, 0x05c4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4567 | SND_PCI_QUIRK(0x1028, 0x05c4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4570 | SND_PCI_QUIRK(0x1028, 0x05c5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4568 | SND_PCI_QUIRK(0x1028, 0x05c5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4571 | SND_PCI_QUIRK(0x1028, 0x05c6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4569 | SND_PCI_QUIRK(0x1028, 0x05c6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4572 | SND_PCI_QUIRK(0x1028, 0x05c7, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4570 | SND_PCI_QUIRK(0x1028, 0x05c7, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4573 | SND_PCI_QUIRK(0x1028, 0x05c8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4571 | SND_PCI_QUIRK(0x1028, 0x05c8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4574 | SND_PCI_QUIRK(0x1028, 0x05c9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4572 | SND_PCI_QUIRK(0x1028, 0x05c9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4575 | SND_PCI_QUIRK(0x1028, 0x05ca, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4573 | SND_PCI_QUIRK(0x1028, 0x05ca, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4576 | SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4574 | SND_PCI_QUIRK(0x1028, 0x05cb, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4577 | SND_PCI_QUIRK(0x1028, 0x05cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4575 | SND_PCI_QUIRK(0x1028, 0x05cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4578 | SND_PCI_QUIRK(0x1028, 0x05cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4576 | SND_PCI_QUIRK(0x1028, 0x05cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4579 | SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER), | 4577 | SND_PCI_QUIRK(0x1028, 0x05da, "Dell Vostro 5460", ALC290_FIXUP_SUBWOOFER), |
4580 | SND_PCI_QUIRK(0x1028, 0x05de, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4578 | SND_PCI_QUIRK(0x1028, 0x05de, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4581 | SND_PCI_QUIRK(0x1028, 0x05e0, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4579 | SND_PCI_QUIRK(0x1028, 0x05e0, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4582 | SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4580 | SND_PCI_QUIRK(0x1028, 0x05e9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4583 | SND_PCI_QUIRK(0x1028, 0x05ea, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4581 | SND_PCI_QUIRK(0x1028, 0x05ea, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4584 | SND_PCI_QUIRK(0x1028, 0x05eb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4582 | SND_PCI_QUIRK(0x1028, 0x05eb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4585 | SND_PCI_QUIRK(0x1028, 0x05ec, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4583 | SND_PCI_QUIRK(0x1028, 0x05ec, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4586 | SND_PCI_QUIRK(0x1028, 0x05ed, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4584 | SND_PCI_QUIRK(0x1028, 0x05ed, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4587 | SND_PCI_QUIRK(0x1028, 0x05ee, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4585 | SND_PCI_QUIRK(0x1028, 0x05ee, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4588 | SND_PCI_QUIRK(0x1028, 0x05f3, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4586 | SND_PCI_QUIRK(0x1028, 0x05f3, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4589 | SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4587 | SND_PCI_QUIRK(0x1028, 0x05f4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4590 | SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4588 | SND_PCI_QUIRK(0x1028, 0x05f5, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4591 | SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4589 | SND_PCI_QUIRK(0x1028, 0x05f6, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4592 | SND_PCI_QUIRK(0x1028, 0x05f8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4590 | SND_PCI_QUIRK(0x1028, 0x05f8, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4593 | SND_PCI_QUIRK(0x1028, 0x05f9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4591 | SND_PCI_QUIRK(0x1028, 0x05f9, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4594 | SND_PCI_QUIRK(0x1028, 0x05fb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4592 | SND_PCI_QUIRK(0x1028, 0x05fb, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4595 | SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4593 | SND_PCI_QUIRK(0x1028, 0x0606, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4596 | SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4594 | SND_PCI_QUIRK(0x1028, 0x0608, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4597 | SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4595 | SND_PCI_QUIRK(0x1028, 0x0609, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4598 | SND_PCI_QUIRK(0x1028, 0x060f, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE), | 4596 | SND_PCI_QUIRK(0x1028, 0x060f, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE), |
4599 | SND_PCI_QUIRK(0x1028, 0x0610, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE), | 4597 | SND_PCI_QUIRK(0x1028, 0x0610, "Dell", ALC269_FIXUP_DELL3_MIC_NO_PRESENCE), |
4600 | SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4598 | SND_PCI_QUIRK(0x1028, 0x0613, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4601 | SND_PCI_QUIRK(0x1028, 0x0614, "Dell Inspiron 3135", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4599 | SND_PCI_QUIRK(0x1028, 0x0614, "Dell Inspiron 3135", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4602 | SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), | 4600 | SND_PCI_QUIRK(0x1028, 0x0615, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), |
4603 | SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), | 4601 | SND_PCI_QUIRK(0x1028, 0x0616, "Dell Vostro 5470", ALC290_FIXUP_SUBWOOFER_HSJACK), |
4604 | SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4602 | SND_PCI_QUIRK(0x1028, 0x061f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4605 | SND_PCI_QUIRK(0x1028, 0x0629, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4603 | SND_PCI_QUIRK(0x1028, 0x0629, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4606 | SND_PCI_QUIRK(0x1028, 0x062c, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4604 | SND_PCI_QUIRK(0x1028, 0x062c, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4607 | SND_PCI_QUIRK(0x1028, 0x062e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4605 | SND_PCI_QUIRK(0x1028, 0x062e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4608 | SND_PCI_QUIRK(0x1028, 0x0632, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4606 | SND_PCI_QUIRK(0x1028, 0x0632, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4609 | SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK), | 4607 | SND_PCI_QUIRK(0x1028, 0x0638, "Dell Inspiron 5439", ALC290_FIXUP_MONO_SPEAKERS_HSJACK), |
4610 | SND_PCI_QUIRK(0x1028, 0x063e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4608 | SND_PCI_QUIRK(0x1028, 0x063e, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4611 | SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4609 | SND_PCI_QUIRK(0x1028, 0x063f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4612 | SND_PCI_QUIRK(0x1028, 0x0640, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4610 | SND_PCI_QUIRK(0x1028, 0x0640, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4613 | SND_PCI_QUIRK(0x1028, 0x064d, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4611 | SND_PCI_QUIRK(0x1028, 0x064d, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4614 | SND_PCI_QUIRK(0x1028, 0x0651, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4612 | SND_PCI_QUIRK(0x1028, 0x0651, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4615 | SND_PCI_QUIRK(0x1028, 0x0652, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4613 | SND_PCI_QUIRK(0x1028, 0x0652, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4616 | SND_PCI_QUIRK(0x1028, 0x0653, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4614 | SND_PCI_QUIRK(0x1028, 0x0653, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4617 | SND_PCI_QUIRK(0x1028, 0x0657, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4615 | SND_PCI_QUIRK(0x1028, 0x0657, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4618 | SND_PCI_QUIRK(0x1028, 0x0658, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4616 | SND_PCI_QUIRK(0x1028, 0x0658, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4619 | SND_PCI_QUIRK(0x1028, 0x065c, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4617 | SND_PCI_QUIRK(0x1028, 0x065c, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4620 | SND_PCI_QUIRK(0x1028, 0x065f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4618 | SND_PCI_QUIRK(0x1028, 0x065f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4621 | SND_PCI_QUIRK(0x1028, 0x0662, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4619 | SND_PCI_QUIRK(0x1028, 0x0662, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4622 | SND_PCI_QUIRK(0x1028, 0x0667, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), | 4620 | SND_PCI_QUIRK(0x1028, 0x0667, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), |
4623 | SND_PCI_QUIRK(0x1028, 0x0668, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), | 4621 | SND_PCI_QUIRK(0x1028, 0x0668, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), |
4624 | SND_PCI_QUIRK(0x1028, 0x0669, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), | 4622 | SND_PCI_QUIRK(0x1028, 0x0669, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), |
4625 | SND_PCI_QUIRK(0x1028, 0x0674, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4623 | SND_PCI_QUIRK(0x1028, 0x0674, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4626 | SND_PCI_QUIRK(0x1028, 0x067e, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4624 | SND_PCI_QUIRK(0x1028, 0x067e, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4627 | SND_PCI_QUIRK(0x1028, 0x067f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4625 | SND_PCI_QUIRK(0x1028, 0x067f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4628 | SND_PCI_QUIRK(0x1028, 0x0680, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4626 | SND_PCI_QUIRK(0x1028, 0x0680, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4629 | SND_PCI_QUIRK(0x1028, 0x0684, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4627 | SND_PCI_QUIRK(0x1028, 0x0684, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4630 | SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4628 | SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4631 | SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4629 | SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4632 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), | 4630 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2), |
4633 | SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), | 4631 | SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), |
4634 | SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4632 | SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4635 | SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4633 | SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4636 | SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED), | 4634 | SND_PCI_QUIRK(0x103c, 0x218b, "HP", ALC269_FIXUP_LIMIT_INT_MIC_BOOST_MUTE_LED), |
4637 | /* ALC282 */ | 4635 | /* ALC282 */ |
4638 | SND_PCI_QUIRK(0x103c, 0x220f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4636 | SND_PCI_QUIRK(0x103c, 0x220f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4639 | SND_PCI_QUIRK(0x103c, 0x2213, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4637 | SND_PCI_QUIRK(0x103c, 0x2213, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4640 | SND_PCI_QUIRK(0x103c, 0x2266, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4638 | SND_PCI_QUIRK(0x103c, 0x2266, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4641 | SND_PCI_QUIRK(0x103c, 0x2267, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4639 | SND_PCI_QUIRK(0x103c, 0x2267, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4642 | SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4640 | SND_PCI_QUIRK(0x103c, 0x2268, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4643 | SND_PCI_QUIRK(0x103c, 0x2269, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4641 | SND_PCI_QUIRK(0x103c, 0x2269, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4644 | SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4642 | SND_PCI_QUIRK(0x103c, 0x226a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4645 | SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4643 | SND_PCI_QUIRK(0x103c, 0x226b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4646 | SND_PCI_QUIRK(0x103c, 0x227a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4644 | SND_PCI_QUIRK(0x103c, 0x227a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4647 | SND_PCI_QUIRK(0x103c, 0x227b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4645 | SND_PCI_QUIRK(0x103c, 0x227b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4648 | SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4646 | SND_PCI_QUIRK(0x103c, 0x229e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4649 | SND_PCI_QUIRK(0x103c, 0x22a0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4647 | SND_PCI_QUIRK(0x103c, 0x22a0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4650 | SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4648 | SND_PCI_QUIRK(0x103c, 0x22b2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4651 | SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4649 | SND_PCI_QUIRK(0x103c, 0x22b7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4652 | SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4650 | SND_PCI_QUIRK(0x103c, 0x22bf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4653 | SND_PCI_QUIRK(0x103c, 0x22c0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4651 | SND_PCI_QUIRK(0x103c, 0x22c0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4654 | SND_PCI_QUIRK(0x103c, 0x22c1, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4652 | SND_PCI_QUIRK(0x103c, 0x22c1, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4655 | SND_PCI_QUIRK(0x103c, 0x22c2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4653 | SND_PCI_QUIRK(0x103c, 0x22c2, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4656 | SND_PCI_QUIRK(0x103c, 0x22cd, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4654 | SND_PCI_QUIRK(0x103c, 0x22cd, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4657 | SND_PCI_QUIRK(0x103c, 0x22ce, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4655 | SND_PCI_QUIRK(0x103c, 0x22ce, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4658 | SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4656 | SND_PCI_QUIRK(0x103c, 0x22cf, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4659 | SND_PCI_QUIRK(0x103c, 0x22d0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4657 | SND_PCI_QUIRK(0x103c, 0x22d0, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4660 | /* ALC290 */ | 4658 | /* ALC290 */ |
4661 | SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4659 | SND_PCI_QUIRK(0x103c, 0x2260, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4662 | SND_PCI_QUIRK(0x103c, 0x2261, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4660 | SND_PCI_QUIRK(0x103c, 0x2261, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4663 | SND_PCI_QUIRK(0x103c, 0x2262, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4661 | SND_PCI_QUIRK(0x103c, 0x2262, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4664 | SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4662 | SND_PCI_QUIRK(0x103c, 0x2263, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4665 | SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4663 | SND_PCI_QUIRK(0x103c, 0x2264, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4666 | SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4664 | SND_PCI_QUIRK(0x103c, 0x2265, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4667 | SND_PCI_QUIRK(0x103c, 0x227d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4665 | SND_PCI_QUIRK(0x103c, 0x227d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4668 | SND_PCI_QUIRK(0x103c, 0x227e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4666 | SND_PCI_QUIRK(0x103c, 0x227e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4669 | SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4667 | SND_PCI_QUIRK(0x103c, 0x227f, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4670 | SND_PCI_QUIRK(0x103c, 0x2280, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4668 | SND_PCI_QUIRK(0x103c, 0x2280, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4671 | SND_PCI_QUIRK(0x103c, 0x2281, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4669 | SND_PCI_QUIRK(0x103c, 0x2281, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4672 | SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4670 | SND_PCI_QUIRK(0x103c, 0x2282, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4673 | SND_PCI_QUIRK(0x103c, 0x2289, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4671 | SND_PCI_QUIRK(0x103c, 0x2289, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4674 | SND_PCI_QUIRK(0x103c, 0x228a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4672 | SND_PCI_QUIRK(0x103c, 0x228a, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4675 | SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4673 | SND_PCI_QUIRK(0x103c, 0x228b, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4676 | SND_PCI_QUIRK(0x103c, 0x228c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4674 | SND_PCI_QUIRK(0x103c, 0x228c, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4677 | SND_PCI_QUIRK(0x103c, 0x228d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4675 | SND_PCI_QUIRK(0x103c, 0x228d, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4678 | SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4676 | SND_PCI_QUIRK(0x103c, 0x228e, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4679 | SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4677 | SND_PCI_QUIRK(0x103c, 0x22c5, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4680 | SND_PCI_QUIRK(0x103c, 0x22c6, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4678 | SND_PCI_QUIRK(0x103c, 0x22c6, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4681 | SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4679 | SND_PCI_QUIRK(0x103c, 0x22c7, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4682 | SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4680 | SND_PCI_QUIRK(0x103c, 0x22c8, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4683 | SND_PCI_QUIRK(0x103c, 0x22c3, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4681 | SND_PCI_QUIRK(0x103c, 0x22c3, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4684 | SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), | 4682 | SND_PCI_QUIRK(0x103c, 0x22c4, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC1), |
4685 | SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), | 4683 | SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), |
4686 | SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), | 4684 | SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), |
4687 | SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4685 | SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4688 | SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4686 | SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4689 | SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), | 4687 | SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_ASUS_ZENBOOK), |
4690 | SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), | 4688 | SND_PCI_QUIRK(0x1043, 0x1517, "Asus Zenbook UX31A", ALC269VB_FIXUP_ASUS_ZENBOOK_UX31A), |
4691 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), | 4689 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), |
4692 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), | 4690 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), |
4693 | SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), | 4691 | SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), |
4694 | SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4692 | SND_PCI_QUIRK(0x1043, 0x1c23, "Asus X55U", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4695 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), | 4693 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), |
4696 | SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), | 4694 | SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), |
4697 | SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), | 4695 | SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), |
4698 | SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), | 4696 | SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005", ALC269_FIXUP_STEREO_DMIC), |
4699 | SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101), | 4697 | SND_PCI_QUIRK(0x1043, 0x8516, "ASUS X101CH", ALC269_FIXUP_ASUS_X101), |
4700 | SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), | 4698 | SND_PCI_QUIRK(0x104d, 0x90b5, "Sony VAIO Pro 11", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), |
4701 | SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), | 4699 | SND_PCI_QUIRK(0x104d, 0x90b6, "Sony VAIO Pro 13", ALC286_FIXUP_SONY_MIC_NO_PRESENCE), |
4702 | SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), | 4700 | SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), |
4703 | SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), | 4701 | SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), |
4704 | SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), | 4702 | SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), |
4705 | SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), | 4703 | SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), |
4706 | SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK), | 4704 | SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK), |
4707 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), | 4705 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), |
4708 | SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), | 4706 | SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), |
4709 | SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), | 4707 | SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), |
4710 | SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), | 4708 | SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), |
4711 | SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), | 4709 | SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), |
4712 | SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK), | 4710 | SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK), |
4713 | SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK), | 4711 | SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK), |
4714 | SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK), | 4712 | SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK), |
4715 | SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), | 4713 | SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), |
4716 | SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), | 4714 | SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), |
4717 | SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK), | 4715 | SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK), |
4718 | SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4716 | SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4719 | SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4717 | SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4720 | SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4718 | SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4721 | SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4719 | SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4722 | SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP), | 4720 | SND_PCI_QUIRK(0x17aa, 0x3978, "IdeaPad Y410P", ALC269_FIXUP_NO_SHUTUP), |
4723 | SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4721 | SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4724 | SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC), | 4722 | SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC283_FIXUP_INT_MIC), |
4725 | SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4723 | SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4726 | SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), | 4724 | SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), |
4727 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), | 4725 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), |
4728 | SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), | 4726 | SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), |
4729 | SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI), | 4727 | SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad", ALC269_FIXUP_THINKPAD_ACPI), |
4730 | SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */ | 4728 | SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */ |
4731 | 4729 | ||
4732 | #if 0 | 4730 | #if 0 |
4733 | /* Below is a quirk table taken from the old code. | 4731 | /* Below is a quirk table taken from the old code. |
4734 | * Basically the device should work as is without the fixup table. | 4732 | * Basically the device should work as is without the fixup table. |
4735 | * If BIOS doesn't give a proper info, enable the corresponding | 4733 | * If BIOS doesn't give a proper info, enable the corresponding |
4736 | * fixup entry. | 4734 | * fixup entry. |
4737 | */ | 4735 | */ |
4738 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", | 4736 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", |
4739 | ALC269_FIXUP_AMIC), | 4737 | ALC269_FIXUP_AMIC), |
4740 | SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC), | 4738 | SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269_FIXUP_AMIC), |
4741 | SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC), | 4739 | SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269_FIXUP_AMIC), |
4742 | SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC), | 4740 | SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_FIXUP_AMIC), |
4743 | SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC), | 4741 | SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269_FIXUP_AMIC), |
4744 | SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC), | 4742 | SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269_FIXUP_AMIC), |
4745 | SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC), | 4743 | SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269_FIXUP_AMIC), |
4746 | SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC), | 4744 | SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269_FIXUP_AMIC), |
4747 | SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC), | 4745 | SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_FIXUP_AMIC), |
4748 | SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC), | 4746 | SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269_FIXUP_AMIC), |
4749 | SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC), | 4747 | SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_FIXUP_AMIC), |
4750 | SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC), | 4748 | SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_FIXUP_AMIC), |
4751 | SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC), | 4749 | SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_FIXUP_AMIC), |
4752 | SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC), | 4750 | SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_FIXUP_AMIC), |
4753 | SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC), | 4751 | SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_FIXUP_AMIC), |
4754 | SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC), | 4752 | SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_FIXUP_AMIC), |
4755 | SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC), | 4753 | SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_FIXUP_AMIC), |
4756 | SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC), | 4754 | SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_FIXUP_AMIC), |
4757 | SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC), | 4755 | SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_FIXUP_AMIC), |
4758 | SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC), | 4756 | SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_FIXUP_AMIC), |
4759 | SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC), | 4757 | SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_FIXUP_AMIC), |
4760 | SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC), | 4758 | SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_FIXUP_AMIC), |
4761 | SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC), | 4759 | SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_FIXUP_AMIC), |
4762 | SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC), | 4760 | SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_FIXUP_AMIC), |
4763 | SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC), | 4761 | SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_FIXUP_AMIC), |
4764 | SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC), | 4762 | SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_FIXUP_AMIC), |
4765 | SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC), | 4763 | SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_FIXUP_AMIC), |
4766 | SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC), | 4764 | SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_FIXUP_AMIC), |
4767 | SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC), | 4765 | SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_FIXUP_AMIC), |
4768 | SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC), | 4766 | SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_FIXUP_AMIC), |
4769 | SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC), | 4767 | SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_FIXUP_AMIC), |
4770 | SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC), | 4768 | SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_FIXUP_AMIC), |
4771 | SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC), | 4769 | SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_FIXUP_AMIC), |
4772 | SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC), | 4770 | SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_FIXUP_AMIC), |
4773 | SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC), | 4771 | SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_FIXUP_AMIC), |
4774 | SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC), | 4772 | SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_FIXUP_DMIC), |
4775 | SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC), | 4773 | SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_FIXUP_AMIC), |
4776 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC), | 4774 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_AMIC), |
4777 | SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC), | 4775 | SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_FIXUP_DMIC), |
4778 | SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC), | 4776 | SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_FIXUP_DMIC), |
4779 | #endif | 4777 | #endif |
4780 | {} | 4778 | {} |
4781 | }; | 4779 | }; |
4782 | 4780 | ||
4783 | static const struct hda_model_fixup alc269_fixup_models[] = { | 4781 | static const struct hda_model_fixup alc269_fixup_models[] = { |
4784 | {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"}, | 4782 | {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"}, |
4785 | {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"}, | 4783 | {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"}, |
4786 | {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"}, | 4784 | {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"}, |
4787 | {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"}, | 4785 | {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"}, |
4788 | {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"}, | 4786 | {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"}, |
4789 | {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"}, | 4787 | {.id = ALC269_FIXUP_HEADSET_MIC, .name = "headset-mic"}, |
4790 | {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"}, | 4788 | {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"}, |
4791 | {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"}, | 4789 | {.id = ALC269_FIXUP_HP_GPIO_LED, .name = "hp-gpio-led"}, |
4792 | {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, | 4790 | {.id = ALC269_FIXUP_DELL1_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, |
4793 | {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"}, | 4791 | {.id = ALC269_FIXUP_DELL2_MIC_NO_PRESENCE, .name = "dell-headset-dock"}, |
4794 | {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"}, | 4792 | {.id = ALC283_FIXUP_CHROME_BOOK, .name = "alc283-dac-wcaps"}, |
4795 | {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"}, | 4793 | {.id = ALC283_FIXUP_SENSE_COMBO_JACK, .name = "alc283-sense-combo"}, |
4796 | {} | 4794 | {} |
4797 | }; | 4795 | }; |
4798 | 4796 | ||
4799 | 4797 | ||
4800 | static void alc269_fill_coef(struct hda_codec *codec) | 4798 | static void alc269_fill_coef(struct hda_codec *codec) |
4801 | { | 4799 | { |
4802 | struct alc_spec *spec = codec->spec; | 4800 | struct alc_spec *spec = codec->spec; |
4803 | int val; | 4801 | int val; |
4804 | 4802 | ||
4805 | if (spec->codec_variant != ALC269_TYPE_ALC269VB) | 4803 | if (spec->codec_variant != ALC269_TYPE_ALC269VB) |
4806 | return; | 4804 | return; |
4807 | 4805 | ||
4808 | if ((alc_get_coef0(codec) & 0x00ff) < 0x015) { | 4806 | if ((alc_get_coef0(codec) & 0x00ff) < 0x015) { |
4809 | alc_write_coef_idx(codec, 0xf, 0x960b); | 4807 | alc_write_coef_idx(codec, 0xf, 0x960b); |
4810 | alc_write_coef_idx(codec, 0xe, 0x8817); | 4808 | alc_write_coef_idx(codec, 0xe, 0x8817); |
4811 | } | 4809 | } |
4812 | 4810 | ||
4813 | if ((alc_get_coef0(codec) & 0x00ff) == 0x016) { | 4811 | if ((alc_get_coef0(codec) & 0x00ff) == 0x016) { |
4814 | alc_write_coef_idx(codec, 0xf, 0x960b); | 4812 | alc_write_coef_idx(codec, 0xf, 0x960b); |
4815 | alc_write_coef_idx(codec, 0xe, 0x8814); | 4813 | alc_write_coef_idx(codec, 0xe, 0x8814); |
4816 | } | 4814 | } |
4817 | 4815 | ||
4818 | if ((alc_get_coef0(codec) & 0x00ff) == 0x017) { | 4816 | if ((alc_get_coef0(codec) & 0x00ff) == 0x017) { |
4819 | val = alc_read_coef_idx(codec, 0x04); | 4817 | val = alc_read_coef_idx(codec, 0x04); |
4820 | /* Power up output pin */ | 4818 | /* Power up output pin */ |
4821 | alc_write_coef_idx(codec, 0x04, val | (1<<11)); | 4819 | alc_write_coef_idx(codec, 0x04, val | (1<<11)); |
4822 | } | 4820 | } |
4823 | 4821 | ||
4824 | if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { | 4822 | if ((alc_get_coef0(codec) & 0x00ff) == 0x018) { |
4825 | val = alc_read_coef_idx(codec, 0xd); | 4823 | val = alc_read_coef_idx(codec, 0xd); |
4826 | if ((val & 0x0c00) >> 10 != 0x1) { | 4824 | if ((val & 0x0c00) >> 10 != 0x1) { |
4827 | /* Capless ramp up clock control */ | 4825 | /* Capless ramp up clock control */ |
4828 | alc_write_coef_idx(codec, 0xd, val | (1<<10)); | 4826 | alc_write_coef_idx(codec, 0xd, val | (1<<10)); |
4829 | } | 4827 | } |
4830 | val = alc_read_coef_idx(codec, 0x17); | 4828 | val = alc_read_coef_idx(codec, 0x17); |
4831 | if ((val & 0x01c0) >> 6 != 0x4) { | 4829 | if ((val & 0x01c0) >> 6 != 0x4) { |
4832 | /* Class D power on reset */ | 4830 | /* Class D power on reset */ |
4833 | alc_write_coef_idx(codec, 0x17, val | (1<<7)); | 4831 | alc_write_coef_idx(codec, 0x17, val | (1<<7)); |
4834 | } | 4832 | } |
4835 | } | 4833 | } |
4836 | 4834 | ||
4837 | val = alc_read_coef_idx(codec, 0xd); /* Class D */ | 4835 | val = alc_read_coef_idx(codec, 0xd); /* Class D */ |
4838 | alc_write_coef_idx(codec, 0xd, val | (1<<14)); | 4836 | alc_write_coef_idx(codec, 0xd, val | (1<<14)); |
4839 | 4837 | ||
4840 | val = alc_read_coef_idx(codec, 0x4); /* HP */ | 4838 | val = alc_read_coef_idx(codec, 0x4); /* HP */ |
4841 | alc_write_coef_idx(codec, 0x4, val | (1<<11)); | 4839 | alc_write_coef_idx(codec, 0x4, val | (1<<11)); |
4842 | } | 4840 | } |
4843 | 4841 | ||
4844 | /* | 4842 | /* |
4845 | */ | 4843 | */ |
4846 | static int patch_alc269(struct hda_codec *codec) | 4844 | static int patch_alc269(struct hda_codec *codec) |
4847 | { | 4845 | { |
4848 | struct alc_spec *spec; | 4846 | struct alc_spec *spec; |
4849 | int err; | 4847 | int err; |
4850 | 4848 | ||
4851 | err = alc_alloc_spec(codec, 0x0b); | 4849 | err = alc_alloc_spec(codec, 0x0b); |
4852 | if (err < 0) | 4850 | if (err < 0) |
4853 | return err; | 4851 | return err; |
4854 | 4852 | ||
4855 | spec = codec->spec; | 4853 | spec = codec->spec; |
4856 | spec->gen.shared_mic_vref_pin = 0x18; | 4854 | spec->gen.shared_mic_vref_pin = 0x18; |
4857 | 4855 | ||
4858 | snd_hda_pick_fixup(codec, alc269_fixup_models, | 4856 | snd_hda_pick_fixup(codec, alc269_fixup_models, |
4859 | alc269_fixup_tbl, alc269_fixups); | 4857 | alc269_fixup_tbl, alc269_fixups); |
4860 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 4858 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
4861 | 4859 | ||
4862 | alc_auto_parse_customize_define(codec); | 4860 | alc_auto_parse_customize_define(codec); |
4863 | 4861 | ||
4864 | if (has_cdefine_beep(codec)) | 4862 | if (has_cdefine_beep(codec)) |
4865 | spec->gen.beep_nid = 0x01; | 4863 | spec->gen.beep_nid = 0x01; |
4866 | 4864 | ||
4867 | switch (codec->vendor_id) { | 4865 | switch (codec->vendor_id) { |
4868 | case 0x10ec0269: | 4866 | case 0x10ec0269: |
4869 | spec->codec_variant = ALC269_TYPE_ALC269VA; | 4867 | spec->codec_variant = ALC269_TYPE_ALC269VA; |
4870 | switch (alc_get_coef0(codec) & 0x00f0) { | 4868 | switch (alc_get_coef0(codec) & 0x00f0) { |
4871 | case 0x0010: | 4869 | case 0x0010: |
4872 | if (codec->bus->pci && | 4870 | if (codec->bus->pci && |
4873 | codec->bus->pci->subsystem_vendor == 0x1025 && | 4871 | codec->bus->pci->subsystem_vendor == 0x1025 && |
4874 | spec->cdefine.platform_type == 1) | 4872 | spec->cdefine.platform_type == 1) |
4875 | err = alc_codec_rename(codec, "ALC271X"); | 4873 | err = alc_codec_rename(codec, "ALC271X"); |
4876 | spec->codec_variant = ALC269_TYPE_ALC269VB; | 4874 | spec->codec_variant = ALC269_TYPE_ALC269VB; |
4877 | break; | 4875 | break; |
4878 | case 0x0020: | 4876 | case 0x0020: |
4879 | if (codec->bus->pci && | 4877 | if (codec->bus->pci && |
4880 | codec->bus->pci->subsystem_vendor == 0x17aa && | 4878 | codec->bus->pci->subsystem_vendor == 0x17aa && |
4881 | codec->bus->pci->subsystem_device == 0x21f3) | 4879 | codec->bus->pci->subsystem_device == 0x21f3) |
4882 | err = alc_codec_rename(codec, "ALC3202"); | 4880 | err = alc_codec_rename(codec, "ALC3202"); |
4883 | spec->codec_variant = ALC269_TYPE_ALC269VC; | 4881 | spec->codec_variant = ALC269_TYPE_ALC269VC; |
4884 | break; | 4882 | break; |
4885 | case 0x0030: | 4883 | case 0x0030: |
4886 | spec->codec_variant = ALC269_TYPE_ALC269VD; | 4884 | spec->codec_variant = ALC269_TYPE_ALC269VD; |
4887 | break; | 4885 | break; |
4888 | default: | 4886 | default: |
4889 | alc_fix_pll_init(codec, 0x20, 0x04, 15); | 4887 | alc_fix_pll_init(codec, 0x20, 0x04, 15); |
4890 | } | 4888 | } |
4891 | if (err < 0) | 4889 | if (err < 0) |
4892 | goto error; | 4890 | goto error; |
4893 | spec->init_hook = alc269_fill_coef; | 4891 | spec->init_hook = alc269_fill_coef; |
4894 | alc269_fill_coef(codec); | 4892 | alc269_fill_coef(codec); |
4895 | break; | 4893 | break; |
4896 | 4894 | ||
4897 | case 0x10ec0280: | 4895 | case 0x10ec0280: |
4898 | case 0x10ec0290: | 4896 | case 0x10ec0290: |
4899 | spec->codec_variant = ALC269_TYPE_ALC280; | 4897 | spec->codec_variant = ALC269_TYPE_ALC280; |
4900 | break; | 4898 | break; |
4901 | case 0x10ec0282: | 4899 | case 0x10ec0282: |
4902 | spec->codec_variant = ALC269_TYPE_ALC282; | 4900 | spec->codec_variant = ALC269_TYPE_ALC282; |
4903 | spec->shutup = alc282_shutup; | 4901 | spec->shutup = alc282_shutup; |
4904 | spec->init_hook = alc282_init; | 4902 | spec->init_hook = alc282_init; |
4905 | break; | 4903 | break; |
4906 | case 0x10ec0233: | 4904 | case 0x10ec0233: |
4907 | case 0x10ec0283: | 4905 | case 0x10ec0283: |
4908 | spec->codec_variant = ALC269_TYPE_ALC283; | 4906 | spec->codec_variant = ALC269_TYPE_ALC283; |
4909 | spec->shutup = alc283_shutup; | 4907 | spec->shutup = alc283_shutup; |
4910 | spec->init_hook = alc283_init; | 4908 | spec->init_hook = alc283_init; |
4911 | break; | 4909 | break; |
4912 | case 0x10ec0284: | 4910 | case 0x10ec0284: |
4913 | case 0x10ec0292: | 4911 | case 0x10ec0292: |
4914 | spec->codec_variant = ALC269_TYPE_ALC284; | 4912 | spec->codec_variant = ALC269_TYPE_ALC284; |
4915 | break; | 4913 | break; |
4916 | case 0x10ec0285: | 4914 | case 0x10ec0285: |
4917 | case 0x10ec0293: | 4915 | case 0x10ec0293: |
4918 | spec->codec_variant = ALC269_TYPE_ALC285; | 4916 | spec->codec_variant = ALC269_TYPE_ALC285; |
4919 | break; | 4917 | break; |
4920 | case 0x10ec0286: | 4918 | case 0x10ec0286: |
4921 | case 0x10ec0288: | 4919 | case 0x10ec0288: |
4922 | spec->codec_variant = ALC269_TYPE_ALC286; | 4920 | spec->codec_variant = ALC269_TYPE_ALC286; |
4923 | break; | 4921 | break; |
4924 | case 0x10ec0255: | 4922 | case 0x10ec0255: |
4925 | spec->codec_variant = ALC269_TYPE_ALC255; | 4923 | spec->codec_variant = ALC269_TYPE_ALC255; |
4926 | break; | 4924 | break; |
4927 | } | 4925 | } |
4928 | 4926 | ||
4929 | if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) { | 4927 | if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) { |
4930 | spec->has_alc5505_dsp = 1; | 4928 | spec->has_alc5505_dsp = 1; |
4931 | spec->init_hook = alc5505_dsp_init; | 4929 | spec->init_hook = alc5505_dsp_init; |
4932 | } | 4930 | } |
4933 | 4931 | ||
4934 | /* automatic parse from the BIOS config */ | 4932 | /* automatic parse from the BIOS config */ |
4935 | err = alc269_parse_auto_config(codec); | 4933 | err = alc269_parse_auto_config(codec); |
4936 | if (err < 0) | 4934 | if (err < 0) |
4937 | goto error; | 4935 | goto error; |
4938 | 4936 | ||
4939 | if (!spec->gen.no_analog && spec->gen.beep_nid) | 4937 | if (!spec->gen.no_analog && spec->gen.beep_nid) |
4940 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); | 4938 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); |
4941 | 4939 | ||
4942 | codec->patch_ops = alc_patch_ops; | 4940 | codec->patch_ops = alc_patch_ops; |
4943 | #ifdef CONFIG_PM | 4941 | #ifdef CONFIG_PM |
4944 | codec->patch_ops.suspend = alc269_suspend; | 4942 | codec->patch_ops.suspend = alc269_suspend; |
4945 | codec->patch_ops.resume = alc269_resume; | 4943 | codec->patch_ops.resume = alc269_resume; |
4946 | #endif | 4944 | #endif |
4947 | if (!spec->shutup) | 4945 | if (!spec->shutup) |
4948 | spec->shutup = alc269_shutup; | 4946 | spec->shutup = alc269_shutup; |
4949 | 4947 | ||
4950 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 4948 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
4951 | 4949 | ||
4952 | return 0; | 4950 | return 0; |
4953 | 4951 | ||
4954 | error: | 4952 | error: |
4955 | alc_free(codec); | 4953 | alc_free(codec); |
4956 | return err; | 4954 | return err; |
4957 | } | 4955 | } |
4958 | 4956 | ||
4959 | /* | 4957 | /* |
4960 | * ALC861 | 4958 | * ALC861 |
4961 | */ | 4959 | */ |
4962 | 4960 | ||
4963 | static int alc861_parse_auto_config(struct hda_codec *codec) | 4961 | static int alc861_parse_auto_config(struct hda_codec *codec) |
4964 | { | 4962 | { |
4965 | static const hda_nid_t alc861_ignore[] = { 0x1d, 0 }; | 4963 | static const hda_nid_t alc861_ignore[] = { 0x1d, 0 }; |
4966 | static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 }; | 4964 | static const hda_nid_t alc861_ssids[] = { 0x0e, 0x0f, 0x0b, 0 }; |
4967 | return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids); | 4965 | return alc_parse_auto_config(codec, alc861_ignore, alc861_ssids); |
4968 | } | 4966 | } |
4969 | 4967 | ||
4970 | /* Pin config fixes */ | 4968 | /* Pin config fixes */ |
4971 | enum { | 4969 | enum { |
4972 | ALC861_FIXUP_FSC_AMILO_PI1505, | 4970 | ALC861_FIXUP_FSC_AMILO_PI1505, |
4973 | ALC861_FIXUP_AMP_VREF_0F, | 4971 | ALC861_FIXUP_AMP_VREF_0F, |
4974 | ALC861_FIXUP_NO_JACK_DETECT, | 4972 | ALC861_FIXUP_NO_JACK_DETECT, |
4975 | ALC861_FIXUP_ASUS_A6RP, | 4973 | ALC861_FIXUP_ASUS_A6RP, |
4976 | ALC660_FIXUP_ASUS_W7J, | 4974 | ALC660_FIXUP_ASUS_W7J, |
4977 | }; | 4975 | }; |
4978 | 4976 | ||
4979 | /* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */ | 4977 | /* On some laptops, VREF of pin 0x0f is abused for controlling the main amp */ |
4980 | static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec, | 4978 | static void alc861_fixup_asus_amp_vref_0f(struct hda_codec *codec, |
4981 | const struct hda_fixup *fix, int action) | 4979 | const struct hda_fixup *fix, int action) |
4982 | { | 4980 | { |
4983 | struct alc_spec *spec = codec->spec; | 4981 | struct alc_spec *spec = codec->spec; |
4984 | unsigned int val; | 4982 | unsigned int val; |
4985 | 4983 | ||
4986 | if (action != HDA_FIXUP_ACT_INIT) | 4984 | if (action != HDA_FIXUP_ACT_INIT) |
4987 | return; | 4985 | return; |
4988 | val = snd_hda_codec_get_pin_target(codec, 0x0f); | 4986 | val = snd_hda_codec_get_pin_target(codec, 0x0f); |
4989 | if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))) | 4987 | if (!(val & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN))) |
4990 | val |= AC_PINCTL_IN_EN; | 4988 | val |= AC_PINCTL_IN_EN; |
4991 | val |= AC_PINCTL_VREF_50; | 4989 | val |= AC_PINCTL_VREF_50; |
4992 | snd_hda_set_pin_ctl(codec, 0x0f, val); | 4990 | snd_hda_set_pin_ctl(codec, 0x0f, val); |
4993 | spec->gen.keep_vref_in_automute = 1; | 4991 | spec->gen.keep_vref_in_automute = 1; |
4994 | } | 4992 | } |
4995 | 4993 | ||
4996 | /* suppress the jack-detection */ | 4994 | /* suppress the jack-detection */ |
4997 | static void alc_fixup_no_jack_detect(struct hda_codec *codec, | 4995 | static void alc_fixup_no_jack_detect(struct hda_codec *codec, |
4998 | const struct hda_fixup *fix, int action) | 4996 | const struct hda_fixup *fix, int action) |
4999 | { | 4997 | { |
5000 | if (action == HDA_FIXUP_ACT_PRE_PROBE) | 4998 | if (action == HDA_FIXUP_ACT_PRE_PROBE) |
5001 | codec->no_jack_detect = 1; | 4999 | codec->no_jack_detect = 1; |
5002 | } | 5000 | } |
5003 | 5001 | ||
5004 | static const struct hda_fixup alc861_fixups[] = { | 5002 | static const struct hda_fixup alc861_fixups[] = { |
5005 | [ALC861_FIXUP_FSC_AMILO_PI1505] = { | 5003 | [ALC861_FIXUP_FSC_AMILO_PI1505] = { |
5006 | .type = HDA_FIXUP_PINS, | 5004 | .type = HDA_FIXUP_PINS, |
5007 | .v.pins = (const struct hda_pintbl[]) { | 5005 | .v.pins = (const struct hda_pintbl[]) { |
5008 | { 0x0b, 0x0221101f }, /* HP */ | 5006 | { 0x0b, 0x0221101f }, /* HP */ |
5009 | { 0x0f, 0x90170310 }, /* speaker */ | 5007 | { 0x0f, 0x90170310 }, /* speaker */ |
5010 | { } | 5008 | { } |
5011 | } | 5009 | } |
5012 | }, | 5010 | }, |
5013 | [ALC861_FIXUP_AMP_VREF_0F] = { | 5011 | [ALC861_FIXUP_AMP_VREF_0F] = { |
5014 | .type = HDA_FIXUP_FUNC, | 5012 | .type = HDA_FIXUP_FUNC, |
5015 | .v.func = alc861_fixup_asus_amp_vref_0f, | 5013 | .v.func = alc861_fixup_asus_amp_vref_0f, |
5016 | }, | 5014 | }, |
5017 | [ALC861_FIXUP_NO_JACK_DETECT] = { | 5015 | [ALC861_FIXUP_NO_JACK_DETECT] = { |
5018 | .type = HDA_FIXUP_FUNC, | 5016 | .type = HDA_FIXUP_FUNC, |
5019 | .v.func = alc_fixup_no_jack_detect, | 5017 | .v.func = alc_fixup_no_jack_detect, |
5020 | }, | 5018 | }, |
5021 | [ALC861_FIXUP_ASUS_A6RP] = { | 5019 | [ALC861_FIXUP_ASUS_A6RP] = { |
5022 | .type = HDA_FIXUP_FUNC, | 5020 | .type = HDA_FIXUP_FUNC, |
5023 | .v.func = alc861_fixup_asus_amp_vref_0f, | 5021 | .v.func = alc861_fixup_asus_amp_vref_0f, |
5024 | .chained = true, | 5022 | .chained = true, |
5025 | .chain_id = ALC861_FIXUP_NO_JACK_DETECT, | 5023 | .chain_id = ALC861_FIXUP_NO_JACK_DETECT, |
5026 | }, | 5024 | }, |
5027 | [ALC660_FIXUP_ASUS_W7J] = { | 5025 | [ALC660_FIXUP_ASUS_W7J] = { |
5028 | .type = HDA_FIXUP_VERBS, | 5026 | .type = HDA_FIXUP_VERBS, |
5029 | .v.verbs = (const struct hda_verb[]) { | 5027 | .v.verbs = (const struct hda_verb[]) { |
5030 | /* ASUS W7J needs a magic pin setup on unused NID 0x10 | 5028 | /* ASUS W7J needs a magic pin setup on unused NID 0x10 |
5031 | * for enabling outputs | 5029 | * for enabling outputs |
5032 | */ | 5030 | */ |
5033 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | 5031 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, |
5034 | { } | 5032 | { } |
5035 | }, | 5033 | }, |
5036 | } | 5034 | } |
5037 | }; | 5035 | }; |
5038 | 5036 | ||
5039 | static const struct snd_pci_quirk alc861_fixup_tbl[] = { | 5037 | static const struct snd_pci_quirk alc861_fixup_tbl[] = { |
5040 | SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J), | 5038 | SND_PCI_QUIRK(0x1043, 0x1253, "ASUS W7J", ALC660_FIXUP_ASUS_W7J), |
5041 | SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J), | 5039 | SND_PCI_QUIRK(0x1043, 0x1263, "ASUS Z35HL", ALC660_FIXUP_ASUS_W7J), |
5042 | SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP), | 5040 | SND_PCI_QUIRK(0x1043, 0x1393, "ASUS A6Rp", ALC861_FIXUP_ASUS_A6RP), |
5043 | SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F), | 5041 | SND_PCI_QUIRK_VENDOR(0x1043, "ASUS laptop", ALC861_FIXUP_AMP_VREF_0F), |
5044 | SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT), | 5042 | SND_PCI_QUIRK(0x1462, 0x7254, "HP DX2200", ALC861_FIXUP_NO_JACK_DETECT), |
5045 | SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F), | 5043 | SND_PCI_QUIRK(0x1584, 0x2b01, "Haier W18", ALC861_FIXUP_AMP_VREF_0F), |
5046 | SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F), | 5044 | SND_PCI_QUIRK(0x1584, 0x0000, "Uniwill ECS M31EI", ALC861_FIXUP_AMP_VREF_0F), |
5047 | SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505), | 5045 | SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", ALC861_FIXUP_FSC_AMILO_PI1505), |
5048 | {} | 5046 | {} |
5049 | }; | 5047 | }; |
5050 | 5048 | ||
5051 | /* | 5049 | /* |
5052 | */ | 5050 | */ |
5053 | static int patch_alc861(struct hda_codec *codec) | 5051 | static int patch_alc861(struct hda_codec *codec) |
5054 | { | 5052 | { |
5055 | struct alc_spec *spec; | 5053 | struct alc_spec *spec; |
5056 | int err; | 5054 | int err; |
5057 | 5055 | ||
5058 | err = alc_alloc_spec(codec, 0x15); | 5056 | err = alc_alloc_spec(codec, 0x15); |
5059 | if (err < 0) | 5057 | if (err < 0) |
5060 | return err; | 5058 | return err; |
5061 | 5059 | ||
5062 | spec = codec->spec; | 5060 | spec = codec->spec; |
5063 | spec->gen.beep_nid = 0x23; | 5061 | spec->gen.beep_nid = 0x23; |
5064 | 5062 | ||
5065 | snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); | 5063 | snd_hda_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); |
5066 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 5064 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
5067 | 5065 | ||
5068 | /* automatic parse from the BIOS config */ | 5066 | /* automatic parse from the BIOS config */ |
5069 | err = alc861_parse_auto_config(codec); | 5067 | err = alc861_parse_auto_config(codec); |
5070 | if (err < 0) | 5068 | if (err < 0) |
5071 | goto error; | 5069 | goto error; |
5072 | 5070 | ||
5073 | if (!spec->gen.no_analog) | 5071 | if (!spec->gen.no_analog) |
5074 | set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); | 5072 | set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); |
5075 | 5073 | ||
5076 | codec->patch_ops = alc_patch_ops; | 5074 | codec->patch_ops = alc_patch_ops; |
5077 | #ifdef CONFIG_PM | 5075 | #ifdef CONFIG_PM |
5078 | spec->power_hook = alc_power_eapd; | 5076 | spec->power_hook = alc_power_eapd; |
5079 | #endif | 5077 | #endif |
5080 | 5078 | ||
5081 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 5079 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
5082 | 5080 | ||
5083 | return 0; | 5081 | return 0; |
5084 | 5082 | ||
5085 | error: | 5083 | error: |
5086 | alc_free(codec); | 5084 | alc_free(codec); |
5087 | return err; | 5085 | return err; |
5088 | } | 5086 | } |
5089 | 5087 | ||
5090 | /* | 5088 | /* |
5091 | * ALC861-VD support | 5089 | * ALC861-VD support |
5092 | * | 5090 | * |
5093 | * Based on ALC882 | 5091 | * Based on ALC882 |
5094 | * | 5092 | * |
5095 | * In addition, an independent DAC | 5093 | * In addition, an independent DAC |
5096 | */ | 5094 | */ |
5097 | static int alc861vd_parse_auto_config(struct hda_codec *codec) | 5095 | static int alc861vd_parse_auto_config(struct hda_codec *codec) |
5098 | { | 5096 | { |
5099 | static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; | 5097 | static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; |
5100 | static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 }; | 5098 | static const hda_nid_t alc861vd_ssids[] = { 0x15, 0x1b, 0x14, 0 }; |
5101 | return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids); | 5099 | return alc_parse_auto_config(codec, alc861vd_ignore, alc861vd_ssids); |
5102 | } | 5100 | } |
5103 | 5101 | ||
5104 | enum { | 5102 | enum { |
5105 | ALC660VD_FIX_ASUS_GPIO1, | 5103 | ALC660VD_FIX_ASUS_GPIO1, |
5106 | ALC861VD_FIX_DALLAS, | 5104 | ALC861VD_FIX_DALLAS, |
5107 | }; | 5105 | }; |
5108 | 5106 | ||
5109 | /* exclude VREF80 */ | 5107 | /* exclude VREF80 */ |
5110 | static void alc861vd_fixup_dallas(struct hda_codec *codec, | 5108 | static void alc861vd_fixup_dallas(struct hda_codec *codec, |
5111 | const struct hda_fixup *fix, int action) | 5109 | const struct hda_fixup *fix, int action) |
5112 | { | 5110 | { |
5113 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 5111 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
5114 | snd_hda_override_pin_caps(codec, 0x18, 0x00000734); | 5112 | snd_hda_override_pin_caps(codec, 0x18, 0x00000734); |
5115 | snd_hda_override_pin_caps(codec, 0x19, 0x0000073c); | 5113 | snd_hda_override_pin_caps(codec, 0x19, 0x0000073c); |
5116 | } | 5114 | } |
5117 | } | 5115 | } |
5118 | 5116 | ||
5119 | static const struct hda_fixup alc861vd_fixups[] = { | 5117 | static const struct hda_fixup alc861vd_fixups[] = { |
5120 | [ALC660VD_FIX_ASUS_GPIO1] = { | 5118 | [ALC660VD_FIX_ASUS_GPIO1] = { |
5121 | .type = HDA_FIXUP_VERBS, | 5119 | .type = HDA_FIXUP_VERBS, |
5122 | .v.verbs = (const struct hda_verb[]) { | 5120 | .v.verbs = (const struct hda_verb[]) { |
5123 | /* reset GPIO1 */ | 5121 | /* reset GPIO1 */ |
5124 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, | 5122 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, |
5125 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | 5123 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, |
5126 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, | 5124 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, |
5127 | { } | 5125 | { } |
5128 | } | 5126 | } |
5129 | }, | 5127 | }, |
5130 | [ALC861VD_FIX_DALLAS] = { | 5128 | [ALC861VD_FIX_DALLAS] = { |
5131 | .type = HDA_FIXUP_FUNC, | 5129 | .type = HDA_FIXUP_FUNC, |
5132 | .v.func = alc861vd_fixup_dallas, | 5130 | .v.func = alc861vd_fixup_dallas, |
5133 | }, | 5131 | }, |
5134 | }; | 5132 | }; |
5135 | 5133 | ||
5136 | static const struct snd_pci_quirk alc861vd_fixup_tbl[] = { | 5134 | static const struct snd_pci_quirk alc861vd_fixup_tbl[] = { |
5137 | SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS), | 5135 | SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_FIX_DALLAS), |
5138 | SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), | 5136 | SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), |
5139 | SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS), | 5137 | SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_FIX_DALLAS), |
5140 | {} | 5138 | {} |
5141 | }; | 5139 | }; |
5142 | 5140 | ||
5143 | /* | 5141 | /* |
5144 | */ | 5142 | */ |
5145 | static int patch_alc861vd(struct hda_codec *codec) | 5143 | static int patch_alc861vd(struct hda_codec *codec) |
5146 | { | 5144 | { |
5147 | struct alc_spec *spec; | 5145 | struct alc_spec *spec; |
5148 | int err; | 5146 | int err; |
5149 | 5147 | ||
5150 | err = alc_alloc_spec(codec, 0x0b); | 5148 | err = alc_alloc_spec(codec, 0x0b); |
5151 | if (err < 0) | 5149 | if (err < 0) |
5152 | return err; | 5150 | return err; |
5153 | 5151 | ||
5154 | spec = codec->spec; | 5152 | spec = codec->spec; |
5155 | spec->gen.beep_nid = 0x23; | 5153 | spec->gen.beep_nid = 0x23; |
5156 | 5154 | ||
5157 | snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); | 5155 | snd_hda_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); |
5158 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 5156 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
5159 | 5157 | ||
5160 | /* automatic parse from the BIOS config */ | 5158 | /* automatic parse from the BIOS config */ |
5161 | err = alc861vd_parse_auto_config(codec); | 5159 | err = alc861vd_parse_auto_config(codec); |
5162 | if (err < 0) | 5160 | if (err < 0) |
5163 | goto error; | 5161 | goto error; |
5164 | 5162 | ||
5165 | if (!spec->gen.no_analog) | 5163 | if (!spec->gen.no_analog) |
5166 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 5164 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
5167 | 5165 | ||
5168 | codec->patch_ops = alc_patch_ops; | 5166 | codec->patch_ops = alc_patch_ops; |
5169 | 5167 | ||
5170 | spec->shutup = alc_eapd_shutup; | 5168 | spec->shutup = alc_eapd_shutup; |
5171 | 5169 | ||
5172 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 5170 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
5173 | 5171 | ||
5174 | return 0; | 5172 | return 0; |
5175 | 5173 | ||
5176 | error: | 5174 | error: |
5177 | alc_free(codec); | 5175 | alc_free(codec); |
5178 | return err; | 5176 | return err; |
5179 | } | 5177 | } |
5180 | 5178 | ||
5181 | /* | 5179 | /* |
5182 | * ALC662 support | 5180 | * ALC662 support |
5183 | * | 5181 | * |
5184 | * ALC662 is almost identical with ALC880 but has cleaner and more flexible | 5182 | * ALC662 is almost identical with ALC880 but has cleaner and more flexible |
5185 | * configuration. Each pin widget can choose any input DACs and a mixer. | 5183 | * configuration. Each pin widget can choose any input DACs and a mixer. |
5186 | * Each ADC is connected from a mixer of all inputs. This makes possible | 5184 | * Each ADC is connected from a mixer of all inputs. This makes possible |
5187 | * 6-channel independent captures. | 5185 | * 6-channel independent captures. |
5188 | * | 5186 | * |
5189 | * In addition, an independent DAC for the multi-playback (not used in this | 5187 | * In addition, an independent DAC for the multi-playback (not used in this |
5190 | * driver yet). | 5188 | * driver yet). |
5191 | */ | 5189 | */ |
5192 | 5190 | ||
5193 | /* | 5191 | /* |
5194 | * BIOS auto configuration | 5192 | * BIOS auto configuration |
5195 | */ | 5193 | */ |
5196 | 5194 | ||
5197 | static int alc662_parse_auto_config(struct hda_codec *codec) | 5195 | static int alc662_parse_auto_config(struct hda_codec *codec) |
5198 | { | 5196 | { |
5199 | static const hda_nid_t alc662_ignore[] = { 0x1d, 0 }; | 5197 | static const hda_nid_t alc662_ignore[] = { 0x1d, 0 }; |
5200 | static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 }; | 5198 | static const hda_nid_t alc663_ssids[] = { 0x15, 0x1b, 0x14, 0x21 }; |
5201 | static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 }; | 5199 | static const hda_nid_t alc662_ssids[] = { 0x15, 0x1b, 0x14, 0 }; |
5202 | const hda_nid_t *ssids; | 5200 | const hda_nid_t *ssids; |
5203 | 5201 | ||
5204 | if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || | 5202 | if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || |
5205 | codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670 || | 5203 | codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670 || |
5206 | codec->vendor_id == 0x10ec0671) | 5204 | codec->vendor_id == 0x10ec0671) |
5207 | ssids = alc663_ssids; | 5205 | ssids = alc663_ssids; |
5208 | else | 5206 | else |
5209 | ssids = alc662_ssids; | 5207 | ssids = alc662_ssids; |
5210 | return alc_parse_auto_config(codec, alc662_ignore, ssids); | 5208 | return alc_parse_auto_config(codec, alc662_ignore, ssids); |
5211 | } | 5209 | } |
5212 | 5210 | ||
5213 | static void alc272_fixup_mario(struct hda_codec *codec, | 5211 | static void alc272_fixup_mario(struct hda_codec *codec, |
5214 | const struct hda_fixup *fix, int action) | 5212 | const struct hda_fixup *fix, int action) |
5215 | { | 5213 | { |
5216 | if (action != HDA_FIXUP_ACT_PRE_PROBE) | 5214 | if (action != HDA_FIXUP_ACT_PRE_PROBE) |
5217 | return; | 5215 | return; |
5218 | if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT, | 5216 | if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT, |
5219 | (0x3b << AC_AMPCAP_OFFSET_SHIFT) | | 5217 | (0x3b << AC_AMPCAP_OFFSET_SHIFT) | |
5220 | (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) | | 5218 | (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) | |
5221 | (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) | | 5219 | (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) | |
5222 | (0 << AC_AMPCAP_MUTE_SHIFT))) | 5220 | (0 << AC_AMPCAP_MUTE_SHIFT))) |
5223 | codec_warn(codec, "failed to override amp caps for NID 0x2\n"); | 5221 | codec_warn(codec, "failed to override amp caps for NID 0x2\n"); |
5224 | } | 5222 | } |
5225 | 5223 | ||
5226 | static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = { | 5224 | static const struct snd_pcm_chmap_elem asus_pcm_2_1_chmaps[] = { |
5227 | { .channels = 2, | 5225 | { .channels = 2, |
5228 | .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } }, | 5226 | .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } }, |
5229 | { .channels = 4, | 5227 | { .channels = 4, |
5230 | .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, | 5228 | .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, |
5231 | SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */ | 5229 | SNDRV_CHMAP_NA, SNDRV_CHMAP_LFE } }, /* LFE only on right */ |
5232 | { } | 5230 | { } |
5233 | }; | 5231 | }; |
5234 | 5232 | ||
5235 | /* override the 2.1 chmap */ | 5233 | /* override the 2.1 chmap */ |
5236 | static void alc_fixup_bass_chmap(struct hda_codec *codec, | 5234 | static void alc_fixup_bass_chmap(struct hda_codec *codec, |
5237 | const struct hda_fixup *fix, int action) | 5235 | const struct hda_fixup *fix, int action) |
5238 | { | 5236 | { |
5239 | if (action == HDA_FIXUP_ACT_BUILD) { | 5237 | if (action == HDA_FIXUP_ACT_BUILD) { |
5240 | struct alc_spec *spec = codec->spec; | 5238 | struct alc_spec *spec = codec->spec; |
5241 | spec->gen.pcm_rec[0].stream[0].chmap = asus_pcm_2_1_chmaps; | 5239 | spec->gen.pcm_rec[0].stream[0].chmap = asus_pcm_2_1_chmaps; |
5242 | } | 5240 | } |
5243 | } | 5241 | } |
5244 | 5242 | ||
5245 | /* turn on/off mute LED per vmaster hook */ | 5243 | /* turn on/off mute LED per vmaster hook */ |
5246 | static void alc662_led_gpio1_mute_hook(void *private_data, int enabled) | 5244 | static void alc662_led_gpio1_mute_hook(void *private_data, int enabled) |
5247 | { | 5245 | { |
5248 | struct hda_codec *codec = private_data; | 5246 | struct hda_codec *codec = private_data; |
5249 | struct alc_spec *spec = codec->spec; | 5247 | struct alc_spec *spec = codec->spec; |
5250 | unsigned int oldval = spec->gpio_led; | 5248 | unsigned int oldval = spec->gpio_led; |
5251 | 5249 | ||
5252 | if (enabled) | 5250 | if (enabled) |
5253 | spec->gpio_led &= ~0x01; | 5251 | spec->gpio_led &= ~0x01; |
5254 | else | 5252 | else |
5255 | spec->gpio_led |= 0x01; | 5253 | spec->gpio_led |= 0x01; |
5256 | if (spec->gpio_led != oldval) | 5254 | if (spec->gpio_led != oldval) |
5257 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, | 5255 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, |
5258 | spec->gpio_led); | 5256 | spec->gpio_led); |
5259 | } | 5257 | } |
5260 | 5258 | ||
5261 | /* avoid D3 for keeping GPIO up */ | 5259 | /* avoid D3 for keeping GPIO up */ |
5262 | static unsigned int gpio_led_power_filter(struct hda_codec *codec, | 5260 | static unsigned int gpio_led_power_filter(struct hda_codec *codec, |
5263 | hda_nid_t nid, | 5261 | hda_nid_t nid, |
5264 | unsigned int power_state) | 5262 | unsigned int power_state) |
5265 | { | 5263 | { |
5266 | struct alc_spec *spec = codec->spec; | 5264 | struct alc_spec *spec = codec->spec; |
5267 | if (nid == codec->afg && power_state == AC_PWRST_D3 && spec->gpio_led) | 5265 | if (nid == codec->afg && power_state == AC_PWRST_D3 && spec->gpio_led) |
5268 | return AC_PWRST_D0; | 5266 | return AC_PWRST_D0; |
5269 | return power_state; | 5267 | return power_state; |
5270 | } | 5268 | } |
5271 | 5269 | ||
5272 | static void alc662_fixup_led_gpio1(struct hda_codec *codec, | 5270 | static void alc662_fixup_led_gpio1(struct hda_codec *codec, |
5273 | const struct hda_fixup *fix, int action) | 5271 | const struct hda_fixup *fix, int action) |
5274 | { | 5272 | { |
5275 | struct alc_spec *spec = codec->spec; | 5273 | struct alc_spec *spec = codec->spec; |
5276 | static const struct hda_verb gpio_init[] = { | 5274 | static const struct hda_verb gpio_init[] = { |
5277 | { 0x01, AC_VERB_SET_GPIO_MASK, 0x01 }, | 5275 | { 0x01, AC_VERB_SET_GPIO_MASK, 0x01 }, |
5278 | { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01 }, | 5276 | { 0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01 }, |
5279 | {} | 5277 | {} |
5280 | }; | 5278 | }; |
5281 | 5279 | ||
5282 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { | 5280 | if (action == HDA_FIXUP_ACT_PRE_PROBE) { |
5283 | spec->gen.vmaster_mute.hook = alc662_led_gpio1_mute_hook; | 5281 | spec->gen.vmaster_mute.hook = alc662_led_gpio1_mute_hook; |
5284 | spec->gpio_led = 0; | 5282 | spec->gpio_led = 0; |
5285 | snd_hda_add_verbs(codec, gpio_init); | 5283 | snd_hda_add_verbs(codec, gpio_init); |
5286 | codec->power_filter = gpio_led_power_filter; | 5284 | codec->power_filter = gpio_led_power_filter; |
5287 | } | 5285 | } |
5288 | } | 5286 | } |
5289 | 5287 | ||
5290 | enum { | 5288 | enum { |
5291 | ALC662_FIXUP_ASPIRE, | 5289 | ALC662_FIXUP_ASPIRE, |
5292 | ALC662_FIXUP_LED_GPIO1, | 5290 | ALC662_FIXUP_LED_GPIO1, |
5293 | ALC662_FIXUP_IDEAPAD, | 5291 | ALC662_FIXUP_IDEAPAD, |
5294 | ALC272_FIXUP_MARIO, | 5292 | ALC272_FIXUP_MARIO, |
5295 | ALC662_FIXUP_CZC_P10T, | 5293 | ALC662_FIXUP_CZC_P10T, |
5296 | ALC662_FIXUP_SKU_IGNORE, | 5294 | ALC662_FIXUP_SKU_IGNORE, |
5297 | ALC662_FIXUP_HP_RP5800, | 5295 | ALC662_FIXUP_HP_RP5800, |
5298 | ALC662_FIXUP_ASUS_MODE1, | 5296 | ALC662_FIXUP_ASUS_MODE1, |
5299 | ALC662_FIXUP_ASUS_MODE2, | 5297 | ALC662_FIXUP_ASUS_MODE2, |
5300 | ALC662_FIXUP_ASUS_MODE3, | 5298 | ALC662_FIXUP_ASUS_MODE3, |
5301 | ALC662_FIXUP_ASUS_MODE4, | 5299 | ALC662_FIXUP_ASUS_MODE4, |
5302 | ALC662_FIXUP_ASUS_MODE5, | 5300 | ALC662_FIXUP_ASUS_MODE5, |
5303 | ALC662_FIXUP_ASUS_MODE6, | 5301 | ALC662_FIXUP_ASUS_MODE6, |
5304 | ALC662_FIXUP_ASUS_MODE7, | 5302 | ALC662_FIXUP_ASUS_MODE7, |
5305 | ALC662_FIXUP_ASUS_MODE8, | 5303 | ALC662_FIXUP_ASUS_MODE8, |
5306 | ALC662_FIXUP_NO_JACK_DETECT, | 5304 | ALC662_FIXUP_NO_JACK_DETECT, |
5307 | ALC662_FIXUP_ZOTAC_Z68, | 5305 | ALC662_FIXUP_ZOTAC_Z68, |
5308 | ALC662_FIXUP_INV_DMIC, | 5306 | ALC662_FIXUP_INV_DMIC, |
5309 | ALC668_FIXUP_DELL_MIC_NO_PRESENCE, | 5307 | ALC668_FIXUP_DELL_MIC_NO_PRESENCE, |
5310 | ALC668_FIXUP_HEADSET_MODE, | 5308 | ALC668_FIXUP_HEADSET_MODE, |
5311 | ALC662_FIXUP_BASS_MODE4_CHMAP, | 5309 | ALC662_FIXUP_BASS_MODE4_CHMAP, |
5312 | ALC662_FIXUP_BASS_16, | 5310 | ALC662_FIXUP_BASS_16, |
5313 | ALC662_FIXUP_BASS_1A, | 5311 | ALC662_FIXUP_BASS_1A, |
5314 | ALC662_FIXUP_BASS_CHMAP, | 5312 | ALC662_FIXUP_BASS_CHMAP, |
5315 | ALC668_FIXUP_AUTO_MUTE, | 5313 | ALC668_FIXUP_AUTO_MUTE, |
5316 | }; | 5314 | }; |
5317 | 5315 | ||
5318 | static const struct hda_fixup alc662_fixups[] = { | 5316 | static const struct hda_fixup alc662_fixups[] = { |
5319 | [ALC662_FIXUP_ASPIRE] = { | 5317 | [ALC662_FIXUP_ASPIRE] = { |
5320 | .type = HDA_FIXUP_PINS, | 5318 | .type = HDA_FIXUP_PINS, |
5321 | .v.pins = (const struct hda_pintbl[]) { | 5319 | .v.pins = (const struct hda_pintbl[]) { |
5322 | { 0x15, 0x99130112 }, /* subwoofer */ | 5320 | { 0x15, 0x99130112 }, /* subwoofer */ |
5323 | { } | 5321 | { } |
5324 | } | 5322 | } |
5325 | }, | 5323 | }, |
5326 | [ALC662_FIXUP_LED_GPIO1] = { | 5324 | [ALC662_FIXUP_LED_GPIO1] = { |
5327 | .type = HDA_FIXUP_FUNC, | 5325 | .type = HDA_FIXUP_FUNC, |
5328 | .v.func = alc662_fixup_led_gpio1, | 5326 | .v.func = alc662_fixup_led_gpio1, |
5329 | }, | 5327 | }, |
5330 | [ALC662_FIXUP_IDEAPAD] = { | 5328 | [ALC662_FIXUP_IDEAPAD] = { |
5331 | .type = HDA_FIXUP_PINS, | 5329 | .type = HDA_FIXUP_PINS, |
5332 | .v.pins = (const struct hda_pintbl[]) { | 5330 | .v.pins = (const struct hda_pintbl[]) { |
5333 | { 0x17, 0x99130112 }, /* subwoofer */ | 5331 | { 0x17, 0x99130112 }, /* subwoofer */ |
5334 | { } | 5332 | { } |
5335 | }, | 5333 | }, |
5336 | .chained = true, | 5334 | .chained = true, |
5337 | .chain_id = ALC662_FIXUP_LED_GPIO1, | 5335 | .chain_id = ALC662_FIXUP_LED_GPIO1, |
5338 | }, | 5336 | }, |
5339 | [ALC272_FIXUP_MARIO] = { | 5337 | [ALC272_FIXUP_MARIO] = { |
5340 | .type = HDA_FIXUP_FUNC, | 5338 | .type = HDA_FIXUP_FUNC, |
5341 | .v.func = alc272_fixup_mario, | 5339 | .v.func = alc272_fixup_mario, |
5342 | }, | 5340 | }, |
5343 | [ALC662_FIXUP_CZC_P10T] = { | 5341 | [ALC662_FIXUP_CZC_P10T] = { |
5344 | .type = HDA_FIXUP_VERBS, | 5342 | .type = HDA_FIXUP_VERBS, |
5345 | .v.verbs = (const struct hda_verb[]) { | 5343 | .v.verbs = (const struct hda_verb[]) { |
5346 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, | 5344 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, |
5347 | {} | 5345 | {} |
5348 | } | 5346 | } |
5349 | }, | 5347 | }, |
5350 | [ALC662_FIXUP_SKU_IGNORE] = { | 5348 | [ALC662_FIXUP_SKU_IGNORE] = { |
5351 | .type = HDA_FIXUP_FUNC, | 5349 | .type = HDA_FIXUP_FUNC, |
5352 | .v.func = alc_fixup_sku_ignore, | 5350 | .v.func = alc_fixup_sku_ignore, |
5353 | }, | 5351 | }, |
5354 | [ALC662_FIXUP_HP_RP5800] = { | 5352 | [ALC662_FIXUP_HP_RP5800] = { |
5355 | .type = HDA_FIXUP_PINS, | 5353 | .type = HDA_FIXUP_PINS, |
5356 | .v.pins = (const struct hda_pintbl[]) { | 5354 | .v.pins = (const struct hda_pintbl[]) { |
5357 | { 0x14, 0x0221201f }, /* HP out */ | 5355 | { 0x14, 0x0221201f }, /* HP out */ |
5358 | { } | 5356 | { } |
5359 | }, | 5357 | }, |
5360 | .chained = true, | 5358 | .chained = true, |
5361 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5359 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5362 | }, | 5360 | }, |
5363 | [ALC662_FIXUP_ASUS_MODE1] = { | 5361 | [ALC662_FIXUP_ASUS_MODE1] = { |
5364 | .type = HDA_FIXUP_PINS, | 5362 | .type = HDA_FIXUP_PINS, |
5365 | .v.pins = (const struct hda_pintbl[]) { | 5363 | .v.pins = (const struct hda_pintbl[]) { |
5366 | { 0x14, 0x99130110 }, /* speaker */ | 5364 | { 0x14, 0x99130110 }, /* speaker */ |
5367 | { 0x18, 0x01a19c20 }, /* mic */ | 5365 | { 0x18, 0x01a19c20 }, /* mic */ |
5368 | { 0x19, 0x99a3092f }, /* int-mic */ | 5366 | { 0x19, 0x99a3092f }, /* int-mic */ |
5369 | { 0x21, 0x0121401f }, /* HP out */ | 5367 | { 0x21, 0x0121401f }, /* HP out */ |
5370 | { } | 5368 | { } |
5371 | }, | 5369 | }, |
5372 | .chained = true, | 5370 | .chained = true, |
5373 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5371 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5374 | }, | 5372 | }, |
5375 | [ALC662_FIXUP_ASUS_MODE2] = { | 5373 | [ALC662_FIXUP_ASUS_MODE2] = { |
5376 | .type = HDA_FIXUP_PINS, | 5374 | .type = HDA_FIXUP_PINS, |
5377 | .v.pins = (const struct hda_pintbl[]) { | 5375 | .v.pins = (const struct hda_pintbl[]) { |
5378 | { 0x14, 0x99130110 }, /* speaker */ | 5376 | { 0x14, 0x99130110 }, /* speaker */ |
5379 | { 0x18, 0x01a19820 }, /* mic */ | 5377 | { 0x18, 0x01a19820 }, /* mic */ |
5380 | { 0x19, 0x99a3092f }, /* int-mic */ | 5378 | { 0x19, 0x99a3092f }, /* int-mic */ |
5381 | { 0x1b, 0x0121401f }, /* HP out */ | 5379 | { 0x1b, 0x0121401f }, /* HP out */ |
5382 | { } | 5380 | { } |
5383 | }, | 5381 | }, |
5384 | .chained = true, | 5382 | .chained = true, |
5385 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5383 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5386 | }, | 5384 | }, |
5387 | [ALC662_FIXUP_ASUS_MODE3] = { | 5385 | [ALC662_FIXUP_ASUS_MODE3] = { |
5388 | .type = HDA_FIXUP_PINS, | 5386 | .type = HDA_FIXUP_PINS, |
5389 | .v.pins = (const struct hda_pintbl[]) { | 5387 | .v.pins = (const struct hda_pintbl[]) { |
5390 | { 0x14, 0x99130110 }, /* speaker */ | 5388 | { 0x14, 0x99130110 }, /* speaker */ |
5391 | { 0x15, 0x0121441f }, /* HP */ | 5389 | { 0x15, 0x0121441f }, /* HP */ |
5392 | { 0x18, 0x01a19840 }, /* mic */ | 5390 | { 0x18, 0x01a19840 }, /* mic */ |
5393 | { 0x19, 0x99a3094f }, /* int-mic */ | 5391 | { 0x19, 0x99a3094f }, /* int-mic */ |
5394 | { 0x21, 0x01211420 }, /* HP2 */ | 5392 | { 0x21, 0x01211420 }, /* HP2 */ |
5395 | { } | 5393 | { } |
5396 | }, | 5394 | }, |
5397 | .chained = true, | 5395 | .chained = true, |
5398 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5396 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5399 | }, | 5397 | }, |
5400 | [ALC662_FIXUP_ASUS_MODE4] = { | 5398 | [ALC662_FIXUP_ASUS_MODE4] = { |
5401 | .type = HDA_FIXUP_PINS, | 5399 | .type = HDA_FIXUP_PINS, |
5402 | .v.pins = (const struct hda_pintbl[]) { | 5400 | .v.pins = (const struct hda_pintbl[]) { |
5403 | { 0x14, 0x99130110 }, /* speaker */ | 5401 | { 0x14, 0x99130110 }, /* speaker */ |
5404 | { 0x16, 0x99130111 }, /* speaker */ | 5402 | { 0x16, 0x99130111 }, /* speaker */ |
5405 | { 0x18, 0x01a19840 }, /* mic */ | 5403 | { 0x18, 0x01a19840 }, /* mic */ |
5406 | { 0x19, 0x99a3094f }, /* int-mic */ | 5404 | { 0x19, 0x99a3094f }, /* int-mic */ |
5407 | { 0x21, 0x0121441f }, /* HP */ | 5405 | { 0x21, 0x0121441f }, /* HP */ |
5408 | { } | 5406 | { } |
5409 | }, | 5407 | }, |
5410 | .chained = true, | 5408 | .chained = true, |
5411 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5409 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5412 | }, | 5410 | }, |
5413 | [ALC662_FIXUP_ASUS_MODE5] = { | 5411 | [ALC662_FIXUP_ASUS_MODE5] = { |
5414 | .type = HDA_FIXUP_PINS, | 5412 | .type = HDA_FIXUP_PINS, |
5415 | .v.pins = (const struct hda_pintbl[]) { | 5413 | .v.pins = (const struct hda_pintbl[]) { |
5416 | { 0x14, 0x99130110 }, /* speaker */ | 5414 | { 0x14, 0x99130110 }, /* speaker */ |
5417 | { 0x15, 0x0121441f }, /* HP */ | 5415 | { 0x15, 0x0121441f }, /* HP */ |
5418 | { 0x16, 0x99130111 }, /* speaker */ | 5416 | { 0x16, 0x99130111 }, /* speaker */ |
5419 | { 0x18, 0x01a19840 }, /* mic */ | 5417 | { 0x18, 0x01a19840 }, /* mic */ |
5420 | { 0x19, 0x99a3094f }, /* int-mic */ | 5418 | { 0x19, 0x99a3094f }, /* int-mic */ |
5421 | { } | 5419 | { } |
5422 | }, | 5420 | }, |
5423 | .chained = true, | 5421 | .chained = true, |
5424 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5422 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5425 | }, | 5423 | }, |
5426 | [ALC662_FIXUP_ASUS_MODE6] = { | 5424 | [ALC662_FIXUP_ASUS_MODE6] = { |
5427 | .type = HDA_FIXUP_PINS, | 5425 | .type = HDA_FIXUP_PINS, |
5428 | .v.pins = (const struct hda_pintbl[]) { | 5426 | .v.pins = (const struct hda_pintbl[]) { |
5429 | { 0x14, 0x99130110 }, /* speaker */ | 5427 | { 0x14, 0x99130110 }, /* speaker */ |
5430 | { 0x15, 0x01211420 }, /* HP2 */ | 5428 | { 0x15, 0x01211420 }, /* HP2 */ |
5431 | { 0x18, 0x01a19840 }, /* mic */ | 5429 | { 0x18, 0x01a19840 }, /* mic */ |
5432 | { 0x19, 0x99a3094f }, /* int-mic */ | 5430 | { 0x19, 0x99a3094f }, /* int-mic */ |
5433 | { 0x1b, 0x0121441f }, /* HP */ | 5431 | { 0x1b, 0x0121441f }, /* HP */ |
5434 | { } | 5432 | { } |
5435 | }, | 5433 | }, |
5436 | .chained = true, | 5434 | .chained = true, |
5437 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5435 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5438 | }, | 5436 | }, |
5439 | [ALC662_FIXUP_ASUS_MODE7] = { | 5437 | [ALC662_FIXUP_ASUS_MODE7] = { |
5440 | .type = HDA_FIXUP_PINS, | 5438 | .type = HDA_FIXUP_PINS, |
5441 | .v.pins = (const struct hda_pintbl[]) { | 5439 | .v.pins = (const struct hda_pintbl[]) { |
5442 | { 0x14, 0x99130110 }, /* speaker */ | 5440 | { 0x14, 0x99130110 }, /* speaker */ |
5443 | { 0x17, 0x99130111 }, /* speaker */ | 5441 | { 0x17, 0x99130111 }, /* speaker */ |
5444 | { 0x18, 0x01a19840 }, /* mic */ | 5442 | { 0x18, 0x01a19840 }, /* mic */ |
5445 | { 0x19, 0x99a3094f }, /* int-mic */ | 5443 | { 0x19, 0x99a3094f }, /* int-mic */ |
5446 | { 0x1b, 0x01214020 }, /* HP */ | 5444 | { 0x1b, 0x01214020 }, /* HP */ |
5447 | { 0x21, 0x0121401f }, /* HP */ | 5445 | { 0x21, 0x0121401f }, /* HP */ |
5448 | { } | 5446 | { } |
5449 | }, | 5447 | }, |
5450 | .chained = true, | 5448 | .chained = true, |
5451 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5449 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5452 | }, | 5450 | }, |
5453 | [ALC662_FIXUP_ASUS_MODE8] = { | 5451 | [ALC662_FIXUP_ASUS_MODE8] = { |
5454 | .type = HDA_FIXUP_PINS, | 5452 | .type = HDA_FIXUP_PINS, |
5455 | .v.pins = (const struct hda_pintbl[]) { | 5453 | .v.pins = (const struct hda_pintbl[]) { |
5456 | { 0x14, 0x99130110 }, /* speaker */ | 5454 | { 0x14, 0x99130110 }, /* speaker */ |
5457 | { 0x12, 0x99a30970 }, /* int-mic */ | 5455 | { 0x12, 0x99a30970 }, /* int-mic */ |
5458 | { 0x15, 0x01214020 }, /* HP */ | 5456 | { 0x15, 0x01214020 }, /* HP */ |
5459 | { 0x17, 0x99130111 }, /* speaker */ | 5457 | { 0x17, 0x99130111 }, /* speaker */ |
5460 | { 0x18, 0x01a19840 }, /* mic */ | 5458 | { 0x18, 0x01a19840 }, /* mic */ |
5461 | { 0x21, 0x0121401f }, /* HP */ | 5459 | { 0x21, 0x0121401f }, /* HP */ |
5462 | { } | 5460 | { } |
5463 | }, | 5461 | }, |
5464 | .chained = true, | 5462 | .chained = true, |
5465 | .chain_id = ALC662_FIXUP_SKU_IGNORE | 5463 | .chain_id = ALC662_FIXUP_SKU_IGNORE |
5466 | }, | 5464 | }, |
5467 | [ALC662_FIXUP_NO_JACK_DETECT] = { | 5465 | [ALC662_FIXUP_NO_JACK_DETECT] = { |
5468 | .type = HDA_FIXUP_FUNC, | 5466 | .type = HDA_FIXUP_FUNC, |
5469 | .v.func = alc_fixup_no_jack_detect, | 5467 | .v.func = alc_fixup_no_jack_detect, |
5470 | }, | 5468 | }, |
5471 | [ALC662_FIXUP_ZOTAC_Z68] = { | 5469 | [ALC662_FIXUP_ZOTAC_Z68] = { |
5472 | .type = HDA_FIXUP_PINS, | 5470 | .type = HDA_FIXUP_PINS, |
5473 | .v.pins = (const struct hda_pintbl[]) { | 5471 | .v.pins = (const struct hda_pintbl[]) { |
5474 | { 0x1b, 0x02214020 }, /* Front HP */ | 5472 | { 0x1b, 0x02214020 }, /* Front HP */ |
5475 | { } | 5473 | { } |
5476 | } | 5474 | } |
5477 | }, | 5475 | }, |
5478 | [ALC662_FIXUP_INV_DMIC] = { | 5476 | [ALC662_FIXUP_INV_DMIC] = { |
5479 | .type = HDA_FIXUP_FUNC, | 5477 | .type = HDA_FIXUP_FUNC, |
5480 | .v.func = alc_fixup_inv_dmic_0x12, | 5478 | .v.func = alc_fixup_inv_dmic_0x12, |
5481 | }, | 5479 | }, |
5482 | [ALC668_FIXUP_AUTO_MUTE] = { | 5480 | [ALC668_FIXUP_AUTO_MUTE] = { |
5483 | .type = HDA_FIXUP_FUNC, | 5481 | .type = HDA_FIXUP_FUNC, |
5484 | .v.func = alc_fixup_auto_mute_via_amp, | 5482 | .v.func = alc_fixup_auto_mute_via_amp, |
5485 | .chained = true, | 5483 | .chained = true, |
5486 | .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE | 5484 | .chain_id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE |
5487 | }, | 5485 | }, |
5488 | [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = { | 5486 | [ALC668_FIXUP_DELL_MIC_NO_PRESENCE] = { |
5489 | .type = HDA_FIXUP_PINS, | 5487 | .type = HDA_FIXUP_PINS, |
5490 | .v.pins = (const struct hda_pintbl[]) { | 5488 | .v.pins = (const struct hda_pintbl[]) { |
5491 | { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */ | 5489 | { 0x19, 0x03a1913d }, /* use as headphone mic, without its own jack detect */ |
5492 | { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */ | 5490 | { 0x1b, 0x03a1113c }, /* use as headset mic, without its own jack detect */ |
5493 | { } | 5491 | { } |
5494 | }, | 5492 | }, |
5495 | .chained = true, | 5493 | .chained = true, |
5496 | .chain_id = ALC668_FIXUP_HEADSET_MODE | 5494 | .chain_id = ALC668_FIXUP_HEADSET_MODE |
5497 | }, | 5495 | }, |
5498 | [ALC668_FIXUP_HEADSET_MODE] = { | 5496 | [ALC668_FIXUP_HEADSET_MODE] = { |
5499 | .type = HDA_FIXUP_FUNC, | 5497 | .type = HDA_FIXUP_FUNC, |
5500 | .v.func = alc_fixup_headset_mode_alc668, | 5498 | .v.func = alc_fixup_headset_mode_alc668, |
5501 | }, | 5499 | }, |
5502 | [ALC662_FIXUP_BASS_MODE4_CHMAP] = { | 5500 | [ALC662_FIXUP_BASS_MODE4_CHMAP] = { |
5503 | .type = HDA_FIXUP_FUNC, | 5501 | .type = HDA_FIXUP_FUNC, |
5504 | .v.func = alc_fixup_bass_chmap, | 5502 | .v.func = alc_fixup_bass_chmap, |
5505 | .chained = true, | 5503 | .chained = true, |
5506 | .chain_id = ALC662_FIXUP_ASUS_MODE4 | 5504 | .chain_id = ALC662_FIXUP_ASUS_MODE4 |
5507 | }, | 5505 | }, |
5508 | [ALC662_FIXUP_BASS_16] = { | 5506 | [ALC662_FIXUP_BASS_16] = { |
5509 | .type = HDA_FIXUP_PINS, | 5507 | .type = HDA_FIXUP_PINS, |
5510 | .v.pins = (const struct hda_pintbl[]) { | 5508 | .v.pins = (const struct hda_pintbl[]) { |
5511 | {0x16, 0x80106111}, /* bass speaker */ | 5509 | {0x16, 0x80106111}, /* bass speaker */ |
5512 | {} | 5510 | {} |
5513 | }, | 5511 | }, |
5514 | .chained = true, | 5512 | .chained = true, |
5515 | .chain_id = ALC662_FIXUP_BASS_CHMAP, | 5513 | .chain_id = ALC662_FIXUP_BASS_CHMAP, |
5516 | }, | 5514 | }, |
5517 | [ALC662_FIXUP_BASS_1A] = { | 5515 | [ALC662_FIXUP_BASS_1A] = { |
5518 | .type = HDA_FIXUP_PINS, | 5516 | .type = HDA_FIXUP_PINS, |
5519 | .v.pins = (const struct hda_pintbl[]) { | 5517 | .v.pins = (const struct hda_pintbl[]) { |
5520 | {0x1a, 0x80106111}, /* bass speaker */ | 5518 | {0x1a, 0x80106111}, /* bass speaker */ |
5521 | {} | 5519 | {} |
5522 | }, | 5520 | }, |
5523 | .chained = true, | 5521 | .chained = true, |
5524 | .chain_id = ALC662_FIXUP_BASS_CHMAP, | 5522 | .chain_id = ALC662_FIXUP_BASS_CHMAP, |
5525 | }, | 5523 | }, |
5526 | [ALC662_FIXUP_BASS_CHMAP] = { | 5524 | [ALC662_FIXUP_BASS_CHMAP] = { |
5527 | .type = HDA_FIXUP_FUNC, | 5525 | .type = HDA_FIXUP_FUNC, |
5528 | .v.func = alc_fixup_bass_chmap, | 5526 | .v.func = alc_fixup_bass_chmap, |
5529 | }, | 5527 | }, |
5530 | }; | 5528 | }; |
5531 | 5529 | ||
5532 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { | 5530 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { |
5533 | SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2), | 5531 | SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2), |
5534 | SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC), | 5532 | SND_PCI_QUIRK(0x1025, 0x022f, "Acer Aspire One", ALC662_FIXUP_INV_DMIC), |
5535 | SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), | 5533 | SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), |
5536 | SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), | 5534 | SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), |
5537 | SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC), | 5535 | SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC), |
5538 | SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC), | 5536 | SND_PCI_QUIRK(0x1025, 0x034a, "Gateway LT27", ALC662_FIXUP_INV_DMIC), |
5539 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), | 5537 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), |
5540 | SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5538 | SND_PCI_QUIRK(0x1028, 0x05d8, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5541 | SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5539 | SND_PCI_QUIRK(0x1028, 0x05db, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5542 | SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5540 | SND_PCI_QUIRK(0x1028, 0x060a, "Dell XPS 13", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5543 | SND_PCI_QUIRK(0x1028, 0x0623, "Dell", ALC668_FIXUP_AUTO_MUTE), | 5541 | SND_PCI_QUIRK(0x1028, 0x0623, "Dell", ALC668_FIXUP_AUTO_MUTE), |
5544 | SND_PCI_QUIRK(0x1028, 0x0624, "Dell", ALC668_FIXUP_AUTO_MUTE), | 5542 | SND_PCI_QUIRK(0x1028, 0x0624, "Dell", ALC668_FIXUP_AUTO_MUTE), |
5545 | SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5543 | SND_PCI_QUIRK(0x1028, 0x0625, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5546 | SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5544 | SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5547 | SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE), | 5545 | SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE), |
5548 | SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_AUTO_MUTE), | 5546 | SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_AUTO_MUTE), |
5549 | SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5547 | SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5550 | SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), | 5548 | SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE), |
5551 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), | 5549 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), |
5552 | SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A), | 5550 | SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A), |
5553 | SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), | 5551 | SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), |
5554 | SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16), | 5552 | SND_PCI_QUIRK(0x1043, 0x15a7, "ASUS UX51VZH", ALC662_FIXUP_BASS_16), |
5555 | SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16), | 5553 | SND_PCI_QUIRK(0x1043, 0x1b73, "ASUS N55SF", ALC662_FIXUP_BASS_16), |
5556 | SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), | 5554 | SND_PCI_QUIRK(0x1043, 0x1bf3, "ASUS N76VZ", ALC662_FIXUP_BASS_MODE4_CHMAP), |
5557 | SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), | 5555 | SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), |
5558 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), | 5556 | SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_FIXUP_ASUS_MODE2), |
5559 | SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), | 5557 | SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), |
5560 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), | 5558 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), |
5561 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), | 5559 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), |
5562 | SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68), | 5560 | SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68), |
5563 | SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), | 5561 | SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), |
5564 | 5562 | ||
5565 | #if 0 | 5563 | #if 0 |
5566 | /* Below is a quirk table taken from the old code. | 5564 | /* Below is a quirk table taken from the old code. |
5567 | * Basically the device should work as is without the fixup table. | 5565 | * Basically the device should work as is without the fixup table. |
5568 | * If BIOS doesn't give a proper info, enable the corresponding | 5566 | * If BIOS doesn't give a proper info, enable the corresponding |
5569 | * fixup entry. | 5567 | * fixup entry. |
5570 | */ | 5568 | */ |
5571 | SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1), | 5569 | SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC662_FIXUP_ASUS_MODE1), |
5572 | SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3), | 5570 | SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC662_FIXUP_ASUS_MODE3), |
5573 | SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1), | 5571 | SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC662_FIXUP_ASUS_MODE1), |
5574 | SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3), | 5572 | SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC662_FIXUP_ASUS_MODE3), |
5575 | SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), | 5573 | SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), |
5576 | SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5574 | SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5577 | SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), | 5575 | SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), |
5578 | SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1), | 5576 | SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC662_FIXUP_ASUS_MODE1), |
5579 | SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1), | 5577 | SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC662_FIXUP_ASUS_MODE1), |
5580 | SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5578 | SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5581 | SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7), | 5579 | SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC662_FIXUP_ASUS_MODE7), |
5582 | SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7), | 5580 | SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC662_FIXUP_ASUS_MODE7), |
5583 | SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8), | 5581 | SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC662_FIXUP_ASUS_MODE8), |
5584 | SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3), | 5582 | SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC662_FIXUP_ASUS_MODE3), |
5585 | SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1), | 5583 | SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC662_FIXUP_ASUS_MODE1), |
5586 | SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5584 | SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5587 | SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2), | 5585 | SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_FIXUP_ASUS_MODE2), |
5588 | SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1), | 5586 | SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC662_FIXUP_ASUS_MODE1), |
5589 | SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5587 | SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5590 | SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), | 5588 | SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), |
5591 | SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), | 5589 | SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), |
5592 | SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5590 | SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5593 | SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1), | 5591 | SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC662_FIXUP_ASUS_MODE1), |
5594 | SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3), | 5592 | SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC662_FIXUP_ASUS_MODE3), |
5595 | SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2), | 5593 | SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_FIXUP_ASUS_MODE2), |
5596 | SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5594 | SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5597 | SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5), | 5595 | SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC662_FIXUP_ASUS_MODE5), |
5598 | SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), | 5596 | SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC662_FIXUP_ASUS_MODE6), |
5599 | SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5597 | SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5600 | SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1), | 5598 | SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC662_FIXUP_ASUS_MODE1), |
5601 | SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5599 | SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5602 | SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5600 | SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5603 | SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3), | 5601 | SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC662_FIXUP_ASUS_MODE3), |
5604 | SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3), | 5602 | SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC662_FIXUP_ASUS_MODE3), |
5605 | SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1), | 5603 | SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC662_FIXUP_ASUS_MODE1), |
5606 | SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1), | 5604 | SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC662_FIXUP_ASUS_MODE1), |
5607 | SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1), | 5605 | SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC662_FIXUP_ASUS_MODE1), |
5608 | SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1), | 5606 | SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC662_FIXUP_ASUS_MODE1), |
5609 | SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1), | 5607 | SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC662_FIXUP_ASUS_MODE1), |
5610 | SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), | 5608 | SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_FIXUP_ASUS_MODE2), |
5611 | SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2), | 5609 | SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_FIXUP_ASUS_MODE2), |
5612 | SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1), | 5610 | SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC662_FIXUP_ASUS_MODE1), |
5613 | SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), | 5611 | SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), |
5614 | SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3), | 5612 | SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC662_FIXUP_ASUS_MODE3), |
5615 | SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1), | 5613 | SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC662_FIXUP_ASUS_MODE1), |
5616 | SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1), | 5614 | SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC662_FIXUP_ASUS_MODE1), |
5617 | SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1), | 5615 | SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC662_FIXUP_ASUS_MODE1), |
5618 | SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2), | 5616 | SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_FIXUP_ASUS_MODE2), |
5619 | SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), | 5617 | SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC662_FIXUP_ASUS_MODE1), |
5620 | SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4), | 5618 | SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC662_FIXUP_ASUS_MODE4), |
5621 | #endif | 5619 | #endif |
5622 | {} | 5620 | {} |
5623 | }; | 5621 | }; |
5624 | 5622 | ||
5625 | static const struct hda_model_fixup alc662_fixup_models[] = { | 5623 | static const struct hda_model_fixup alc662_fixup_models[] = { |
5626 | {.id = ALC272_FIXUP_MARIO, .name = "mario"}, | 5624 | {.id = ALC272_FIXUP_MARIO, .name = "mario"}, |
5627 | {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"}, | 5625 | {.id = ALC662_FIXUP_ASUS_MODE1, .name = "asus-mode1"}, |
5628 | {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"}, | 5626 | {.id = ALC662_FIXUP_ASUS_MODE2, .name = "asus-mode2"}, |
5629 | {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"}, | 5627 | {.id = ALC662_FIXUP_ASUS_MODE3, .name = "asus-mode3"}, |
5630 | {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"}, | 5628 | {.id = ALC662_FIXUP_ASUS_MODE4, .name = "asus-mode4"}, |
5631 | {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"}, | 5629 | {.id = ALC662_FIXUP_ASUS_MODE5, .name = "asus-mode5"}, |
5632 | {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"}, | 5630 | {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"}, |
5633 | {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, | 5631 | {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, |
5634 | {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, | 5632 | {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, |
5635 | {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"}, | 5633 | {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"}, |
5636 | {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, | 5634 | {.id = ALC668_FIXUP_DELL_MIC_NO_PRESENCE, .name = "dell-headset-multi"}, |
5637 | {} | 5635 | {} |
5638 | }; | 5636 | }; |
5639 | 5637 | ||
5640 | static void alc662_fill_coef(struct hda_codec *codec) | 5638 | static void alc662_fill_coef(struct hda_codec *codec) |
5641 | { | 5639 | { |
5642 | int val, coef; | 5640 | int val, coef; |
5643 | 5641 | ||
5644 | coef = alc_get_coef0(codec); | 5642 | coef = alc_get_coef0(codec); |
5645 | 5643 | ||
5646 | switch (codec->vendor_id) { | 5644 | switch (codec->vendor_id) { |
5647 | case 0x10ec0662: | 5645 | case 0x10ec0662: |
5648 | if ((coef & 0x00f0) == 0x0030) { | 5646 | if ((coef & 0x00f0) == 0x0030) { |
5649 | val = alc_read_coef_idx(codec, 0x4); /* EAPD Ctrl */ | 5647 | val = alc_read_coef_idx(codec, 0x4); /* EAPD Ctrl */ |
5650 | alc_write_coef_idx(codec, 0x4, val & ~(1<<10)); | 5648 | alc_write_coef_idx(codec, 0x4, val & ~(1<<10)); |
5651 | } | 5649 | } |
5652 | break; | 5650 | break; |
5653 | case 0x10ec0272: | 5651 | case 0x10ec0272: |
5654 | case 0x10ec0273: | 5652 | case 0x10ec0273: |
5655 | case 0x10ec0663: | 5653 | case 0x10ec0663: |
5656 | case 0x10ec0665: | 5654 | case 0x10ec0665: |
5657 | case 0x10ec0670: | 5655 | case 0x10ec0670: |
5658 | case 0x10ec0671: | 5656 | case 0x10ec0671: |
5659 | case 0x10ec0672: | 5657 | case 0x10ec0672: |
5660 | val = alc_read_coef_idx(codec, 0xd); /* EAPD Ctrl */ | 5658 | val = alc_read_coef_idx(codec, 0xd); /* EAPD Ctrl */ |
5661 | alc_write_coef_idx(codec, 0xd, val | (1<<14)); | 5659 | alc_write_coef_idx(codec, 0xd, val | (1<<14)); |
5662 | break; | 5660 | break; |
5663 | } | 5661 | } |
5664 | } | 5662 | } |
5665 | 5663 | ||
5666 | /* | 5664 | /* |
5667 | */ | 5665 | */ |
5668 | static int patch_alc662(struct hda_codec *codec) | 5666 | static int patch_alc662(struct hda_codec *codec) |
5669 | { | 5667 | { |
5670 | struct alc_spec *spec; | 5668 | struct alc_spec *spec; |
5671 | int err; | 5669 | int err; |
5672 | 5670 | ||
5673 | err = alc_alloc_spec(codec, 0x0b); | 5671 | err = alc_alloc_spec(codec, 0x0b); |
5674 | if (err < 0) | 5672 | if (err < 0) |
5675 | return err; | 5673 | return err; |
5676 | 5674 | ||
5677 | spec = codec->spec; | 5675 | spec = codec->spec; |
5678 | 5676 | ||
5679 | /* handle multiple HPs as is */ | 5677 | /* handle multiple HPs as is */ |
5680 | spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; | 5678 | spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP; |
5681 | 5679 | ||
5682 | alc_fix_pll_init(codec, 0x20, 0x04, 15); | 5680 | alc_fix_pll_init(codec, 0x20, 0x04, 15); |
5683 | 5681 | ||
5684 | spec->init_hook = alc662_fill_coef; | 5682 | spec->init_hook = alc662_fill_coef; |
5685 | alc662_fill_coef(codec); | 5683 | alc662_fill_coef(codec); |
5686 | 5684 | ||
5687 | snd_hda_pick_fixup(codec, alc662_fixup_models, | 5685 | snd_hda_pick_fixup(codec, alc662_fixup_models, |
5688 | alc662_fixup_tbl, alc662_fixups); | 5686 | alc662_fixup_tbl, alc662_fixups); |
5689 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); | 5687 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); |
5690 | 5688 | ||
5691 | alc_auto_parse_customize_define(codec); | 5689 | alc_auto_parse_customize_define(codec); |
5692 | 5690 | ||
5693 | if (has_cdefine_beep(codec)) | 5691 | if (has_cdefine_beep(codec)) |
5694 | spec->gen.beep_nid = 0x01; | 5692 | spec->gen.beep_nid = 0x01; |
5695 | 5693 | ||
5696 | if ((alc_get_coef0(codec) & (1 << 14)) && | 5694 | if ((alc_get_coef0(codec) & (1 << 14)) && |
5697 | codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 && | 5695 | codec->bus->pci && codec->bus->pci->subsystem_vendor == 0x1025 && |
5698 | spec->cdefine.platform_type == 1) { | 5696 | spec->cdefine.platform_type == 1) { |
5699 | err = alc_codec_rename(codec, "ALC272X"); | 5697 | err = alc_codec_rename(codec, "ALC272X"); |
5700 | if (err < 0) | 5698 | if (err < 0) |
5701 | goto error; | 5699 | goto error; |
5702 | } | 5700 | } |
5703 | 5701 | ||
5704 | /* automatic parse from the BIOS config */ | 5702 | /* automatic parse from the BIOS config */ |
5705 | err = alc662_parse_auto_config(codec); | 5703 | err = alc662_parse_auto_config(codec); |
5706 | if (err < 0) | 5704 | if (err < 0) |
5707 | goto error; | 5705 | goto error; |
5708 | 5706 | ||
5709 | if (!spec->gen.no_analog && spec->gen.beep_nid) { | 5707 | if (!spec->gen.no_analog && spec->gen.beep_nid) { |
5710 | switch (codec->vendor_id) { | 5708 | switch (codec->vendor_id) { |
5711 | case 0x10ec0662: | 5709 | case 0x10ec0662: |
5712 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 5710 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
5713 | break; | 5711 | break; |
5714 | case 0x10ec0272: | 5712 | case 0x10ec0272: |
5715 | case 0x10ec0663: | 5713 | case 0x10ec0663: |
5716 | case 0x10ec0665: | 5714 | case 0x10ec0665: |
5717 | case 0x10ec0668: | 5715 | case 0x10ec0668: |
5718 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); | 5716 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); |
5719 | break; | 5717 | break; |
5720 | case 0x10ec0273: | 5718 | case 0x10ec0273: |
5721 | set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT); | 5719 | set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT); |
5722 | break; | 5720 | break; |
5723 | } | 5721 | } |
5724 | } | 5722 | } |
5725 | 5723 | ||
5726 | codec->patch_ops = alc_patch_ops; | 5724 | codec->patch_ops = alc_patch_ops; |
5727 | spec->shutup = alc_eapd_shutup; | 5725 | spec->shutup = alc_eapd_shutup; |
5728 | 5726 | ||
5729 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); | 5727 | snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); |
5730 | 5728 | ||
5731 | return 0; | 5729 | return 0; |
5732 | 5730 | ||
5733 | error: | 5731 | error: |
5734 | alc_free(codec); | 5732 | alc_free(codec); |
5735 | return err; | 5733 | return err; |
5736 | } | 5734 | } |
5737 | 5735 | ||
5738 | /* | 5736 | /* |
5739 | * ALC680 support | 5737 | * ALC680 support |
5740 | */ | 5738 | */ |
5741 | 5739 | ||
5742 | static int alc680_parse_auto_config(struct hda_codec *codec) | 5740 | static int alc680_parse_auto_config(struct hda_codec *codec) |
5743 | { | 5741 | { |
5744 | return alc_parse_auto_config(codec, NULL, NULL); | 5742 | return alc_parse_auto_config(codec, NULL, NULL); |
5745 | } | 5743 | } |
5746 | 5744 | ||
5747 | /* | 5745 | /* |
5748 | */ | 5746 | */ |
5749 | static int patch_alc680(struct hda_codec *codec) | 5747 | static int patch_alc680(struct hda_codec *codec) |
5750 | { | 5748 | { |
5751 | int err; | 5749 | int err; |
5752 | 5750 | ||
5753 | /* ALC680 has no aa-loopback mixer */ | 5751 | /* ALC680 has no aa-loopback mixer */ |
5754 | err = alc_alloc_spec(codec, 0); | 5752 | err = alc_alloc_spec(codec, 0); |
5755 | if (err < 0) | 5753 | if (err < 0) |
5756 | return err; | 5754 | return err; |
5757 | 5755 | ||
5758 | /* automatic parse from the BIOS config */ | 5756 | /* automatic parse from the BIOS config */ |
5759 | err = alc680_parse_auto_config(codec); | 5757 | err = alc680_parse_auto_config(codec); |
5760 | if (err < 0) { | 5758 | if (err < 0) { |
5761 | alc_free(codec); | 5759 | alc_free(codec); |
5762 | return err; | 5760 | return err; |
5763 | } | 5761 | } |
5764 | 5762 | ||
5765 | codec->patch_ops = alc_patch_ops; | 5763 | codec->patch_ops = alc_patch_ops; |
5766 | 5764 | ||
5767 | return 0; | 5765 | return 0; |
5768 | } | 5766 | } |
5769 | 5767 | ||
5770 | /* | 5768 | /* |
5771 | * patch entries | 5769 | * patch entries |
5772 | */ | 5770 | */ |
5773 | static const struct hda_codec_preset snd_hda_preset_realtek[] = { | 5771 | static const struct hda_codec_preset snd_hda_preset_realtek[] = { |
5774 | { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 }, | 5772 | { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 }, |
5775 | { .id = 0x10ec0231, .name = "ALC231", .patch = patch_alc269 }, | 5773 | { .id = 0x10ec0231, .name = "ALC231", .patch = patch_alc269 }, |
5776 | { .id = 0x10ec0233, .name = "ALC233", .patch = patch_alc269 }, | 5774 | { .id = 0x10ec0233, .name = "ALC233", .patch = patch_alc269 }, |
5777 | { .id = 0x10ec0255, .name = "ALC255", .patch = patch_alc269 }, | 5775 | { .id = 0x10ec0255, .name = "ALC255", .patch = patch_alc269 }, |
5778 | { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, | 5776 | { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, |
5779 | { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, | 5777 | { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, |
5780 | { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, | 5778 | { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, |
5781 | { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, | 5779 | { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 }, |
5782 | { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, | 5780 | { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 }, |
5783 | { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, | 5781 | { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, |
5784 | { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, | 5782 | { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, |
5785 | { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, | 5783 | { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, |
5786 | { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 }, | 5784 | { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 }, |
5787 | { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 }, | 5785 | { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 }, |
5788 | { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 }, | 5786 | { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 }, |
5789 | { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 }, | 5787 | { .id = 0x10ec0283, .name = "ALC283", .patch = patch_alc269 }, |
5790 | { .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 }, | 5788 | { .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 }, |
5791 | { .id = 0x10ec0285, .name = "ALC285", .patch = patch_alc269 }, | 5789 | { .id = 0x10ec0285, .name = "ALC285", .patch = patch_alc269 }, |
5792 | { .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 }, | 5790 | { .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 }, |
5793 | { .id = 0x10ec0288, .name = "ALC288", .patch = patch_alc269 }, | 5791 | { .id = 0x10ec0288, .name = "ALC288", .patch = patch_alc269 }, |
5794 | { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 }, | 5792 | { .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 }, |
5795 | { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 }, | 5793 | { .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 }, |
5796 | { .id = 0x10ec0293, .name = "ALC293", .patch = patch_alc269 }, | 5794 | { .id = 0x10ec0293, .name = "ALC293", .patch = patch_alc269 }, |
5797 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", | 5795 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", |
5798 | .patch = patch_alc861 }, | 5796 | .patch = patch_alc861 }, |
5799 | { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, | 5797 | { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, |
5800 | { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, | 5798 | { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, |
5801 | { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, | 5799 | { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, |
5802 | { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", | 5800 | { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", |
5803 | .patch = patch_alc882 }, | 5801 | .patch = patch_alc882 }, |
5804 | { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", | 5802 | { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", |
5805 | .patch = patch_alc662 }, | 5803 | .patch = patch_alc662 }, |
5806 | { .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3", | 5804 | { .id = 0x10ec0662, .rev = 0x100300, .name = "ALC662 rev3", |
5807 | .patch = patch_alc662 }, | 5805 | .patch = patch_alc662 }, |
5808 | { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, | 5806 | { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 }, |
5809 | { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, | 5807 | { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 }, |
5810 | { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 }, | 5808 | { .id = 0x10ec0668, .name = "ALC668", .patch = patch_alc662 }, |
5811 | { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, | 5809 | { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 }, |
5812 | { .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 }, | 5810 | { .id = 0x10ec0671, .name = "ALC671", .patch = patch_alc662 }, |
5813 | { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, | 5811 | { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 }, |
5814 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, | 5812 | { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, |
5815 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, | 5813 | { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, |
5816 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, | 5814 | { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 }, |
5817 | { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", | 5815 | { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", |
5818 | .patch = patch_alc882 }, | 5816 | .patch = patch_alc882 }, |
5819 | { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", | 5817 | { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", |
5820 | .patch = patch_alc882 }, | 5818 | .patch = patch_alc882 }, |
5821 | { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, | 5819 | { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, |
5822 | { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 }, | 5820 | { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc882 }, |
5823 | { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", | 5821 | { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200", |
5824 | .patch = patch_alc882 }, | 5822 | .patch = patch_alc882 }, |
5825 | { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 }, | 5823 | { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc882 }, |
5826 | { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, | 5824 | { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, |
5827 | { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, | 5825 | { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, |
5828 | { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 }, | 5826 | { .id = 0x10ec0899, .name = "ALC898", .patch = patch_alc882 }, |
5829 | { .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 }, | 5827 | { .id = 0x10ec0900, .name = "ALC1150", .patch = patch_alc882 }, |
5830 | {} /* terminator */ | 5828 | {} /* terminator */ |
5831 | }; | 5829 | }; |
5832 | 5830 | ||
5833 | MODULE_ALIAS("snd-hda-codec-id:10ec*"); | 5831 | MODULE_ALIAS("snd-hda-codec-id:10ec*"); |
5834 | 5832 | ||
5835 | MODULE_LICENSE("GPL"); | 5833 | MODULE_LICENSE("GPL"); |
5836 | MODULE_DESCRIPTION("Realtek HD-audio codec"); | 5834 | MODULE_DESCRIPTION("Realtek HD-audio codec"); |
5837 | 5835 | ||
5838 | static struct hda_codec_preset_list realtek_list = { | 5836 | static struct hda_codec_preset_list realtek_list = { |
5839 | .preset = snd_hda_preset_realtek, | 5837 | .preset = snd_hda_preset_realtek, |
5840 | .owner = THIS_MODULE, | 5838 | .owner = THIS_MODULE, |
5841 | }; | 5839 | }; |
5842 | 5840 | ||
5843 | static int __init patch_realtek_init(void) | 5841 | static int __init patch_realtek_init(void) |
5844 | { | 5842 | { |
5845 | return snd_hda_add_codec_preset(&realtek_list); | 5843 | return snd_hda_add_codec_preset(&realtek_list); |
5846 | } | 5844 | } |
5847 | 5845 | ||
5848 | static void __exit patch_realtek_exit(void) | 5846 | static void __exit patch_realtek_exit(void) |
5849 | { | 5847 | { |
5850 | snd_hda_delete_codec_preset(&realtek_list); | 5848 | snd_hda_delete_codec_preset(&realtek_list); |
5851 | } | 5849 | } |
5852 | 5850 | ||
5853 | module_init(patch_realtek_init) | 5851 | module_init(patch_realtek_init) |
5854 | module_exit(patch_realtek_exit) | 5852 | module_exit(patch_realtek_exit) |
5855 | 5853 |