diff options
Diffstat (limited to 'sound/pci/hda/alc269_quirks.c')
-rw-r--r-- | sound/pci/hda/alc269_quirks.c | 681 |
1 files changed, 681 insertions, 0 deletions
diff --git a/sound/pci/hda/alc269_quirks.c b/sound/pci/hda/alc269_quirks.c new file mode 100644 index 00000000000..14fdcf29b15 --- /dev/null +++ b/sound/pci/hda/alc269_quirks.c | |||
@@ -0,0 +1,681 @@ | |||
1 | /* | ||
2 | * ALC269/ALC270/ALC275/ALC276 quirk models | ||
3 | * included by patch_realtek.c | ||
4 | */ | ||
5 | |||
6 | /* ALC269 models */ | ||
7 | enum { | ||
8 | ALC269_AUTO, | ||
9 | ALC269_BASIC, | ||
10 | ALC269_QUANTA_FL1, | ||
11 | ALC269_AMIC, | ||
12 | ALC269_DMIC, | ||
13 | ALC269VB_AMIC, | ||
14 | ALC269VB_DMIC, | ||
15 | ALC269_FUJITSU, | ||
16 | ALC269_LIFEBOOK, | ||
17 | ALC271_ACER, | ||
18 | ALC269_MODEL_LAST /* last tag */ | ||
19 | }; | ||
20 | |||
21 | /* | ||
22 | * ALC269 channel source setting (2 channel) | ||
23 | */ | ||
24 | #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID | ||
25 | |||
26 | #define alc269_dac_nids alc260_dac_nids | ||
27 | |||
28 | static const hda_nid_t alc269_adc_nids[1] = { | ||
29 | /* ADC1 */ | ||
30 | 0x08, | ||
31 | }; | ||
32 | |||
33 | static const hda_nid_t alc269_capsrc_nids[1] = { | ||
34 | 0x23, | ||
35 | }; | ||
36 | |||
37 | static const hda_nid_t alc269vb_adc_nids[1] = { | ||
38 | /* ADC1 */ | ||
39 | 0x09, | ||
40 | }; | ||
41 | |||
42 | static const hda_nid_t alc269vb_capsrc_nids[1] = { | ||
43 | 0x22, | ||
44 | }; | ||
45 | |||
46 | #define alc269_modes alc260_modes | ||
47 | #define alc269_capture_source alc880_lg_lw_capture_source | ||
48 | |||
49 | static const struct snd_kcontrol_new alc269_base_mixer[] = { | ||
50 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
51 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
52 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | ||
53 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | ||
54 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
55 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
56 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
57 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
58 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
59 | HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
60 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
61 | HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT), | ||
62 | { } /* end */ | ||
63 | }; | ||
64 | |||
65 | static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { | ||
66 | /* output mixer control */ | ||
67 | HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), | ||
68 | { | ||
69 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
70 | .name = "Master Playback Switch", | ||
71 | .subdevice = HDA_SUBDEV_AMP_FLAG, | ||
72 | .info = snd_hda_mixer_amp_switch_info, | ||
73 | .get = snd_hda_mixer_amp_switch_get, | ||
74 | .put = alc268_acer_master_sw_put, | ||
75 | .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | ||
76 | }, | ||
77 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
78 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
79 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
80 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
81 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
82 | HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
83 | { } | ||
84 | }; | ||
85 | |||
86 | static const struct snd_kcontrol_new alc269_lifebook_mixer[] = { | ||
87 | /* output mixer control */ | ||
88 | HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), | ||
89 | { | ||
90 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
91 | .name = "Master Playback Switch", | ||
92 | .subdevice = HDA_SUBDEV_AMP_FLAG, | ||
93 | .info = snd_hda_mixer_amp_switch_info, | ||
94 | .get = snd_hda_mixer_amp_switch_get, | ||
95 | .put = alc268_acer_master_sw_put, | ||
96 | .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | ||
97 | }, | ||
98 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | ||
99 | HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | ||
100 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
101 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | ||
102 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), | ||
103 | HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
104 | HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT), | ||
105 | HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT), | ||
106 | HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT), | ||
107 | { } | ||
108 | }; | ||
109 | |||
110 | static const struct snd_kcontrol_new alc269_laptop_mixer[] = { | ||
111 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
112 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
113 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
114 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
115 | { } /* end */ | ||
116 | }; | ||
117 | |||
118 | static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = { | ||
119 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | ||
120 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
121 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), | ||
122 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | ||
123 | { } /* end */ | ||
124 | }; | ||
125 | |||
126 | static const struct snd_kcontrol_new alc269_asus_mixer[] = { | ||
127 | HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), | ||
128 | HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT), | ||
129 | { } /* end */ | ||
130 | }; | ||
131 | |||
132 | /* capture mixer elements */ | ||
133 | static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = { | ||
134 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
135 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
136 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
137 | HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
138 | { } /* end */ | ||
139 | }; | ||
140 | |||
141 | static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = { | ||
142 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | ||
143 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | ||
144 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
145 | { } /* end */ | ||
146 | }; | ||
147 | |||
148 | static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = { | ||
149 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), | ||
150 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), | ||
151 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
152 | HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), | ||
153 | { } /* end */ | ||
154 | }; | ||
155 | |||
156 | static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = { | ||
157 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), | ||
158 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), | ||
159 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | ||
160 | { } /* end */ | ||
161 | }; | ||
162 | |||
163 | /* FSC amilo */ | ||
164 | #define alc269_fujitsu_mixer alc269_laptop_mixer | ||
165 | |||
166 | static const struct hda_verb alc269_quanta_fl1_verbs[] = { | ||
167 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
168 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
169 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
170 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, | ||
171 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
172 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
173 | { } | ||
174 | }; | ||
175 | |||
176 | static const struct hda_verb alc269_lifebook_verbs[] = { | ||
177 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
178 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
179 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
180 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
181 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, | ||
182 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
183 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
184 | {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC_HP_EVENT | AC_USRSP_EN}, | ||
185 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
186 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
187 | { } | ||
188 | }; | ||
189 | |||
190 | /* toggle speaker-output according to the hp-jack state */ | ||
191 | static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) | ||
192 | { | ||
193 | alc_hp_automute(codec); | ||
194 | |||
195 | snd_hda_codec_write(codec, 0x20, 0, | ||
196 | AC_VERB_SET_COEF_INDEX, 0x0c); | ||
197 | snd_hda_codec_write(codec, 0x20, 0, | ||
198 | AC_VERB_SET_PROC_COEF, 0x680); | ||
199 | |||
200 | snd_hda_codec_write(codec, 0x20, 0, | ||
201 | AC_VERB_SET_COEF_INDEX, 0x0c); | ||
202 | snd_hda_codec_write(codec, 0x20, 0, | ||
203 | AC_VERB_SET_PROC_COEF, 0x480); | ||
204 | } | ||
205 | |||
206 | #define alc269_lifebook_speaker_automute \ | ||
207 | alc269_quanta_fl1_speaker_automute | ||
208 | |||
209 | static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec) | ||
210 | { | ||
211 | unsigned int present_laptop; | ||
212 | unsigned int present_dock; | ||
213 | |||
214 | present_laptop = snd_hda_jack_detect(codec, 0x18); | ||
215 | present_dock = snd_hda_jack_detect(codec, 0x1b); | ||
216 | |||
217 | /* Laptop mic port overrides dock mic port, design decision */ | ||
218 | if (present_dock) | ||
219 | snd_hda_codec_write(codec, 0x23, 0, | ||
220 | AC_VERB_SET_CONNECT_SEL, 0x3); | ||
221 | if (present_laptop) | ||
222 | snd_hda_codec_write(codec, 0x23, 0, | ||
223 | AC_VERB_SET_CONNECT_SEL, 0x0); | ||
224 | if (!present_dock && !present_laptop) | ||
225 | snd_hda_codec_write(codec, 0x23, 0, | ||
226 | AC_VERB_SET_CONNECT_SEL, 0x1); | ||
227 | } | ||
228 | |||
229 | static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec, | ||
230 | unsigned int res) | ||
231 | { | ||
232 | switch (res >> 26) { | ||
233 | case ALC_HP_EVENT: | ||
234 | alc269_quanta_fl1_speaker_automute(codec); | ||
235 | break; | ||
236 | case ALC_MIC_EVENT: | ||
237 | alc_mic_automute(codec); | ||
238 | break; | ||
239 | } | ||
240 | } | ||
241 | |||
242 | static void alc269_lifebook_unsol_event(struct hda_codec *codec, | ||
243 | unsigned int res) | ||
244 | { | ||
245 | if ((res >> 26) == ALC_HP_EVENT) | ||
246 | alc269_lifebook_speaker_automute(codec); | ||
247 | if ((res >> 26) == ALC_MIC_EVENT) | ||
248 | alc269_lifebook_mic_autoswitch(codec); | ||
249 | } | ||
250 | |||
251 | static void alc269_quanta_fl1_setup(struct hda_codec *codec) | ||
252 | { | ||
253 | struct alc_spec *spec = codec->spec; | ||
254 | spec->autocfg.hp_pins[0] = 0x15; | ||
255 | spec->autocfg.speaker_pins[0] = 0x14; | ||
256 | spec->automute_mixer_nid[0] = 0x0c; | ||
257 | spec->automute = 1; | ||
258 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
259 | spec->ext_mic_pin = 0x18; | ||
260 | spec->int_mic_pin = 0x19; | ||
261 | spec->auto_mic = 1; | ||
262 | } | ||
263 | |||
264 | static void alc269_quanta_fl1_init_hook(struct hda_codec *codec) | ||
265 | { | ||
266 | alc269_quanta_fl1_speaker_automute(codec); | ||
267 | alc_mic_automute(codec); | ||
268 | } | ||
269 | |||
270 | static void alc269_lifebook_setup(struct hda_codec *codec) | ||
271 | { | ||
272 | struct alc_spec *spec = codec->spec; | ||
273 | spec->autocfg.hp_pins[0] = 0x15; | ||
274 | spec->autocfg.hp_pins[1] = 0x1a; | ||
275 | spec->autocfg.speaker_pins[0] = 0x14; | ||
276 | spec->automute_mixer_nid[0] = 0x0c; | ||
277 | spec->automute = 1; | ||
278 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
279 | } | ||
280 | |||
281 | static void alc269_lifebook_init_hook(struct hda_codec *codec) | ||
282 | { | ||
283 | alc269_lifebook_speaker_automute(codec); | ||
284 | alc269_lifebook_mic_autoswitch(codec); | ||
285 | } | ||
286 | |||
287 | static const struct hda_verb alc269_laptop_dmic_init_verbs[] = { | ||
288 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
289 | {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, | ||
290 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, | ||
291 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, | ||
292 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
293 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
294 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
295 | {} | ||
296 | }; | ||
297 | |||
298 | static const struct hda_verb alc269_laptop_amic_init_verbs[] = { | ||
299 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
300 | {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
301 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, | ||
302 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))}, | ||
303 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
304 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
305 | {} | ||
306 | }; | ||
307 | |||
308 | static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = { | ||
309 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
310 | {0x22, AC_VERB_SET_CONNECT_SEL, 0x06}, | ||
311 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, | ||
312 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, | ||
313 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
314 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
315 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
316 | {} | ||
317 | }; | ||
318 | |||
319 | static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = { | ||
320 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
321 | {0x22, AC_VERB_SET_CONNECT_SEL, 0x01}, | ||
322 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, | ||
323 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))}, | ||
324 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
325 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
326 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
327 | {} | ||
328 | }; | ||
329 | |||
330 | static const struct hda_verb alc271_acer_dmic_verbs[] = { | ||
331 | {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, | ||
332 | {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, | ||
333 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
334 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
335 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
336 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
337 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
338 | {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | ||
339 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_MIC_EVENT}, | ||
340 | {0x22, AC_VERB_SET_CONNECT_SEL, 6}, | ||
341 | { } | ||
342 | }; | ||
343 | |||
344 | static void alc269_laptop_amic_setup(struct hda_codec *codec) | ||
345 | { | ||
346 | struct alc_spec *spec = codec->spec; | ||
347 | spec->autocfg.hp_pins[0] = 0x15; | ||
348 | spec->autocfg.speaker_pins[0] = 0x14; | ||
349 | spec->automute_mixer_nid[0] = 0x0c; | ||
350 | spec->automute = 1; | ||
351 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
352 | spec->ext_mic_pin = 0x18; | ||
353 | spec->int_mic_pin = 0x19; | ||
354 | spec->auto_mic = 1; | ||
355 | } | ||
356 | |||
357 | static void alc269_laptop_dmic_setup(struct hda_codec *codec) | ||
358 | { | ||
359 | struct alc_spec *spec = codec->spec; | ||
360 | spec->autocfg.hp_pins[0] = 0x15; | ||
361 | spec->autocfg.speaker_pins[0] = 0x14; | ||
362 | spec->automute_mixer_nid[0] = 0x0c; | ||
363 | spec->automute = 1; | ||
364 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
365 | spec->ext_mic_pin = 0x18; | ||
366 | spec->int_mic_pin = 0x12; | ||
367 | spec->auto_mic = 1; | ||
368 | } | ||
369 | |||
370 | static void alc269vb_laptop_amic_setup(struct hda_codec *codec) | ||
371 | { | ||
372 | struct alc_spec *spec = codec->spec; | ||
373 | spec->autocfg.hp_pins[0] = 0x21; | ||
374 | spec->autocfg.speaker_pins[0] = 0x14; | ||
375 | spec->automute_mixer_nid[0] = 0x0c; | ||
376 | spec->automute = 1; | ||
377 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
378 | spec->ext_mic_pin = 0x18; | ||
379 | spec->int_mic_pin = 0x19; | ||
380 | spec->auto_mic = 1; | ||
381 | } | ||
382 | |||
383 | static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) | ||
384 | { | ||
385 | struct alc_spec *spec = codec->spec; | ||
386 | spec->autocfg.hp_pins[0] = 0x21; | ||
387 | spec->autocfg.speaker_pins[0] = 0x14; | ||
388 | spec->automute_mixer_nid[0] = 0x0c; | ||
389 | spec->automute = 1; | ||
390 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
391 | spec->ext_mic_pin = 0x18; | ||
392 | spec->int_mic_pin = 0x12; | ||
393 | spec->auto_mic = 1; | ||
394 | } | ||
395 | |||
396 | /* | ||
397 | * generic initialization of ADC, input mixers and output mixers | ||
398 | */ | ||
399 | static const struct hda_verb alc269_init_verbs[] = { | ||
400 | /* | ||
401 | * Unmute ADC0 and set the default input to mic-in | ||
402 | */ | ||
403 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
404 | |||
405 | /* | ||
406 | * Set up output mixers (0x02 - 0x03) | ||
407 | */ | ||
408 | /* set vol=0 to output mixers */ | ||
409 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
410 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
411 | |||
412 | /* set up input amps for analog loopback */ | ||
413 | /* Amp Indices: DAC = 0, mixer = 1 */ | ||
414 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
415 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
416 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
417 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
418 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
419 | {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
420 | |||
421 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
422 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
423 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
424 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
425 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
426 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
427 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
428 | |||
429 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
430 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
431 | |||
432 | /* FIXME: use Mux-type input source selection */ | ||
433 | /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ | ||
434 | /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ | ||
435 | {0x23, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
436 | |||
437 | /* set EAPD */ | ||
438 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
439 | { } | ||
440 | }; | ||
441 | |||
442 | static const struct hda_verb alc269vb_init_verbs[] = { | ||
443 | /* | ||
444 | * Unmute ADC0 and set the default input to mic-in | ||
445 | */ | ||
446 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
447 | |||
448 | /* | ||
449 | * Set up output mixers (0x02 - 0x03) | ||
450 | */ | ||
451 | /* set vol=0 to output mixers */ | ||
452 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
453 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | ||
454 | |||
455 | /* set up input amps for analog loopback */ | ||
456 | /* Amp Indices: DAC = 0, mixer = 1 */ | ||
457 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
458 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
459 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
460 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
461 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
462 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
463 | |||
464 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
465 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
466 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
467 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
468 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | ||
469 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
470 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | ||
471 | |||
472 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
473 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
474 | |||
475 | /* FIXME: use Mux-type input source selection */ | ||
476 | /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ | ||
477 | /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ | ||
478 | {0x22, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
479 | |||
480 | /* set EAPD */ | ||
481 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
482 | { } | ||
483 | }; | ||
484 | |||
485 | /* | ||
486 | * configuration and preset | ||
487 | */ | ||
488 | static const char * const alc269_models[ALC269_MODEL_LAST] = { | ||
489 | [ALC269_BASIC] = "basic", | ||
490 | [ALC269_QUANTA_FL1] = "quanta", | ||
491 | [ALC269_AMIC] = "laptop-amic", | ||
492 | [ALC269_DMIC] = "laptop-dmic", | ||
493 | [ALC269_FUJITSU] = "fujitsu", | ||
494 | [ALC269_LIFEBOOK] = "lifebook", | ||
495 | [ALC269_AUTO] = "auto", | ||
496 | }; | ||
497 | |||
498 | static const struct snd_pci_quirk alc269_cfg_tbl[] = { | ||
499 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), | ||
500 | SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER), | ||
501 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", | ||
502 | ALC269_AMIC), | ||
503 | SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC), | ||
504 | SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC), | ||
505 | SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC), | ||
506 | SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC), | ||
507 | SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC), | ||
508 | SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC), | ||
509 | SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC), | ||
510 | SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC), | ||
511 | SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC), | ||
512 | SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC), | ||
513 | SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC), | ||
514 | SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC), | ||
515 | SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC), | ||
516 | SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC), | ||
517 | SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC), | ||
518 | SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC), | ||
519 | SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC), | ||
520 | SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC), | ||
521 | SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC), | ||
522 | SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC), | ||
523 | SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC), | ||
524 | SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC), | ||
525 | SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC), | ||
526 | SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC), | ||
527 | SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC), | ||
528 | SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC), | ||
529 | SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC), | ||
530 | SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC), | ||
531 | SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC), | ||
532 | SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC), | ||
533 | SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC), | ||
534 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC), | ||
535 | SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC), | ||
536 | SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC), | ||
537 | SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC), | ||
538 | SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC), | ||
539 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", | ||
540 | ALC269_DMIC), | ||
541 | SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", | ||
542 | ALC269_DMIC), | ||
543 | SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC), | ||
544 | SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC), | ||
545 | SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO), | ||
546 | SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), | ||
547 | SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC), | ||
548 | SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), | ||
549 | SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC), | ||
550 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC), | ||
551 | SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC), | ||
552 | SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC), | ||
553 | {} | ||
554 | }; | ||
555 | |||
556 | static const struct alc_config_preset alc269_presets[] = { | ||
557 | [ALC269_BASIC] = { | ||
558 | .mixers = { alc269_base_mixer }, | ||
559 | .init_verbs = { alc269_init_verbs }, | ||
560 | .num_dacs = ARRAY_SIZE(alc269_dac_nids), | ||
561 | .dac_nids = alc269_dac_nids, | ||
562 | .hp_nid = 0x03, | ||
563 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | ||
564 | .channel_mode = alc269_modes, | ||
565 | .input_mux = &alc269_capture_source, | ||
566 | }, | ||
567 | [ALC269_QUANTA_FL1] = { | ||
568 | .mixers = { alc269_quanta_fl1_mixer }, | ||
569 | .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs }, | ||
570 | .num_dacs = ARRAY_SIZE(alc269_dac_nids), | ||
571 | .dac_nids = alc269_dac_nids, | ||
572 | .hp_nid = 0x03, | ||
573 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | ||
574 | .channel_mode = alc269_modes, | ||
575 | .input_mux = &alc269_capture_source, | ||
576 | .unsol_event = alc269_quanta_fl1_unsol_event, | ||
577 | .setup = alc269_quanta_fl1_setup, | ||
578 | .init_hook = alc269_quanta_fl1_init_hook, | ||
579 | }, | ||
580 | [ALC269_AMIC] = { | ||
581 | .mixers = { alc269_laptop_mixer }, | ||
582 | .cap_mixer = alc269_laptop_analog_capture_mixer, | ||
583 | .init_verbs = { alc269_init_verbs, | ||
584 | alc269_laptop_amic_init_verbs }, | ||
585 | .num_dacs = ARRAY_SIZE(alc269_dac_nids), | ||
586 | .dac_nids = alc269_dac_nids, | ||
587 | .hp_nid = 0x03, | ||
588 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | ||
589 | .channel_mode = alc269_modes, | ||
590 | .unsol_event = alc_sku_unsol_event, | ||
591 | .setup = alc269_laptop_amic_setup, | ||
592 | .init_hook = alc_inithook, | ||
593 | }, | ||
594 | [ALC269_DMIC] = { | ||
595 | .mixers = { alc269_laptop_mixer }, | ||
596 | .cap_mixer = alc269_laptop_digital_capture_mixer, | ||
597 | .init_verbs = { alc269_init_verbs, | ||
598 | alc269_laptop_dmic_init_verbs }, | ||
599 | .num_dacs = ARRAY_SIZE(alc269_dac_nids), | ||
600 | .dac_nids = alc269_dac_nids, | ||
601 | .hp_nid = 0x03, | ||
602 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | ||
603 | .channel_mode = alc269_modes, | ||
604 | .unsol_event = alc_sku_unsol_event, | ||
605 | .setup = alc269_laptop_dmic_setup, | ||
606 | .init_hook = alc_inithook, | ||
607 | }, | ||
608 | [ALC269VB_AMIC] = { | ||
609 | .mixers = { alc269vb_laptop_mixer }, | ||
610 | .cap_mixer = alc269vb_laptop_analog_capture_mixer, | ||
611 | .init_verbs = { alc269vb_init_verbs, | ||
612 | alc269vb_laptop_amic_init_verbs }, | ||
613 | .num_dacs = ARRAY_SIZE(alc269_dac_nids), | ||
614 | .dac_nids = alc269_dac_nids, | ||
615 | .hp_nid = 0x03, | ||
616 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | ||
617 | .channel_mode = alc269_modes, | ||
618 | .unsol_event = alc_sku_unsol_event, | ||
619 | .setup = alc269vb_laptop_amic_setup, | ||
620 | .init_hook = alc_inithook, | ||
621 | }, | ||
622 | [ALC269VB_DMIC] = { | ||
623 | .mixers = { alc269vb_laptop_mixer }, | ||
624 | .cap_mixer = alc269vb_laptop_digital_capture_mixer, | ||
625 | .init_verbs = { alc269vb_init_verbs, | ||
626 | alc269vb_laptop_dmic_init_verbs }, | ||
627 | .num_dacs = ARRAY_SIZE(alc269_dac_nids), | ||
628 | .dac_nids = alc269_dac_nids, | ||
629 | .hp_nid = 0x03, | ||
630 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | ||
631 | .channel_mode = alc269_modes, | ||
632 | .unsol_event = alc_sku_unsol_event, | ||
633 | .setup = alc269vb_laptop_dmic_setup, | ||
634 | .init_hook = alc_inithook, | ||
635 | }, | ||
636 | [ALC269_FUJITSU] = { | ||
637 | .mixers = { alc269_fujitsu_mixer }, | ||
638 | .cap_mixer = alc269_laptop_digital_capture_mixer, | ||
639 | .init_verbs = { alc269_init_verbs, | ||
640 | alc269_laptop_dmic_init_verbs }, | ||
641 | .num_dacs = ARRAY_SIZE(alc269_dac_nids), | ||
642 | .dac_nids = alc269_dac_nids, | ||
643 | .hp_nid = 0x03, | ||
644 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | ||
645 | .channel_mode = alc269_modes, | ||
646 | .unsol_event = alc_sku_unsol_event, | ||
647 | .setup = alc269_laptop_dmic_setup, | ||
648 | .init_hook = alc_inithook, | ||
649 | }, | ||
650 | [ALC269_LIFEBOOK] = { | ||
651 | .mixers = { alc269_lifebook_mixer }, | ||
652 | .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs }, | ||
653 | .num_dacs = ARRAY_SIZE(alc269_dac_nids), | ||
654 | .dac_nids = alc269_dac_nids, | ||
655 | .hp_nid = 0x03, | ||
656 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | ||
657 | .channel_mode = alc269_modes, | ||
658 | .input_mux = &alc269_capture_source, | ||
659 | .unsol_event = alc269_lifebook_unsol_event, | ||
660 | .setup = alc269_lifebook_setup, | ||
661 | .init_hook = alc269_lifebook_init_hook, | ||
662 | }, | ||
663 | [ALC271_ACER] = { | ||
664 | .mixers = { alc269_asus_mixer }, | ||
665 | .cap_mixer = alc269vb_laptop_digital_capture_mixer, | ||
666 | .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs }, | ||
667 | .num_dacs = ARRAY_SIZE(alc269_dac_nids), | ||
668 | .dac_nids = alc269_dac_nids, | ||
669 | .adc_nids = alc262_dmic_adc_nids, | ||
670 | .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids), | ||
671 | .capsrc_nids = alc262_dmic_capsrc_nids, | ||
672 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | ||
673 | .channel_mode = alc269_modes, | ||
674 | .input_mux = &alc269_capture_source, | ||
675 | .dig_out_nid = ALC880_DIGOUT_NID, | ||
676 | .unsol_event = alc_sku_unsol_event, | ||
677 | .setup = alc269vb_laptop_dmic_setup, | ||
678 | .init_hook = alc_inithook, | ||
679 | }, | ||
680 | }; | ||
681 | |||