ALSA: hda - Remove ALC268 model override for CPR2000
[deliverable/linux.git] / sound / pci / hda / patch_realtek.c
1 /*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * HD audio interface patch for ALC 260/880/882 codecs
5 *
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw>
8 * Takashi Iwai <tiwai@suse.de>
9 * Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
10 *
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
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This driver is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
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
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26 #include <linux/init.h>
27 #include <linux/delay.h>
28 #include <linux/slab.h>
29 #include <linux/pci.h>
30 #include <sound/core.h>
31 #include <sound/jack.h>
32 #include "hda_codec.h"
33 #include "hda_local.h"
34 #include "hda_beep.h"
35
36 #define ALC880_FRONT_EVENT 0x01
37 #define ALC880_DCVOL_EVENT 0x02
38 #define ALC880_HP_EVENT 0x04
39 #define ALC880_MIC_EVENT 0x08
40
41 /* ALC880 board config type */
42 enum {
43 ALC880_3ST,
44 ALC880_3ST_DIG,
45 ALC880_5ST,
46 ALC880_5ST_DIG,
47 ALC880_W810,
48 ALC880_Z71V,
49 ALC880_6ST,
50 ALC880_6ST_DIG,
51 ALC880_F1734,
52 ALC880_ASUS,
53 ALC880_ASUS_DIG,
54 ALC880_ASUS_W1V,
55 ALC880_ASUS_DIG2,
56 ALC880_FUJITSU,
57 ALC880_UNIWILL_DIG,
58 ALC880_UNIWILL,
59 ALC880_UNIWILL_P53,
60 ALC880_CLEVO,
61 ALC880_TCL_S700,
62 ALC880_LG,
63 ALC880_LG_LW,
64 ALC880_MEDION_RIM,
65 #ifdef CONFIG_SND_DEBUG
66 ALC880_TEST,
67 #endif
68 ALC880_AUTO,
69 ALC880_MODEL_LAST /* last tag */
70 };
71
72 /* ALC260 models */
73 enum {
74 ALC260_BASIC,
75 ALC260_HP,
76 ALC260_HP_DC7600,
77 ALC260_HP_3013,
78 ALC260_FUJITSU_S702X,
79 ALC260_ACER,
80 ALC260_WILL,
81 ALC260_REPLACER_672V,
82 ALC260_FAVORIT100,
83 #ifdef CONFIG_SND_DEBUG
84 ALC260_TEST,
85 #endif
86 ALC260_AUTO,
87 ALC260_MODEL_LAST /* last tag */
88 };
89
90 /* ALC262 models */
91 enum {
92 ALC262_BASIC,
93 ALC262_HIPPO,
94 ALC262_HIPPO_1,
95 ALC262_FUJITSU,
96 ALC262_HP_BPC,
97 ALC262_HP_BPC_D7000_WL,
98 ALC262_HP_BPC_D7000_WF,
99 ALC262_HP_TC_T5735,
100 ALC262_HP_RP5700,
101 ALC262_BENQ_ED8,
102 ALC262_SONY_ASSAMD,
103 ALC262_BENQ_T31,
104 ALC262_ULTRA,
105 ALC262_LENOVO_3000,
106 ALC262_NEC,
107 ALC262_TOSHIBA_S06,
108 ALC262_TOSHIBA_RX1,
109 ALC262_TYAN,
110 ALC262_AUTO,
111 ALC262_MODEL_LAST /* last tag */
112 };
113
114 /* ALC268 models */
115 enum {
116 ALC267_QUANTA_IL1,
117 ALC268_3ST,
118 ALC268_TOSHIBA,
119 ALC268_ACER,
120 ALC268_ACER_DMIC,
121 ALC268_ACER_ASPIRE_ONE,
122 ALC268_DELL,
123 ALC268_ZEPTO,
124 #ifdef CONFIG_SND_DEBUG
125 ALC268_TEST,
126 #endif
127 ALC268_AUTO,
128 ALC268_MODEL_LAST /* last tag */
129 };
130
131 /* ALC269 models */
132 enum {
133 ALC269_BASIC,
134 ALC269_QUANTA_FL1,
135 ALC269_AMIC,
136 ALC269_DMIC,
137 ALC269VB_AMIC,
138 ALC269VB_DMIC,
139 ALC269_FUJITSU,
140 ALC269_LIFEBOOK,
141 ALC271_ACER,
142 ALC269_AUTO,
143 ALC269_MODEL_LAST /* last tag */
144 };
145
146 /* ALC861 models */
147 enum {
148 ALC861_3ST,
149 ALC660_3ST,
150 ALC861_3ST_DIG,
151 ALC861_6ST_DIG,
152 ALC861_UNIWILL_M31,
153 ALC861_TOSHIBA,
154 ALC861_ASUS,
155 ALC861_ASUS_LAPTOP,
156 ALC861_AUTO,
157 ALC861_MODEL_LAST,
158 };
159
160 /* ALC861-VD models */
161 enum {
162 ALC660VD_3ST,
163 ALC660VD_3ST_DIG,
164 ALC660VD_ASUS_V1S,
165 ALC861VD_3ST,
166 ALC861VD_3ST_DIG,
167 ALC861VD_6ST_DIG,
168 ALC861VD_LENOVO,
169 ALC861VD_DALLAS,
170 ALC861VD_HP,
171 ALC861VD_AUTO,
172 ALC861VD_MODEL_LAST,
173 };
174
175 /* ALC662 models */
176 enum {
177 ALC662_3ST_2ch_DIG,
178 ALC662_3ST_6ch_DIG,
179 ALC662_3ST_6ch,
180 ALC662_5ST_DIG,
181 ALC662_LENOVO_101E,
182 ALC662_ASUS_EEEPC_P701,
183 ALC662_ASUS_EEEPC_EP20,
184 ALC663_ASUS_M51VA,
185 ALC663_ASUS_G71V,
186 ALC663_ASUS_H13,
187 ALC663_ASUS_G50V,
188 ALC662_ECS,
189 ALC663_ASUS_MODE1,
190 ALC662_ASUS_MODE2,
191 ALC663_ASUS_MODE3,
192 ALC663_ASUS_MODE4,
193 ALC663_ASUS_MODE5,
194 ALC663_ASUS_MODE6,
195 ALC663_ASUS_MODE7,
196 ALC663_ASUS_MODE8,
197 ALC272_DELL,
198 ALC272_DELL_ZM1,
199 ALC272_SAMSUNG_NC10,
200 ALC662_AUTO,
201 ALC662_MODEL_LAST,
202 };
203
204 /* ALC882 models */
205 enum {
206 ALC882_3ST_DIG,
207 ALC882_6ST_DIG,
208 ALC882_ARIMA,
209 ALC882_W2JC,
210 ALC882_TARGA,
211 ALC882_ASUS_A7J,
212 ALC882_ASUS_A7M,
213 ALC885_MACPRO,
214 ALC885_MBA21,
215 ALC885_MBP3,
216 ALC885_MB5,
217 ALC885_MACMINI3,
218 ALC885_IMAC24,
219 ALC885_IMAC91,
220 ALC883_3ST_2ch_DIG,
221 ALC883_3ST_6ch_DIG,
222 ALC883_3ST_6ch,
223 ALC883_6ST_DIG,
224 ALC883_TARGA_DIG,
225 ALC883_TARGA_2ch_DIG,
226 ALC883_TARGA_8ch_DIG,
227 ALC883_ACER,
228 ALC883_ACER_ASPIRE,
229 ALC888_ACER_ASPIRE_4930G,
230 ALC888_ACER_ASPIRE_6530G,
231 ALC888_ACER_ASPIRE_8930G,
232 ALC888_ACER_ASPIRE_7730G,
233 ALC883_MEDION,
234 ALC883_MEDION_WIM2160,
235 ALC883_LAPTOP_EAPD,
236 ALC883_LENOVO_101E_2ch,
237 ALC883_LENOVO_NB0763,
238 ALC888_LENOVO_MS7195_DIG,
239 ALC888_LENOVO_SKY,
240 ALC883_HAIER_W66,
241 ALC888_3ST_HP,
242 ALC888_6ST_DELL,
243 ALC883_MITAC,
244 ALC883_CLEVO_M540R,
245 ALC883_CLEVO_M720,
246 ALC883_FUJITSU_PI2515,
247 ALC888_FUJITSU_XA3530,
248 ALC883_3ST_6ch_INTEL,
249 ALC889A_INTEL,
250 ALC889_INTEL,
251 ALC888_ASUS_M90V,
252 ALC888_ASUS_EEE1601,
253 ALC889A_MB31,
254 ALC1200_ASUS_P5Q,
255 ALC883_SONY_VAIO_TT,
256 ALC882_AUTO,
257 ALC882_MODEL_LAST,
258 };
259
260 /* ALC680 models */
261 enum {
262 ALC680_BASE,
263 ALC680_AUTO,
264 ALC680_MODEL_LAST,
265 };
266
267 /* for GPIO Poll */
268 #define GPIO_MASK 0x03
269
270 /* extra amp-initialization sequence types */
271 enum {
272 ALC_INIT_NONE,
273 ALC_INIT_DEFAULT,
274 ALC_INIT_GPIO1,
275 ALC_INIT_GPIO2,
276 ALC_INIT_GPIO3,
277 };
278
279 struct alc_mic_route {
280 hda_nid_t pin;
281 unsigned char mux_idx;
282 unsigned char amix_idx;
283 };
284
285 #define MUX_IDX_UNDEF ((unsigned char)-1)
286
287 struct alc_customize_define {
288 unsigned int sku_cfg;
289 unsigned char port_connectivity;
290 unsigned char check_sum;
291 unsigned char customization;
292 unsigned char external_amp;
293 unsigned int enable_pcbeep:1;
294 unsigned int platform_type:1;
295 unsigned int swap:1;
296 unsigned int override:1;
297 unsigned int fixup:1; /* Means that this sku is set by driver, not read from hw */
298 };
299
300 struct alc_fixup;
301
302 struct alc_multi_io {
303 hda_nid_t pin; /* multi-io widget pin NID */
304 hda_nid_t dac; /* DAC to be connected */
305 unsigned int ctl_in; /* cached input-pin control value */
306 };
307
308 enum {
309 ALC_AUTOMUTE_PIN, /* change the pin control */
310 ALC_AUTOMUTE_AMP, /* mute/unmute the pin AMP */
311 ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */
312 };
313
314 struct alc_spec {
315 /* codec parameterization */
316 const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
317 unsigned int num_mixers;
318 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
319 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
320
321 const struct hda_verb *init_verbs[10]; /* initialization verbs
322 * don't forget NULL
323 * termination!
324 */
325 unsigned int num_init_verbs;
326
327 char stream_name_analog[32]; /* analog PCM stream */
328 const struct hda_pcm_stream *stream_analog_playback;
329 const struct hda_pcm_stream *stream_analog_capture;
330 const struct hda_pcm_stream *stream_analog_alt_playback;
331 const struct hda_pcm_stream *stream_analog_alt_capture;
332
333 char stream_name_digital[32]; /* digital PCM stream */
334 const struct hda_pcm_stream *stream_digital_playback;
335 const struct hda_pcm_stream *stream_digital_capture;
336
337 /* playback */
338 struct hda_multi_out multiout; /* playback set-up
339 * max_channels, dacs must be set
340 * dig_out_nid and hp_nid are optional
341 */
342 hda_nid_t alt_dac_nid;
343 hda_nid_t slave_dig_outs[3]; /* optional - for auto-parsing */
344 int dig_out_type;
345
346 /* capture */
347 unsigned int num_adc_nids;
348 const hda_nid_t *adc_nids;
349 const hda_nid_t *capsrc_nids;
350 hda_nid_t dig_in_nid; /* digital-in NID; optional */
351
352 /* capture setup for dynamic dual-adc switch */
353 unsigned int cur_adc_idx;
354 hda_nid_t cur_adc;
355 unsigned int cur_adc_stream_tag;
356 unsigned int cur_adc_format;
357
358 /* capture source */
359 unsigned int num_mux_defs;
360 const struct hda_input_mux *input_mux;
361 unsigned int cur_mux[3];
362 struct alc_mic_route ext_mic;
363 struct alc_mic_route dock_mic;
364 struct alc_mic_route int_mic;
365
366 /* channel model */
367 const struct hda_channel_mode *channel_mode;
368 int num_channel_mode;
369 int need_dac_fix;
370 int const_channel_count;
371 int ext_channel_count;
372
373 /* PCM information */
374 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
375
376 /* dynamic controls, init_verbs and input_mux */
377 struct auto_pin_cfg autocfg;
378 struct alc_customize_define cdefine;
379 struct snd_array kctls;
380 struct hda_input_mux private_imux[3];
381 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
382 hda_nid_t private_adc_nids[AUTO_CFG_MAX_OUTS];
383 hda_nid_t private_capsrc_nids[AUTO_CFG_MAX_OUTS];
384
385 /* hooks */
386 void (*init_hook)(struct hda_codec *codec);
387 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
388 #ifdef CONFIG_SND_HDA_POWER_SAVE
389 void (*power_hook)(struct hda_codec *codec);
390 #endif
391 void (*shutup)(struct hda_codec *codec);
392
393 /* for pin sensing */
394 unsigned int jack_present: 1;
395 unsigned int line_jack_present:1;
396 unsigned int master_mute:1;
397 unsigned int auto_mic:1;
398 unsigned int automute:1; /* HP automute enabled */
399 unsigned int detect_line:1; /* Line-out detection enabled */
400 unsigned int automute_lines:1; /* automute line-out as well */
401 unsigned int automute_hp_lo:1; /* both HP and LO available */
402
403 /* other flags */
404 unsigned int no_analog :1; /* digital I/O only */
405 unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */
406 unsigned int single_input_src:1;
407
408 /* auto-mute control */
409 int automute_mode;
410 hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS];
411
412 int init_amp;
413 int codec_variant; /* flag for other variants */
414
415 /* for virtual master */
416 hda_nid_t vmaster_nid;
417 #ifdef CONFIG_SND_HDA_POWER_SAVE
418 struct hda_loopback_check loopback;
419 #endif
420
421 /* for PLL fix */
422 hda_nid_t pll_nid;
423 unsigned int pll_coef_idx, pll_coef_bit;
424
425 /* fix-up list */
426 int fixup_id;
427 const struct alc_fixup *fixup_list;
428 const char *fixup_name;
429
430 /* multi-io */
431 int multi_ios;
432 struct alc_multi_io multi_io[4];
433 };
434
435 /*
436 * configuration template - to be copied to the spec instance
437 */
438 struct alc_config_preset {
439 const struct snd_kcontrol_new *mixers[5]; /* should be identical size
440 * with spec
441 */
442 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
443 const struct hda_verb *init_verbs[5];
444 unsigned int num_dacs;
445 const hda_nid_t *dac_nids;
446 hda_nid_t dig_out_nid; /* optional */
447 hda_nid_t hp_nid; /* optional */
448 const hda_nid_t *slave_dig_outs;
449 unsigned int num_adc_nids;
450 const hda_nid_t *adc_nids;
451 const hda_nid_t *capsrc_nids;
452 hda_nid_t dig_in_nid;
453 unsigned int num_channel_mode;
454 const struct hda_channel_mode *channel_mode;
455 int need_dac_fix;
456 int const_channel_count;
457 unsigned int num_mux_defs;
458 const struct hda_input_mux *input_mux;
459 void (*unsol_event)(struct hda_codec *, unsigned int);
460 void (*setup)(struct hda_codec *);
461 void (*init_hook)(struct hda_codec *);
462 #ifdef CONFIG_SND_HDA_POWER_SAVE
463 const struct hda_amp_list *loopbacks;
464 void (*power_hook)(struct hda_codec *codec);
465 #endif
466 };
467
468
469 /*
470 * input MUX handling
471 */
472 static int alc_mux_enum_info(struct snd_kcontrol *kcontrol,
473 struct snd_ctl_elem_info *uinfo)
474 {
475 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
476 struct alc_spec *spec = codec->spec;
477 unsigned int mux_idx = snd_ctl_get_ioffidx(kcontrol, &uinfo->id);
478 if (mux_idx >= spec->num_mux_defs)
479 mux_idx = 0;
480 if (!spec->input_mux[mux_idx].num_items && mux_idx > 0)
481 mux_idx = 0;
482 return snd_hda_input_mux_info(&spec->input_mux[mux_idx], uinfo);
483 }
484
485 static int alc_mux_enum_get(struct snd_kcontrol *kcontrol,
486 struct snd_ctl_elem_value *ucontrol)
487 {
488 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
489 struct alc_spec *spec = codec->spec;
490 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
491
492 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
493 return 0;
494 }
495
496 static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
497 struct snd_ctl_elem_value *ucontrol)
498 {
499 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
500 struct alc_spec *spec = codec->spec;
501 const struct hda_input_mux *imux;
502 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
503 unsigned int mux_idx;
504 hda_nid_t nid = spec->capsrc_nids ?
505 spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx];
506 unsigned int type;
507
508 mux_idx = adc_idx >= spec->num_mux_defs ? 0 : adc_idx;
509 imux = &spec->input_mux[mux_idx];
510 if (!imux->num_items && mux_idx > 0)
511 imux = &spec->input_mux[0];
512
513 type = get_wcaps_type(get_wcaps(codec, nid));
514 if (type == AC_WID_AUD_MIX) {
515 /* Matrix-mixer style (e.g. ALC882) */
516 unsigned int *cur_val = &spec->cur_mux[adc_idx];
517 unsigned int i, idx;
518
519 idx = ucontrol->value.enumerated.item[0];
520 if (idx >= imux->num_items)
521 idx = imux->num_items - 1;
522 if (*cur_val == idx)
523 return 0;
524 for (i = 0; i < imux->num_items; i++) {
525 unsigned int v = (i == idx) ? 0 : HDA_AMP_MUTE;
526 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT,
527 imux->items[i].index,
528 HDA_AMP_MUTE, v);
529 }
530 *cur_val = idx;
531 return 1;
532 } else {
533 /* MUX style (e.g. ALC880) */
534 return snd_hda_input_mux_put(codec, imux, ucontrol, nid,
535 &spec->cur_mux[adc_idx]);
536 }
537 }
538
539 /*
540 * channel mode setting
541 */
542 static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
543 struct snd_ctl_elem_info *uinfo)
544 {
545 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
546 struct alc_spec *spec = codec->spec;
547 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
548 spec->num_channel_mode);
549 }
550
551 static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
552 struct snd_ctl_elem_value *ucontrol)
553 {
554 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
555 struct alc_spec *spec = codec->spec;
556 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
557 spec->num_channel_mode,
558 spec->ext_channel_count);
559 }
560
561 static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
562 struct snd_ctl_elem_value *ucontrol)
563 {
564 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
565 struct alc_spec *spec = codec->spec;
566 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
567 spec->num_channel_mode,
568 &spec->ext_channel_count);
569 if (err >= 0 && !spec->const_channel_count) {
570 spec->multiout.max_channels = spec->ext_channel_count;
571 if (spec->need_dac_fix)
572 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
573 }
574 return err;
575 }
576
577 /*
578 * Control the mode of pin widget settings via the mixer. "pc" is used
579 * instead of "%" to avoid consequences of accidentally treating the % as
580 * being part of a format specifier. Maximum allowed length of a value is
581 * 63 characters plus NULL terminator.
582 *
583 * Note: some retasking pin complexes seem to ignore requests for input
584 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
585 * are requested. Therefore order this list so that this behaviour will not
586 * cause problems when mixer clients move through the enum sequentially.
587 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
588 * March 2006.
589 */
590 static const char * const alc_pin_mode_names[] = {
591 "Mic 50pc bias", "Mic 80pc bias",
592 "Line in", "Line out", "Headphone out",
593 };
594 static const unsigned char alc_pin_mode_values[] = {
595 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
596 };
597 /* The control can present all 5 options, or it can limit the options based
598 * in the pin being assumed to be exclusively an input or an output pin. In
599 * addition, "input" pins may or may not process the mic bias option
600 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
601 * accept requests for bias as of chip versions up to March 2006) and/or
602 * wiring in the computer.
603 */
604 #define ALC_PIN_DIR_IN 0x00
605 #define ALC_PIN_DIR_OUT 0x01
606 #define ALC_PIN_DIR_INOUT 0x02
607 #define ALC_PIN_DIR_IN_NOMICBIAS 0x03
608 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
609
610 /* Info about the pin modes supported by the different pin direction modes.
611 * For each direction the minimum and maximum values are given.
612 */
613 static const signed char alc_pin_mode_dir_info[5][2] = {
614 { 0, 2 }, /* ALC_PIN_DIR_IN */
615 { 3, 4 }, /* ALC_PIN_DIR_OUT */
616 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
617 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
618 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
619 };
620 #define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
621 #define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
622 #define alc_pin_mode_n_items(_dir) \
623 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
624
625 static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
626 struct snd_ctl_elem_info *uinfo)
627 {
628 unsigned int item_num = uinfo->value.enumerated.item;
629 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
630
631 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
632 uinfo->count = 1;
633 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
634
635 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
636 item_num = alc_pin_mode_min(dir);
637 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
638 return 0;
639 }
640
641 static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
642 struct snd_ctl_elem_value *ucontrol)
643 {
644 unsigned int i;
645 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
646 hda_nid_t nid = kcontrol->private_value & 0xffff;
647 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
648 long *valp = ucontrol->value.integer.value;
649 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
650 AC_VERB_GET_PIN_WIDGET_CONTROL,
651 0x00);
652
653 /* Find enumerated value for current pinctl setting */
654 i = alc_pin_mode_min(dir);
655 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
656 i++;
657 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
658 return 0;
659 }
660
661 static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
662 struct snd_ctl_elem_value *ucontrol)
663 {
664 signed int change;
665 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
666 hda_nid_t nid = kcontrol->private_value & 0xffff;
667 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
668 long val = *ucontrol->value.integer.value;
669 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
670 AC_VERB_GET_PIN_WIDGET_CONTROL,
671 0x00);
672
673 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
674 val = alc_pin_mode_min(dir);
675
676 change = pinctl != alc_pin_mode_values[val];
677 if (change) {
678 /* Set pin mode to that requested */
679 snd_hda_codec_write_cache(codec, nid, 0,
680 AC_VERB_SET_PIN_WIDGET_CONTROL,
681 alc_pin_mode_values[val]);
682
683 /* Also enable the retasking pin's input/output as required
684 * for the requested pin mode. Enum values of 2 or less are
685 * input modes.
686 *
687 * Dynamically switching the input/output buffers probably
688 * reduces noise slightly (particularly on input) so we'll
689 * do it. However, having both input and output buffers
690 * enabled simultaneously doesn't seem to be problematic if
691 * this turns out to be necessary in the future.
692 */
693 if (val <= 2) {
694 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
695 HDA_AMP_MUTE, HDA_AMP_MUTE);
696 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
697 HDA_AMP_MUTE, 0);
698 } else {
699 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
700 HDA_AMP_MUTE, HDA_AMP_MUTE);
701 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
702 HDA_AMP_MUTE, 0);
703 }
704 }
705 return change;
706 }
707
708 #define ALC_PIN_MODE(xname, nid, dir) \
709 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
710 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
711 .info = alc_pin_mode_info, \
712 .get = alc_pin_mode_get, \
713 .put = alc_pin_mode_put, \
714 .private_value = nid | (dir<<16) }
715
716 /* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
717 * together using a mask with more than one bit set. This control is
718 * currently used only by the ALC260 test model. At this stage they are not
719 * needed for any "production" models.
720 */
721 #ifdef CONFIG_SND_DEBUG
722 #define alc_gpio_data_info snd_ctl_boolean_mono_info
723
724 static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
725 struct snd_ctl_elem_value *ucontrol)
726 {
727 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
728 hda_nid_t nid = kcontrol->private_value & 0xffff;
729 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
730 long *valp = ucontrol->value.integer.value;
731 unsigned int val = snd_hda_codec_read(codec, nid, 0,
732 AC_VERB_GET_GPIO_DATA, 0x00);
733
734 *valp = (val & mask) != 0;
735 return 0;
736 }
737 static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
738 struct snd_ctl_elem_value *ucontrol)
739 {
740 signed int change;
741 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
742 hda_nid_t nid = kcontrol->private_value & 0xffff;
743 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
744 long val = *ucontrol->value.integer.value;
745 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
746 AC_VERB_GET_GPIO_DATA,
747 0x00);
748
749 /* Set/unset the masked GPIO bit(s) as needed */
750 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
751 if (val == 0)
752 gpio_data &= ~mask;
753 else
754 gpio_data |= mask;
755 snd_hda_codec_write_cache(codec, nid, 0,
756 AC_VERB_SET_GPIO_DATA, gpio_data);
757
758 return change;
759 }
760 #define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
761 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
762 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
763 .info = alc_gpio_data_info, \
764 .get = alc_gpio_data_get, \
765 .put = alc_gpio_data_put, \
766 .private_value = nid | (mask<<16) }
767 #endif /* CONFIG_SND_DEBUG */
768
769 /* A switch control to allow the enabling of the digital IO pins on the
770 * ALC260. This is incredibly simplistic; the intention of this control is
771 * to provide something in the test model allowing digital outputs to be
772 * identified if present. If models are found which can utilise these
773 * outputs a more complete mixer control can be devised for those models if
774 * necessary.
775 */
776 #ifdef CONFIG_SND_DEBUG
777 #define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
778
779 static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
780 struct snd_ctl_elem_value *ucontrol)
781 {
782 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
783 hda_nid_t nid = kcontrol->private_value & 0xffff;
784 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
785 long *valp = ucontrol->value.integer.value;
786 unsigned int val = snd_hda_codec_read(codec, nid, 0,
787 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
788
789 *valp = (val & mask) != 0;
790 return 0;
791 }
792 static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
793 struct snd_ctl_elem_value *ucontrol)
794 {
795 signed int change;
796 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
797 hda_nid_t nid = kcontrol->private_value & 0xffff;
798 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
799 long val = *ucontrol->value.integer.value;
800 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
801 AC_VERB_GET_DIGI_CONVERT_1,
802 0x00);
803
804 /* Set/unset the masked control bit(s) as needed */
805 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
806 if (val==0)
807 ctrl_data &= ~mask;
808 else
809 ctrl_data |= mask;
810 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
811 ctrl_data);
812
813 return change;
814 }
815 #define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
816 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
817 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
818 .info = alc_spdif_ctrl_info, \
819 .get = alc_spdif_ctrl_get, \
820 .put = alc_spdif_ctrl_put, \
821 .private_value = nid | (mask<<16) }
822 #endif /* CONFIG_SND_DEBUG */
823
824 /* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
825 * Again, this is only used in the ALC26x test models to help identify when
826 * the EAPD line must be asserted for features to work.
827 */
828 #ifdef CONFIG_SND_DEBUG
829 #define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
830
831 static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
832 struct snd_ctl_elem_value *ucontrol)
833 {
834 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
835 hda_nid_t nid = kcontrol->private_value & 0xffff;
836 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
837 long *valp = ucontrol->value.integer.value;
838 unsigned int val = snd_hda_codec_read(codec, nid, 0,
839 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
840
841 *valp = (val & mask) != 0;
842 return 0;
843 }
844
845 static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
846 struct snd_ctl_elem_value *ucontrol)
847 {
848 int change;
849 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
850 hda_nid_t nid = kcontrol->private_value & 0xffff;
851 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
852 long val = *ucontrol->value.integer.value;
853 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
854 AC_VERB_GET_EAPD_BTLENABLE,
855 0x00);
856
857 /* Set/unset the masked control bit(s) as needed */
858 change = (!val ? 0 : mask) != (ctrl_data & mask);
859 if (!val)
860 ctrl_data &= ~mask;
861 else
862 ctrl_data |= mask;
863 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
864 ctrl_data);
865
866 return change;
867 }
868
869 #define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
870 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
871 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
872 .info = alc_eapd_ctrl_info, \
873 .get = alc_eapd_ctrl_get, \
874 .put = alc_eapd_ctrl_put, \
875 .private_value = nid | (mask<<16) }
876 #endif /* CONFIG_SND_DEBUG */
877
878 /*
879 * set up the input pin config (depending on the given auto-pin type)
880 */
881 static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
882 int auto_pin_type)
883 {
884 unsigned int val = PIN_IN;
885
886 if (auto_pin_type == AUTO_PIN_MIC) {
887 unsigned int pincap;
888 unsigned int oldval;
889 oldval = snd_hda_codec_read(codec, nid, 0,
890 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
891 pincap = snd_hda_query_pin_caps(codec, nid);
892 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
893 /* if the default pin setup is vref50, we give it priority */
894 if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
895 val = PIN_VREF80;
896 else if (pincap & AC_PINCAP_VREF_50)
897 val = PIN_VREF50;
898 else if (pincap & AC_PINCAP_VREF_100)
899 val = PIN_VREF100;
900 else if (pincap & AC_PINCAP_VREF_GRD)
901 val = PIN_VREFGRD;
902 }
903 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
904 }
905
906 static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
907 {
908 struct alc_spec *spec = codec->spec;
909 struct auto_pin_cfg *cfg = &spec->autocfg;
910
911 if (!cfg->line_outs) {
912 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
913 cfg->line_out_pins[cfg->line_outs])
914 cfg->line_outs++;
915 }
916 if (!cfg->speaker_outs) {
917 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
918 cfg->speaker_pins[cfg->speaker_outs])
919 cfg->speaker_outs++;
920 }
921 if (!cfg->hp_outs) {
922 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
923 cfg->hp_pins[cfg->hp_outs])
924 cfg->hp_outs++;
925 }
926 }
927
928 /*
929 */
930 static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
931 {
932 if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers)))
933 return;
934 spec->mixers[spec->num_mixers++] = mix;
935 }
936
937 static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
938 {
939 if (snd_BUG_ON(spec->num_init_verbs >= ARRAY_SIZE(spec->init_verbs)))
940 return;
941 spec->init_verbs[spec->num_init_verbs++] = verb;
942 }
943
944 /*
945 * set up from the preset table
946 */
947 static void setup_preset(struct hda_codec *codec,
948 const struct alc_config_preset *preset)
949 {
950 struct alc_spec *spec = codec->spec;
951 int i;
952
953 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
954 add_mixer(spec, preset->mixers[i]);
955 spec->cap_mixer = preset->cap_mixer;
956 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
957 i++)
958 add_verb(spec, preset->init_verbs[i]);
959
960 spec->channel_mode = preset->channel_mode;
961 spec->num_channel_mode = preset->num_channel_mode;
962 spec->need_dac_fix = preset->need_dac_fix;
963 spec->const_channel_count = preset->const_channel_count;
964
965 if (preset->const_channel_count)
966 spec->multiout.max_channels = preset->const_channel_count;
967 else
968 spec->multiout.max_channels = spec->channel_mode[0].channels;
969 spec->ext_channel_count = spec->channel_mode[0].channels;
970
971 spec->multiout.num_dacs = preset->num_dacs;
972 spec->multiout.dac_nids = preset->dac_nids;
973 spec->multiout.dig_out_nid = preset->dig_out_nid;
974 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
975 spec->multiout.hp_nid = preset->hp_nid;
976
977 spec->num_mux_defs = preset->num_mux_defs;
978 if (!spec->num_mux_defs)
979 spec->num_mux_defs = 1;
980 spec->input_mux = preset->input_mux;
981
982 spec->num_adc_nids = preset->num_adc_nids;
983 spec->adc_nids = preset->adc_nids;
984 spec->capsrc_nids = preset->capsrc_nids;
985 spec->dig_in_nid = preset->dig_in_nid;
986
987 spec->unsol_event = preset->unsol_event;
988 spec->init_hook = preset->init_hook;
989 #ifdef CONFIG_SND_HDA_POWER_SAVE
990 spec->power_hook = preset->power_hook;
991 spec->loopback.amplist = preset->loopbacks;
992 #endif
993
994 if (preset->setup)
995 preset->setup(codec);
996
997 alc_fixup_autocfg_pin_nums(codec);
998 }
999
1000 /* Enable GPIO mask and set output */
1001 static const struct hda_verb alc_gpio1_init_verbs[] = {
1002 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
1003 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
1004 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
1005 { }
1006 };
1007
1008 static const struct hda_verb alc_gpio2_init_verbs[] = {
1009 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
1010 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
1011 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
1012 { }
1013 };
1014
1015 static const struct hda_verb alc_gpio3_init_verbs[] = {
1016 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
1017 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03},
1018 {0x01, AC_VERB_SET_GPIO_DATA, 0x03},
1019 { }
1020 };
1021
1022 /*
1023 * Fix hardware PLL issue
1024 * On some codecs, the analog PLL gating control must be off while
1025 * the default value is 1.
1026 */
1027 static void alc_fix_pll(struct hda_codec *codec)
1028 {
1029 struct alc_spec *spec = codec->spec;
1030 unsigned int val;
1031
1032 if (!spec->pll_nid)
1033 return;
1034 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1035 spec->pll_coef_idx);
1036 val = snd_hda_codec_read(codec, spec->pll_nid, 0,
1037 AC_VERB_GET_PROC_COEF, 0);
1038 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_COEF_INDEX,
1039 spec->pll_coef_idx);
1040 snd_hda_codec_write(codec, spec->pll_nid, 0, AC_VERB_SET_PROC_COEF,
1041 val & ~(1 << spec->pll_coef_bit));
1042 }
1043
1044 static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1045 unsigned int coef_idx, unsigned int coef_bit)
1046 {
1047 struct alc_spec *spec = codec->spec;
1048 spec->pll_nid = nid;
1049 spec->pll_coef_idx = coef_idx;
1050 spec->pll_coef_bit = coef_bit;
1051 alc_fix_pll(codec);
1052 }
1053
1054 static int alc_init_jacks(struct hda_codec *codec)
1055 {
1056 #ifdef CONFIG_SND_HDA_INPUT_JACK
1057 struct alc_spec *spec = codec->spec;
1058 int err;
1059 unsigned int hp_nid = spec->autocfg.hp_pins[0];
1060 unsigned int mic_nid = spec->ext_mic.pin;
1061 unsigned int dock_nid = spec->dock_mic.pin;
1062
1063 if (hp_nid) {
1064 err = snd_hda_input_jack_add(codec, hp_nid,
1065 SND_JACK_HEADPHONE, NULL);
1066 if (err < 0)
1067 return err;
1068 snd_hda_input_jack_report(codec, hp_nid);
1069 }
1070
1071 if (mic_nid) {
1072 err = snd_hda_input_jack_add(codec, mic_nid,
1073 SND_JACK_MICROPHONE, NULL);
1074 if (err < 0)
1075 return err;
1076 snd_hda_input_jack_report(codec, mic_nid);
1077 }
1078 if (dock_nid) {
1079 err = snd_hda_input_jack_add(codec, dock_nid,
1080 SND_JACK_MICROPHONE, NULL);
1081 if (err < 0)
1082 return err;
1083 snd_hda_input_jack_report(codec, dock_nid);
1084 }
1085 #endif /* CONFIG_SND_HDA_INPUT_JACK */
1086 return 0;
1087 }
1088
1089 static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
1090 {
1091 int i, present = 0;
1092
1093 for (i = 0; i < num_pins; i++) {
1094 hda_nid_t nid = pins[i];
1095 if (!nid)
1096 break;
1097 snd_hda_input_jack_report(codec, nid);
1098 present |= snd_hda_jack_detect(codec, nid);
1099 }
1100 return present;
1101 }
1102
1103 static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
1104 bool mute, bool hp_out)
1105 {
1106 struct alc_spec *spec = codec->spec;
1107 unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0;
1108 unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT);
1109 int i;
1110
1111 for (i = 0; i < num_pins; i++) {
1112 hda_nid_t nid = pins[i];
1113 if (!nid)
1114 break;
1115 switch (spec->automute_mode) {
1116 case ALC_AUTOMUTE_PIN:
1117 snd_hda_codec_write(codec, nid, 0,
1118 AC_VERB_SET_PIN_WIDGET_CONTROL,
1119 pin_bits);
1120 break;
1121 case ALC_AUTOMUTE_AMP:
1122 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
1123 HDA_AMP_MUTE, mute_bits);
1124 break;
1125 case ALC_AUTOMUTE_MIXER:
1126 nid = spec->automute_mixer_nid[i];
1127 if (!nid)
1128 break;
1129 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
1130 HDA_AMP_MUTE, mute_bits);
1131 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1,
1132 HDA_AMP_MUTE, mute_bits);
1133 break;
1134 }
1135 }
1136 }
1137
1138 /* Toggle internal speakers muting */
1139 static void update_speakers(struct hda_codec *codec)
1140 {
1141 struct alc_spec *spec = codec->spec;
1142 int on;
1143
1144 /* Control HP pins/amps depending on master_mute state;
1145 * in general, HP pins/amps control should be enabled in all cases,
1146 * but currently set only for master_mute, just to be safe
1147 */
1148 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1149 spec->autocfg.hp_pins, spec->master_mute, true);
1150
1151 if (!spec->automute)
1152 on = 0;
1153 else
1154 on = spec->jack_present | spec->line_jack_present;
1155 on |= spec->master_mute;
1156 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
1157 spec->autocfg.speaker_pins, on, false);
1158
1159 /* toggle line-out mutes if needed, too */
1160 /* if LO is a copy of either HP or Speaker, don't need to handle it */
1161 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
1162 spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
1163 return;
1164 if (!spec->automute_lines || !spec->automute)
1165 on = 0;
1166 else
1167 on = spec->jack_present;
1168 on |= spec->master_mute;
1169 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1170 spec->autocfg.line_out_pins, on, false);
1171 }
1172
1173 static void alc_hp_automute(struct hda_codec *codec)
1174 {
1175 struct alc_spec *spec = codec->spec;
1176
1177 if (!spec->automute)
1178 return;
1179 spec->jack_present =
1180 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
1181 spec->autocfg.hp_pins);
1182 update_speakers(codec);
1183 }
1184
1185 static void alc_line_automute(struct hda_codec *codec)
1186 {
1187 struct alc_spec *spec = codec->spec;
1188
1189 if (!spec->automute || !spec->detect_line)
1190 return;
1191 spec->line_jack_present =
1192 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
1193 spec->autocfg.line_out_pins);
1194 update_speakers(codec);
1195 }
1196
1197 static int get_connection_index(struct hda_codec *codec, hda_nid_t mux,
1198 hda_nid_t nid)
1199 {
1200 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
1201 int i, nums;
1202
1203 nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
1204 for (i = 0; i < nums; i++)
1205 if (conn[i] == nid)
1206 return i;
1207 return -1;
1208 }
1209
1210 /* switch the current ADC according to the jack state */
1211 static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec)
1212 {
1213 struct alc_spec *spec = codec->spec;
1214 unsigned int present;
1215 hda_nid_t new_adc;
1216
1217 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1218 if (present)
1219 spec->cur_adc_idx = 1;
1220 else
1221 spec->cur_adc_idx = 0;
1222 new_adc = spec->adc_nids[spec->cur_adc_idx];
1223 if (spec->cur_adc && spec->cur_adc != new_adc) {
1224 /* stream is running, let's swap the current ADC */
1225 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
1226 spec->cur_adc = new_adc;
1227 snd_hda_codec_setup_stream(codec, new_adc,
1228 spec->cur_adc_stream_tag, 0,
1229 spec->cur_adc_format);
1230 }
1231 }
1232
1233 static void alc_mic_automute(struct hda_codec *codec)
1234 {
1235 struct alc_spec *spec = codec->spec;
1236 struct alc_mic_route *dead1, *dead2, *alive;
1237 unsigned int present, type;
1238 hda_nid_t cap_nid;
1239
1240 if (!spec->auto_mic)
1241 return;
1242 if (!spec->int_mic.pin || !spec->ext_mic.pin)
1243 return;
1244 if (snd_BUG_ON(!spec->adc_nids))
1245 return;
1246
1247 if (spec->dual_adc_switch) {
1248 alc_dual_mic_adc_auto_switch(codec);
1249 return;
1250 }
1251
1252 cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0];
1253
1254 alive = &spec->int_mic;
1255 dead1 = &spec->ext_mic;
1256 dead2 = &spec->dock_mic;
1257
1258 present = snd_hda_jack_detect(codec, spec->ext_mic.pin);
1259 if (present) {
1260 alive = &spec->ext_mic;
1261 dead1 = &spec->int_mic;
1262 dead2 = &spec->dock_mic;
1263 }
1264 if (!present && spec->dock_mic.pin > 0) {
1265 present = snd_hda_jack_detect(codec, spec->dock_mic.pin);
1266 if (present) {
1267 alive = &spec->dock_mic;
1268 dead1 = &spec->int_mic;
1269 dead2 = &spec->ext_mic;
1270 }
1271 snd_hda_input_jack_report(codec, spec->dock_mic.pin);
1272 }
1273
1274 type = get_wcaps_type(get_wcaps(codec, cap_nid));
1275 if (type == AC_WID_AUD_MIX) {
1276 /* Matrix-mixer style (e.g. ALC882) */
1277 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1278 alive->mux_idx,
1279 HDA_AMP_MUTE, 0);
1280 if (dead1->pin > 0)
1281 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1282 dead1->mux_idx,
1283 HDA_AMP_MUTE, HDA_AMP_MUTE);
1284 if (dead2->pin > 0)
1285 snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT,
1286 dead2->mux_idx,
1287 HDA_AMP_MUTE, HDA_AMP_MUTE);
1288 } else {
1289 /* MUX style (e.g. ALC880) */
1290 snd_hda_codec_write_cache(codec, cap_nid, 0,
1291 AC_VERB_SET_CONNECT_SEL,
1292 alive->mux_idx);
1293 }
1294 snd_hda_input_jack_report(codec, spec->ext_mic.pin);
1295
1296 /* FIXME: analog mixer */
1297 }
1298
1299 /* unsolicited event for HP jack sensing */
1300 static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1301 {
1302 if (codec->vendor_id == 0x10ec0880)
1303 res >>= 28;
1304 else
1305 res >>= 26;
1306 switch (res) {
1307 case ALC880_HP_EVENT:
1308 alc_hp_automute(codec);
1309 break;
1310 case ALC880_FRONT_EVENT:
1311 alc_line_automute(codec);
1312 break;
1313 case ALC880_MIC_EVENT:
1314 alc_mic_automute(codec);
1315 break;
1316 }
1317 }
1318
1319 static void alc_inithook(struct hda_codec *codec)
1320 {
1321 alc_hp_automute(codec);
1322 alc_line_automute(codec);
1323 alc_mic_automute(codec);
1324 }
1325
1326 /* additional initialization for ALC888 variants */
1327 static void alc888_coef_init(struct hda_codec *codec)
1328 {
1329 unsigned int tmp;
1330
1331 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0);
1332 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1333 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1334 if ((tmp & 0xf0) == 0x20)
1335 /* alc888S-VC */
1336 snd_hda_codec_read(codec, 0x20, 0,
1337 AC_VERB_SET_PROC_COEF, 0x830);
1338 else
1339 /* alc888-VB */
1340 snd_hda_codec_read(codec, 0x20, 0,
1341 AC_VERB_SET_PROC_COEF, 0x3030);
1342 }
1343
1344 static void alc889_coef_init(struct hda_codec *codec)
1345 {
1346 unsigned int tmp;
1347
1348 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1349 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
1350 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 7);
1351 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp|0x2010);
1352 }
1353
1354 /* turn on/off EAPD control (only if available) */
1355 static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on)
1356 {
1357 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
1358 return;
1359 if (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)
1360 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
1361 on ? 2 : 0);
1362 }
1363
1364 /* turn on/off EAPD controls of the codec */
1365 static void alc_auto_setup_eapd(struct hda_codec *codec, bool on)
1366 {
1367 /* We currently only handle front, HP */
1368 switch (codec->vendor_id) {
1369 case 0x10ec0260:
1370 set_eapd(codec, 0x0f, on);
1371 set_eapd(codec, 0x10, on);
1372 break;
1373 case 0x10ec0262:
1374 case 0x10ec0267:
1375 case 0x10ec0268:
1376 case 0x10ec0269:
1377 case 0x10ec0270:
1378 case 0x10ec0272:
1379 case 0x10ec0660:
1380 case 0x10ec0662:
1381 case 0x10ec0663:
1382 case 0x10ec0665:
1383 case 0x10ec0862:
1384 case 0x10ec0889:
1385 case 0x10ec0892:
1386 set_eapd(codec, 0x14, on);
1387 set_eapd(codec, 0x15, on);
1388 break;
1389 }
1390 }
1391
1392 /* generic shutup callback;
1393 * just turning off EPAD and a little pause for avoiding pop-noise
1394 */
1395 static void alc_eapd_shutup(struct hda_codec *codec)
1396 {
1397 alc_auto_setup_eapd(codec, false);
1398 msleep(200);
1399 }
1400
1401 static void alc_auto_init_amp(struct hda_codec *codec, int type)
1402 {
1403 unsigned int tmp;
1404
1405 switch (type) {
1406 case ALC_INIT_GPIO1:
1407 snd_hda_sequence_write(codec, alc_gpio1_init_verbs);
1408 break;
1409 case ALC_INIT_GPIO2:
1410 snd_hda_sequence_write(codec, alc_gpio2_init_verbs);
1411 break;
1412 case ALC_INIT_GPIO3:
1413 snd_hda_sequence_write(codec, alc_gpio3_init_verbs);
1414 break;
1415 case ALC_INIT_DEFAULT:
1416 alc_auto_setup_eapd(codec, true);
1417 switch (codec->vendor_id) {
1418 case 0x10ec0260:
1419 snd_hda_codec_write(codec, 0x1a, 0,
1420 AC_VERB_SET_COEF_INDEX, 7);
1421 tmp = snd_hda_codec_read(codec, 0x1a, 0,
1422 AC_VERB_GET_PROC_COEF, 0);
1423 snd_hda_codec_write(codec, 0x1a, 0,
1424 AC_VERB_SET_COEF_INDEX, 7);
1425 snd_hda_codec_write(codec, 0x1a, 0,
1426 AC_VERB_SET_PROC_COEF,
1427 tmp | 0x2010);
1428 break;
1429 case 0x10ec0262:
1430 case 0x10ec0880:
1431 case 0x10ec0882:
1432 case 0x10ec0883:
1433 case 0x10ec0885:
1434 case 0x10ec0887:
1435 /*case 0x10ec0889:*/ /* this causes an SPDIF problem */
1436 alc889_coef_init(codec);
1437 break;
1438 case 0x10ec0888:
1439 alc888_coef_init(codec);
1440 break;
1441 #if 0 /* XXX: This may cause the silent output on speaker on some machines */
1442 case 0x10ec0267:
1443 case 0x10ec0268:
1444 snd_hda_codec_write(codec, 0x20, 0,
1445 AC_VERB_SET_COEF_INDEX, 7);
1446 tmp = snd_hda_codec_read(codec, 0x20, 0,
1447 AC_VERB_GET_PROC_COEF, 0);
1448 snd_hda_codec_write(codec, 0x20, 0,
1449 AC_VERB_SET_COEF_INDEX, 7);
1450 snd_hda_codec_write(codec, 0x20, 0,
1451 AC_VERB_SET_PROC_COEF,
1452 tmp | 0x3000);
1453 break;
1454 #endif /* XXX */
1455 }
1456 break;
1457 }
1458 }
1459
1460 static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1461 struct snd_ctl_elem_info *uinfo)
1462 {
1463 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1464 struct alc_spec *spec = codec->spec;
1465 static const char * const texts2[] = {
1466 "Disabled", "Enabled"
1467 };
1468 static const char * const texts3[] = {
1469 "Disabled", "Speaker Only", "Line-Out+Speaker"
1470 };
1471 const char * const *texts;
1472
1473 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1474 uinfo->count = 1;
1475 if (spec->automute_hp_lo) {
1476 uinfo->value.enumerated.items = 3;
1477 texts = texts3;
1478 } else {
1479 uinfo->value.enumerated.items = 2;
1480 texts = texts2;
1481 }
1482 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
1483 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
1484 strcpy(uinfo->value.enumerated.name,
1485 texts[uinfo->value.enumerated.item]);
1486 return 0;
1487 }
1488
1489 static int alc_automute_mode_get(struct snd_kcontrol *kcontrol,
1490 struct snd_ctl_elem_value *ucontrol)
1491 {
1492 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1493 struct alc_spec *spec = codec->spec;
1494 unsigned int val;
1495 if (!spec->automute)
1496 val = 0;
1497 else if (!spec->automute_lines)
1498 val = 1;
1499 else
1500 val = 2;
1501 ucontrol->value.enumerated.item[0] = val;
1502 return 0;
1503 }
1504
1505 static int alc_automute_mode_put(struct snd_kcontrol *kcontrol,
1506 struct snd_ctl_elem_value *ucontrol)
1507 {
1508 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1509 struct alc_spec *spec = codec->spec;
1510
1511 switch (ucontrol->value.enumerated.item[0]) {
1512 case 0:
1513 if (!spec->automute)
1514 return 0;
1515 spec->automute = 0;
1516 break;
1517 case 1:
1518 if (spec->automute && !spec->automute_lines)
1519 return 0;
1520 spec->automute = 1;
1521 spec->automute_lines = 0;
1522 break;
1523 case 2:
1524 if (!spec->automute_hp_lo)
1525 return -EINVAL;
1526 if (spec->automute && spec->automute_lines)
1527 return 0;
1528 spec->automute = 1;
1529 spec->automute_lines = 1;
1530 break;
1531 default:
1532 return -EINVAL;
1533 }
1534 update_speakers(codec);
1535 return 1;
1536 }
1537
1538 static const struct snd_kcontrol_new alc_automute_mode_enum = {
1539 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1540 .name = "Auto-Mute Mode",
1541 .info = alc_automute_mode_info,
1542 .get = alc_automute_mode_get,
1543 .put = alc_automute_mode_put,
1544 };
1545
1546 static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec);
1547
1548 static int alc_add_automute_mode_enum(struct hda_codec *codec)
1549 {
1550 struct alc_spec *spec = codec->spec;
1551 struct snd_kcontrol_new *knew;
1552
1553 knew = alc_kcontrol_new(spec);
1554 if (!knew)
1555 return -ENOMEM;
1556 *knew = alc_automute_mode_enum;
1557 knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL);
1558 if (!knew->name)
1559 return -ENOMEM;
1560 return 0;
1561 }
1562
1563 static void alc_init_auto_hp(struct hda_codec *codec)
1564 {
1565 struct alc_spec *spec = codec->spec;
1566 struct auto_pin_cfg *cfg = &spec->autocfg;
1567 int present = 0;
1568 int i;
1569
1570 if (cfg->hp_pins[0])
1571 present++;
1572 if (cfg->line_out_pins[0])
1573 present++;
1574 if (cfg->speaker_pins[0])
1575 present++;
1576 if (present < 2) /* need two different output types */
1577 return;
1578 if (present == 3)
1579 spec->automute_hp_lo = 1; /* both HP and LO automute */
1580
1581 if (!cfg->speaker_pins[0]) {
1582 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1583 sizeof(cfg->speaker_pins));
1584 cfg->speaker_outs = cfg->line_outs;
1585 }
1586
1587 if (!cfg->hp_pins[0]) {
1588 memcpy(cfg->hp_pins, cfg->line_out_pins,
1589 sizeof(cfg->hp_pins));
1590 cfg->hp_outs = cfg->line_outs;
1591 }
1592
1593 for (i = 0; i < cfg->hp_outs; i++) {
1594 hda_nid_t nid = cfg->hp_pins[i];
1595 if (!is_jack_detectable(codec, nid))
1596 continue;
1597 snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n",
1598 nid);
1599 snd_hda_codec_write_cache(codec, nid, 0,
1600 AC_VERB_SET_UNSOLICITED_ENABLE,
1601 AC_USRSP_EN | ALC880_HP_EVENT);
1602 spec->automute = 1;
1603 spec->automute_mode = ALC_AUTOMUTE_PIN;
1604 }
1605 if (spec->automute && cfg->line_out_pins[0] &&
1606 cfg->line_out_pins[0] != cfg->hp_pins[0] &&
1607 cfg->line_out_pins[0] != cfg->speaker_pins[0]) {
1608 for (i = 0; i < cfg->line_outs; i++) {
1609 hda_nid_t nid = cfg->line_out_pins[i];
1610 if (!is_jack_detectable(codec, nid))
1611 continue;
1612 snd_printdd("realtek: Enable Line-Out auto-muting "
1613 "on NID 0x%x\n", nid);
1614 snd_hda_codec_write_cache(codec, nid, 0,
1615 AC_VERB_SET_UNSOLICITED_ENABLE,
1616 AC_USRSP_EN | ALC880_FRONT_EVENT);
1617 spec->detect_line = 1;
1618 }
1619 spec->automute_lines = spec->detect_line;
1620 }
1621
1622 if (spec->automute) {
1623 /* create a control for automute mode */
1624 alc_add_automute_mode_enum(codec);
1625 spec->unsol_event = alc_sku_unsol_event;
1626 }
1627 }
1628
1629 static void alc_init_auto_mic(struct hda_codec *codec)
1630 {
1631 struct alc_spec *spec = codec->spec;
1632 struct auto_pin_cfg *cfg = &spec->autocfg;
1633 hda_nid_t fixed, ext, dock;
1634 int i;
1635
1636 fixed = ext = dock = 0;
1637 for (i = 0; i < cfg->num_inputs; i++) {
1638 hda_nid_t nid = cfg->inputs[i].pin;
1639 unsigned int defcfg;
1640 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1641 switch (snd_hda_get_input_pin_attr(defcfg)) {
1642 case INPUT_PIN_ATTR_INT:
1643 if (fixed)
1644 return; /* already occupied */
1645 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1646 return; /* invalid type */
1647 fixed = nid;
1648 break;
1649 case INPUT_PIN_ATTR_UNUSED:
1650 return; /* invalid entry */
1651 case INPUT_PIN_ATTR_DOCK:
1652 if (dock)
1653 return; /* already occupied */
1654 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
1655 return; /* invalid type */
1656 dock = nid;
1657 break;
1658 default:
1659 if (ext)
1660 return; /* already occupied */
1661 if (cfg->inputs[i].type != AUTO_PIN_MIC)
1662 return; /* invalid type */
1663 ext = nid;
1664 break;
1665 }
1666 }
1667 if (!ext && dock) {
1668 ext = dock;
1669 dock = 0;
1670 }
1671 if (!ext || !fixed)
1672 return;
1673 if (!is_jack_detectable(codec, ext))
1674 return; /* no unsol support */
1675 if (dock && !is_jack_detectable(codec, dock))
1676 return; /* no unsol support */
1677 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1678 ext, fixed, dock);
1679 spec->ext_mic.pin = ext;
1680 spec->dock_mic.pin = dock;
1681 spec->int_mic.pin = fixed;
1682 spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1683 spec->dock_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1684 spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */
1685 spec->auto_mic = 1;
1686 snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0,
1687 AC_VERB_SET_UNSOLICITED_ENABLE,
1688 AC_USRSP_EN | ALC880_MIC_EVENT);
1689 spec->unsol_event = alc_sku_unsol_event;
1690 }
1691
1692 /* Could be any non-zero and even value. When used as fixup, tells
1693 * the driver to ignore any present sku defines.
1694 */
1695 #define ALC_FIXUP_SKU_IGNORE (2)
1696
1697 static int alc_auto_parse_customize_define(struct hda_codec *codec)
1698 {
1699 unsigned int ass, tmp, i;
1700 unsigned nid = 0;
1701 struct alc_spec *spec = codec->spec;
1702
1703 spec->cdefine.enable_pcbeep = 1; /* assume always enabled */
1704
1705 if (spec->cdefine.fixup) {
1706 ass = spec->cdefine.sku_cfg;
1707 if (ass == ALC_FIXUP_SKU_IGNORE)
1708 return -1;
1709 goto do_sku;
1710 }
1711
1712 ass = codec->subsystem_id & 0xffff;
1713 if (ass != codec->bus->pci->subsystem_device && (ass & 1))
1714 goto do_sku;
1715
1716 nid = 0x1d;
1717 if (codec->vendor_id == 0x10ec0260)
1718 nid = 0x17;
1719 ass = snd_hda_codec_get_pincfg(codec, nid);
1720
1721 if (!(ass & 1)) {
1722 printk(KERN_INFO "hda_codec: %s: SKU not ready 0x%08x\n",
1723 codec->chip_name, ass);
1724 return -1;
1725 }
1726
1727 /* check sum */
1728 tmp = 0;
1729 for (i = 1; i < 16; i++) {
1730 if ((ass >> i) & 1)
1731 tmp++;
1732 }
1733 if (((ass >> 16) & 0xf) != tmp)
1734 return -1;
1735
1736 spec->cdefine.port_connectivity = ass >> 30;
1737 spec->cdefine.enable_pcbeep = (ass & 0x100000) >> 20;
1738 spec->cdefine.check_sum = (ass >> 16) & 0xf;
1739 spec->cdefine.customization = ass >> 8;
1740 do_sku:
1741 spec->cdefine.sku_cfg = ass;
1742 spec->cdefine.external_amp = (ass & 0x38) >> 3;
1743 spec->cdefine.platform_type = (ass & 0x4) >> 2;
1744 spec->cdefine.swap = (ass & 0x2) >> 1;
1745 spec->cdefine.override = ass & 0x1;
1746
1747 snd_printd("SKU: Nid=0x%x sku_cfg=0x%08x\n",
1748 nid, spec->cdefine.sku_cfg);
1749 snd_printd("SKU: port_connectivity=0x%x\n",
1750 spec->cdefine.port_connectivity);
1751 snd_printd("SKU: enable_pcbeep=0x%x\n", spec->cdefine.enable_pcbeep);
1752 snd_printd("SKU: check_sum=0x%08x\n", spec->cdefine.check_sum);
1753 snd_printd("SKU: customization=0x%08x\n", spec->cdefine.customization);
1754 snd_printd("SKU: external_amp=0x%x\n", spec->cdefine.external_amp);
1755 snd_printd("SKU: platform_type=0x%x\n", spec->cdefine.platform_type);
1756 snd_printd("SKU: swap=0x%x\n", spec->cdefine.swap);
1757 snd_printd("SKU: override=0x%x\n", spec->cdefine.override);
1758
1759 return 0;
1760 }
1761
1762 /* check subsystem ID and set up device-specific initialization;
1763 * return 1 if initialized, 0 if invalid SSID
1764 */
1765 /* 32-bit subsystem ID for BIOS loading in HD Audio codec.
1766 * 31 ~ 16 : Manufacture ID
1767 * 15 ~ 8 : SKU ID
1768 * 7 ~ 0 : Assembly ID
1769 * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36
1770 */
1771 static int alc_subsystem_id(struct hda_codec *codec,
1772 hda_nid_t porta, hda_nid_t porte,
1773 hda_nid_t portd, hda_nid_t porti)
1774 {
1775 unsigned int ass, tmp, i;
1776 unsigned nid;
1777 struct alc_spec *spec = codec->spec;
1778
1779 if (spec->cdefine.fixup) {
1780 ass = spec->cdefine.sku_cfg;
1781 if (ass == ALC_FIXUP_SKU_IGNORE)
1782 return 0;
1783 goto do_sku;
1784 }
1785
1786 ass = codec->subsystem_id & 0xffff;
1787 if ((ass != codec->bus->pci->subsystem_device) && (ass & 1))
1788 goto do_sku;
1789
1790 /* invalid SSID, check the special NID pin defcfg instead */
1791 /*
1792 * 31~30 : port connectivity
1793 * 29~21 : reserve
1794 * 20 : PCBEEP input
1795 * 19~16 : Check sum (15:1)
1796 * 15~1 : Custom
1797 * 0 : override
1798 */
1799 nid = 0x1d;
1800 if (codec->vendor_id == 0x10ec0260)
1801 nid = 0x17;
1802 ass = snd_hda_codec_get_pincfg(codec, nid);
1803 snd_printd("realtek: No valid SSID, "
1804 "checking pincfg 0x%08x for NID 0x%x\n",
1805 ass, nid);
1806 if (!(ass & 1))
1807 return 0;
1808 if ((ass >> 30) != 1) /* no physical connection */
1809 return 0;
1810
1811 /* check sum */
1812 tmp = 0;
1813 for (i = 1; i < 16; i++) {
1814 if ((ass >> i) & 1)
1815 tmp++;
1816 }
1817 if (((ass >> 16) & 0xf) != tmp)
1818 return 0;
1819 do_sku:
1820 snd_printd("realtek: Enabling init ASM_ID=0x%04x CODEC_ID=%08x\n",
1821 ass & 0xffff, codec->vendor_id);
1822 /*
1823 * 0 : override
1824 * 1 : Swap Jack
1825 * 2 : 0 --> Desktop, 1 --> Laptop
1826 * 3~5 : External Amplifier control
1827 * 7~6 : Reserved
1828 */
1829 tmp = (ass & 0x38) >> 3; /* external Amp control */
1830 switch (tmp) {
1831 case 1:
1832 spec->init_amp = ALC_INIT_GPIO1;
1833 break;
1834 case 3:
1835 spec->init_amp = ALC_INIT_GPIO2;
1836 break;
1837 case 7:
1838 spec->init_amp = ALC_INIT_GPIO3;
1839 break;
1840 case 5:
1841 default:
1842 spec->init_amp = ALC_INIT_DEFAULT;
1843 break;
1844 }
1845
1846 /* is laptop or Desktop and enable the function "Mute internal speaker
1847 * when the external headphone out jack is plugged"
1848 */
1849 if (!(ass & 0x8000))
1850 return 1;
1851 /*
1852 * 10~8 : Jack location
1853 * 12~11: Headphone out -> 00: PortA, 01: PortE, 02: PortD, 03: Resvered
1854 * 14~13: Resvered
1855 * 15 : 1 --> enable the function "Mute internal speaker
1856 * when the external headphone out jack is plugged"
1857 */
1858 if (!spec->autocfg.hp_pins[0]) {
1859 hda_nid_t nid;
1860 tmp = (ass >> 11) & 0x3; /* HP to chassis */
1861 if (tmp == 0)
1862 nid = porta;
1863 else if (tmp == 1)
1864 nid = porte;
1865 else if (tmp == 2)
1866 nid = portd;
1867 else if (tmp == 3)
1868 nid = porti;
1869 else
1870 return 1;
1871 for (i = 0; i < spec->autocfg.line_outs; i++)
1872 if (spec->autocfg.line_out_pins[i] == nid)
1873 return 1;
1874 spec->autocfg.hp_pins[0] = nid;
1875 }
1876 return 1;
1877 }
1878
1879 static void alc_ssid_check(struct hda_codec *codec,
1880 hda_nid_t porta, hda_nid_t porte,
1881 hda_nid_t portd, hda_nid_t porti)
1882 {
1883 if (!alc_subsystem_id(codec, porta, porte, portd, porti)) {
1884 struct alc_spec *spec = codec->spec;
1885 snd_printd("realtek: "
1886 "Enable default setup for auto mode as fallback\n");
1887 spec->init_amp = ALC_INIT_DEFAULT;
1888 }
1889
1890 alc_init_auto_hp(codec);
1891 alc_init_auto_mic(codec);
1892 }
1893
1894 /*
1895 * Fix-up pin default configurations and add default verbs
1896 */
1897
1898 struct alc_pincfg {
1899 hda_nid_t nid;
1900 u32 val;
1901 };
1902
1903 struct alc_model_fixup {
1904 const int id;
1905 const char *name;
1906 };
1907
1908 struct alc_fixup {
1909 int type;
1910 bool chained;
1911 int chain_id;
1912 union {
1913 unsigned int sku;
1914 const struct alc_pincfg *pins;
1915 const struct hda_verb *verbs;
1916 void (*func)(struct hda_codec *codec,
1917 const struct alc_fixup *fix,
1918 int action);
1919 } v;
1920 };
1921
1922 enum {
1923 ALC_FIXUP_INVALID,
1924 ALC_FIXUP_SKU,
1925 ALC_FIXUP_PINS,
1926 ALC_FIXUP_VERBS,
1927 ALC_FIXUP_FUNC,
1928 };
1929
1930 enum {
1931 ALC_FIXUP_ACT_PRE_PROBE,
1932 ALC_FIXUP_ACT_PROBE,
1933 ALC_FIXUP_ACT_INIT,
1934 };
1935
1936 static void alc_apply_fixup(struct hda_codec *codec, int action)
1937 {
1938 struct alc_spec *spec = codec->spec;
1939 int id = spec->fixup_id;
1940 #ifdef CONFIG_SND_DEBUG_VERBOSE
1941 const char *modelname = spec->fixup_name;
1942 #endif
1943 int depth = 0;
1944
1945 if (!spec->fixup_list)
1946 return;
1947
1948 while (id >= 0) {
1949 const struct alc_fixup *fix = spec->fixup_list + id;
1950 const struct alc_pincfg *cfg;
1951
1952 switch (fix->type) {
1953 case ALC_FIXUP_SKU:
1954 if (action != ALC_FIXUP_ACT_PRE_PROBE || !fix->v.sku)
1955 break;;
1956 snd_printdd(KERN_INFO "hda_codec: %s: "
1957 "Apply sku override for %s\n",
1958 codec->chip_name, modelname);
1959 spec->cdefine.sku_cfg = fix->v.sku;
1960 spec->cdefine.fixup = 1;
1961 break;
1962 case ALC_FIXUP_PINS:
1963 cfg = fix->v.pins;
1964 if (action != ALC_FIXUP_ACT_PRE_PROBE || !cfg)
1965 break;
1966 snd_printdd(KERN_INFO "hda_codec: %s: "
1967 "Apply pincfg for %s\n",
1968 codec->chip_name, modelname);
1969 for (; cfg->nid; cfg++)
1970 snd_hda_codec_set_pincfg(codec, cfg->nid,
1971 cfg->val);
1972 break;
1973 case ALC_FIXUP_VERBS:
1974 if (action != ALC_FIXUP_ACT_PROBE || !fix->v.verbs)
1975 break;
1976 snd_printdd(KERN_INFO "hda_codec: %s: "
1977 "Apply fix-verbs for %s\n",
1978 codec->chip_name, modelname);
1979 add_verb(codec->spec, fix->v.verbs);
1980 break;
1981 case ALC_FIXUP_FUNC:
1982 if (!fix->v.func)
1983 break;
1984 snd_printdd(KERN_INFO "hda_codec: %s: "
1985 "Apply fix-func for %s\n",
1986 codec->chip_name, modelname);
1987 fix->v.func(codec, fix, action);
1988 break;
1989 default:
1990 snd_printk(KERN_ERR "hda_codec: %s: "
1991 "Invalid fixup type %d\n",
1992 codec->chip_name, fix->type);
1993 break;
1994 }
1995 if (!fix->chained)
1996 break;
1997 if (++depth > 10)
1998 break;
1999 id = fix->chain_id;
2000 }
2001 }
2002
2003 static void alc_pick_fixup(struct hda_codec *codec,
2004 const struct alc_model_fixup *models,
2005 const struct snd_pci_quirk *quirk,
2006 const struct alc_fixup *fixlist)
2007 {
2008 struct alc_spec *spec = codec->spec;
2009 int id = -1;
2010 const char *name = NULL;
2011
2012 if (codec->modelname && models) {
2013 while (models->name) {
2014 if (!strcmp(codec->modelname, models->name)) {
2015 id = models->id;
2016 name = models->name;
2017 break;
2018 }
2019 models++;
2020 }
2021 }
2022 if (id < 0) {
2023 quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk);
2024 if (quirk) {
2025 id = quirk->value;
2026 #ifdef CONFIG_SND_DEBUG_VERBOSE
2027 name = quirk->name;
2028 #endif
2029 }
2030 }
2031
2032 spec->fixup_id = id;
2033 if (id >= 0) {
2034 spec->fixup_list = fixlist;
2035 spec->fixup_name = name;
2036 }
2037 }
2038
2039 static int alc_read_coef_idx(struct hda_codec *codec,
2040 unsigned int coef_idx)
2041 {
2042 unsigned int val;
2043 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2044 coef_idx);
2045 val = snd_hda_codec_read(codec, 0x20, 0,
2046 AC_VERB_GET_PROC_COEF, 0);
2047 return val;
2048 }
2049
2050 static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
2051 unsigned int coef_val)
2052 {
2053 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX,
2054 coef_idx);
2055 snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF,
2056 coef_val);
2057 }
2058
2059 /* set right pin controls for digital I/O */
2060 static void alc_auto_init_digital(struct hda_codec *codec)
2061 {
2062 struct alc_spec *spec = codec->spec;
2063 int i;
2064 hda_nid_t pin;
2065
2066 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2067 pin = spec->autocfg.dig_out_pins[i];
2068 if (pin) {
2069 snd_hda_codec_write(codec, pin, 0,
2070 AC_VERB_SET_PIN_WIDGET_CONTROL,
2071 PIN_OUT);
2072 }
2073 }
2074 pin = spec->autocfg.dig_in_pin;
2075 if (pin)
2076 snd_hda_codec_write(codec, pin, 0,
2077 AC_VERB_SET_PIN_WIDGET_CONTROL,
2078 PIN_IN);
2079 }
2080
2081 /* parse digital I/Os and set up NIDs in BIOS auto-parse mode */
2082 static void alc_auto_parse_digital(struct hda_codec *codec)
2083 {
2084 struct alc_spec *spec = codec->spec;
2085 int i, err;
2086 hda_nid_t dig_nid;
2087
2088 /* support multiple SPDIFs; the secondary is set up as a slave */
2089 for (i = 0; i < spec->autocfg.dig_outs; i++) {
2090 err = snd_hda_get_connections(codec,
2091 spec->autocfg.dig_out_pins[i],
2092 &dig_nid, 1);
2093 if (err < 0)
2094 continue;
2095 if (!i) {
2096 spec->multiout.dig_out_nid = dig_nid;
2097 spec->dig_out_type = spec->autocfg.dig_out_type[0];
2098 } else {
2099 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
2100 if (i >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
2101 break;
2102 spec->slave_dig_outs[i - 1] = dig_nid;
2103 }
2104 }
2105
2106 if (spec->autocfg.dig_in_pin) {
2107 dig_nid = codec->start_nid;
2108 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
2109 unsigned int wcaps = get_wcaps(codec, dig_nid);
2110 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
2111 continue;
2112 if (!(wcaps & AC_WCAP_DIGITAL))
2113 continue;
2114 if (!(wcaps & AC_WCAP_CONN_LIST))
2115 continue;
2116 err = get_connection_index(codec, dig_nid,
2117 spec->autocfg.dig_in_pin);
2118 if (err >= 0) {
2119 spec->dig_in_nid = dig_nid;
2120 break;
2121 }
2122 }
2123 }
2124 }
2125
2126 /*
2127 * ALC888
2128 */
2129
2130 /*
2131 * 2ch mode
2132 */
2133 static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
2134 /* Mic-in jack as mic in */
2135 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2136 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2137 /* Line-in jack as Line in */
2138 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2139 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2140 /* Line-Out as Front */
2141 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2142 { } /* end */
2143 };
2144
2145 /*
2146 * 4ch mode
2147 */
2148 static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
2149 /* Mic-in jack as mic in */
2150 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2151 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2152 /* Line-in jack as Surround */
2153 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2154 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2155 /* Line-Out as Front */
2156 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2157 { } /* end */
2158 };
2159
2160 /*
2161 * 6ch mode
2162 */
2163 static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
2164 /* Mic-in jack as CLFE */
2165 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2166 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2167 /* Line-in jack as Surround */
2168 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2169 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2170 /* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
2171 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2172 { } /* end */
2173 };
2174
2175 /*
2176 * 8ch mode
2177 */
2178 static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
2179 /* Mic-in jack as CLFE */
2180 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2181 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2182 /* Line-in jack as Surround */
2183 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2184 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2185 /* Line-Out as Side */
2186 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2187 { } /* end */
2188 };
2189
2190 static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
2191 { 2, alc888_4ST_ch2_intel_init },
2192 { 4, alc888_4ST_ch4_intel_init },
2193 { 6, alc888_4ST_ch6_intel_init },
2194 { 8, alc888_4ST_ch8_intel_init },
2195 };
2196
2197 /*
2198 * ALC888 Fujitsu Siemens Amillo xa3530
2199 */
2200
2201 static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
2202 /* Front Mic: set to PIN_IN (empty by default) */
2203 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2204 /* Connect Internal HP to Front */
2205 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2206 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2207 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2208 /* Connect Bass HP to Front */
2209 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2210 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2211 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2212 /* Connect Line-Out side jack (SPDIF) to Side */
2213 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2214 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2215 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2216 /* Connect Mic jack to CLFE */
2217 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2218 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2219 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2220 /* Connect Line-in jack to Surround */
2221 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2222 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2223 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2224 /* Connect HP out jack to Front */
2225 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2226 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2227 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2228 /* Enable unsolicited event for HP jack and Line-out jack */
2229 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2230 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2231 {}
2232 };
2233
2234 static void alc889_automute_setup(struct hda_codec *codec)
2235 {
2236 struct alc_spec *spec = codec->spec;
2237
2238 spec->autocfg.hp_pins[0] = 0x15;
2239 spec->autocfg.speaker_pins[0] = 0x14;
2240 spec->autocfg.speaker_pins[1] = 0x16;
2241 spec->autocfg.speaker_pins[2] = 0x17;
2242 spec->autocfg.speaker_pins[3] = 0x19;
2243 spec->autocfg.speaker_pins[4] = 0x1a;
2244 spec->automute = 1;
2245 spec->automute_mode = ALC_AUTOMUTE_AMP;
2246 }
2247
2248 static void alc889_intel_init_hook(struct hda_codec *codec)
2249 {
2250 alc889_coef_init(codec);
2251 alc_hp_automute(codec);
2252 }
2253
2254 static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
2255 {
2256 struct alc_spec *spec = codec->spec;
2257
2258 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2259 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2260 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2261 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
2262 spec->automute = 1;
2263 spec->automute_mode = ALC_AUTOMUTE_AMP;
2264 }
2265
2266 /*
2267 * ALC888 Acer Aspire 4930G model
2268 */
2269
2270 static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
2271 /* Front Mic: set to PIN_IN (empty by default) */
2272 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2273 /* Unselect Front Mic by default in input mixer 3 */
2274 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2275 /* Enable unsolicited event for HP jack */
2276 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2277 /* Connect Internal HP to front */
2278 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2279 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2280 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2281 /* Connect HP out to front */
2282 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2283 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2284 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2285 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2286 { }
2287 };
2288
2289 /*
2290 * ALC888 Acer Aspire 6530G model
2291 */
2292
2293 static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
2294 /* Route to built-in subwoofer as well as speakers */
2295 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2296 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2297 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2298 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2299 /* Bias voltage on for external mic port */
2300 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2301 /* Front Mic: set to PIN_IN (empty by default) */
2302 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2303 /* Unselect Front Mic by default in input mixer 3 */
2304 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2305 /* Enable unsolicited event for HP jack */
2306 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2307 /* Enable speaker output */
2308 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2309 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2310 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2311 /* Enable headphone output */
2312 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2313 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2314 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2315 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2316 { }
2317 };
2318
2319 /*
2320 *ALC888 Acer Aspire 7730G model
2321 */
2322
2323 static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2324 /* Bias voltage on for external mic port */
2325 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2326 /* Front Mic: set to PIN_IN (empty by default) */
2327 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2328 /* Unselect Front Mic by default in input mixer 3 */
2329 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2330 /* Enable unsolicited event for HP jack */
2331 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2332 /* Enable speaker output */
2333 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2334 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2335 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2336 /* Enable headphone output */
2337 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2338 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2339 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2340 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2341 /*Enable internal subwoofer */
2342 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2343 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2344 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2345 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2346 { }
2347 };
2348
2349 /*
2350 * ALC889 Acer Aspire 8930G model
2351 */
2352
2353 static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
2354 /* Front Mic: set to PIN_IN (empty by default) */
2355 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2356 /* Unselect Front Mic by default in input mixer 3 */
2357 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2358 /* Enable unsolicited event for HP jack */
2359 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2360 /* Connect Internal Front to Front */
2361 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2362 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2363 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2364 /* Connect Internal Rear to Rear */
2365 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2366 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2367 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2368 /* Connect Internal CLFE to CLFE */
2369 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2370 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2371 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2372 /* Connect HP out to Front */
2373 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2374 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2375 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2376 /* Enable all DACs */
2377 /* DAC DISABLE/MUTE 1? */
2378 /* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2379 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2380 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2381 /* DAC DISABLE/MUTE 2? */
2382 /* some bit here disables the other DACs. Init=0x4900 */
2383 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2384 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2385 /* DMIC fix
2386 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2387 * which makes the stereo useless. However, either the mic or the ALC889
2388 * makes the signal become a difference/sum signal instead of standard
2389 * stereo, which is annoying. So instead we flip this bit which makes the
2390 * codec replicate the sum signal to both channels, turning it into a
2391 * normal mono mic.
2392 */
2393 /* DMIC_CONTROL? Init value = 0x0001 */
2394 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2395 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
2396 { }
2397 };
2398
2399 static const struct hda_input_mux alc888_2_capture_sources[2] = {
2400 /* Front mic only available on one ADC */
2401 {
2402 .num_items = 4,
2403 .items = {
2404 { "Mic", 0x0 },
2405 { "Line", 0x2 },
2406 { "CD", 0x4 },
2407 { "Front Mic", 0xb },
2408 },
2409 },
2410 {
2411 .num_items = 3,
2412 .items = {
2413 { "Mic", 0x0 },
2414 { "Line", 0x2 },
2415 { "CD", 0x4 },
2416 },
2417 }
2418 };
2419
2420 static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2421 /* Interal mic only available on one ADC */
2422 {
2423 .num_items = 5,
2424 .items = {
2425 { "Mic", 0x0 },
2426 { "Line In", 0x2 },
2427 { "CD", 0x4 },
2428 { "Input Mix", 0xa },
2429 { "Internal Mic", 0xb },
2430 },
2431 },
2432 {
2433 .num_items = 4,
2434 .items = {
2435 { "Mic", 0x0 },
2436 { "Line In", 0x2 },
2437 { "CD", 0x4 },
2438 { "Input Mix", 0xa },
2439 },
2440 }
2441 };
2442
2443 static const struct hda_input_mux alc889_capture_sources[3] = {
2444 /* Digital mic only available on first "ADC" */
2445 {
2446 .num_items = 5,
2447 .items = {
2448 { "Mic", 0x0 },
2449 { "Line", 0x2 },
2450 { "CD", 0x4 },
2451 { "Front Mic", 0xb },
2452 { "Input Mix", 0xa },
2453 },
2454 },
2455 {
2456 .num_items = 4,
2457 .items = {
2458 { "Mic", 0x0 },
2459 { "Line", 0x2 },
2460 { "CD", 0x4 },
2461 { "Input Mix", 0xa },
2462 },
2463 },
2464 {
2465 .num_items = 4,
2466 .items = {
2467 { "Mic", 0x0 },
2468 { "Line", 0x2 },
2469 { "CD", 0x4 },
2470 { "Input Mix", 0xa },
2471 },
2472 }
2473 };
2474
2475 static const struct snd_kcontrol_new alc888_base_mixer[] = {
2476 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2477 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2478 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2479 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2480 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2481 HDA_OUTPUT),
2482 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2483 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2484 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2485 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2486 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2487 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2488 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2489 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2490 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2491 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2492 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2493 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2494 { } /* end */
2495 };
2496
2497 static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2498 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2499 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2500 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2501 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2502 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2503 HDA_OUTPUT),
2504 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2505 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2506 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2507 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2508 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
2509 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2510 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2511 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2512 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2513 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2514 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2515 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2516 { } /* end */
2517 };
2518
2519 static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2520 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2521 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2522 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2523 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2524 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2525 HDA_OUTPUT),
2526 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2527 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2528 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2529 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2530 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2531 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2532 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2533 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2534 { } /* end */
2535 };
2536
2537
2538 static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
2539 {
2540 struct alc_spec *spec = codec->spec;
2541
2542 spec->autocfg.hp_pins[0] = 0x15;
2543 spec->autocfg.speaker_pins[0] = 0x14;
2544 spec->autocfg.speaker_pins[1] = 0x16;
2545 spec->autocfg.speaker_pins[2] = 0x17;
2546 spec->automute = 1;
2547 spec->automute_mode = ALC_AUTOMUTE_AMP;
2548 }
2549
2550 static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
2551 {
2552 struct alc_spec *spec = codec->spec;
2553
2554 spec->autocfg.hp_pins[0] = 0x15;
2555 spec->autocfg.speaker_pins[0] = 0x14;
2556 spec->autocfg.speaker_pins[1] = 0x16;
2557 spec->autocfg.speaker_pins[2] = 0x17;
2558 spec->automute = 1;
2559 spec->automute_mode = ALC_AUTOMUTE_AMP;
2560 }
2561
2562 static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2563 {
2564 struct alc_spec *spec = codec->spec;
2565
2566 spec->autocfg.hp_pins[0] = 0x15;
2567 spec->autocfg.speaker_pins[0] = 0x14;
2568 spec->autocfg.speaker_pins[1] = 0x16;
2569 spec->autocfg.speaker_pins[2] = 0x17;
2570 spec->automute = 1;
2571 spec->automute_mode = ALC_AUTOMUTE_AMP;
2572 }
2573
2574 static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
2575 {
2576 struct alc_spec *spec = codec->spec;
2577
2578 spec->autocfg.hp_pins[0] = 0x15;
2579 spec->autocfg.speaker_pins[0] = 0x14;
2580 spec->autocfg.speaker_pins[1] = 0x16;
2581 spec->autocfg.speaker_pins[2] = 0x1b;
2582 spec->automute = 1;
2583 spec->automute_mode = ALC_AUTOMUTE_AMP;
2584 }
2585
2586 /*
2587 * ALC880 3-stack model
2588 *
2589 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
2590 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2591 * F-Mic = 0x1b, HP = 0x19
2592 */
2593
2594 static const hda_nid_t alc880_dac_nids[4] = {
2595 /* front, rear, clfe, rear_surr */
2596 0x02, 0x05, 0x04, 0x03
2597 };
2598
2599 static const hda_nid_t alc880_adc_nids[3] = {
2600 /* ADC0-2 */
2601 0x07, 0x08, 0x09,
2602 };
2603
2604 /* The datasheet says the node 0x07 is connected from inputs,
2605 * but it shows zero connection in the real implementation on some devices.
2606 * Note: this is a 915GAV bug, fixed on 915GLV
2607 */
2608 static const hda_nid_t alc880_adc_nids_alt[2] = {
2609 /* ADC1-2 */
2610 0x08, 0x09,
2611 };
2612
2613 #define ALC880_DIGOUT_NID 0x06
2614 #define ALC880_DIGIN_NID 0x0a
2615
2616 static const struct hda_input_mux alc880_capture_source = {
2617 .num_items = 4,
2618 .items = {
2619 { "Mic", 0x0 },
2620 { "Front Mic", 0x3 },
2621 { "Line", 0x2 },
2622 { "CD", 0x4 },
2623 },
2624 };
2625
2626 /* channel source setting (2/6 channel selection for 3-stack) */
2627 /* 2ch mode */
2628 static const struct hda_verb alc880_threestack_ch2_init[] = {
2629 /* set line-in to input, mute it */
2630 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2631 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2632 /* set mic-in to input vref 80%, mute it */
2633 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2634 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2635 { } /* end */
2636 };
2637
2638 /* 6ch mode */
2639 static const struct hda_verb alc880_threestack_ch6_init[] = {
2640 /* set line-in to output, unmute it */
2641 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2642 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2643 /* set mic-in to output, unmute it */
2644 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2645 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2646 { } /* end */
2647 };
2648
2649 static const struct hda_channel_mode alc880_threestack_modes[2] = {
2650 { 2, alc880_threestack_ch2_init },
2651 { 6, alc880_threestack_ch6_init },
2652 };
2653
2654 static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
2655 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2656 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2657 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2658 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2659 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2660 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2661 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2662 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2663 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2664 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2665 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2666 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2667 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2668 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2669 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2670 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2671 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2672 {
2673 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2674 .name = "Channel Mode",
2675 .info = alc_ch_mode_info,
2676 .get = alc_ch_mode_get,
2677 .put = alc_ch_mode_put,
2678 },
2679 { } /* end */
2680 };
2681
2682 /* capture mixer elements */
2683 static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2684 struct snd_ctl_elem_info *uinfo)
2685 {
2686 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2687 struct alc_spec *spec = codec->spec;
2688 int err;
2689
2690 mutex_lock(&codec->control_mutex);
2691 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2692 HDA_INPUT);
2693 err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
2694 mutex_unlock(&codec->control_mutex);
2695 return err;
2696 }
2697
2698 static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2699 unsigned int size, unsigned int __user *tlv)
2700 {
2701 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2702 struct alc_spec *spec = codec->spec;
2703 int err;
2704
2705 mutex_lock(&codec->control_mutex);
2706 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
2707 HDA_INPUT);
2708 err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
2709 mutex_unlock(&codec->control_mutex);
2710 return err;
2711 }
2712
2713 typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
2714 struct snd_ctl_elem_value *ucontrol);
2715
2716 static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
2717 struct snd_ctl_elem_value *ucontrol,
2718 getput_call_t func)
2719 {
2720 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2721 struct alc_spec *spec = codec->spec;
2722 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
2723 int err;
2724
2725 mutex_lock(&codec->control_mutex);
2726 kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
2727 3, 0, HDA_INPUT);
2728 err = func(kcontrol, ucontrol);
2729 mutex_unlock(&codec->control_mutex);
2730 return err;
2731 }
2732
2733 static int alc_cap_vol_get(struct snd_kcontrol *kcontrol,
2734 struct snd_ctl_elem_value *ucontrol)
2735 {
2736 return alc_cap_getput_caller(kcontrol, ucontrol,
2737 snd_hda_mixer_amp_volume_get);
2738 }
2739
2740 static int alc_cap_vol_put(struct snd_kcontrol *kcontrol,
2741 struct snd_ctl_elem_value *ucontrol)
2742 {
2743 return alc_cap_getput_caller(kcontrol, ucontrol,
2744 snd_hda_mixer_amp_volume_put);
2745 }
2746
2747 /* capture mixer elements */
2748 #define alc_cap_sw_info snd_ctl_boolean_stereo_info
2749
2750 static int alc_cap_sw_get(struct snd_kcontrol *kcontrol,
2751 struct snd_ctl_elem_value *ucontrol)
2752 {
2753 return alc_cap_getput_caller(kcontrol, ucontrol,
2754 snd_hda_mixer_amp_switch_get);
2755 }
2756
2757 static int alc_cap_sw_put(struct snd_kcontrol *kcontrol,
2758 struct snd_ctl_elem_value *ucontrol)
2759 {
2760 return alc_cap_getput_caller(kcontrol, ucontrol,
2761 snd_hda_mixer_amp_switch_put);
2762 }
2763
2764 #define _DEFINE_CAPMIX(num) \
2765 { \
2766 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2767 .name = "Capture Switch", \
2768 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, \
2769 .count = num, \
2770 .info = alc_cap_sw_info, \
2771 .get = alc_cap_sw_get, \
2772 .put = alc_cap_sw_put, \
2773 }, \
2774 { \
2775 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2776 .name = "Capture Volume", \
2777 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | \
2778 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
2779 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), \
2780 .count = num, \
2781 .info = alc_cap_vol_info, \
2782 .get = alc_cap_vol_get, \
2783 .put = alc_cap_vol_put, \
2784 .tlv = { .c = alc_cap_vol_tlv }, \
2785 }
2786
2787 #define _DEFINE_CAPSRC(num) \
2788 { \
2789 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
2790 /* .name = "Capture Source", */ \
2791 .name = "Input Source", \
2792 .count = num, \
2793 .info = alc_mux_enum_info, \
2794 .get = alc_mux_enum_get, \
2795 .put = alc_mux_enum_put, \
2796 }
2797
2798 #define DEFINE_CAPMIX(num) \
2799 static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \
2800 _DEFINE_CAPMIX(num), \
2801 _DEFINE_CAPSRC(num), \
2802 { } /* end */ \
2803 }
2804
2805 #define DEFINE_CAPMIX_NOSRC(num) \
2806 static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \
2807 _DEFINE_CAPMIX(num), \
2808 { } /* end */ \
2809 }
2810
2811 /* up to three ADCs */
2812 DEFINE_CAPMIX(1);
2813 DEFINE_CAPMIX(2);
2814 DEFINE_CAPMIX(3);
2815 DEFINE_CAPMIX_NOSRC(1);
2816 DEFINE_CAPMIX_NOSRC(2);
2817 DEFINE_CAPMIX_NOSRC(3);
2818
2819 /*
2820 * ALC880 5-stack model
2821 *
2822 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2823 * Side = 0x02 (0xd)
2824 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2825 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2826 */
2827
2828 /* additional mixers to alc880_three_stack_mixer */
2829 static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2830 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2831 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2832 { } /* end */
2833 };
2834
2835 /* channel source setting (6/8 channel selection for 5-stack) */
2836 /* 6ch mode */
2837 static const struct hda_verb alc880_fivestack_ch6_init[] = {
2838 /* set line-in to input, mute it */
2839 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2840 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2841 { } /* end */
2842 };
2843
2844 /* 8ch mode */
2845 static const struct hda_verb alc880_fivestack_ch8_init[] = {
2846 /* set line-in to output, unmute it */
2847 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2848 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2849 { } /* end */
2850 };
2851
2852 static const struct hda_channel_mode alc880_fivestack_modes[2] = {
2853 { 6, alc880_fivestack_ch6_init },
2854 { 8, alc880_fivestack_ch8_init },
2855 };
2856
2857
2858 /*
2859 * ALC880 6-stack model
2860 *
2861 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2862 * Side = 0x05 (0x0f)
2863 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2864 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2865 */
2866
2867 static const hda_nid_t alc880_6st_dac_nids[4] = {
2868 /* front, rear, clfe, rear_surr */
2869 0x02, 0x03, 0x04, 0x05
2870 };
2871
2872 static const struct hda_input_mux alc880_6stack_capture_source = {
2873 .num_items = 4,
2874 .items = {
2875 { "Mic", 0x0 },
2876 { "Front Mic", 0x1 },
2877 { "Line", 0x2 },
2878 { "CD", 0x4 },
2879 },
2880 };
2881
2882 /* fixed 8-channels */
2883 static const struct hda_channel_mode alc880_sixstack_modes[1] = {
2884 { 8, NULL },
2885 };
2886
2887 static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2888 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2889 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2890 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2891 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2892 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2893 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2894 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2895 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2896 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2897 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2898 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2899 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2900 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2901 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2902 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2903 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2904 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2905 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2906 {
2907 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2908 .name = "Channel Mode",
2909 .info = alc_ch_mode_info,
2910 .get = alc_ch_mode_get,
2911 .put = alc_ch_mode_put,
2912 },
2913 { } /* end */
2914 };
2915
2916
2917 /*
2918 * ALC880 W810 model
2919 *
2920 * W810 has rear IO for:
2921 * Front (DAC 02)
2922 * Surround (DAC 03)
2923 * Center/LFE (DAC 04)
2924 * Digital out (06)
2925 *
2926 * The system also has a pair of internal speakers, and a headphone jack.
2927 * These are both connected to Line2 on the codec, hence to DAC 02.
2928 *
2929 * There is a variable resistor to control the speaker or headphone
2930 * volume. This is a hardware-only device without a software API.
2931 *
2932 * Plugging headphones in will disable the internal speakers. This is
2933 * implemented in hardware, not via the driver using jack sense. In
2934 * a similar fashion, plugging into the rear socket marked "front" will
2935 * disable both the speakers and headphones.
2936 *
2937 * For input, there's a microphone jack, and an "audio in" jack.
2938 * These may not do anything useful with this driver yet, because I
2939 * haven't setup any initialization verbs for these yet...
2940 */
2941
2942 static const hda_nid_t alc880_w810_dac_nids[3] = {
2943 /* front, rear/surround, clfe */
2944 0x02, 0x03, 0x04
2945 };
2946
2947 /* fixed 6 channels */
2948 static const struct hda_channel_mode alc880_w810_modes[1] = {
2949 { 6, NULL }
2950 };
2951
2952 /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
2953 static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
2954 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2955 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2956 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2957 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2958 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2959 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2960 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2961 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2962 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
2963 { } /* end */
2964 };
2965
2966
2967 /*
2968 * Z710V model
2969 *
2970 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
2971 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
2972 * Line = 0x1a
2973 */
2974
2975 static const hda_nid_t alc880_z71v_dac_nids[1] = {
2976 0x02
2977 };
2978 #define ALC880_Z71V_HP_DAC 0x03
2979
2980 /* fixed 2 channels */
2981 static const struct hda_channel_mode alc880_2_jack_modes[1] = {
2982 { 2, NULL }
2983 };
2984
2985 static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
2986 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2987 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2988 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2989 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
2990 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2991 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2992 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2993 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2994 { } /* end */
2995 };
2996
2997
2998 /*
2999 * ALC880 F1734 model
3000 *
3001 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
3002 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
3003 */
3004
3005 static const hda_nid_t alc880_f1734_dac_nids[1] = {
3006 0x03
3007 };
3008 #define ALC880_F1734_HP_DAC 0x02
3009
3010 static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
3011 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3012 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3013 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3014 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3015 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3016 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3017 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3018 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3019 { } /* end */
3020 };
3021
3022 static const struct hda_input_mux alc880_f1734_capture_source = {
3023 .num_items = 2,
3024 .items = {
3025 { "Mic", 0x1 },
3026 { "CD", 0x4 },
3027 },
3028 };
3029
3030
3031 /*
3032 * ALC880 ASUS model
3033 *
3034 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3035 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3036 * Mic = 0x18, Line = 0x1a
3037 */
3038
3039 #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
3040 #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
3041
3042 static const struct snd_kcontrol_new alc880_asus_mixer[] = {
3043 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3044 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3045 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3046 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3047 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3048 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3049 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3050 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3051 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3052 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3053 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3054 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3055 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3056 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3057 {
3058 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3059 .name = "Channel Mode",
3060 .info = alc_ch_mode_info,
3061 .get = alc_ch_mode_get,
3062 .put = alc_ch_mode_put,
3063 },
3064 { } /* end */
3065 };
3066
3067 /*
3068 * ALC880 ASUS W1V model
3069 *
3070 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3071 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3072 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
3073 */
3074
3075 /* additional mixers to alc880_asus_mixer */
3076 static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
3077 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
3078 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
3079 { } /* end */
3080 };
3081
3082 /* TCL S700 */
3083 static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
3084 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3085 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3086 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
3087 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
3088 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
3089 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
3090 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
3091 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3092 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
3093 { } /* end */
3094 };
3095
3096 /* Uniwill */
3097 static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
3098 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3099 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3100 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3101 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3102 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3103 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3104 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3105 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3106 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3107 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3108 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3109 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3110 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3111 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3112 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3113 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3114 {
3115 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3116 .name = "Channel Mode",
3117 .info = alc_ch_mode_info,
3118 .get = alc_ch_mode_get,
3119 .put = alc_ch_mode_put,
3120 },
3121 { } /* end */
3122 };
3123
3124 static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
3125 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3126 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3127 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3128 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3129 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3130 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3131 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3132 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3133 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3134 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3135 { } /* end */
3136 };
3137
3138 static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
3139 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3140 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3141 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3142 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3143 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3144 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3145 { } /* end */
3146 };
3147
3148 /*
3149 * virtual master controls
3150 */
3151
3152 /*
3153 * slave controls for virtual master
3154 */
3155 static const char * const alc_slave_vols[] = {
3156 "Front Playback Volume",
3157 "Surround Playback Volume",
3158 "Center Playback Volume",
3159 "LFE Playback Volume",
3160 "Side Playback Volume",
3161 "Headphone Playback Volume",
3162 "Speaker Playback Volume",
3163 "Mono Playback Volume",
3164 "Line-Out Playback Volume",
3165 NULL,
3166 };
3167
3168 static const char * const alc_slave_sws[] = {
3169 "Front Playback Switch",
3170 "Surround Playback Switch",
3171 "Center Playback Switch",
3172 "LFE Playback Switch",
3173 "Side Playback Switch",
3174 "Headphone Playback Switch",
3175 "Speaker Playback Switch",
3176 "Mono Playback Switch",
3177 "IEC958 Playback Switch",
3178 "Line-Out Playback Switch",
3179 NULL,
3180 };
3181
3182 /*
3183 * build control elements
3184 */
3185
3186 #define NID_MAPPING (-1)
3187
3188 #define SUBDEV_SPEAKER_ (0 << 6)
3189 #define SUBDEV_HP_ (1 << 6)
3190 #define SUBDEV_LINE_ (2 << 6)
3191 #define SUBDEV_SPEAKER(x) (SUBDEV_SPEAKER_ | ((x) & 0x3f))
3192 #define SUBDEV_HP(x) (SUBDEV_HP_ | ((x) & 0x3f))
3193 #define SUBDEV_LINE(x) (SUBDEV_LINE_ | ((x) & 0x3f))
3194
3195 static void alc_free_kctls(struct hda_codec *codec);
3196
3197 #ifdef CONFIG_SND_HDA_INPUT_BEEP
3198 /* additional beep mixers; the actual parameters are overwritten at build */
3199 static const struct snd_kcontrol_new alc_beep_mixer[] = {
3200 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT),
3201 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT),
3202 { } /* end */
3203 };
3204 #endif
3205
3206 static int alc_build_controls(struct hda_codec *codec)
3207 {
3208 struct alc_spec *spec = codec->spec;
3209 struct snd_kcontrol *kctl = NULL;
3210 const struct snd_kcontrol_new *knew;
3211 int i, j, err;
3212 unsigned int u;
3213 hda_nid_t nid;
3214
3215 for (i = 0; i < spec->num_mixers; i++) {
3216 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
3217 if (err < 0)
3218 return err;
3219 }
3220 if (spec->cap_mixer) {
3221 err = snd_hda_add_new_ctls(codec, spec->cap_mixer);
3222 if (err < 0)
3223 return err;
3224 }
3225 if (spec->multiout.dig_out_nid) {
3226 err = snd_hda_create_spdif_out_ctls(codec,
3227 spec->multiout.dig_out_nid);
3228 if (err < 0)
3229 return err;
3230 if (!spec->no_analog) {
3231 err = snd_hda_create_spdif_share_sw(codec,
3232 &spec->multiout);
3233 if (err < 0)
3234 return err;
3235 spec->multiout.share_spdif = 1;
3236 }
3237 }
3238 if (spec->dig_in_nid) {
3239 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
3240 if (err < 0)
3241 return err;
3242 }
3243
3244 #ifdef CONFIG_SND_HDA_INPUT_BEEP
3245 /* create beep controls if needed */
3246 if (spec->beep_amp) {
3247 const struct snd_kcontrol_new *knew;
3248 for (knew = alc_beep_mixer; knew->name; knew++) {
3249 struct snd_kcontrol *kctl;
3250 kctl = snd_ctl_new1(knew, codec);
3251 if (!kctl)
3252 return -ENOMEM;
3253 kctl->private_value = spec->beep_amp;
3254 err = snd_hda_ctl_add(codec, 0, kctl);
3255 if (err < 0)
3256 return err;
3257 }
3258 }
3259 #endif
3260
3261 /* if we have no master control, let's create it */
3262 if (!spec->no_analog &&
3263 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
3264 unsigned int vmaster_tlv[4];
3265 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
3266 HDA_OUTPUT, vmaster_tlv);
3267 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
3268 vmaster_tlv, alc_slave_vols);
3269 if (err < 0)
3270 return err;
3271 }
3272 if (!spec->no_analog &&
3273 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
3274 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
3275 NULL, alc_slave_sws);
3276 if (err < 0)
3277 return err;
3278 }
3279
3280 /* assign Capture Source enums to NID */
3281 if (spec->capsrc_nids || spec->adc_nids) {
3282 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
3283 if (!kctl)
3284 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
3285 for (i = 0; kctl && i < kctl->count; i++) {
3286 const hda_nid_t *nids = spec->capsrc_nids;
3287 if (!nids)
3288 nids = spec->adc_nids;
3289 err = snd_hda_add_nid(codec, kctl, i, nids[i]);
3290 if (err < 0)
3291 return err;
3292 }
3293 }
3294 if (spec->cap_mixer) {
3295 const char *kname = kctl ? kctl->id.name : NULL;
3296 for (knew = spec->cap_mixer; knew->name; knew++) {
3297 if (kname && strcmp(knew->name, kname) == 0)
3298 continue;
3299 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3300 for (i = 0; kctl && i < kctl->count; i++) {
3301 err = snd_hda_add_nid(codec, kctl, i,
3302 spec->adc_nids[i]);
3303 if (err < 0)
3304 return err;
3305 }
3306 }
3307 }
3308
3309 /* other nid->control mapping */
3310 for (i = 0; i < spec->num_mixers; i++) {
3311 for (knew = spec->mixers[i]; knew->name; knew++) {
3312 if (knew->iface != NID_MAPPING)
3313 continue;
3314 kctl = snd_hda_find_mixer_ctl(codec, knew->name);
3315 if (kctl == NULL)
3316 continue;
3317 u = knew->subdevice;
3318 for (j = 0; j < 4; j++, u >>= 8) {
3319 nid = u & 0x3f;
3320 if (nid == 0)
3321 continue;
3322 switch (u & 0xc0) {
3323 case SUBDEV_SPEAKER_:
3324 nid = spec->autocfg.speaker_pins[nid];
3325 break;
3326 case SUBDEV_LINE_:
3327 nid = spec->autocfg.line_out_pins[nid];
3328 break;
3329 case SUBDEV_HP_:
3330 nid = spec->autocfg.hp_pins[nid];
3331 break;
3332 default:
3333 continue;
3334 }
3335 err = snd_hda_add_nid(codec, kctl, 0, nid);
3336 if (err < 0)
3337 return err;
3338 }
3339 u = knew->private_value;
3340 for (j = 0; j < 4; j++, u >>= 8) {
3341 nid = u & 0xff;
3342 if (nid == 0)
3343 continue;
3344 err = snd_hda_add_nid(codec, kctl, 0, nid);
3345 if (err < 0)
3346 return err;
3347 }
3348 }
3349 }
3350
3351 alc_free_kctls(codec); /* no longer needed */
3352
3353 return 0;
3354 }
3355
3356
3357 /*
3358 * initialize the codec volumes, etc
3359 */
3360
3361 /*
3362 * generic initialization of ADC, input mixers and output mixers
3363 */
3364 static const struct hda_verb alc880_volume_init_verbs[] = {
3365 /*
3366 * Unmute ADC0-2 and set the default input to mic-in
3367 */
3368 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3369 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3370 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3371 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3372 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3373 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3374
3375 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3376 * mixer widget
3377 * Note: PASD motherboards uses the Line In 2 as the input for front
3378 * panel mic (mic 2)
3379 */
3380 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
3381 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3382 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3383 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3384 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3385 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3386 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3387 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3388
3389 /*
3390 * Set up output mixers (0x0c - 0x0f)
3391 */
3392 /* set vol=0 to output mixers */
3393 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3394 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3395 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3396 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3397 /* set up input amps for analog loopback */
3398 /* Amp Indices: DAC = 0, mixer = 1 */
3399 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3400 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3401 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3402 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3403 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3404 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3405 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3406 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3407
3408 { }
3409 };
3410
3411 /*
3412 * 3-stack pin configuration:
3413 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3414 */
3415 static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
3416 /*
3417 * preset connection lists of input pins
3418 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3419 */
3420 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3421 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3422 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3423
3424 /*
3425 * Set pin mode and muting
3426 */
3427 /* set front pin widgets 0x14 for output */
3428 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3429 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3430 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3431 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3432 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3433 /* Mic2 (as headphone out) for HP output */
3434 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3435 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3436 /* Line In pin widget for input */
3437 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3438 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3439 /* Line2 (as front mic) pin widget for input and vref at 80% */
3440 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3441 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3442 /* CD pin widget for input */
3443 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3444
3445 { }
3446 };
3447
3448 /*
3449 * 5-stack pin configuration:
3450 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3451 * line-in/side = 0x1a, f-mic = 0x1b
3452 */
3453 static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
3454 /*
3455 * preset connection lists of input pins
3456 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3457 */
3458 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3459 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
3460
3461 /*
3462 * Set pin mode and muting
3463 */
3464 /* set pin widgets 0x14-0x17 for output */
3465 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3466 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3467 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3468 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3469 /* unmute pins for output (no gain on this amp) */
3470 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3471 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3472 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3473 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3474
3475 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3476 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3477 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3478 /* Mic2 (as headphone out) for HP output */
3479 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3480 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3481 /* Line In pin widget for input */
3482 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3483 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3484 /* Line2 (as front mic) pin widget for input and vref at 80% */
3485 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3486 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3487 /* CD pin widget for input */
3488 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3489
3490 { }
3491 };
3492
3493 /*
3494 * W810 pin configuration:
3495 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3496 */
3497 static const struct hda_verb alc880_pin_w810_init_verbs[] = {
3498 /* hphone/speaker input selector: front DAC */
3499 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
3500
3501 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3502 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3503 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3504 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3505 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3506 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3507
3508 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3509 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3510
3511 { }
3512 };
3513
3514 /*
3515 * Z71V pin configuration:
3516 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3517 */
3518 static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
3519 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3520 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3521 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3522 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3523
3524 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3525 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3526 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3527 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3528
3529 { }
3530 };
3531
3532 /*
3533 * 6-stack pin configuration:
3534 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3535 * f-mic = 0x19, line = 0x1a, HP = 0x1b
3536 */
3537 static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
3538 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3539
3540 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3541 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3542 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3543 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3544 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3545 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3546 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3547 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3548
3549 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3550 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3551 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3552 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3553 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3554 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3555 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3556 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3557 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3558
3559 { }
3560 };
3561
3562 /*
3563 * Uniwill pin configuration:
3564 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3565 * line = 0x1a
3566 */
3567 static const struct hda_verb alc880_uniwill_init_verbs[] = {
3568 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3569
3570 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3571 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3572 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3573 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3574 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3575 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3576 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3577 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3578 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3579 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3580 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3581 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3582 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3583 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3584
3585 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3586 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3587 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3588 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3589 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3590 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3591 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3592 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3593 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3594
3595 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3596 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3597
3598 { }
3599 };
3600
3601 /*
3602 * Uniwill P53
3603 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
3604 */
3605 static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3606 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3607
3608 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3609 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3610 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3611 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3612 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3613 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3614 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3615 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3616 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3617 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3618 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3619 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3620
3621 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3622 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3623 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3624 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3625 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3626 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3627
3628 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3629 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3630
3631 { }
3632 };
3633
3634 static const struct hda_verb alc880_beep_init_verbs[] = {
3635 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3636 { }
3637 };
3638
3639 /* auto-toggle front mic */
3640 static void alc88x_simple_mic_automute(struct hda_codec *codec)
3641 {
3642 unsigned int present;
3643 unsigned char bits;
3644
3645 present = snd_hda_jack_detect(codec, 0x18);
3646 bits = present ? HDA_AMP_MUTE : 0;
3647 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
3648 }
3649
3650 static void alc880_uniwill_setup(struct hda_codec *codec)
3651 {
3652 struct alc_spec *spec = codec->spec;
3653
3654 spec->autocfg.hp_pins[0] = 0x14;
3655 spec->autocfg.speaker_pins[0] = 0x15;
3656 spec->autocfg.speaker_pins[0] = 0x16;
3657 spec->automute = 1;
3658 spec->automute_mode = ALC_AUTOMUTE_AMP;
3659 }
3660
3661 static void alc880_uniwill_init_hook(struct hda_codec *codec)
3662 {
3663 alc_hp_automute(codec);
3664 alc88x_simple_mic_automute(codec);
3665 }
3666
3667 static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3668 unsigned int res)
3669 {
3670 /* Looks like the unsol event is incompatible with the standard
3671 * definition. 4bit tag is placed at 28 bit!
3672 */
3673 switch (res >> 28) {
3674 case ALC880_MIC_EVENT:
3675 alc88x_simple_mic_automute(codec);
3676 break;
3677 default:
3678 alc_sku_unsol_event(codec, res);
3679 break;
3680 }
3681 }
3682
3683 static void alc880_uniwill_p53_setup(struct hda_codec *codec)
3684 {
3685 struct alc_spec *spec = codec->spec;
3686
3687 spec->autocfg.hp_pins[0] = 0x14;
3688 spec->autocfg.speaker_pins[0] = 0x15;
3689 spec->automute = 1;
3690 spec->automute_mode = ALC_AUTOMUTE_AMP;
3691 }
3692
3693 static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3694 {
3695 unsigned int present;
3696
3697 present = snd_hda_codec_read(codec, 0x21, 0,
3698 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3699 present &= HDA_AMP_VOLMASK;
3700 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3701 HDA_AMP_VOLMASK, present);
3702 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3703 HDA_AMP_VOLMASK, present);
3704 }
3705
3706 static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3707 unsigned int res)
3708 {
3709 /* Looks like the unsol event is incompatible with the standard
3710 * definition. 4bit tag is placed at 28 bit!
3711 */
3712 if ((res >> 28) == ALC880_DCVOL_EVENT)
3713 alc880_uniwill_p53_dcvol_automute(codec);
3714 else
3715 alc_sku_unsol_event(codec, res);
3716 }
3717
3718 /*
3719 * F1734 pin configuration:
3720 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3721 */
3722 static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
3723 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
3724 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3725 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3726 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3727 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3728
3729 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3730 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3731 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3732 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3733
3734 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3735 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3736 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3737 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3738 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3739 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3740 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3741 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3742 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3743
3744 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3745 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3746
3747 { }
3748 };
3749
3750 /*
3751 * ASUS pin configuration:
3752 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3753 */
3754 static const struct hda_verb alc880_pin_asus_init_verbs[] = {
3755 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3756 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3757 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3758 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3759
3760 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3761 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3762 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3763 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3764 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3765 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3766 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3767 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3768
3769 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3770 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3771 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3772 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3773 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3774 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3775 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3776 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3777 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3778
3779 { }
3780 };
3781
3782 /* Enable GPIO mask and set output */
3783 #define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3784 #define alc880_gpio2_init_verbs alc_gpio2_init_verbs
3785 #define alc880_gpio3_init_verbs alc_gpio3_init_verbs
3786
3787 /* Clevo m520g init */
3788 static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
3789 /* headphone output */
3790 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3791 /* line-out */
3792 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3793 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3794 /* Line-in */
3795 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3796 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3797 /* CD */
3798 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3799 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3800 /* Mic1 (rear panel) */
3801 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3802 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3803 /* Mic2 (front panel) */
3804 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3805 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3806 /* headphone */
3807 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3808 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3809 /* change to EAPD mode */
3810 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3811 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3812
3813 { }
3814 };
3815
3816 static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3817 /* change to EAPD mode */
3818 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3819 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3820
3821 /* Headphone output */
3822 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3823 /* Front output*/
3824 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3825 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3826
3827 /* Line In pin widget for input */
3828 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3829 /* CD pin widget for input */
3830 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3831 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3832 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3833
3834 /* change to EAPD mode */
3835 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3836 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3837
3838 { }
3839 };
3840
3841 /*
3842 * LG m1 express dual
3843 *
3844 * Pin assignment:
3845 * Rear Line-In/Out (blue): 0x14
3846 * Build-in Mic-In: 0x15
3847 * Speaker-out: 0x17
3848 * HP-Out (green): 0x1b
3849 * Mic-In/Out (red): 0x19
3850 * SPDIF-Out: 0x1e
3851 */
3852
3853 /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3854 static const hda_nid_t alc880_lg_dac_nids[3] = {
3855 0x05, 0x02, 0x03
3856 };
3857
3858 /* seems analog CD is not working */
3859 static const struct hda_input_mux alc880_lg_capture_source = {
3860 .num_items = 3,
3861 .items = {
3862 { "Mic", 0x1 },
3863 { "Line", 0x5 },
3864 { "Internal Mic", 0x6 },
3865 },
3866 };
3867
3868 /* 2,4,6 channel modes */
3869 static const struct hda_verb alc880_lg_ch2_init[] = {
3870 /* set line-in and mic-in to input */
3871 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3872 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3873 { }
3874 };
3875
3876 static const struct hda_verb alc880_lg_ch4_init[] = {
3877 /* set line-in to out and mic-in to input */
3878 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3879 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3880 { }
3881 };
3882
3883 static const struct hda_verb alc880_lg_ch6_init[] = {
3884 /* set line-in and mic-in to output */
3885 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3886 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3887 { }
3888 };
3889
3890 static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
3891 { 2, alc880_lg_ch2_init },
3892 { 4, alc880_lg_ch4_init },
3893 { 6, alc880_lg_ch6_init },
3894 };
3895
3896 static const struct snd_kcontrol_new alc880_lg_mixer[] = {
3897 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3898 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3899 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3900 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3901 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3902 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3903 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3904 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3905 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3906 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3907 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3908 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3909 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3910 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3911 {
3912 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3913 .name = "Channel Mode",
3914 .info = alc_ch_mode_info,
3915 .get = alc_ch_mode_get,
3916 .put = alc_ch_mode_put,
3917 },
3918 { } /* end */
3919 };
3920
3921 static const struct hda_verb alc880_lg_init_verbs[] = {
3922 /* set capture source to mic-in */
3923 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3924 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3925 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3926 /* mute all amp mixer inputs */
3927 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3928 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3929 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3930 /* line-in to input */
3931 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3932 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3933 /* built-in mic */
3934 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3935 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3936 /* speaker-out */
3937 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3938 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3939 /* mic-in to input */
3940 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3941 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3942 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3943 /* HP-out */
3944 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
3945 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3946 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3947 /* jack sense */
3948 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3949 { }
3950 };
3951
3952 /* toggle speaker-output according to the hp-jack state */
3953 static void alc880_lg_setup(struct hda_codec *codec)
3954 {
3955 struct alc_spec *spec = codec->spec;
3956
3957 spec->autocfg.hp_pins[0] = 0x1b;
3958 spec->autocfg.speaker_pins[0] = 0x17;
3959 spec->automute = 1;
3960 spec->automute_mode = ALC_AUTOMUTE_AMP;
3961 }
3962
3963 /*
3964 * LG LW20
3965 *
3966 * Pin assignment:
3967 * Speaker-out: 0x14
3968 * Mic-In: 0x18
3969 * Built-in Mic-In: 0x19
3970 * Line-In: 0x1b
3971 * HP-Out: 0x1a
3972 * SPDIF-Out: 0x1e
3973 */
3974
3975 static const struct hda_input_mux alc880_lg_lw_capture_source = {
3976 .num_items = 3,
3977 .items = {
3978 { "Mic", 0x0 },
3979 { "Internal Mic", 0x1 },
3980 { "Line In", 0x2 },
3981 },
3982 };
3983
3984 #define alc880_lg_lw_modes alc880_threestack_modes
3985
3986 static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
3987 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3988 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3989 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3990 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
3991 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3992 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3993 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3994 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3995 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3996 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3997 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3998 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3999 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
4000 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
4001 {
4002 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4003 .name = "Channel Mode",
4004 .info = alc_ch_mode_info,
4005 .get = alc_ch_mode_get,
4006 .put = alc_ch_mode_put,
4007 },
4008 { } /* end */
4009 };
4010
4011 static const struct hda_verb alc880_lg_lw_init_verbs[] = {
4012 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4013 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
4014 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
4015
4016 /* set capture source to mic-in */
4017 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4018 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4019 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4020 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
4021 /* speaker-out */
4022 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4023 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4024 /* HP-out */
4025 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4026 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4027 /* mic-in to input */
4028 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4029 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4030 /* built-in mic */
4031 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4032 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4033 /* jack sense */
4034 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4035 { }
4036 };
4037
4038 /* toggle speaker-output according to the hp-jack state */
4039 static void alc880_lg_lw_setup(struct hda_codec *codec)
4040 {
4041 struct alc_spec *spec = codec->spec;
4042
4043 spec->autocfg.hp_pins[0] = 0x1b;
4044 spec->autocfg.speaker_pins[0] = 0x14;
4045 spec->automute = 1;
4046 spec->automute_mode = ALC_AUTOMUTE_AMP;
4047 }
4048
4049 static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
4050 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4051 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
4052 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4053 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4054 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4055 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
4056 { } /* end */
4057 };
4058
4059 static const struct hda_input_mux alc880_medion_rim_capture_source = {
4060 .num_items = 2,
4061 .items = {
4062 { "Mic", 0x0 },
4063 { "Internal Mic", 0x1 },
4064 },
4065 };
4066
4067 static const struct hda_verb alc880_medion_rim_init_verbs[] = {
4068 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4069
4070 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4071 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4072
4073 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4074 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4075 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4076 /* Mic2 (as headphone out) for HP output */
4077 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4078 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4079 /* Internal Speaker */
4080 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4081 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4082
4083 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4084 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4085
4086 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4087 { }
4088 };
4089
4090 /* toggle speaker-output according to the hp-jack state */
4091 static void alc880_medion_rim_automute(struct hda_codec *codec)
4092 {
4093 struct alc_spec *spec = codec->spec;
4094 alc_hp_automute(codec);
4095 /* toggle EAPD */
4096 if (spec->jack_present)
4097 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4098 else
4099 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
4100 }
4101
4102 static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
4103 unsigned int res)
4104 {
4105 /* Looks like the unsol event is incompatible with the standard
4106 * definition. 4bit tag is placed at 28 bit!
4107 */
4108 if ((res >> 28) == ALC880_HP_EVENT)
4109 alc880_medion_rim_automute(codec);
4110 }
4111
4112 static void alc880_medion_rim_setup(struct hda_codec *codec)
4113 {
4114 struct alc_spec *spec = codec->spec;
4115
4116 spec->autocfg.hp_pins[0] = 0x14;
4117 spec->autocfg.speaker_pins[0] = 0x1b;
4118 spec->automute = 1;
4119 spec->automute_mode = ALC_AUTOMUTE_AMP;
4120 }
4121
4122 #ifdef CONFIG_SND_HDA_POWER_SAVE
4123 static const struct hda_amp_list alc880_loopbacks[] = {
4124 { 0x0b, HDA_INPUT, 0 },
4125 { 0x0b, HDA_INPUT, 1 },
4126 { 0x0b, HDA_INPUT, 2 },
4127 { 0x0b, HDA_INPUT, 3 },
4128 { 0x0b, HDA_INPUT, 4 },
4129 { } /* end */
4130 };
4131
4132 static const struct hda_amp_list alc880_lg_loopbacks[] = {
4133 { 0x0b, HDA_INPUT, 1 },
4134 { 0x0b, HDA_INPUT, 6 },
4135 { 0x0b, HDA_INPUT, 7 },
4136 { } /* end */
4137 };
4138 #endif
4139
4140 /*
4141 * Common callbacks
4142 */
4143
4144 static void alc_init_special_input_src(struct hda_codec *codec);
4145
4146 static int alc_init(struct hda_codec *codec)
4147 {
4148 struct alc_spec *spec = codec->spec;
4149 unsigned int i;
4150
4151 alc_fix_pll(codec);
4152 alc_auto_init_amp(codec, spec->init_amp);
4153
4154 for (i = 0; i < spec->num_init_verbs; i++)
4155 snd_hda_sequence_write(codec, spec->init_verbs[i]);
4156 alc_init_special_input_src(codec);
4157
4158 if (spec->init_hook)
4159 spec->init_hook(codec);
4160
4161 alc_apply_fixup(codec, ALC_FIXUP_ACT_INIT);
4162
4163 hda_call_check_power_status(codec, 0x01);
4164 return 0;
4165 }
4166
4167 static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
4168 {
4169 struct alc_spec *spec = codec->spec;
4170
4171 if (spec->unsol_event)
4172 spec->unsol_event(codec, res);
4173 }
4174
4175 #ifdef CONFIG_SND_HDA_POWER_SAVE
4176 static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
4177 {
4178 struct alc_spec *spec = codec->spec;
4179 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
4180 }
4181 #endif
4182
4183 /*
4184 * Analog playback callbacks
4185 */
4186 static int alc880_playback_pcm_open(struct hda_pcm_stream *hinfo,
4187 struct hda_codec *codec,
4188 struct snd_pcm_substream *substream)
4189 {
4190 struct alc_spec *spec = codec->spec;
4191 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
4192 hinfo);
4193 }
4194
4195 static int alc880_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4196 struct hda_codec *codec,
4197 unsigned int stream_tag,
4198 unsigned int format,
4199 struct snd_pcm_substream *substream)
4200 {
4201 struct alc_spec *spec = codec->spec;
4202 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
4203 stream_tag, format, substream);
4204 }
4205
4206 static int alc880_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4207 struct hda_codec *codec,
4208 struct snd_pcm_substream *substream)
4209 {
4210 struct alc_spec *spec = codec->spec;
4211 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
4212 }
4213
4214 /*
4215 * Digital out
4216 */
4217 static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
4218 struct hda_codec *codec,
4219 struct snd_pcm_substream *substream)
4220 {
4221 struct alc_spec *spec = codec->spec;
4222 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
4223 }
4224
4225 static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4226 struct hda_codec *codec,
4227 unsigned int stream_tag,
4228 unsigned int format,
4229 struct snd_pcm_substream *substream)
4230 {
4231 struct alc_spec *spec = codec->spec;
4232 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
4233 stream_tag, format, substream);
4234 }
4235
4236 static int alc880_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4237 struct hda_codec *codec,
4238 struct snd_pcm_substream *substream)
4239 {
4240 struct alc_spec *spec = codec->spec;
4241 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4242 }
4243
4244 static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4245 struct hda_codec *codec,
4246 struct snd_pcm_substream *substream)
4247 {
4248 struct alc_spec *spec = codec->spec;
4249 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
4250 }
4251
4252 /*
4253 * Analog capture
4254 */
4255 static int alc880_alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4256 struct hda_codec *codec,
4257 unsigned int stream_tag,
4258 unsigned int format,
4259 struct snd_pcm_substream *substream)
4260 {
4261 struct alc_spec *spec = codec->spec;
4262
4263 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
4264 stream_tag, 0, format);
4265 return 0;
4266 }
4267
4268 static int alc880_alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4269 struct hda_codec *codec,
4270 struct snd_pcm_substream *substream)
4271 {
4272 struct alc_spec *spec = codec->spec;
4273
4274 snd_hda_codec_cleanup_stream(codec,
4275 spec->adc_nids[substream->number + 1]);
4276 return 0;
4277 }
4278
4279 /* analog capture with dynamic dual-adc changes */
4280 static int dualmic_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4281 struct hda_codec *codec,
4282 unsigned int stream_tag,
4283 unsigned int format,
4284 struct snd_pcm_substream *substream)
4285 {
4286 struct alc_spec *spec = codec->spec;
4287 spec->cur_adc = spec->adc_nids[spec->cur_adc_idx];
4288 spec->cur_adc_stream_tag = stream_tag;
4289 spec->cur_adc_format = format;
4290 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4291 return 0;
4292 }
4293
4294 static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4295 struct hda_codec *codec,
4296 struct snd_pcm_substream *substream)
4297 {
4298 struct alc_spec *spec = codec->spec;
4299 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4300 spec->cur_adc = 0;
4301 return 0;
4302 }
4303
4304 static const struct hda_pcm_stream dualmic_pcm_analog_capture = {
4305 .substreams = 1,
4306 .channels_min = 2,
4307 .channels_max = 2,
4308 .nid = 0, /* fill later */
4309 .ops = {
4310 .prepare = dualmic_capture_pcm_prepare,
4311 .cleanup = dualmic_capture_pcm_cleanup
4312 },
4313 };
4314
4315 /*
4316 */
4317 static const struct hda_pcm_stream alc880_pcm_analog_playback = {
4318 .substreams = 1,
4319 .channels_min = 2,
4320 .channels_max = 8,
4321 /* NID is set in alc_build_pcms */
4322 .ops = {
4323 .open = alc880_playback_pcm_open,
4324 .prepare = alc880_playback_pcm_prepare,
4325 .cleanup = alc880_playback_pcm_cleanup
4326 },
4327 };
4328
4329 static const struct hda_pcm_stream alc880_pcm_analog_capture = {
4330 .substreams = 1,
4331 .channels_min = 2,
4332 .channels_max = 2,
4333 /* NID is set in alc_build_pcms */
4334 };
4335
4336 static const struct hda_pcm_stream alc880_pcm_analog_alt_playback = {
4337 .substreams = 1,
4338 .channels_min = 2,
4339 .channels_max = 2,
4340 /* NID is set in alc_build_pcms */
4341 };
4342
4343 static const struct hda_pcm_stream alc880_pcm_analog_alt_capture = {
4344 .substreams = 2, /* can be overridden */
4345 .channels_min = 2,
4346 .channels_max = 2,
4347 /* NID is set in alc_build_pcms */
4348 .ops = {
4349 .prepare = alc880_alt_capture_pcm_prepare,
4350 .cleanup = alc880_alt_capture_pcm_cleanup
4351 },
4352 };
4353
4354 static const struct hda_pcm_stream alc880_pcm_digital_playback = {
4355 .substreams = 1,
4356 .channels_min = 2,
4357 .channels_max = 2,
4358 /* NID is set in alc_build_pcms */
4359 .ops = {
4360 .open = alc880_dig_playback_pcm_open,
4361 .close = alc880_dig_playback_pcm_close,
4362 .prepare = alc880_dig_playback_pcm_prepare,
4363 .cleanup = alc880_dig_playback_pcm_cleanup
4364 },
4365 };
4366
4367 static const struct hda_pcm_stream alc880_pcm_digital_capture = {
4368 .substreams = 1,
4369 .channels_min = 2,
4370 .channels_max = 2,
4371 /* NID is set in alc_build_pcms */
4372 };
4373
4374 /* Used by alc_build_pcms to flag that a PCM has no playback stream */
4375 static const struct hda_pcm_stream alc_pcm_null_stream = {
4376 .substreams = 0,
4377 .channels_min = 0,
4378 .channels_max = 0,
4379 };
4380
4381 static int alc_build_pcms(struct hda_codec *codec)
4382 {
4383 struct alc_spec *spec = codec->spec;
4384 struct hda_pcm *info = spec->pcm_rec;
4385 int i;
4386
4387 codec->num_pcms = 1;
4388 codec->pcm_info = info;
4389
4390 if (spec->no_analog)
4391 goto skip_analog;
4392
4393 snprintf(spec->stream_name_analog, sizeof(spec->stream_name_analog),
4394 "%s Analog", codec->chip_name);
4395 info->name = spec->stream_name_analog;
4396
4397 if (spec->stream_analog_playback) {
4398 if (snd_BUG_ON(!spec->multiout.dac_nids))
4399 return -EINVAL;
4400 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback);
4401 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4402 }
4403 if (spec->stream_analog_capture) {
4404 if (snd_BUG_ON(!spec->adc_nids))
4405 return -EINVAL;
4406 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture);
4407 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4408 }
4409
4410 if (spec->channel_mode) {
4411 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = 0;
4412 for (i = 0; i < spec->num_channel_mode; i++) {
4413 if (spec->channel_mode[i].channels > info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max) {
4414 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->channel_mode[i].channels;
4415 }
4416 }
4417 }
4418
4419 skip_analog:
4420 /* SPDIF for stream index #1 */
4421 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
4422 snprintf(spec->stream_name_digital,
4423 sizeof(spec->stream_name_digital),
4424 "%s Digital", codec->chip_name);
4425 codec->num_pcms = 2;
4426 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
4427 info = spec->pcm_rec + 1;
4428 info->name = spec->stream_name_digital;
4429 if (spec->dig_out_type)
4430 info->pcm_type = spec->dig_out_type;
4431 else
4432 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4433 if (spec->multiout.dig_out_nid &&
4434 spec->stream_digital_playback) {
4435 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_digital_playback);
4436 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4437 }
4438 if (spec->dig_in_nid &&
4439 spec->stream_digital_capture) {
4440 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture);
4441 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4442 }
4443 /* FIXME: do we need this for all Realtek codec models? */
4444 codec->spdif_status_reset = 1;
4445 }
4446
4447 if (spec->no_analog)
4448 return 0;
4449
4450 /* If the use of more than one ADC is requested for the current
4451 * model, configure a second analog capture-only PCM.
4452 */
4453 /* Additional Analaog capture for index #2 */
4454 if ((spec->alt_dac_nid && spec->stream_analog_alt_playback) ||
4455 (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture)) {
4456 codec->num_pcms = 3;
4457 info = spec->pcm_rec + 2;
4458 info->name = spec->stream_name_analog;
4459 if (spec->alt_dac_nid) {
4460 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4461 *spec->stream_analog_alt_playback;
4462 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4463 spec->alt_dac_nid;
4464 } else {
4465 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4466 alc_pcm_null_stream;
4467 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4468 }
4469 if (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture) {
4470 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4471 *spec->stream_analog_alt_capture;
4472 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4473 spec->adc_nids[1];
4474 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4475 spec->num_adc_nids - 1;
4476 } else {
4477 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4478 alc_pcm_null_stream;
4479 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
4480 }
4481 }
4482
4483 return 0;
4484 }
4485
4486 static inline void alc_shutup(struct hda_codec *codec)
4487 {
4488 struct alc_spec *spec = codec->spec;
4489
4490 if (spec && spec->shutup)
4491 spec->shutup(codec);
4492 snd_hda_shutup_pins(codec);
4493 }
4494
4495 static void alc_free_kctls(struct hda_codec *codec)
4496 {
4497 struct alc_spec *spec = codec->spec;
4498
4499 if (spec->kctls.list) {
4500 struct snd_kcontrol_new *kctl = spec->kctls.list;
4501 int i;
4502 for (i = 0; i < spec->kctls.used; i++)
4503 kfree(kctl[i].name);
4504 }
4505 snd_array_free(&spec->kctls);
4506 }
4507
4508 static void alc_free(struct hda_codec *codec)
4509 {
4510 struct alc_spec *spec = codec->spec;
4511
4512 if (!spec)
4513 return;
4514
4515 alc_shutup(codec);
4516 snd_hda_input_jack_free(codec);
4517 alc_free_kctls(codec);
4518 kfree(spec);
4519 snd_hda_detach_beep_device(codec);
4520 }
4521
4522 #ifdef CONFIG_SND_HDA_POWER_SAVE
4523 static void alc_power_eapd(struct hda_codec *codec)
4524 {
4525 alc_auto_setup_eapd(codec, false);
4526 }
4527
4528 static int alc_suspend(struct hda_codec *codec, pm_message_t state)
4529 {
4530 struct alc_spec *spec = codec->spec;
4531 alc_shutup(codec);
4532 if (spec && spec->power_hook)
4533 spec->power_hook(codec);
4534 return 0;
4535 }
4536 #endif
4537
4538 #ifdef SND_HDA_NEEDS_RESUME
4539 static int alc_resume(struct hda_codec *codec)
4540 {
4541 msleep(150); /* to avoid pop noise */
4542 codec->patch_ops.init(codec);
4543 snd_hda_codec_resume_amp(codec);
4544 snd_hda_codec_resume_cache(codec);
4545 hda_call_check_power_status(codec, 0x01);
4546 return 0;
4547 }
4548 #endif
4549
4550 /*
4551 */
4552 static const struct hda_codec_ops alc_patch_ops = {
4553 .build_controls = alc_build_controls,
4554 .build_pcms = alc_build_pcms,
4555 .init = alc_init,
4556 .free = alc_free,
4557 .unsol_event = alc_unsol_event,
4558 #ifdef SND_HDA_NEEDS_RESUME
4559 .resume = alc_resume,
4560 #endif
4561 #ifdef CONFIG_SND_HDA_POWER_SAVE
4562 .suspend = alc_suspend,
4563 .check_power_status = alc_check_power_status,
4564 #endif
4565 .reboot_notify = alc_shutup,
4566 };
4567
4568 /* replace the codec chip_name with the given string */
4569 static int alc_codec_rename(struct hda_codec *codec, const char *name)
4570 {
4571 kfree(codec->chip_name);
4572 codec->chip_name = kstrdup(name, GFP_KERNEL);
4573 if (!codec->chip_name) {
4574 alc_free(codec);
4575 return -ENOMEM;
4576 }
4577 return 0;
4578 }
4579
4580 /*
4581 * Test configuration for debugging
4582 *
4583 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4584 * enum controls.
4585 */
4586 #ifdef CONFIG_SND_DEBUG
4587 static const hda_nid_t alc880_test_dac_nids[4] = {
4588 0x02, 0x03, 0x04, 0x05
4589 };
4590
4591 static const struct hda_input_mux alc880_test_capture_source = {
4592 .num_items = 7,
4593 .items = {
4594 { "In-1", 0x0 },
4595 { "In-2", 0x1 },
4596 { "In-3", 0x2 },
4597 { "In-4", 0x3 },
4598 { "CD", 0x4 },
4599 { "Front", 0x5 },
4600 { "Surround", 0x6 },
4601 },
4602 };
4603
4604 static const struct hda_channel_mode alc880_test_modes[4] = {
4605 { 2, NULL },
4606 { 4, NULL },
4607 { 6, NULL },
4608 { 8, NULL },
4609 };
4610
4611 static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4612 struct snd_ctl_elem_info *uinfo)
4613 {
4614 static const char * const texts[] = {
4615 "N/A", "Line Out", "HP Out",
4616 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4617 };
4618 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4619 uinfo->count = 1;
4620 uinfo->value.enumerated.items = 8;
4621 if (uinfo->value.enumerated.item >= 8)
4622 uinfo->value.enumerated.item = 7;
4623 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4624 return 0;
4625 }
4626
4627 static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4628 struct snd_ctl_elem_value *ucontrol)
4629 {
4630 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4631 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4632 unsigned int pin_ctl, item = 0;
4633
4634 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4635 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4636 if (pin_ctl & AC_PINCTL_OUT_EN) {
4637 if (pin_ctl & AC_PINCTL_HP_EN)
4638 item = 2;
4639 else
4640 item = 1;
4641 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4642 switch (pin_ctl & AC_PINCTL_VREFEN) {
4643 case AC_PINCTL_VREF_HIZ: item = 3; break;
4644 case AC_PINCTL_VREF_50: item = 4; break;
4645 case AC_PINCTL_VREF_GRD: item = 5; break;
4646 case AC_PINCTL_VREF_80: item = 6; break;
4647 case AC_PINCTL_VREF_100: item = 7; break;
4648 }
4649 }
4650 ucontrol->value.enumerated.item[0] = item;
4651 return 0;
4652 }
4653
4654 static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4655 struct snd_ctl_elem_value *ucontrol)
4656 {
4657 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4658 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4659 static const unsigned int ctls[] = {
4660 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4661 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4662 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4663 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4664 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4665 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4666 };
4667 unsigned int old_ctl, new_ctl;
4668
4669 old_ctl = snd_hda_codec_read(codec, nid, 0,
4670 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4671 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4672 if (old_ctl != new_ctl) {
4673 int val;
4674 snd_hda_codec_write_cache(codec, nid, 0,
4675 AC_VERB_SET_PIN_WIDGET_CONTROL,
4676 new_ctl);
4677 val = ucontrol->value.enumerated.item[0] >= 3 ?
4678 HDA_AMP_MUTE : 0;
4679 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4680 HDA_AMP_MUTE, val);
4681 return 1;
4682 }
4683 return 0;
4684 }
4685
4686 static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4687 struct snd_ctl_elem_info *uinfo)
4688 {
4689 static const char * const texts[] = {
4690 "Front", "Surround", "CLFE", "Side"
4691 };
4692 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4693 uinfo->count = 1;
4694 uinfo->value.enumerated.items = 4;
4695 if (uinfo->value.enumerated.item >= 4)
4696 uinfo->value.enumerated.item = 3;
4697 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4698 return 0;
4699 }
4700
4701 static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4702 struct snd_ctl_elem_value *ucontrol)
4703 {
4704 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4705 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4706 unsigned int sel;
4707
4708 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4709 ucontrol->value.enumerated.item[0] = sel & 3;
4710 return 0;
4711 }
4712
4713 static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4714 struct snd_ctl_elem_value *ucontrol)
4715 {
4716 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4717 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4718 unsigned int sel;
4719
4720 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4721 if (ucontrol->value.enumerated.item[0] != sel) {
4722 sel = ucontrol->value.enumerated.item[0] & 3;
4723 snd_hda_codec_write_cache(codec, nid, 0,
4724 AC_VERB_SET_CONNECT_SEL, sel);
4725 return 1;
4726 }
4727 return 0;
4728 }
4729
4730 #define PIN_CTL_TEST(xname,nid) { \
4731 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4732 .name = xname, \
4733 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4734 .info = alc_test_pin_ctl_info, \
4735 .get = alc_test_pin_ctl_get, \
4736 .put = alc_test_pin_ctl_put, \
4737 .private_value = nid \
4738 }
4739
4740 #define PIN_SRC_TEST(xname,nid) { \
4741 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4742 .name = xname, \
4743 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4744 .info = alc_test_pin_src_info, \
4745 .get = alc_test_pin_src_get, \
4746 .put = alc_test_pin_src_put, \
4747 .private_value = nid \
4748 }
4749
4750 static const struct snd_kcontrol_new alc880_test_mixer[] = {
4751 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4752 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4753 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4754 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4755 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4756 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4757 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4758 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4759 PIN_CTL_TEST("Front Pin Mode", 0x14),
4760 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4761 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4762 PIN_CTL_TEST("Side Pin Mode", 0x17),
4763 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4764 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4765 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4766 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4767 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4768 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4769 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4770 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4771 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4772 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4773 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4774 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4775 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4776 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4777 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4778 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4779 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4780 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
4781 {
4782 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4783 .name = "Channel Mode",
4784 .info = alc_ch_mode_info,
4785 .get = alc_ch_mode_get,
4786 .put = alc_ch_mode_put,
4787 },
4788 { } /* end */
4789 };
4790
4791 static const struct hda_verb alc880_test_init_verbs[] = {
4792 /* Unmute inputs of 0x0c - 0x0f */
4793 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4794 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4795 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4796 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4797 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4798 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4799 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4800 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4801 /* Vol output for 0x0c-0x0f */
4802 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4803 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4804 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4805 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4806 /* Set output pins 0x14-0x17 */
4807 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4808 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4809 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4810 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4811 /* Unmute output pins 0x14-0x17 */
4812 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4813 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4814 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4815 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4816 /* Set input pins 0x18-0x1c */
4817 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4818 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4819 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4820 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4821 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4822 /* Mute input pins 0x18-0x1b */
4823 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4824 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4825 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4826 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4827 /* ADC set up */
4828 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4829 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4830 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4831 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4832 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4833 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4834 /* Analog input/passthru */
4835 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4836 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4837 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4838 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4839 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4840 { }
4841 };
4842 #endif
4843
4844 /*
4845 */
4846
4847 static const char * const alc880_models[ALC880_MODEL_LAST] = {
4848 [ALC880_3ST] = "3stack",
4849 [ALC880_TCL_S700] = "tcl",
4850 [ALC880_3ST_DIG] = "3stack-digout",
4851 [ALC880_CLEVO] = "clevo",
4852 [ALC880_5ST] = "5stack",
4853 [ALC880_5ST_DIG] = "5stack-digout",
4854 [ALC880_W810] = "w810",
4855 [ALC880_Z71V] = "z71v",
4856 [ALC880_6ST] = "6stack",
4857 [ALC880_6ST_DIG] = "6stack-digout",
4858 [ALC880_ASUS] = "asus",
4859 [ALC880_ASUS_W1V] = "asus-w1v",
4860 [ALC880_ASUS_DIG] = "asus-dig",
4861 [ALC880_ASUS_DIG2] = "asus-dig2",
4862 [ALC880_UNIWILL_DIG] = "uniwill",
4863 [ALC880_UNIWILL_P53] = "uniwill-p53",
4864 [ALC880_FUJITSU] = "fujitsu",
4865 [ALC880_F1734] = "F1734",
4866 [ALC880_LG] = "lg",
4867 [ALC880_LG_LW] = "lg-lw",
4868 [ALC880_MEDION_RIM] = "medion",
4869 #ifdef CONFIG_SND_DEBUG
4870 [ALC880_TEST] = "test",
4871 #endif
4872 [ALC880_AUTO] = "auto",
4873 };
4874
4875 static const struct snd_pci_quirk alc880_cfg_tbl[] = {
4876 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
4877 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4878 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4879 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4880 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4881 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4882 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4883 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4884 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
4885 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4886 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4887 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4888 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4889 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4890 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4891 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4892 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4893 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4894 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4895 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
4896 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
4897 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4898 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4899 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
4900 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
4901 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
4902 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4903 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
4904 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4905 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
4906 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4907 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4908 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4909 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
4910 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4911 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
4912 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4913 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4914 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4915 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
4916 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
4917 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
4918 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
4919 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
4920 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
4921 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
4922 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
4923 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
4924 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
4925 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
4926 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
4927 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
4928 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
4929 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
4930 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
4931 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
4932 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
4933 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
4934 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
4935 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
4936 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
4937 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
4938 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
4939 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
4940 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
4941 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
4942 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
4943 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
4944 /* default Intel */
4945 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
4946 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
4947 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
4948 {}
4949 };
4950
4951 /*
4952 * ALC880 codec presets
4953 */
4954 static const struct alc_config_preset alc880_presets[] = {
4955 [ALC880_3ST] = {
4956 .mixers = { alc880_three_stack_mixer },
4957 .init_verbs = { alc880_volume_init_verbs,
4958 alc880_pin_3stack_init_verbs },
4959 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4960 .dac_nids = alc880_dac_nids,
4961 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4962 .channel_mode = alc880_threestack_modes,
4963 .need_dac_fix = 1,
4964 .input_mux = &alc880_capture_source,
4965 },
4966 [ALC880_3ST_DIG] = {
4967 .mixers = { alc880_three_stack_mixer },
4968 .init_verbs = { alc880_volume_init_verbs,
4969 alc880_pin_3stack_init_verbs },
4970 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4971 .dac_nids = alc880_dac_nids,
4972 .dig_out_nid = ALC880_DIGOUT_NID,
4973 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
4974 .channel_mode = alc880_threestack_modes,
4975 .need_dac_fix = 1,
4976 .input_mux = &alc880_capture_source,
4977 },
4978 [ALC880_TCL_S700] = {
4979 .mixers = { alc880_tcl_s700_mixer },
4980 .init_verbs = { alc880_volume_init_verbs,
4981 alc880_pin_tcl_S700_init_verbs,
4982 alc880_gpio2_init_verbs },
4983 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4984 .dac_nids = alc880_dac_nids,
4985 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
4986 .num_adc_nids = 1, /* single ADC */
4987 .hp_nid = 0x03,
4988 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
4989 .channel_mode = alc880_2_jack_modes,
4990 .input_mux = &alc880_capture_source,
4991 },
4992 [ALC880_5ST] = {
4993 .mixers = { alc880_three_stack_mixer,
4994 alc880_five_stack_mixer},
4995 .init_verbs = { alc880_volume_init_verbs,
4996 alc880_pin_5stack_init_verbs },
4997 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
4998 .dac_nids = alc880_dac_nids,
4999 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5000 .channel_mode = alc880_fivestack_modes,
5001 .input_mux = &alc880_capture_source,
5002 },
5003 [ALC880_5ST_DIG] = {
5004 .mixers = { alc880_three_stack_mixer,
5005 alc880_five_stack_mixer },
5006 .init_verbs = { alc880_volume_init_verbs,
5007 alc880_pin_5stack_init_verbs },
5008 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5009 .dac_nids = alc880_dac_nids,
5010 .dig_out_nid = ALC880_DIGOUT_NID,
5011 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5012 .channel_mode = alc880_fivestack_modes,
5013 .input_mux = &alc880_capture_source,
5014 },
5015 [ALC880_6ST] = {
5016 .mixers = { alc880_six_stack_mixer },
5017 .init_verbs = { alc880_volume_init_verbs,
5018 alc880_pin_6stack_init_verbs },
5019 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5020 .dac_nids = alc880_6st_dac_nids,
5021 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5022 .channel_mode = alc880_sixstack_modes,
5023 .input_mux = &alc880_6stack_capture_source,
5024 },
5025 [ALC880_6ST_DIG] = {
5026 .mixers = { alc880_six_stack_mixer },
5027 .init_verbs = { alc880_volume_init_verbs,
5028 alc880_pin_6stack_init_verbs },
5029 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5030 .dac_nids = alc880_6st_dac_nids,
5031 .dig_out_nid = ALC880_DIGOUT_NID,
5032 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5033 .channel_mode = alc880_sixstack_modes,
5034 .input_mux = &alc880_6stack_capture_source,
5035 },
5036 [ALC880_W810] = {
5037 .mixers = { alc880_w810_base_mixer },
5038 .init_verbs = { alc880_volume_init_verbs,
5039 alc880_pin_w810_init_verbs,
5040 alc880_gpio2_init_verbs },
5041 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
5042 .dac_nids = alc880_w810_dac_nids,
5043 .dig_out_nid = ALC880_DIGOUT_NID,
5044 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5045 .channel_mode = alc880_w810_modes,
5046 .input_mux = &alc880_capture_source,
5047 },
5048 [ALC880_Z71V] = {
5049 .mixers = { alc880_z71v_mixer },
5050 .init_verbs = { alc880_volume_init_verbs,
5051 alc880_pin_z71v_init_verbs },
5052 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
5053 .dac_nids = alc880_z71v_dac_nids,
5054 .dig_out_nid = ALC880_DIGOUT_NID,
5055 .hp_nid = 0x03,
5056 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5057 .channel_mode = alc880_2_jack_modes,
5058 .input_mux = &alc880_capture_source,
5059 },
5060 [ALC880_F1734] = {
5061 .mixers = { alc880_f1734_mixer },
5062 .init_verbs = { alc880_volume_init_verbs,
5063 alc880_pin_f1734_init_verbs },
5064 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
5065 .dac_nids = alc880_f1734_dac_nids,
5066 .hp_nid = 0x02,
5067 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5068 .channel_mode = alc880_2_jack_modes,
5069 .input_mux = &alc880_f1734_capture_source,
5070 .unsol_event = alc880_uniwill_p53_unsol_event,
5071 .setup = alc880_uniwill_p53_setup,
5072 .init_hook = alc_hp_automute,
5073 },
5074 [ALC880_ASUS] = {
5075 .mixers = { alc880_asus_mixer },
5076 .init_verbs = { alc880_volume_init_verbs,
5077 alc880_pin_asus_init_verbs,
5078 alc880_gpio1_init_verbs },
5079 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5080 .dac_nids = alc880_asus_dac_nids,
5081 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5082 .channel_mode = alc880_asus_modes,
5083 .need_dac_fix = 1,
5084 .input_mux = &alc880_capture_source,
5085 },
5086 [ALC880_ASUS_DIG] = {
5087 .mixers = { alc880_asus_mixer },
5088 .init_verbs = { alc880_volume_init_verbs,
5089 alc880_pin_asus_init_verbs,
5090 alc880_gpio1_init_verbs },
5091 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5092 .dac_nids = alc880_asus_dac_nids,
5093 .dig_out_nid = ALC880_DIGOUT_NID,
5094 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5095 .channel_mode = alc880_asus_modes,
5096 .need_dac_fix = 1,
5097 .input_mux = &alc880_capture_source,
5098 },
5099 [ALC880_ASUS_DIG2] = {
5100 .mixers = { alc880_asus_mixer },
5101 .init_verbs = { alc880_volume_init_verbs,
5102 alc880_pin_asus_init_verbs,
5103 alc880_gpio2_init_verbs }, /* use GPIO2 */
5104 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5105 .dac_nids = alc880_asus_dac_nids,
5106 .dig_out_nid = ALC880_DIGOUT_NID,
5107 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5108 .channel_mode = alc880_asus_modes,
5109 .need_dac_fix = 1,
5110 .input_mux = &alc880_capture_source,
5111 },
5112 [ALC880_ASUS_W1V] = {
5113 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
5114 .init_verbs = { alc880_volume_init_verbs,
5115 alc880_pin_asus_init_verbs,
5116 alc880_gpio1_init_verbs },
5117 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5118 .dac_nids = alc880_asus_dac_nids,
5119 .dig_out_nid = ALC880_DIGOUT_NID,
5120 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5121 .channel_mode = alc880_asus_modes,
5122 .need_dac_fix = 1,
5123 .input_mux = &alc880_capture_source,
5124 },
5125 [ALC880_UNIWILL_DIG] = {
5126 .mixers = { alc880_asus_mixer },
5127 .init_verbs = { alc880_volume_init_verbs,
5128 alc880_pin_asus_init_verbs },
5129 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5130 .dac_nids = alc880_asus_dac_nids,
5131 .dig_out_nid = ALC880_DIGOUT_NID,
5132 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5133 .channel_mode = alc880_asus_modes,
5134 .need_dac_fix = 1,
5135 .input_mux = &alc880_capture_source,
5136 },
5137 [ALC880_UNIWILL] = {
5138 .mixers = { alc880_uniwill_mixer },
5139 .init_verbs = { alc880_volume_init_verbs,
5140 alc880_uniwill_init_verbs },
5141 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5142 .dac_nids = alc880_asus_dac_nids,
5143 .dig_out_nid = ALC880_DIGOUT_NID,
5144 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5145 .channel_mode = alc880_threestack_modes,
5146 .need_dac_fix = 1,
5147 .input_mux = &alc880_capture_source,
5148 .unsol_event = alc880_uniwill_unsol_event,
5149 .setup = alc880_uniwill_setup,
5150 .init_hook = alc880_uniwill_init_hook,
5151 },
5152 [ALC880_UNIWILL_P53] = {
5153 .mixers = { alc880_uniwill_p53_mixer },
5154 .init_verbs = { alc880_volume_init_verbs,
5155 alc880_uniwill_p53_init_verbs },
5156 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5157 .dac_nids = alc880_asus_dac_nids,
5158 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5159 .channel_mode = alc880_threestack_modes,
5160 .input_mux = &alc880_capture_source,
5161 .unsol_event = alc880_uniwill_p53_unsol_event,
5162 .setup = alc880_uniwill_p53_setup,
5163 .init_hook = alc_hp_automute,
5164 },
5165 [ALC880_FUJITSU] = {
5166 .mixers = { alc880_fujitsu_mixer },
5167 .init_verbs = { alc880_volume_init_verbs,
5168 alc880_uniwill_p53_init_verbs,
5169 alc880_beep_init_verbs },
5170 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5171 .dac_nids = alc880_dac_nids,
5172 .dig_out_nid = ALC880_DIGOUT_NID,
5173 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5174 .channel_mode = alc880_2_jack_modes,
5175 .input_mux = &alc880_capture_source,
5176 .unsol_event = alc880_uniwill_p53_unsol_event,
5177 .setup = alc880_uniwill_p53_setup,
5178 .init_hook = alc_hp_automute,
5179 },
5180 [ALC880_CLEVO] = {
5181 .mixers = { alc880_three_stack_mixer },
5182 .init_verbs = { alc880_volume_init_verbs,
5183 alc880_pin_clevo_init_verbs },
5184 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5185 .dac_nids = alc880_dac_nids,
5186 .hp_nid = 0x03,
5187 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5188 .channel_mode = alc880_threestack_modes,
5189 .need_dac_fix = 1,
5190 .input_mux = &alc880_capture_source,
5191 },
5192 [ALC880_LG] = {
5193 .mixers = { alc880_lg_mixer },
5194 .init_verbs = { alc880_volume_init_verbs,
5195 alc880_lg_init_verbs },
5196 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
5197 .dac_nids = alc880_lg_dac_nids,
5198 .dig_out_nid = ALC880_DIGOUT_NID,
5199 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
5200 .channel_mode = alc880_lg_ch_modes,
5201 .need_dac_fix = 1,
5202 .input_mux = &alc880_lg_capture_source,
5203 .unsol_event = alc_sku_unsol_event,
5204 .setup = alc880_lg_setup,
5205 .init_hook = alc_hp_automute,
5206 #ifdef CONFIG_SND_HDA_POWER_SAVE
5207 .loopbacks = alc880_lg_loopbacks,
5208 #endif
5209 },
5210 [ALC880_LG_LW] = {
5211 .mixers = { alc880_lg_lw_mixer },
5212 .init_verbs = { alc880_volume_init_verbs,
5213 alc880_lg_lw_init_verbs },
5214 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5215 .dac_nids = alc880_dac_nids,
5216 .dig_out_nid = ALC880_DIGOUT_NID,
5217 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5218 .channel_mode = alc880_lg_lw_modes,
5219 .input_mux = &alc880_lg_lw_capture_source,
5220 .unsol_event = alc_sku_unsol_event,
5221 .setup = alc880_lg_lw_setup,
5222 .init_hook = alc_hp_automute,
5223 },
5224 [ALC880_MEDION_RIM] = {
5225 .mixers = { alc880_medion_rim_mixer },
5226 .init_verbs = { alc880_volume_init_verbs,
5227 alc880_medion_rim_init_verbs,
5228 alc_gpio2_init_verbs },
5229 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5230 .dac_nids = alc880_dac_nids,
5231 .dig_out_nid = ALC880_DIGOUT_NID,
5232 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5233 .channel_mode = alc880_2_jack_modes,
5234 .input_mux = &alc880_medion_rim_capture_source,
5235 .unsol_event = alc880_medion_rim_unsol_event,
5236 .setup = alc880_medion_rim_setup,
5237 .init_hook = alc880_medion_rim_automute,
5238 },
5239 #ifdef CONFIG_SND_DEBUG
5240 [ALC880_TEST] = {
5241 .mixers = { alc880_test_mixer },
5242 .init_verbs = { alc880_test_init_verbs },
5243 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5244 .dac_nids = alc880_test_dac_nids,
5245 .dig_out_nid = ALC880_DIGOUT_NID,
5246 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5247 .channel_mode = alc880_test_modes,
5248 .input_mux = &alc880_test_capture_source,
5249 },
5250 #endif
5251 };
5252
5253 /*
5254 * Automatic parse of I/O pins from the BIOS configuration
5255 */
5256
5257 enum {
5258 ALC_CTL_WIDGET_VOL,
5259 ALC_CTL_WIDGET_MUTE,
5260 ALC_CTL_BIND_MUTE,
5261 };
5262 static const struct snd_kcontrol_new alc880_control_templates[] = {
5263 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5264 HDA_CODEC_MUTE(NULL, 0, 0, 0),
5265 HDA_BIND_MUTE(NULL, 0, 0, 0),
5266 };
5267
5268 static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5269 {
5270 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5271 return snd_array_new(&spec->kctls);
5272 }
5273
5274 /* add dynamic controls */
5275 static int add_control(struct alc_spec *spec, int type, const char *name,
5276 int cidx, unsigned long val)
5277 {
5278 struct snd_kcontrol_new *knew;
5279
5280 knew = alc_kcontrol_new(spec);
5281 if (!knew)
5282 return -ENOMEM;
5283 *knew = alc880_control_templates[type];
5284 knew->name = kstrdup(name, GFP_KERNEL);
5285 if (!knew->name)
5286 return -ENOMEM;
5287 knew->index = cidx;
5288 if (get_amp_nid_(val))
5289 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
5290 knew->private_value = val;
5291 return 0;
5292 }
5293
5294 static int add_control_with_pfx(struct alc_spec *spec, int type,
5295 const char *pfx, const char *dir,
5296 const char *sfx, int cidx, unsigned long val)
5297 {
5298 char name[32];
5299 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
5300 return add_control(spec, type, name, cidx, val);
5301 }
5302
5303 #define add_pb_vol_ctrl(spec, type, pfx, val) \
5304 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
5305 #define add_pb_sw_ctrl(spec, type, pfx, val) \
5306 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
5307 #define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
5308 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
5309 #define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5310 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
5311
5312 #define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5313 #define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5314 #define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5315 #define alc880_multi_pin_idx(nid) ((nid) - 0x18)
5316 #define alc880_idx_to_dac(nid) ((nid) + 0x02)
5317 #define alc880_dac_to_idx(nid) ((nid) - 0x02)
5318 #define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5319 #define alc880_idx_to_selector(nid) ((nid) + 0x10)
5320 #define ALC880_PIN_CD_NID 0x1c
5321
5322 /* fill in the dac_nids table from the parsed pin configuration */
5323 static int alc880_auto_fill_dac_nids(struct alc_spec *spec,
5324 const struct auto_pin_cfg *cfg)
5325 {
5326 hda_nid_t nid;
5327 int assigned[4];
5328 int i, j;
5329
5330 memset(assigned, 0, sizeof(assigned));
5331 spec->multiout.dac_nids = spec->private_dac_nids;
5332
5333 /* check the pins hardwired to audio widget */
5334 for (i = 0; i < cfg->line_outs; i++) {
5335 nid = cfg->line_out_pins[i];
5336 if (alc880_is_fixed_pin(nid)) {
5337 int idx = alc880_fixed_pin_idx(nid);
5338 spec->private_dac_nids[i] = alc880_idx_to_dac(idx);
5339 assigned[idx] = 1;
5340 }
5341 }
5342 /* left pins can be connect to any audio widget */
5343 for (i = 0; i < cfg->line_outs; i++) {
5344 nid = cfg->line_out_pins[i];
5345 if (alc880_is_fixed_pin(nid))
5346 continue;
5347 /* search for an empty channel */
5348 for (j = 0; j < cfg->line_outs; j++) {
5349 if (!assigned[j]) {
5350 spec->private_dac_nids[i] =
5351 alc880_idx_to_dac(j);
5352 assigned[j] = 1;
5353 break;
5354 }
5355 }
5356 }
5357 spec->multiout.num_dacs = cfg->line_outs;
5358 return 0;
5359 }
5360
5361 static const char *alc_get_line_out_pfx(struct alc_spec *spec,
5362 bool can_be_master)
5363 {
5364 struct auto_pin_cfg *cfg = &spec->autocfg;
5365
5366 if (cfg->line_outs == 1 && !spec->multi_ios &&
5367 !cfg->hp_outs && !cfg->speaker_outs && can_be_master)
5368 return "Master";
5369
5370 switch (cfg->line_out_type) {
5371 case AUTO_PIN_SPEAKER_OUT:
5372 if (cfg->line_outs == 1)
5373 return "Speaker";
5374 break;
5375 case AUTO_PIN_HP_OUT:
5376 return "Headphone";
5377 default:
5378 if (cfg->line_outs == 1 && !spec->multi_ios)
5379 return "PCM";
5380 break;
5381 }
5382 return NULL;
5383 }
5384
5385 /* add playback controls from the parsed DAC table */
5386 static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec,
5387 const struct auto_pin_cfg *cfg)
5388 {
5389 static const char * const chname[4] = {
5390 "Front", "Surround", NULL /*CLFE*/, "Side"
5391 };
5392 const char *pfx = alc_get_line_out_pfx(spec, false);
5393 hda_nid_t nid;
5394 int i, err, noutputs;
5395
5396 noutputs = cfg->line_outs;
5397 if (spec->multi_ios > 0)
5398 noutputs += spec->multi_ios;
5399
5400 for (i = 0; i < noutputs; i++) {
5401 if (!spec->multiout.dac_nids[i])
5402 continue;
5403 nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i]));
5404 if (!pfx && i == 2) {
5405 /* Center/LFE */
5406 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5407 "Center",
5408 HDA_COMPOSE_AMP_VAL(nid, 1, 0,
5409 HDA_OUTPUT));
5410 if (err < 0)
5411 return err;
5412 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5413 "LFE",
5414 HDA_COMPOSE_AMP_VAL(nid, 2, 0,
5415 HDA_OUTPUT));
5416 if (err < 0)
5417 return err;
5418 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5419 "Center",
5420 HDA_COMPOSE_AMP_VAL(nid, 1, 2,
5421 HDA_INPUT));
5422 if (err < 0)
5423 return err;
5424 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5425 "LFE",
5426 HDA_COMPOSE_AMP_VAL(nid, 2, 2,
5427 HDA_INPUT));
5428 if (err < 0)
5429 return err;
5430 } else {
5431 const char *name = pfx;
5432 int index = i;
5433 if (!name) {
5434 name = chname[i];
5435 index = 0;
5436 }
5437 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
5438 name, index,
5439 HDA_COMPOSE_AMP_VAL(nid, 3, 0,
5440 HDA_OUTPUT));
5441 if (err < 0)
5442 return err;
5443 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
5444 name, index,
5445 HDA_COMPOSE_AMP_VAL(nid, 3, 2,
5446 HDA_INPUT));
5447 if (err < 0)
5448 return err;
5449 }
5450 }
5451 return 0;
5452 }
5453
5454 /* add playback controls for speaker and HP outputs */
5455 static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin,
5456 const char *pfx)
5457 {
5458 hda_nid_t nid;
5459 int err;
5460
5461 if (!pin)
5462 return 0;
5463
5464 if (alc880_is_fixed_pin(pin)) {
5465 nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
5466 /* specify the DAC as the extra output */
5467 if (!spec->multiout.hp_nid)
5468 spec->multiout.hp_nid = nid;
5469 else
5470 spec->multiout.extra_out_nid[0] = nid;
5471 /* control HP volume/switch on the output mixer amp */
5472 nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin));
5473 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
5474 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT));
5475 if (err < 0)
5476 return err;
5477 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
5478 HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT));
5479 if (err < 0)
5480 return err;
5481 } else if (alc880_is_multi_pin(pin)) {
5482 /* set manual connection */
5483 /* we have only a switch on HP-out PIN */
5484 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
5485 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
5486 if (err < 0)
5487 return err;
5488 }
5489 return 0;
5490 }
5491
5492 /* create input playback/capture controls for the given pin */
5493 static int new_analog_input(struct alc_spec *spec, hda_nid_t pin,
5494 const char *ctlname, int ctlidx,
5495 int idx, hda_nid_t mix_nid)
5496 {
5497 int err;
5498
5499 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname, ctlidx,
5500 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5501 if (err < 0)
5502 return err;
5503 err = __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname, ctlidx,
5504 HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT));
5505 if (err < 0)
5506 return err;
5507 return 0;
5508 }
5509
5510 static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5511 {
5512 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
5513 return (pincap & AC_PINCAP_IN) != 0;
5514 }
5515
5516 /* create playback/capture controls for input pins */
5517 static int alc_auto_create_input_ctls(struct hda_codec *codec,
5518 const struct auto_pin_cfg *cfg,
5519 hda_nid_t mixer,
5520 hda_nid_t cap1, hda_nid_t cap2)
5521 {
5522 struct alc_spec *spec = codec->spec;
5523 struct hda_input_mux *imux = &spec->private_imux[0];
5524 int i, err, idx, type_idx = 0;
5525 const char *prev_label = NULL;
5526
5527 for (i = 0; i < cfg->num_inputs; i++) {
5528 hda_nid_t pin;
5529 const char *label;
5530
5531 pin = cfg->inputs[i].pin;
5532 if (!alc_is_input_pin(codec, pin))
5533 continue;
5534
5535 label = hda_get_autocfg_input_label(codec, cfg, i);
5536 if (prev_label && !strcmp(label, prev_label))
5537 type_idx++;
5538 else
5539 type_idx = 0;
5540 prev_label = label;
5541
5542 if (mixer) {
5543 idx = get_connection_index(codec, mixer, pin);
5544 if (idx >= 0) {
5545 err = new_analog_input(spec, pin,
5546 label, type_idx,
5547 idx, mixer);
5548 if (err < 0)
5549 return err;
5550 }
5551 }
5552
5553 if (!cap1)
5554 continue;
5555 idx = get_connection_index(codec, cap1, pin);
5556 if (idx < 0 && cap2)
5557 idx = get_connection_index(codec, cap2, pin);
5558 if (idx >= 0)
5559 snd_hda_add_imux_item(imux, label, idx, NULL);
5560 }
5561 return 0;
5562 }
5563
5564 static int alc880_auto_create_input_ctls(struct hda_codec *codec,
5565 const struct auto_pin_cfg *cfg)
5566 {
5567 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x08, 0x09);
5568 }
5569
5570 static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5571 unsigned int pin_type)
5572 {
5573 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
5574 pin_type);
5575 /* unmute pin */
5576 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
5577 AMP_OUT_UNMUTE);
5578 }
5579
5580 static void alc880_auto_set_output_and_unmute(struct hda_codec *codec,
5581 hda_nid_t nid, int pin_type,
5582 int dac_idx)
5583 {
5584 alc_set_pin_output(codec, nid, pin_type);
5585 /* need the manual connection? */
5586 if (alc880_is_multi_pin(nid)) {
5587 struct alc_spec *spec = codec->spec;
5588 int idx = alc880_multi_pin_idx(nid);
5589 snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0,
5590 AC_VERB_SET_CONNECT_SEL,
5591 alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx]));
5592 }
5593 }
5594
5595 static int get_pin_type(int line_out_type)
5596 {
5597 if (line_out_type == AUTO_PIN_HP_OUT)
5598 return PIN_HP;
5599 else
5600 return PIN_OUT;
5601 }
5602
5603 static void alc880_auto_init_multi_out(struct hda_codec *codec)
5604 {
5605 struct alc_spec *spec = codec->spec;
5606 int i;
5607
5608 for (i = 0; i < spec->autocfg.line_outs; i++) {
5609 hda_nid_t nid = spec->autocfg.line_out_pins[i];
5610 int pin_type = get_pin_type(spec->autocfg.line_out_type);
5611 alc880_auto_set_output_and_unmute(codec, nid, pin_type, i);
5612 }
5613 }
5614
5615 static void alc880_auto_init_extra_out(struct hda_codec *codec)
5616 {
5617 struct alc_spec *spec = codec->spec;
5618 hda_nid_t pin;
5619
5620 pin = spec->autocfg.speaker_pins[0];
5621 if (pin) /* connect to front */
5622 alc880_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
5623 pin = spec->autocfg.hp_pins[0];
5624 if (pin) /* connect to front */
5625 alc880_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
5626 }
5627
5628 static void alc880_auto_init_analog_input(struct hda_codec *codec)
5629 {
5630 struct alc_spec *spec = codec->spec;
5631 struct auto_pin_cfg *cfg = &spec->autocfg;
5632 int i;
5633
5634 for (i = 0; i < cfg->num_inputs; i++) {
5635 hda_nid_t nid = cfg->inputs[i].pin;
5636 if (alc_is_input_pin(codec, nid)) {
5637 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
5638 if (nid != ALC880_PIN_CD_NID &&
5639 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
5640 snd_hda_codec_write(codec, nid, 0,
5641 AC_VERB_SET_AMP_GAIN_MUTE,
5642 AMP_OUT_MUTE);
5643 }
5644 }
5645 }
5646
5647 static void alc880_auto_init_input_src(struct hda_codec *codec)
5648 {
5649 struct alc_spec *spec = codec->spec;
5650 int c;
5651
5652 for (c = 0; c < spec->num_adc_nids; c++) {
5653 unsigned int mux_idx;
5654 const struct hda_input_mux *imux;
5655 mux_idx = c >= spec->num_mux_defs ? 0 : c;
5656 imux = &spec->input_mux[mux_idx];
5657 if (!imux->num_items && mux_idx > 0)
5658 imux = &spec->input_mux[0];
5659 if (imux)
5660 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
5661 AC_VERB_SET_CONNECT_SEL,
5662 imux->items[0].index);
5663 }
5664 }
5665
5666 static int alc_auto_add_multi_channel_mode(struct hda_codec *codec);
5667
5668 /* parse the BIOS configuration and set up the alc_spec */
5669 /* return 1 if successful, 0 if the proper config is not found,
5670 * or a negative error code
5671 */
5672 static int alc880_parse_auto_config(struct hda_codec *codec)
5673 {
5674 struct alc_spec *spec = codec->spec;
5675 int err;
5676 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
5677
5678 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
5679 alc880_ignore);
5680 if (err < 0)
5681 return err;
5682 if (!spec->autocfg.line_outs)
5683 return 0; /* can't find valid BIOS pin config */
5684
5685 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
5686 if (err < 0)
5687 return err;
5688 err = alc_auto_add_multi_channel_mode(codec);
5689 if (err < 0)
5690 return err;
5691 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
5692 if (err < 0)
5693 return err;
5694 err = alc880_auto_create_extra_out(spec,
5695 spec->autocfg.speaker_pins[0],
5696 "Speaker");
5697 if (err < 0)
5698 return err;
5699 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
5700 "Headphone");
5701 if (err < 0)
5702 return err;
5703 err = alc880_auto_create_input_ctls(codec, &spec->autocfg);
5704 if (err < 0)
5705 return err;
5706
5707 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
5708
5709 alc_auto_parse_digital(codec);
5710
5711 if (spec->kctls.list)
5712 add_mixer(spec, spec->kctls.list);
5713
5714 add_verb(spec, alc880_volume_init_verbs);
5715
5716 spec->num_mux_defs = 1;
5717 spec->input_mux = &spec->private_imux[0];
5718
5719 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
5720
5721 return 1;
5722 }
5723
5724 /* additional initialization for auto-configuration model */
5725 static void alc880_auto_init(struct hda_codec *codec)
5726 {
5727 struct alc_spec *spec = codec->spec;
5728 alc880_auto_init_multi_out(codec);
5729 alc880_auto_init_extra_out(codec);
5730 alc880_auto_init_analog_input(codec);
5731 alc880_auto_init_input_src(codec);
5732 alc_auto_init_digital(codec);
5733 if (spec->unsol_event)
5734 alc_inithook(codec);
5735 }
5736
5737 /* check the ADC/MUX contains all input pins; some ADC/MUX contains only
5738 * one of two digital mic pins, e.g. on ALC272
5739 */
5740 static void fixup_automic_adc(struct hda_codec *codec)
5741 {
5742 struct alc_spec *spec = codec->spec;
5743 int i;
5744
5745 for (i = 0; i < spec->num_adc_nids; i++) {
5746 hda_nid_t cap = spec->capsrc_nids ?
5747 spec->capsrc_nids[i] : spec->adc_nids[i];
5748 int iidx, eidx;
5749
5750 iidx = get_connection_index(codec, cap, spec->int_mic.pin);
5751 if (iidx < 0)
5752 continue;
5753 eidx = get_connection_index(codec, cap, spec->ext_mic.pin);
5754 if (eidx < 0)
5755 continue;
5756 spec->int_mic.mux_idx = iidx;
5757 spec->ext_mic.mux_idx = eidx;
5758 if (spec->capsrc_nids)
5759 spec->capsrc_nids += i;
5760 spec->adc_nids += i;
5761 spec->num_adc_nids = 1;
5762 /* optional dock-mic */
5763 eidx = get_connection_index(codec, cap, spec->dock_mic.pin);
5764 if (eidx < 0)
5765 spec->dock_mic.pin = 0;
5766 else
5767 spec->dock_mic.mux_idx = eidx;
5768 return;
5769 }
5770 snd_printd(KERN_INFO "hda_codec: %s: "
5771 "No ADC/MUX containing both 0x%x and 0x%x pins\n",
5772 codec->chip_name, spec->int_mic.pin, spec->ext_mic.pin);
5773 spec->auto_mic = 0; /* disable auto-mic to be sure */
5774 }
5775
5776 /* select or unmute the given capsrc route */
5777 static void select_or_unmute_capsrc(struct hda_codec *codec, hda_nid_t cap,
5778 int idx)
5779 {
5780 if (get_wcaps_type(get_wcaps(codec, cap)) == AC_WID_AUD_MIX) {
5781 snd_hda_codec_amp_stereo(codec, cap, HDA_INPUT, idx,
5782 HDA_AMP_MUTE, 0);
5783 } else {
5784 snd_hda_codec_write_cache(codec, cap, 0,
5785 AC_VERB_SET_CONNECT_SEL, idx);
5786 }
5787 }
5788
5789 /* set the default connection to that pin */
5790 static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin)
5791 {
5792 struct alc_spec *spec = codec->spec;
5793 int i;
5794
5795 if (!pin)
5796 return 0;
5797 for (i = 0; i < spec->num_adc_nids; i++) {
5798 hda_nid_t cap = spec->capsrc_nids ?
5799 spec->capsrc_nids[i] : spec->adc_nids[i];
5800 int idx;
5801
5802 idx = get_connection_index(codec, cap, pin);
5803 if (idx < 0)
5804 continue;
5805 select_or_unmute_capsrc(codec, cap, idx);
5806 return i; /* return the found index */
5807 }
5808 return -1; /* not found */
5809 }
5810
5811 /* choose the ADC/MUX containing the input pin and initialize the setup */
5812 static void fixup_single_adc(struct hda_codec *codec)
5813 {
5814 struct alc_spec *spec = codec->spec;
5815 struct auto_pin_cfg *cfg = &spec->autocfg;
5816 int i;
5817
5818 /* search for the input pin; there must be only one */
5819 if (cfg->num_inputs != 1)
5820 return;
5821 i = init_capsrc_for_pin(codec, cfg->inputs[0].pin);
5822 if (i >= 0) {
5823 /* use only this ADC */
5824 if (spec->capsrc_nids)
5825 spec->capsrc_nids += i;
5826 spec->adc_nids += i;
5827 spec->num_adc_nids = 1;
5828 spec->single_input_src = 1;
5829 }
5830 }
5831
5832 /* initialize dual adcs */
5833 static void fixup_dual_adc_switch(struct hda_codec *codec)
5834 {
5835 struct alc_spec *spec = codec->spec;
5836 init_capsrc_for_pin(codec, spec->ext_mic.pin);
5837 init_capsrc_for_pin(codec, spec->dock_mic.pin);
5838 init_capsrc_for_pin(codec, spec->int_mic.pin);
5839 }
5840
5841 /* initialize some special cases for input sources */
5842 static void alc_init_special_input_src(struct hda_codec *codec)
5843 {
5844 struct alc_spec *spec = codec->spec;
5845 if (spec->dual_adc_switch)
5846 fixup_dual_adc_switch(codec);
5847 else if (spec->single_input_src)
5848 init_capsrc_for_pin(codec, spec->autocfg.inputs[0].pin);
5849 }
5850
5851 static void set_capture_mixer(struct hda_codec *codec)
5852 {
5853 struct alc_spec *spec = codec->spec;
5854 static const struct snd_kcontrol_new *caps[2][3] = {
5855 { alc_capture_mixer_nosrc1,
5856 alc_capture_mixer_nosrc2,
5857 alc_capture_mixer_nosrc3 },
5858 { alc_capture_mixer1,
5859 alc_capture_mixer2,
5860 alc_capture_mixer3 },
5861 };
5862 if (spec->num_adc_nids > 0 && spec->num_adc_nids <= 3) {
5863 int mux = 0;
5864 int num_adcs = spec->num_adc_nids;
5865 if (spec->dual_adc_switch)
5866 num_adcs = 1;
5867 else if (spec->auto_mic)
5868 fixup_automic_adc(codec);
5869 else if (spec->input_mux) {
5870 if (spec->input_mux->num_items > 1)
5871 mux = 1;
5872 else if (spec->input_mux->num_items == 1)
5873 fixup_single_adc(codec);
5874 }
5875 spec->cap_mixer = caps[mux][num_adcs - 1];
5876 }
5877 }
5878
5879 /* fill adc_nids (and capsrc_nids) containing all active input pins */
5880 static void fillup_priv_adc_nids(struct hda_codec *codec, const hda_nid_t *nids,
5881 int num_nids)
5882 {
5883 struct alc_spec *spec = codec->spec;
5884 struct auto_pin_cfg *cfg = &spec->autocfg;
5885 int n;
5886 hda_nid_t fallback_adc = 0, fallback_cap = 0;
5887
5888 for (n = 0; n < num_nids; n++) {
5889 hda_nid_t adc, cap;
5890 hda_nid_t conn[HDA_MAX_NUM_INPUTS];
5891 int nconns, i, j;
5892
5893 adc = nids[n];
5894 if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN)
5895 continue;
5896 cap = adc;
5897 nconns = snd_hda_get_connections(codec, cap, conn,
5898 ARRAY_SIZE(conn));
5899 if (nconns == 1) {
5900 cap = conn[0];
5901 nconns = snd_hda_get_connections(codec, cap, conn,
5902 ARRAY_SIZE(conn));
5903 }
5904 if (nconns <= 0)
5905 continue;
5906 if (!fallback_adc) {
5907 fallback_adc = adc;
5908 fallback_cap = cap;
5909 }
5910 for (i = 0; i < cfg->num_inputs; i++) {
5911 hda_nid_t nid = cfg->inputs[i].pin;
5912 for (j = 0; j < nconns; j++) {
5913 if (conn[j] == nid)
5914 break;
5915 }
5916 if (j >= nconns)
5917 break;
5918 }
5919 if (i >= cfg->num_inputs) {
5920 int num_adcs = spec->num_adc_nids;
5921 spec->private_adc_nids[num_adcs] = adc;
5922 spec->private_capsrc_nids[num_adcs] = cap;
5923 spec->num_adc_nids++;
5924 spec->adc_nids = spec->private_adc_nids;
5925 if (adc != cap)
5926 spec->capsrc_nids = spec->private_capsrc_nids;
5927 }
5928 }
5929 if (!spec->num_adc_nids) {
5930 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
5931 " using fallback 0x%x\n",
5932 codec->chip_name, fallback_adc);
5933 spec->private_adc_nids[0] = fallback_adc;
5934 spec->adc_nids = spec->private_adc_nids;
5935 if (fallback_adc != fallback_cap) {
5936 spec->private_capsrc_nids[0] = fallback_cap;
5937 spec->capsrc_nids = spec->private_adc_nids;
5938 }
5939 }
5940 }
5941
5942 #ifdef CONFIG_SND_HDA_INPUT_BEEP
5943 #define set_beep_amp(spec, nid, idx, dir) \
5944 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
5945
5946 static const struct snd_pci_quirk beep_white_list[] = {
5947 SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1),
5948 SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1),
5949 SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1),
5950 SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1),
5951 SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1),
5952 {}
5953 };
5954
5955 static inline int has_cdefine_beep(struct hda_codec *codec)
5956 {
5957 struct alc_spec *spec = codec->spec;
5958 const struct snd_pci_quirk *q;
5959 q = snd_pci_quirk_lookup(codec->bus->pci, beep_white_list);
5960 if (q)
5961 return q->value;
5962 return spec->cdefine.enable_pcbeep;
5963 }
5964 #else
5965 #define set_beep_amp(spec, nid, idx, dir) /* NOP */
5966 #define has_cdefine_beep(codec) 0
5967 #endif
5968
5969 /*
5970 * OK, here we have finally the patch for ALC880
5971 */
5972
5973 static int patch_alc880(struct hda_codec *codec)
5974 {
5975 struct alc_spec *spec;
5976 int board_config;
5977 int err;
5978
5979 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
5980 if (spec == NULL)
5981 return -ENOMEM;
5982
5983 codec->spec = spec;
5984
5985 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST,
5986 alc880_models,
5987 alc880_cfg_tbl);
5988 if (board_config < 0) {
5989 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5990 codec->chip_name);
5991 board_config = ALC880_AUTO;
5992 }
5993
5994 if (board_config == ALC880_AUTO) {
5995 /* automatic parse from the BIOS config */
5996 err = alc880_parse_auto_config(codec);
5997 if (err < 0) {
5998 alc_free(codec);
5999 return err;
6000 } else if (!err) {
6001 printk(KERN_INFO
6002 "hda_codec: Cannot set up configuration "
6003 "from BIOS. Using 3-stack mode...\n");
6004 board_config = ALC880_3ST;
6005 }
6006 }
6007
6008 err = snd_hda_attach_beep_device(codec, 0x1);
6009 if (err < 0) {
6010 alc_free(codec);
6011 return err;
6012 }
6013
6014 if (board_config != ALC880_AUTO)
6015 setup_preset(codec, &alc880_presets[board_config]);
6016
6017 spec->stream_analog_playback = &alc880_pcm_analog_playback;
6018 spec->stream_analog_capture = &alc880_pcm_analog_capture;
6019 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
6020
6021 spec->stream_digital_playback = &alc880_pcm_digital_playback;
6022 spec->stream_digital_capture = &alc880_pcm_digital_capture;
6023
6024 if (!spec->adc_nids && spec->input_mux) {
6025 /* check whether NID 0x07 is valid */
6026 unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]);
6027 /* get type */
6028 wcap = get_wcaps_type(wcap);
6029 if (wcap != AC_WID_AUD_IN) {
6030 spec->adc_nids = alc880_adc_nids_alt;
6031 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt);
6032 } else {
6033 spec->adc_nids = alc880_adc_nids;
6034 spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids);
6035 }
6036 }
6037 set_capture_mixer(codec);
6038 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
6039
6040 spec->vmaster_nid = 0x0c;
6041
6042 codec->patch_ops = alc_patch_ops;
6043 if (board_config == ALC880_AUTO)
6044 spec->init_hook = alc880_auto_init;
6045 #ifdef CONFIG_SND_HDA_POWER_SAVE
6046 if (!spec->loopback.amplist)
6047 spec->loopback.amplist = alc880_loopbacks;
6048 #endif
6049
6050 return 0;
6051 }
6052
6053
6054 /*
6055 * ALC260 support
6056 */
6057
6058 static const hda_nid_t alc260_dac_nids[1] = {
6059 /* front */
6060 0x02,
6061 };
6062
6063 static const hda_nid_t alc260_adc_nids[1] = {
6064 /* ADC0 */
6065 0x04,
6066 };
6067
6068 static const hda_nid_t alc260_adc_nids_alt[1] = {
6069 /* ADC1 */
6070 0x05,
6071 };
6072
6073 /* NIDs used when simultaneous access to both ADCs makes sense. Note that
6074 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
6075 */
6076 static const hda_nid_t alc260_dual_adc_nids[2] = {
6077 /* ADC0, ADC1 */
6078 0x04, 0x05
6079 };
6080
6081 #define ALC260_DIGOUT_NID 0x03
6082 #define ALC260_DIGIN_NID 0x06
6083
6084 static const struct hda_input_mux alc260_capture_source = {
6085 .num_items = 4,
6086 .items = {
6087 { "Mic", 0x0 },
6088 { "Front Mic", 0x1 },
6089 { "Line", 0x2 },
6090 { "CD", 0x4 },
6091 },
6092 };
6093
6094 /* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
6095 * headphone jack and the internal CD lines since these are the only pins at
6096 * which audio can appear. For flexibility, also allow the option of
6097 * recording the mixer output on the second ADC (ADC0 doesn't have a
6098 * connection to the mixer output).
6099 */
6100 static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
6101 {
6102 .num_items = 3,
6103 .items = {
6104 { "Mic/Line", 0x0 },
6105 { "CD", 0x4 },
6106 { "Headphone", 0x2 },
6107 },
6108 },
6109 {
6110 .num_items = 4,
6111 .items = {
6112 { "Mic/Line", 0x0 },
6113 { "CD", 0x4 },
6114 { "Headphone", 0x2 },
6115 { "Mixer", 0x5 },
6116 },
6117 },
6118
6119 };
6120
6121 /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
6122 * the Fujitsu S702x, but jacks are marked differently.
6123 */
6124 static const struct hda_input_mux alc260_acer_capture_sources[2] = {
6125 {
6126 .num_items = 4,
6127 .items = {
6128 { "Mic", 0x0 },
6129 { "Line", 0x2 },
6130 { "CD", 0x4 },
6131 { "Headphone", 0x5 },
6132 },
6133 },
6134 {
6135 .num_items = 5,
6136 .items = {
6137 { "Mic", 0x0 },
6138 { "Line", 0x2 },
6139 { "CD", 0x4 },
6140 { "Headphone", 0x6 },
6141 { "Mixer", 0x5 },
6142 },
6143 },
6144 };
6145
6146 /* Maxdata Favorit 100XS */
6147 static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
6148 {
6149 .num_items = 2,
6150 .items = {
6151 { "Line/Mic", 0x0 },
6152 { "CD", 0x4 },
6153 },
6154 },
6155 {
6156 .num_items = 3,
6157 .items = {
6158 { "Line/Mic", 0x0 },
6159 { "CD", 0x4 },
6160 { "Mixer", 0x5 },
6161 },
6162 },
6163 };
6164
6165 /*
6166 * This is just place-holder, so there's something for alc_build_pcms to look
6167 * at when it calculates the maximum number of channels. ALC260 has no mixer
6168 * element which allows changing the channel mode, so the verb list is
6169 * never used.
6170 */
6171 static const struct hda_channel_mode alc260_modes[1] = {
6172 { 2, NULL },
6173 };
6174
6175
6176 /* Mixer combinations
6177 *
6178 * basic: base_output + input + pc_beep + capture
6179 * HP: base_output + input + capture_alt
6180 * HP_3013: hp_3013 + input + capture
6181 * fujitsu: fujitsu + capture
6182 * acer: acer + capture
6183 */
6184
6185 static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
6186 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6187 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6188 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6189 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6190 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6191 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6192 { } /* end */
6193 };
6194
6195 static const struct snd_kcontrol_new alc260_input_mixer[] = {
6196 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6197 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6198 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6199 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6200 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6201 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6202 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
6203 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
6204 { } /* end */
6205 };
6206
6207 /* update HP, line and mono out pins according to the master switch */
6208 static void alc260_hp_master_update(struct hda_codec *codec)
6209 {
6210 update_speakers(codec);
6211 }
6212
6213 static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
6214 struct snd_ctl_elem_value *ucontrol)
6215 {
6216 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6217 struct alc_spec *spec = codec->spec;
6218 *ucontrol->value.integer.value = !spec->master_mute;
6219 return 0;
6220 }
6221
6222 static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
6223 struct snd_ctl_elem_value *ucontrol)
6224 {
6225 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6226 struct alc_spec *spec = codec->spec;
6227 int val = !*ucontrol->value.integer.value;
6228
6229 if (val == spec->master_mute)
6230 return 0;
6231 spec->master_mute = val;
6232 alc260_hp_master_update(codec);
6233 return 1;
6234 }
6235
6236 static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
6237 {
6238 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6239 .name = "Master Playback Switch",
6240 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6241 .info = snd_ctl_boolean_mono_info,
6242 .get = alc260_hp_master_sw_get,
6243 .put = alc260_hp_master_sw_put,
6244 },
6245 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6246 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6247 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6248 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6249 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6250 HDA_OUTPUT),
6251 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6252 { } /* end */
6253 };
6254
6255 static const struct hda_verb alc260_hp_unsol_verbs[] = {
6256 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6257 {},
6258 };
6259
6260 static void alc260_hp_setup(struct hda_codec *codec)
6261 {
6262 struct alc_spec *spec = codec->spec;
6263
6264 spec->autocfg.hp_pins[0] = 0x0f;
6265 spec->autocfg.speaker_pins[0] = 0x10;
6266 spec->autocfg.speaker_pins[1] = 0x11;
6267 spec->automute = 1;
6268 spec->automute_mode = ALC_AUTOMUTE_PIN;
6269 }
6270
6271 static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
6272 {
6273 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6274 .name = "Master Playback Switch",
6275 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6276 .info = snd_ctl_boolean_mono_info,
6277 .get = alc260_hp_master_sw_get,
6278 .put = alc260_hp_master_sw_put,
6279 },
6280 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6281 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6282 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6283 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6284 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6285 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6286 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6287 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
6288 { } /* end */
6289 };
6290
6291 static void alc260_hp_3013_setup(struct hda_codec *codec)
6292 {
6293 struct alc_spec *spec = codec->spec;
6294
6295 spec->autocfg.hp_pins[0] = 0x15;
6296 spec->autocfg.speaker_pins[0] = 0x10;
6297 spec->autocfg.speaker_pins[1] = 0x11;
6298 spec->automute = 1;
6299 spec->automute_mode = ALC_AUTOMUTE_PIN;
6300 }
6301
6302 static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
6303 .ops = &snd_hda_bind_vol,
6304 .values = {
6305 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6306 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6307 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6308 0
6309 },
6310 };
6311
6312 static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
6313 .ops = &snd_hda_bind_sw,
6314 .values = {
6315 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6316 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6317 0
6318 },
6319 };
6320
6321 static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6322 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6323 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6324 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6325 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6326 { } /* end */
6327 };
6328
6329 static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6330 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6331 {},
6332 };
6333
6334 static void alc260_hp_3012_setup(struct hda_codec *codec)
6335 {
6336 struct alc_spec *spec = codec->spec;
6337
6338 spec->autocfg.hp_pins[0] = 0x10;
6339 spec->autocfg.speaker_pins[0] = 0x0f;
6340 spec->autocfg.speaker_pins[1] = 0x11;
6341 spec->autocfg.speaker_pins[2] = 0x15;
6342 spec->automute = 1;
6343 spec->automute_mode = ALC_AUTOMUTE_PIN;
6344 }
6345
6346 /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
6347 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6348 */
6349 static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
6350 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6351 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
6352 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6353 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6354 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6355 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6356 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
6357 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
6358 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6359 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
6360 { } /* end */
6361 };
6362
6363 /* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6364 * versions of the ALC260 don't act on requests to enable mic bias from NID
6365 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6366 * datasheet doesn't mention this restriction. At this stage it's not clear
6367 * whether this behaviour is intentional or is a hardware bug in chip
6368 * revisions available in early 2006. Therefore for now allow the
6369 * "Headphone Jack Mode" control to span all choices, but if it turns out
6370 * that the lack of mic bias for this NID is intentional we could change the
6371 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6372 *
6373 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6374 * don't appear to make the mic bias available from the "line" jack, even
6375 * though the NID used for this jack (0x14) can supply it. The theory is
6376 * that perhaps Acer have included blocking capacitors between the ALC260
6377 * and the output jack. If this turns out to be the case for all such
6378 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6379 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
6380 *
6381 * The C20x Tablet series have a mono internal speaker which is controlled
6382 * via the chip's Mono sum widget and pin complex, so include the necessary
6383 * controls for such models. On models without a "mono speaker" the control
6384 * won't do anything.
6385 */
6386 static const struct snd_kcontrol_new alc260_acer_mixer[] = {
6387 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6388 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6389 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6390 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6391 HDA_OUTPUT),
6392 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
6393 HDA_INPUT),
6394 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6395 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6396 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6397 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6398 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6399 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6400 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6401 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6402 { } /* end */
6403 };
6404
6405 /* Maxdata Favorit 100XS: one output and one input (0x12) jack
6406 */
6407 static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6408 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6409 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6410 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6411 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6412 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6413 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6414 { } /* end */
6415 };
6416
6417 /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6418 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6419 */
6420 static const struct snd_kcontrol_new alc260_will_mixer[] = {
6421 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6422 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6423 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6424 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6425 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6426 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6427 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6428 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6429 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6430 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6431 { } /* end */
6432 };
6433
6434 /* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6435 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6436 */
6437 static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6438 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6439 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6440 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6441 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6442 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6443 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6444 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6445 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6446 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6447 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6448 { } /* end */
6449 };
6450
6451 /*
6452 * initialization verbs
6453 */
6454 static const struct hda_verb alc260_init_verbs[] = {
6455 /* Line In pin widget for input */
6456 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6457 /* CD pin widget for input */
6458 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6459 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6460 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6461 /* Mic2 (front panel) pin widget for input and vref at 80% */
6462 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6463 /* LINE-2 is used for line-out in rear */
6464 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6465 /* select line-out */
6466 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
6467 /* LINE-OUT pin */
6468 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6469 /* enable HP */
6470 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6471 /* enable Mono */
6472 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6473 /* mute capture amp left and right */
6474 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6475 /* set connection select to line in (default select for this ADC) */
6476 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6477 /* mute capture amp left and right */
6478 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6479 /* set connection select to line in (default select for this ADC) */
6480 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
6481 /* set vol=0 Line-Out mixer amp left and right */
6482 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6483 /* unmute pin widget amp left and right (no gain on this amp) */
6484 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6485 /* set vol=0 HP mixer amp left and right */
6486 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6487 /* unmute pin widget amp left and right (no gain on this amp) */
6488 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6489 /* set vol=0 Mono mixer amp left and right */
6490 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6491 /* unmute pin widget amp left and right (no gain on this amp) */
6492 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6493 /* unmute LINE-2 out pin */
6494 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6495 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6496 * Line In 2 = 0x03
6497 */
6498 /* mute analog inputs */
6499 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6500 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6501 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6502 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6503 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6504 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6505 /* mute Front out path */
6506 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6507 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6508 /* mute Headphone out path */
6509 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6510 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6511 /* mute Mono out path */
6512 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6513 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6514 { }
6515 };
6516
6517 #if 0 /* should be identical with alc260_init_verbs? */
6518 static const struct hda_verb alc260_hp_init_verbs[] = {
6519 /* Headphone and output */
6520 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6521 /* mono output */
6522 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6523 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6524 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6525 /* Mic2 (front panel) pin widget for input and vref at 80% */
6526 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6527 /* Line In pin widget for input */
6528 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6529 /* Line-2 pin widget for output */
6530 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6531 /* CD pin widget for input */
6532 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6533 /* unmute amp left and right */
6534 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6535 /* set connection select to line in (default select for this ADC) */
6536 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6537 /* unmute Line-Out mixer amp left and right (volume = 0) */
6538 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6539 /* mute pin widget amp left and right (no gain on this amp) */
6540 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6541 /* unmute HP mixer amp left and right (volume = 0) */
6542 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6543 /* mute pin widget amp left and right (no gain on this amp) */
6544 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6545 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6546 * Line In 2 = 0x03
6547 */
6548 /* mute analog inputs */
6549 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6550 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6551 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6552 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6553 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6554 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6555 /* Unmute Front out path */
6556 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6557 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6558 /* Unmute Headphone out path */
6559 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6560 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6561 /* Unmute Mono out path */
6562 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6563 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6564 { }
6565 };
6566 #endif
6567
6568 static const struct hda_verb alc260_hp_3013_init_verbs[] = {
6569 /* Line out and output */
6570 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6571 /* mono output */
6572 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6573 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6574 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6575 /* Mic2 (front panel) pin widget for input and vref at 80% */
6576 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6577 /* Line In pin widget for input */
6578 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6579 /* Headphone pin widget for output */
6580 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6581 /* CD pin widget for input */
6582 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6583 /* unmute amp left and right */
6584 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6585 /* set connection select to line in (default select for this ADC) */
6586 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6587 /* unmute Line-Out mixer amp left and right (volume = 0) */
6588 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6589 /* mute pin widget amp left and right (no gain on this amp) */
6590 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6591 /* unmute HP mixer amp left and right (volume = 0) */
6592 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6593 /* mute pin widget amp left and right (no gain on this amp) */
6594 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6595 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6596 * Line In 2 = 0x03
6597 */
6598 /* mute analog inputs */
6599 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6600 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6601 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6602 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6603 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6604 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6605 /* Unmute Front out path */
6606 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6607 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6608 /* Unmute Headphone out path */
6609 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6610 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6611 /* Unmute Mono out path */
6612 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6613 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6614 { }
6615 };
6616
6617 /* Initialisation sequence for ALC260 as configured in Fujitsu S702x
6618 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6619 * audio = 0x16, internal speaker = 0x10.
6620 */
6621 static const struct hda_verb alc260_fujitsu_init_verbs[] = {
6622 /* Disable all GPIOs */
6623 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6624 /* Internal speaker is connected to headphone pin */
6625 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6626 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6627 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6628 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6629 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6630 /* Ensure all other unused pins are disabled and muted. */
6631 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6632 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6633 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6634 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6635 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6636 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6637 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6638 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6639
6640 /* Disable digital (SPDIF) pins */
6641 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6642 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6643
6644 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
6645 * when acting as an output.
6646 */
6647 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6648
6649 /* Start with output sum widgets muted and their output gains at min */
6650 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6651 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6652 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6653 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6654 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6655 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6656 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6657 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6658 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6659
6660 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6661 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6662 /* Unmute Line1 pin widget output buffer since it starts as an output.
6663 * If the pin mode is changed by the user the pin mode control will
6664 * take care of enabling the pin's input/output buffers as needed.
6665 * Therefore there's no need to enable the input buffer at this
6666 * stage.
6667 */
6668 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6669 /* Unmute input buffer of pin widget used for Line-in (no equiv
6670 * mixer ctrl)
6671 */
6672 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6673
6674 /* Mute capture amp left and right */
6675 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6676 /* Set ADC connection select to match default mixer setting - line
6677 * in (on mic1 pin)
6678 */
6679 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6680
6681 /* Do the same for the second ADC: mute capture input amp and
6682 * set ADC connection to line in (on mic1 pin)
6683 */
6684 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6685 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6686
6687 /* Mute all inputs to mixer widget (even unconnected ones) */
6688 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6689 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6690 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6691 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6692 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6693 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6694 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6695 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6696
6697 { }
6698 };
6699
6700 /* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6701 * similar laptops (adapted from Fujitsu init verbs).
6702 */
6703 static const struct hda_verb alc260_acer_init_verbs[] = {
6704 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6705 * the headphone jack. Turn this on and rely on the standard mute
6706 * methods whenever the user wants to turn these outputs off.
6707 */
6708 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6709 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6710 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6711 /* Internal speaker/Headphone jack is connected to Line-out pin */
6712 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6713 /* Internal microphone/Mic jack is connected to Mic1 pin */
6714 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6715 /* Line In jack is connected to Line1 pin */
6716 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6717 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6718 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6719 /* Ensure all other unused pins are disabled and muted. */
6720 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6721 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6722 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6723 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6724 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6725 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6726 /* Disable digital (SPDIF) pins */
6727 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6728 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6729
6730 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6731 * bus when acting as outputs.
6732 */
6733 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6734 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6735
6736 /* Start with output sum widgets muted and their output gains at min */
6737 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6738 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6739 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6740 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6741 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6742 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6743 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6744 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6745 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6746
6747 /* Unmute Line-out pin widget amp left and right
6748 * (no equiv mixer ctrl)
6749 */
6750 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6751 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6752 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6753 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6754 * inputs. If the pin mode is changed by the user the pin mode control
6755 * will take care of enabling the pin's input/output buffers as needed.
6756 * Therefore there's no need to enable the input buffer at this
6757 * stage.
6758 */
6759 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6760 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6761
6762 /* Mute capture amp left and right */
6763 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6764 /* Set ADC connection select to match default mixer setting - mic
6765 * (on mic1 pin)
6766 */
6767 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6768
6769 /* Do similar with the second ADC: mute capture input amp and
6770 * set ADC connection to mic to match ALSA's default state.
6771 */
6772 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6773 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6774
6775 /* Mute all inputs to mixer widget (even unconnected ones) */
6776 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6777 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6778 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6779 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6780 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6781 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6782 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6783 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6784
6785 { }
6786 };
6787
6788 /* Initialisation sequence for Maxdata Favorit 100XS
6789 * (adapted from Acer init verbs).
6790 */
6791 static const struct hda_verb alc260_favorit100_init_verbs[] = {
6792 /* GPIO 0 enables the output jack.
6793 * Turn this on and rely on the standard mute
6794 * methods whenever the user wants to turn these outputs off.
6795 */
6796 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6797 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6798 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6799 /* Line/Mic input jack is connected to Mic1 pin */
6800 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6801 /* Ensure all other unused pins are disabled and muted. */
6802 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6803 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6804 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6805 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6806 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6807 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6808 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6809 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6810 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6811 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6812 /* Disable digital (SPDIF) pins */
6813 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6814 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6815
6816 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6817 * bus when acting as outputs.
6818 */
6819 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6820 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6821
6822 /* Start with output sum widgets muted and their output gains at min */
6823 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6824 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6825 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6826 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6827 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6828 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6829 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6830 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6831 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6832
6833 /* Unmute Line-out pin widget amp left and right
6834 * (no equiv mixer ctrl)
6835 */
6836 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6837 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6838 * inputs. If the pin mode is changed by the user the pin mode control
6839 * will take care of enabling the pin's input/output buffers as needed.
6840 * Therefore there's no need to enable the input buffer at this
6841 * stage.
6842 */
6843 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6844
6845 /* Mute capture amp left and right */
6846 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6847 /* Set ADC connection select to match default mixer setting - mic
6848 * (on mic1 pin)
6849 */
6850 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6851
6852 /* Do similar with the second ADC: mute capture input amp and
6853 * set ADC connection to mic to match ALSA's default state.
6854 */
6855 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6856 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6857
6858 /* Mute all inputs to mixer widget (even unconnected ones) */
6859 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6860 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6861 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6862 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6863 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6864 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6865 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6866 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6867
6868 { }
6869 };
6870
6871 static const struct hda_verb alc260_will_verbs[] = {
6872 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6873 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6874 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6875 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6876 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6877 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6878 {}
6879 };
6880
6881 static const struct hda_verb alc260_replacer_672v_verbs[] = {
6882 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6883 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6884 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6885
6886 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6887 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6888 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6889
6890 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6891 {}
6892 };
6893
6894 /* toggle speaker-output according to the hp-jack state */
6895 static void alc260_replacer_672v_automute(struct hda_codec *codec)
6896 {
6897 unsigned int present;
6898
6899 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
6900 present = snd_hda_jack_detect(codec, 0x0f);
6901 if (present) {
6902 snd_hda_codec_write_cache(codec, 0x01, 0,
6903 AC_VERB_SET_GPIO_DATA, 1);
6904 snd_hda_codec_write_cache(codec, 0x0f, 0,
6905 AC_VERB_SET_PIN_WIDGET_CONTROL,
6906 PIN_HP);
6907 } else {
6908 snd_hda_codec_write_cache(codec, 0x01, 0,
6909 AC_VERB_SET_GPIO_DATA, 0);
6910 snd_hda_codec_write_cache(codec, 0x0f, 0,
6911 AC_VERB_SET_PIN_WIDGET_CONTROL,
6912 PIN_OUT);
6913 }
6914 }
6915
6916 static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6917 unsigned int res)
6918 {
6919 if ((res >> 26) == ALC880_HP_EVENT)
6920 alc260_replacer_672v_automute(codec);
6921 }
6922
6923 static const struct hda_verb alc260_hp_dc7600_verbs[] = {
6924 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6925 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6926 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6927 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6928 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6929 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6930 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6931 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6932 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6933 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6934 {}
6935 };
6936
6937 /* Test configuration for debugging, modelled after the ALC880 test
6938 * configuration.
6939 */
6940 #ifdef CONFIG_SND_DEBUG
6941 static const hda_nid_t alc260_test_dac_nids[1] = {
6942 0x02,
6943 };
6944 static const hda_nid_t alc260_test_adc_nids[2] = {
6945 0x04, 0x05,
6946 };
6947 /* For testing the ALC260, each input MUX needs its own definition since
6948 * the signal assignments are different. This assumes that the first ADC
6949 * is NID 0x04.
6950 */
6951 static const struct hda_input_mux alc260_test_capture_sources[2] = {
6952 {
6953 .num_items = 7,
6954 .items = {
6955 { "MIC1 pin", 0x0 },
6956 { "MIC2 pin", 0x1 },
6957 { "LINE1 pin", 0x2 },
6958 { "LINE2 pin", 0x3 },
6959 { "CD pin", 0x4 },
6960 { "LINE-OUT pin", 0x5 },
6961 { "HP-OUT pin", 0x6 },
6962 },
6963 },
6964 {
6965 .num_items = 8,
6966 .items = {
6967 { "MIC1 pin", 0x0 },
6968 { "MIC2 pin", 0x1 },
6969 { "LINE1 pin", 0x2 },
6970 { "LINE2 pin", 0x3 },
6971 { "CD pin", 0x4 },
6972 { "Mixer", 0x5 },
6973 { "LINE-OUT pin", 0x6 },
6974 { "HP-OUT pin", 0x7 },
6975 },
6976 },
6977 };
6978 static const struct snd_kcontrol_new alc260_test_mixer[] = {
6979 /* Output driver widgets */
6980 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6981 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6982 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6983 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6984 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6985 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6986
6987 /* Modes for retasking pin widgets
6988 * Note: the ALC260 doesn't seem to act on requests to enable mic
6989 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6990 * mention this restriction. At this stage it's not clear whether
6991 * this behaviour is intentional or is a hardware bug in chip
6992 * revisions available at least up until early 2006. Therefore for
6993 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6994 * choices, but if it turns out that the lack of mic bias for these
6995 * NIDs is intentional we could change their modes from
6996 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6997 */
6998 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6999 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
7000 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
7001 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
7002 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
7003 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
7004
7005 /* Loopback mixer controls */
7006 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
7007 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
7008 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
7009 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
7010 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
7011 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
7012 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
7013 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
7014 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
7015 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
7016 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
7017 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
7018 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
7019 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
7020
7021 /* Controls for GPIO pins, assuming they are configured as outputs */
7022 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
7023 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
7024 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
7025 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
7026
7027 /* Switches to allow the digital IO pins to be enabled. The datasheet
7028 * is ambigious as to which NID is which; testing on laptops which
7029 * make this output available should provide clarification.
7030 */
7031 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
7032 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
7033
7034 /* A switch allowing EAPD to be enabled. Some laptops seem to use
7035 * this output to turn on an external amplifier.
7036 */
7037 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
7038 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
7039
7040 { } /* end */
7041 };
7042 static const struct hda_verb alc260_test_init_verbs[] = {
7043 /* Enable all GPIOs as outputs with an initial value of 0 */
7044 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
7045 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
7046 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
7047
7048 /* Enable retasking pins as output, initially without power amp */
7049 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7050 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7051 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7052 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7053 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7054 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7055
7056 /* Disable digital (SPDIF) pins initially, but users can enable
7057 * them via a mixer switch. In the case of SPDIF-out, this initverb
7058 * payload also sets the generation to 0, output to be in "consumer"
7059 * PCM format, copyright asserted, no pre-emphasis and no validity
7060 * control.
7061 */
7062 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
7063 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
7064
7065 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
7066 * OUT1 sum bus when acting as an output.
7067 */
7068 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
7069 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
7070 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
7071 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
7072
7073 /* Start with output sum widgets muted and their output gains at min */
7074 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7075 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7076 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7077 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7078 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7079 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7080 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7081 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7082 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7083
7084 /* Unmute retasking pin widget output buffers since the default
7085 * state appears to be output. As the pin mode is changed by the
7086 * user the pin mode control will take care of enabling the pin's
7087 * input/output buffers as needed.
7088 */
7089 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7090 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7091 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7092 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7093 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7094 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7095 /* Also unmute the mono-out pin widget */
7096 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7097
7098 /* Mute capture amp left and right */
7099 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7100 /* Set ADC connection select to match default mixer setting (mic1
7101 * pin)
7102 */
7103 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7104
7105 /* Do the same for the second ADC: mute capture input amp and
7106 * set ADC connection to mic1 pin
7107 */
7108 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7109 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7110
7111 /* Mute all inputs to mixer widget (even unconnected ones) */
7112 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
7113 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
7114 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
7115 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
7116 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
7117 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
7118 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
7119 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
7120
7121 { }
7122 };
7123 #endif
7124
7125 #define alc260_pcm_analog_playback alc880_pcm_analog_alt_playback
7126 #define alc260_pcm_analog_capture alc880_pcm_analog_capture
7127
7128 #define alc260_pcm_digital_playback alc880_pcm_digital_playback
7129 #define alc260_pcm_digital_capture alc880_pcm_digital_capture
7130
7131 /*
7132 * for BIOS auto-configuration
7133 */
7134
7135 static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid,
7136 const char *pfx, int *vol_bits)
7137 {
7138 hda_nid_t nid_vol;
7139 unsigned long vol_val, sw_val;
7140 int err;
7141
7142 if (nid >= 0x0f && nid < 0x11) {
7143 nid_vol = nid - 0x7;
7144 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7145 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7146 } else if (nid == 0x11) {
7147 nid_vol = nid - 0x7;
7148 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, HDA_OUTPUT);
7149 sw_val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
7150 } else if (nid >= 0x12 && nid <= 0x15) {
7151 nid_vol = 0x08;
7152 vol_val = HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, HDA_OUTPUT);
7153 sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
7154 } else
7155 return 0; /* N/A */
7156
7157 if (!(*vol_bits & (1 << nid_vol))) {
7158 /* first control for the volume widget */
7159 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, vol_val);
7160 if (err < 0)
7161 return err;
7162 *vol_bits |= (1 << nid_vol);
7163 }
7164 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, sw_val);
7165 if (err < 0)
7166 return err;
7167 return 1;
7168 }
7169
7170 /* add playback controls from the parsed DAC table */
7171 static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec,
7172 const struct auto_pin_cfg *cfg)
7173 {
7174 hda_nid_t nid;
7175 int err;
7176 int vols = 0;
7177
7178 spec->multiout.num_dacs = 1;
7179 spec->multiout.dac_nids = spec->private_dac_nids;
7180 spec->private_dac_nids[0] = 0x02;
7181
7182 nid = cfg->line_out_pins[0];
7183 if (nid) {
7184 const char *pfx;
7185 if (!cfg->speaker_pins[0] && !cfg->hp_pins[0])
7186 pfx = "Master";
7187 else if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
7188 pfx = "Speaker";
7189 else
7190 pfx = "Front";
7191 err = alc260_add_playback_controls(spec, nid, pfx, &vols);
7192 if (err < 0)
7193 return err;
7194 }
7195
7196 nid = cfg->speaker_pins[0];
7197 if (nid) {
7198 err = alc260_add_playback_controls(spec, nid, "Speaker", &vols);
7199 if (err < 0)
7200 return err;
7201 }
7202
7203 nid = cfg->hp_pins[0];
7204 if (nid) {
7205 err = alc260_add_playback_controls(spec, nid, "Headphone",
7206 &vols);
7207 if (err < 0)
7208 return err;
7209 }
7210 return 0;
7211 }
7212
7213 /* create playback/capture controls for input pins */
7214 static int alc260_auto_create_input_ctls(struct hda_codec *codec,
7215 const struct auto_pin_cfg *cfg)
7216 {
7217 return alc_auto_create_input_ctls(codec, cfg, 0x07, 0x04, 0x05);
7218 }
7219
7220 static void alc260_auto_set_output_and_unmute(struct hda_codec *codec,
7221 hda_nid_t nid, int pin_type,
7222 int sel_idx)
7223 {
7224 alc_set_pin_output(codec, nid, pin_type);
7225 /* need the manual connection? */
7226 if (nid >= 0x12) {
7227 int idx = nid - 0x12;
7228 snd_hda_codec_write(codec, idx + 0x0b, 0,
7229 AC_VERB_SET_CONNECT_SEL, sel_idx);
7230 }
7231 }
7232
7233 static void alc260_auto_init_multi_out(struct hda_codec *codec)
7234 {
7235 struct alc_spec *spec = codec->spec;
7236 hda_nid_t nid;
7237
7238 nid = spec->autocfg.line_out_pins[0];
7239 if (nid) {
7240 int pin_type = get_pin_type(spec->autocfg.line_out_type);
7241 alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0);
7242 }
7243
7244 nid = spec->autocfg.speaker_pins[0];
7245 if (nid)
7246 alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0);
7247
7248 nid = spec->autocfg.hp_pins[0];
7249 if (nid)
7250 alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0);
7251 }
7252
7253 #define ALC260_PIN_CD_NID 0x16
7254 static void alc260_auto_init_analog_input(struct hda_codec *codec)
7255 {
7256 struct alc_spec *spec = codec->spec;
7257 struct auto_pin_cfg *cfg = &spec->autocfg;
7258 int i;
7259
7260 for (i = 0; i < cfg->num_inputs; i++) {
7261 hda_nid_t nid = cfg->inputs[i].pin;
7262 if (nid >= 0x12) {
7263 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
7264 if (nid != ALC260_PIN_CD_NID &&
7265 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
7266 snd_hda_codec_write(codec, nid, 0,
7267 AC_VERB_SET_AMP_GAIN_MUTE,
7268 AMP_OUT_MUTE);
7269 }
7270 }
7271 }
7272
7273 #define alc260_auto_init_input_src alc880_auto_init_input_src
7274
7275 /*
7276 * generic initialization of ADC, input mixers and output mixers
7277 */
7278 static const struct hda_verb alc260_volume_init_verbs[] = {
7279 /*
7280 * Unmute ADC0-1 and set the default input to mic-in
7281 */
7282 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7283 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7284 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7285 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7286
7287 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
7288 * mixer widget
7289 * Note: PASD motherboards uses the Line In 2 as the input for
7290 * front panel mic (mic 2)
7291 */
7292 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
7293 /* mute analog inputs */
7294 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7295 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7296 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
7297 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
7298 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
7299
7300 /*
7301 * Set up output mixers (0x08 - 0x0a)
7302 */
7303 /* set vol=0 to output mixers */
7304 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7305 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7306 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7307 /* set up input amps for analog loopback */
7308 /* Amp Indices: DAC = 0, mixer = 1 */
7309 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7310 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7311 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7312 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7313 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7314 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7315
7316 { }
7317 };
7318
7319 static int alc260_parse_auto_config(struct hda_codec *codec)
7320 {
7321 struct alc_spec *spec = codec->spec;
7322 int err;
7323 static const hda_nid_t alc260_ignore[] = { 0x17, 0 };
7324
7325 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
7326 alc260_ignore);
7327 if (err < 0)
7328 return err;
7329 err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
7330 if (err < 0)
7331 return err;
7332 if (!spec->kctls.list)
7333 return 0; /* can't find valid BIOS pin config */
7334 err = alc260_auto_create_input_ctls(codec, &spec->autocfg);
7335 if (err < 0)
7336 return err;
7337
7338 spec->multiout.max_channels = 2;
7339
7340 if (spec->autocfg.dig_outs)
7341 spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
7342 if (spec->kctls.list)
7343 add_mixer(spec, spec->kctls.list);
7344
7345 add_verb(spec, alc260_volume_init_verbs);
7346
7347 spec->num_mux_defs = 1;
7348 spec->input_mux = &spec->private_imux[0];
7349
7350 alc_ssid_check(codec, 0x10, 0x15, 0x0f, 0);
7351
7352 return 1;
7353 }
7354
7355 /* additional initialization for auto-configuration model */
7356 static void alc260_auto_init(struct hda_codec *codec)
7357 {
7358 struct alc_spec *spec = codec->spec;
7359 alc260_auto_init_multi_out(codec);
7360 alc260_auto_init_analog_input(codec);
7361 alc260_auto_init_input_src(codec);
7362 alc_auto_init_digital(codec);
7363 if (spec->unsol_event)
7364 alc_inithook(codec);
7365 }
7366
7367 #ifdef CONFIG_SND_HDA_POWER_SAVE
7368 static const struct hda_amp_list alc260_loopbacks[] = {
7369 { 0x07, HDA_INPUT, 0 },
7370 { 0x07, HDA_INPUT, 1 },
7371 { 0x07, HDA_INPUT, 2 },
7372 { 0x07, HDA_INPUT, 3 },
7373 { 0x07, HDA_INPUT, 4 },
7374 { } /* end */
7375 };
7376 #endif
7377
7378 /*
7379 * Pin config fixes
7380 */
7381 enum {
7382 PINFIX_HP_DC5750,
7383 };
7384
7385 static const struct alc_fixup alc260_fixups[] = {
7386 [PINFIX_HP_DC5750] = {
7387 .type = ALC_FIXUP_PINS,
7388 .v.pins = (const struct alc_pincfg[]) {
7389 { 0x11, 0x90130110 }, /* speaker */
7390 { }
7391 }
7392 },
7393 };
7394
7395 static const struct snd_pci_quirk alc260_fixup_tbl[] = {
7396 SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750),
7397 {}
7398 };
7399
7400 /*
7401 * ALC260 configurations
7402 */
7403 static const char * const alc260_models[ALC260_MODEL_LAST] = {
7404 [ALC260_BASIC] = "basic",
7405 [ALC260_HP] = "hp",
7406 [ALC260_HP_3013] = "hp-3013",
7407 [ALC260_HP_DC7600] = "hp-dc7600",
7408 [ALC260_FUJITSU_S702X] = "fujitsu",
7409 [ALC260_ACER] = "acer",
7410 [ALC260_WILL] = "will",
7411 [ALC260_REPLACER_672V] = "replacer",
7412 [ALC260_FAVORIT100] = "favorit100",
7413 #ifdef CONFIG_SND_DEBUG
7414 [ALC260_TEST] = "test",
7415 #endif
7416 [ALC260_AUTO] = "auto",
7417 };
7418
7419 static const struct snd_pci_quirk alc260_cfg_tbl[] = {
7420 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
7421 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
7422 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
7423 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
7424 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
7425 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
7426 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
7427 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
7428 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
7429 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7430 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7431 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7432 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7433 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7434 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7435 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7436 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7437 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
7438 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
7439 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
7440 {}
7441 };
7442
7443 static const struct alc_config_preset alc260_presets[] = {
7444 [ALC260_BASIC] = {
7445 .mixers = { alc260_base_output_mixer,
7446 alc260_input_mixer },
7447 .init_verbs = { alc260_init_verbs },
7448 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7449 .dac_nids = alc260_dac_nids,
7450 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7451 .adc_nids = alc260_dual_adc_nids,
7452 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7453 .channel_mode = alc260_modes,
7454 .input_mux = &alc260_capture_source,
7455 },
7456 [ALC260_HP] = {
7457 .mixers = { alc260_hp_output_mixer,
7458 alc260_input_mixer },
7459 .init_verbs = { alc260_init_verbs,
7460 alc260_hp_unsol_verbs },
7461 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7462 .dac_nids = alc260_dac_nids,
7463 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7464 .adc_nids = alc260_adc_nids_alt,
7465 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7466 .channel_mode = alc260_modes,
7467 .input_mux = &alc260_capture_source,
7468 .unsol_event = alc_sku_unsol_event,
7469 .setup = alc260_hp_setup,
7470 .init_hook = alc_inithook,
7471 },
7472 [ALC260_HP_DC7600] = {
7473 .mixers = { alc260_hp_dc7600_mixer,
7474 alc260_input_mixer },
7475 .init_verbs = { alc260_init_verbs,
7476 alc260_hp_dc7600_verbs },
7477 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7478 .dac_nids = alc260_dac_nids,
7479 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7480 .adc_nids = alc260_adc_nids_alt,
7481 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7482 .channel_mode = alc260_modes,
7483 .input_mux = &alc260_capture_source,
7484 .unsol_event = alc_sku_unsol_event,
7485 .setup = alc260_hp_3012_setup,
7486 .init_hook = alc_inithook,
7487 },
7488 [ALC260_HP_3013] = {
7489 .mixers = { alc260_hp_3013_mixer,
7490 alc260_input_mixer },
7491 .init_verbs = { alc260_hp_3013_init_verbs,
7492 alc260_hp_3013_unsol_verbs },
7493 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7494 .dac_nids = alc260_dac_nids,
7495 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7496 .adc_nids = alc260_adc_nids_alt,
7497 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7498 .channel_mode = alc260_modes,
7499 .input_mux = &alc260_capture_source,
7500 .unsol_event = alc_sku_unsol_event,
7501 .setup = alc260_hp_3013_setup,
7502 .init_hook = alc_inithook,
7503 },
7504 [ALC260_FUJITSU_S702X] = {
7505 .mixers = { alc260_fujitsu_mixer },
7506 .init_verbs = { alc260_fujitsu_init_verbs },
7507 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7508 .dac_nids = alc260_dac_nids,
7509 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7510 .adc_nids = alc260_dual_adc_nids,
7511 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7512 .channel_mode = alc260_modes,
7513 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7514 .input_mux = alc260_fujitsu_capture_sources,
7515 },
7516 [ALC260_ACER] = {
7517 .mixers = { alc260_acer_mixer },
7518 .init_verbs = { alc260_acer_init_verbs },
7519 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7520 .dac_nids = alc260_dac_nids,
7521 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7522 .adc_nids = alc260_dual_adc_nids,
7523 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7524 .channel_mode = alc260_modes,
7525 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7526 .input_mux = alc260_acer_capture_sources,
7527 },
7528 [ALC260_FAVORIT100] = {
7529 .mixers = { alc260_favorit100_mixer },
7530 .init_verbs = { alc260_favorit100_init_verbs },
7531 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7532 .dac_nids = alc260_dac_nids,
7533 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7534 .adc_nids = alc260_dual_adc_nids,
7535 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7536 .channel_mode = alc260_modes,
7537 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7538 .input_mux = alc260_favorit100_capture_sources,
7539 },
7540 [ALC260_WILL] = {
7541 .mixers = { alc260_will_mixer },
7542 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7543 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7544 .dac_nids = alc260_dac_nids,
7545 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7546 .adc_nids = alc260_adc_nids,
7547 .dig_out_nid = ALC260_DIGOUT_NID,
7548 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7549 .channel_mode = alc260_modes,
7550 .input_mux = &alc260_capture_source,
7551 },
7552 [ALC260_REPLACER_672V] = {
7553 .mixers = { alc260_replacer_672v_mixer },
7554 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7555 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7556 .dac_nids = alc260_dac_nids,
7557 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7558 .adc_nids = alc260_adc_nids,
7559 .dig_out_nid = ALC260_DIGOUT_NID,
7560 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7561 .channel_mode = alc260_modes,
7562 .input_mux = &alc260_capture_source,
7563 .unsol_event = alc260_replacer_672v_unsol_event,
7564 .init_hook = alc260_replacer_672v_automute,
7565 },
7566 #ifdef CONFIG_SND_DEBUG
7567 [ALC260_TEST] = {
7568 .mixers = { alc260_test_mixer },
7569 .init_verbs = { alc260_test_init_verbs },
7570 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7571 .dac_nids = alc260_test_dac_nids,
7572 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7573 .adc_nids = alc260_test_adc_nids,
7574 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7575 .channel_mode = alc260_modes,
7576 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7577 .input_mux = alc260_test_capture_sources,
7578 },
7579 #endif
7580 };
7581
7582 static int patch_alc260(struct hda_codec *codec)
7583 {
7584 struct alc_spec *spec;
7585 int err, board_config;
7586
7587 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
7588 if (spec == NULL)
7589 return -ENOMEM;
7590
7591 codec->spec = spec;
7592
7593 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST,
7594 alc260_models,
7595 alc260_cfg_tbl);
7596 if (board_config < 0) {
7597 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
7598 codec->chip_name);
7599 board_config = ALC260_AUTO;
7600 }
7601
7602 if (board_config == ALC260_AUTO) {
7603 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7604 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7605 }
7606
7607 if (board_config == ALC260_AUTO) {
7608 /* automatic parse from the BIOS config */
7609 err = alc260_parse_auto_config(codec);
7610 if (err < 0) {
7611 alc_free(codec);
7612 return err;
7613 } else if (!err) {
7614 printk(KERN_INFO
7615 "hda_codec: Cannot set up configuration "
7616 "from BIOS. Using base mode...\n");
7617 board_config = ALC260_BASIC;
7618 }
7619 }
7620
7621 err = snd_hda_attach_beep_device(codec, 0x1);
7622 if (err < 0) {
7623 alc_free(codec);
7624 return err;
7625 }
7626
7627 if (board_config != ALC260_AUTO)
7628 setup_preset(codec, &alc260_presets[board_config]);
7629
7630 spec->stream_analog_playback = &alc260_pcm_analog_playback;
7631 spec->stream_analog_capture = &alc260_pcm_analog_capture;
7632 spec->stream_analog_alt_capture = &alc260_pcm_analog_capture;
7633
7634 spec->stream_digital_playback = &alc260_pcm_digital_playback;
7635 spec->stream_digital_capture = &alc260_pcm_digital_capture;
7636
7637 if (!spec->adc_nids && spec->input_mux) {
7638 /* check whether NID 0x04 is valid */
7639 unsigned int wcap = get_wcaps(codec, 0x04);
7640 wcap = get_wcaps_type(wcap);
7641 /* get type */
7642 if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
7643 spec->adc_nids = alc260_adc_nids_alt;
7644 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt);
7645 } else {
7646 spec->adc_nids = alc260_adc_nids;
7647 spec->num_adc_nids = ARRAY_SIZE(alc260_adc_nids);
7648 }
7649 }
7650 set_capture_mixer(codec);
7651 set_beep_amp(spec, 0x07, 0x05, HDA_INPUT);
7652
7653 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
7654
7655 spec->vmaster_nid = 0x08;
7656
7657 codec->patch_ops = alc_patch_ops;
7658 if (board_config == ALC260_AUTO)
7659 spec->init_hook = alc260_auto_init;
7660 spec->shutup = alc_eapd_shutup;
7661 #ifdef CONFIG_SND_HDA_POWER_SAVE
7662 if (!spec->loopback.amplist)
7663 spec->loopback.amplist = alc260_loopbacks;
7664 #endif
7665
7666 return 0;
7667 }
7668
7669
7670 /*
7671 * ALC882/883/885/888/889 support
7672 *
7673 * ALC882 is almost identical with ALC880 but has cleaner and more flexible
7674 * configuration. Each pin widget can choose any input DACs and a mixer.
7675 * Each ADC is connected from a mixer of all inputs. This makes possible
7676 * 6-channel independent captures.
7677 *
7678 * In addition, an independent DAC for the multi-playback (not used in this
7679 * driver yet).
7680 */
7681 #define ALC882_DIGOUT_NID 0x06
7682 #define ALC882_DIGIN_NID 0x0a
7683 #define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7684 #define ALC883_DIGIN_NID ALC882_DIGIN_NID
7685 #define ALC1200_DIGOUT_NID 0x10
7686
7687
7688 static const struct hda_channel_mode alc882_ch_modes[1] = {
7689 { 8, NULL }
7690 };
7691
7692 /* DACs */
7693 static const hda_nid_t alc882_dac_nids[4] = {
7694 /* front, rear, clfe, rear_surr */
7695 0x02, 0x03, 0x04, 0x05
7696 };
7697 #define alc883_dac_nids alc882_dac_nids
7698
7699 /* ADCs */
7700 #define alc882_adc_nids alc880_adc_nids
7701 #define alc882_adc_nids_alt alc880_adc_nids_alt
7702 #define alc883_adc_nids alc882_adc_nids_alt
7703 static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7704 static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7705 #define alc889_adc_nids alc880_adc_nids
7706
7707 static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7708 static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
7709 #define alc883_capsrc_nids alc882_capsrc_nids_alt
7710 static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7711 #define alc889_capsrc_nids alc882_capsrc_nids
7712
7713 /* input MUX */
7714 /* FIXME: should be a matrix-type input source selection */
7715
7716 static const struct hda_input_mux alc882_capture_source = {
7717 .num_items = 4,
7718 .items = {
7719 { "Mic", 0x0 },
7720 { "Front Mic", 0x1 },
7721 { "Line", 0x2 },
7722 { "CD", 0x4 },
7723 },
7724 };
7725
7726 #define alc883_capture_source alc882_capture_source
7727
7728 static const struct hda_input_mux alc889_capture_source = {
7729 .num_items = 3,
7730 .items = {
7731 { "Front Mic", 0x0 },
7732 { "Mic", 0x3 },
7733 { "Line", 0x2 },
7734 },
7735 };
7736
7737 static const struct hda_input_mux mb5_capture_source = {
7738 .num_items = 3,
7739 .items = {
7740 { "Mic", 0x1 },
7741 { "Line", 0x7 },
7742 { "CD", 0x4 },
7743 },
7744 };
7745
7746 static const struct hda_input_mux macmini3_capture_source = {
7747 .num_items = 2,
7748 .items = {
7749 { "Line", 0x2 },
7750 { "CD", 0x4 },
7751 },
7752 };
7753
7754 static const struct hda_input_mux alc883_3stack_6ch_intel = {
7755 .num_items = 4,
7756 .items = {
7757 { "Mic", 0x1 },
7758 { "Front Mic", 0x0 },
7759 { "Line", 0x2 },
7760 { "CD", 0x4 },
7761 },
7762 };
7763
7764 static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
7765 .num_items = 2,
7766 .items = {
7767 { "Mic", 0x1 },
7768 { "Line", 0x2 },
7769 },
7770 };
7771
7772 static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7773 .num_items = 4,
7774 .items = {
7775 { "Mic", 0x0 },
7776 { "Internal Mic", 0x1 },
7777 { "Line", 0x2 },
7778 { "CD", 0x4 },
7779 },
7780 };
7781
7782 static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7783 .num_items = 2,
7784 .items = {
7785 { "Mic", 0x0 },
7786 { "Internal Mic", 0x1 },
7787 },
7788 };
7789
7790 static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
7791 .num_items = 3,
7792 .items = {
7793 { "Mic", 0x0 },
7794 { "Front Mic", 0x1 },
7795 { "Line", 0x4 },
7796 },
7797 };
7798
7799 static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
7800 .num_items = 2,
7801 .items = {
7802 { "Mic", 0x0 },
7803 { "Line", 0x2 },
7804 },
7805 };
7806
7807 static const struct hda_input_mux alc889A_mb31_capture_source = {
7808 .num_items = 2,
7809 .items = {
7810 { "Mic", 0x0 },
7811 /* Front Mic (0x01) unused */
7812 { "Line", 0x2 },
7813 /* Line 2 (0x03) unused */
7814 /* CD (0x04) unused? */
7815 },
7816 };
7817
7818 static const struct hda_input_mux alc889A_imac91_capture_source = {
7819 .num_items = 2,
7820 .items = {
7821 { "Mic", 0x01 },
7822 { "Line", 0x2 }, /* Not sure! */
7823 },
7824 };
7825
7826 /*
7827 * 2ch mode
7828 */
7829 static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7830 { 2, NULL }
7831 };
7832
7833 /*
7834 * 2ch mode
7835 */
7836 static const struct hda_verb alc882_3ST_ch2_init[] = {
7837 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7838 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7839 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7840 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7841 { } /* end */
7842 };
7843
7844 /*
7845 * 4ch mode
7846 */
7847 static const struct hda_verb alc882_3ST_ch4_init[] = {
7848 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7849 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7850 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7851 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7852 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7853 { } /* end */
7854 };
7855
7856 /*
7857 * 6ch mode
7858 */
7859 static const struct hda_verb alc882_3ST_ch6_init[] = {
7860 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7861 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7862 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7863 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7864 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7865 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7866 { } /* end */
7867 };
7868
7869 static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7870 { 2, alc882_3ST_ch2_init },
7871 { 4, alc882_3ST_ch4_init },
7872 { 6, alc882_3ST_ch6_init },
7873 };
7874
7875 #define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7876
7877 /*
7878 * 2ch mode
7879 */
7880 static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7881 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7882 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7883 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7884 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7885 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7886 { } /* end */
7887 };
7888
7889 /*
7890 * 4ch mode
7891 */
7892 static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7893 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7894 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7895 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7896 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7897 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7898 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7899 { } /* end */
7900 };
7901
7902 /*
7903 * 6ch mode
7904 */
7905 static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7906 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7907 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7908 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7909 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7910 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7911 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7912 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7913 { } /* end */
7914 };
7915
7916 static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7917 { 2, alc883_3ST_ch2_clevo_init },
7918 { 4, alc883_3ST_ch4_clevo_init },
7919 { 6, alc883_3ST_ch6_clevo_init },
7920 };
7921
7922
7923 /*
7924 * 6ch mode
7925 */
7926 static const struct hda_verb alc882_sixstack_ch6_init[] = {
7927 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7928 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7929 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7930 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7931 { } /* end */
7932 };
7933
7934 /*
7935 * 8ch mode
7936 */
7937 static const struct hda_verb alc882_sixstack_ch8_init[] = {
7938 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7939 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7940 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7941 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7942 { } /* end */
7943 };
7944
7945 static const struct hda_channel_mode alc882_sixstack_modes[2] = {
7946 { 6, alc882_sixstack_ch6_init },
7947 { 8, alc882_sixstack_ch8_init },
7948 };
7949
7950
7951 /* Macbook Air 2,1 */
7952
7953 static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7954 { 2, NULL },
7955 };
7956
7957 /*
7958 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
7959 */
7960
7961 /*
7962 * 2ch mode
7963 */
7964 static const struct hda_verb alc885_mbp_ch2_init[] = {
7965 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7966 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7967 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7968 { } /* end */
7969 };
7970
7971 /*
7972 * 4ch mode
7973 */
7974 static const struct hda_verb alc885_mbp_ch4_init[] = {
7975 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7976 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7977 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7978 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7979 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7980 { } /* end */
7981 };
7982
7983 static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
7984 { 2, alc885_mbp_ch2_init },
7985 { 4, alc885_mbp_ch4_init },
7986 };
7987
7988 /*
7989 * 2ch
7990 * Speakers/Woofer/HP = Front
7991 * LineIn = Input
7992 */
7993 static const struct hda_verb alc885_mb5_ch2_init[] = {
7994 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7995 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7996 { } /* end */
7997 };
7998
7999 /*
8000 * 6ch mode
8001 * Speakers/HP = Front
8002 * Woofer = LFE
8003 * LineIn = Surround
8004 */
8005 static const struct hda_verb alc885_mb5_ch6_init[] = {
8006 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8007 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8008 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8009 { } /* end */
8010 };
8011
8012 static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
8013 { 2, alc885_mb5_ch2_init },
8014 { 6, alc885_mb5_ch6_init },
8015 };
8016
8017 #define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
8018
8019 /*
8020 * 2ch mode
8021 */
8022 static const struct hda_verb alc883_4ST_ch2_init[] = {
8023 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8024 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8025 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8026 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8027 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8028 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8029 { } /* end */
8030 };
8031
8032 /*
8033 * 4ch mode
8034 */
8035 static const struct hda_verb alc883_4ST_ch4_init[] = {
8036 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8037 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8038 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8039 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8040 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8041 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8042 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8043 { } /* end */
8044 };
8045
8046 /*
8047 * 6ch mode
8048 */
8049 static const struct hda_verb alc883_4ST_ch6_init[] = {
8050 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8051 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8052 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8053 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8054 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8055 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8056 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8057 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8058 { } /* end */
8059 };
8060
8061 /*
8062 * 8ch mode
8063 */
8064 static const struct hda_verb alc883_4ST_ch8_init[] = {
8065 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8066 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8067 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8068 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8069 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8070 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
8071 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8072 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8073 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8074 { } /* end */
8075 };
8076
8077 static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
8078 { 2, alc883_4ST_ch2_init },
8079 { 4, alc883_4ST_ch4_init },
8080 { 6, alc883_4ST_ch6_init },
8081 { 8, alc883_4ST_ch8_init },
8082 };
8083
8084
8085 /*
8086 * 2ch mode
8087 */
8088 static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
8089 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8090 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8091 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8092 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8093 { } /* end */
8094 };
8095
8096 /*
8097 * 4ch mode
8098 */
8099 static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
8100 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
8101 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8102 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8103 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8104 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8105 { } /* end */
8106 };
8107
8108 /*
8109 * 6ch mode
8110 */
8111 static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
8112 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8113 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8114 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
8115 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8116 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8117 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
8118 { } /* end */
8119 };
8120
8121 static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
8122 { 2, alc883_3ST_ch2_intel_init },
8123 { 4, alc883_3ST_ch4_intel_init },
8124 { 6, alc883_3ST_ch6_intel_init },
8125 };
8126
8127 /*
8128 * 2ch mode
8129 */
8130 static const struct hda_verb alc889_ch2_intel_init[] = {
8131 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8132 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
8133 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
8134 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
8135 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8136 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8137 { } /* end */
8138 };
8139
8140 /*
8141 * 6ch mode
8142 */
8143 static const struct hda_verb alc889_ch6_intel_init[] = {
8144 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8145 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8146 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8147 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8148 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
8149 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
8150 { } /* end */
8151 };
8152
8153 /*
8154 * 8ch mode
8155 */
8156 static const struct hda_verb alc889_ch8_intel_init[] = {
8157 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8158 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8159 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8160 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8161 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
8162 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8163 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8164 { } /* end */
8165 };
8166
8167 static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
8168 { 2, alc889_ch2_intel_init },
8169 { 6, alc889_ch6_intel_init },
8170 { 8, alc889_ch8_intel_init },
8171 };
8172
8173 /*
8174 * 6ch mode
8175 */
8176 static const struct hda_verb alc883_sixstack_ch6_init[] = {
8177 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8178 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8179 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8180 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8181 { } /* end */
8182 };
8183
8184 /*
8185 * 8ch mode
8186 */
8187 static const struct hda_verb alc883_sixstack_ch8_init[] = {
8188 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8189 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8190 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8191 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8192 { } /* end */
8193 };
8194
8195 static const struct hda_channel_mode alc883_sixstack_modes[2] = {
8196 { 6, alc883_sixstack_ch6_init },
8197 { 8, alc883_sixstack_ch8_init },
8198 };
8199
8200
8201 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8202 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8203 */
8204 static const struct snd_kcontrol_new alc882_base_mixer[] = {
8205 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8206 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8207 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8208 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8209 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8210 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8211 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8212 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8213 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8214 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8215 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8216 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8217 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8218 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8219 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8220 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8221 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8222 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8223 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8224 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8225 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8226 { } /* end */
8227 };
8228
8229 /* Macbook Air 2,1 same control for HP and internal Speaker */
8230
8231 static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
8232 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8233 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8234 { }
8235 };
8236
8237
8238 static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
8239 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8240 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8241 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8242 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8243 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8244 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8245 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8246 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8247 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8248 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8249 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
8250 { } /* end */
8251 };
8252
8253 static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
8254 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8255 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8256 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8257 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8258 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8259 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8260 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8261 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8262 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8263 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8264 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8265 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8266 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8267 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
8268 { } /* end */
8269 };
8270
8271 static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
8272 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8273 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8274 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8275 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8276 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8277 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8278 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8279 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8280 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8281 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8282 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8283 { } /* end */
8284 };
8285
8286 static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
8287 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8288 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8289 { } /* end */
8290 };
8291
8292
8293 static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8294 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8295 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8296 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8297 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8298 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8299 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8300 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8301 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8302 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8303 { } /* end */
8304 };
8305
8306 static const struct snd_kcontrol_new alc882_targa_mixer[] = {
8307 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8308 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8309 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8310 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8311 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8312 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8313 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8314 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8315 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8316 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8317 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8318 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8319 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8320 { } /* end */
8321 };
8322
8323 /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8324 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8325 */
8326 static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8327 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8328 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8329 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8330 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8331 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8332 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8333 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8334 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8335 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8336 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8337 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8338 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8339 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8340 { } /* end */
8341 };
8342
8343 static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8344 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8345 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8346 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8347 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8348 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8349 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8350 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8351 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8352 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8353 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8354 { } /* end */
8355 };
8356
8357 static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
8358 {
8359 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8360 .name = "Channel Mode",
8361 .info = alc_ch_mode_info,
8362 .get = alc_ch_mode_get,
8363 .put = alc_ch_mode_put,
8364 },
8365 { } /* end */
8366 };
8367
8368 static const struct hda_verb alc882_base_init_verbs[] = {
8369 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8370 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8371 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8372 /* Rear mixer */
8373 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8374 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8375 /* CLFE mixer */
8376 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8377 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8378 /* Side mixer */
8379 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8380 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8381
8382 /* Front Pin: output 0 (0x0c) */
8383 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8384 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8385 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8386 /* Rear Pin: output 1 (0x0d) */
8387 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8388 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8389 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8390 /* CLFE Pin: output 2 (0x0e) */
8391 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8392 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8393 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8394 /* Side Pin: output 3 (0x0f) */
8395 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8396 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8397 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8398 /* Mic (rear) pin: input vref at 80% */
8399 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8400 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8401 /* Front Mic pin: input vref at 80% */
8402 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8403 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8404 /* Line In pin: input */
8405 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8406 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8407 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8408 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8409 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8410 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8411 /* CD pin widget for input */
8412 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8413
8414 /* FIXME: use matrix-type input source selection */
8415 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8416 /* Input mixer2 */
8417 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8418 /* Input mixer3 */
8419 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8420 /* ADC2: mute amp left and right */
8421 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8422 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8423 /* ADC3: mute amp left and right */
8424 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8425 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8426
8427 { }
8428 };
8429
8430 static const struct hda_verb alc882_adc1_init_verbs[] = {
8431 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8432 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8433 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8434 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8435 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8436 /* ADC1: mute amp left and right */
8437 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8438 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8439 { }
8440 };
8441
8442 static const struct hda_verb alc882_eapd_verbs[] = {
8443 /* change to EAPD mode */
8444 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8445 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
8446 { }
8447 };
8448
8449 static const struct hda_verb alc889_eapd_verbs[] = {
8450 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8451 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8452 { }
8453 };
8454
8455 static const struct hda_verb alc_hp15_unsol_verbs[] = {
8456 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8457 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8458 {}
8459 };
8460
8461 static const struct hda_verb alc885_init_verbs[] = {
8462 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8463 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8464 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8465 /* Rear mixer */
8466 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8467 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8468 /* CLFE mixer */
8469 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8470 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8471 /* Side mixer */
8472 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8473 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8474
8475 /* Front HP Pin: output 0 (0x0c) */
8476 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8477 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8478 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8479 /* Front Pin: output 0 (0x0c) */
8480 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8481 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8482 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8483 /* Rear Pin: output 1 (0x0d) */
8484 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8485 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8486 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8487 /* CLFE Pin: output 2 (0x0e) */
8488 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8489 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8490 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8491 /* Side Pin: output 3 (0x0f) */
8492 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8493 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8494 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8495 /* Mic (rear) pin: input vref at 80% */
8496 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8497 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8498 /* Front Mic pin: input vref at 80% */
8499 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8500 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8501 /* Line In pin: input */
8502 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8503 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8504
8505 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8506 /* Input mixer1 */
8507 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8508 /* Input mixer2 */
8509 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8510 /* Input mixer3 */
8511 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8512 /* ADC2: mute amp left and right */
8513 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8514 /* ADC3: mute amp left and right */
8515 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8516
8517 { }
8518 };
8519
8520 static const struct hda_verb alc885_init_input_verbs[] = {
8521 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8522 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8523 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8524 { }
8525 };
8526
8527
8528 /* Unmute Selector 24h and set the default input to front mic */
8529 static const struct hda_verb alc889_init_input_verbs[] = {
8530 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8531 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8532 { }
8533 };
8534
8535
8536 #define alc883_init_verbs alc882_base_init_verbs
8537
8538 /* Mac Pro test */
8539 static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
8540 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8541 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8542 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8543 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8544 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8545 /* FIXME: this looks suspicious...
8546 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8547 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
8548 */
8549 { } /* end */
8550 };
8551
8552 static const struct hda_verb alc882_macpro_init_verbs[] = {
8553 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8554 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8555 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8556 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8557 /* Front Pin: output 0 (0x0c) */
8558 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8559 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8560 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8561 /* Front Mic pin: input vref at 80% */
8562 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8563 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8564 /* Speaker: output */
8565 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8566 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8567 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8568 /* Headphone output (output 0 - 0x0c) */
8569 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8570 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8571 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8572
8573 /* FIXME: use matrix-type input source selection */
8574 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8575 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8576 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8577 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8578 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8579 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8580 /* Input mixer2 */
8581 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8582 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8583 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8584 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8585 /* Input mixer3 */
8586 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8587 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8588 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8589 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8590 /* ADC1: mute amp left and right */
8591 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8592 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8593 /* ADC2: mute amp left and right */
8594 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8595 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8596 /* ADC3: mute amp left and right */
8597 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8598 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8599
8600 { }
8601 };
8602
8603 /* Macbook 5,1 */
8604 static const struct hda_verb alc885_mb5_init_verbs[] = {
8605 /* DACs */
8606 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8607 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8608 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8609 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8610 /* Front mixer */
8611 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8612 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8613 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8614 /* Surround mixer */
8615 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8616 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8617 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8618 /* LFE mixer */
8619 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8620 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8621 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8622 /* HP mixer */
8623 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8624 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8625 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8626 /* Front Pin (0x0c) */
8627 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8628 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8629 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8630 /* LFE Pin (0x0e) */
8631 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8632 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8633 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8634 /* HP Pin (0x0f) */
8635 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8636 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8637 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8638 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8639 /* Front Mic pin: input vref at 80% */
8640 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8641 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8642 /* Line In pin */
8643 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8644 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8645
8646 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8647 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8648 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
8649 { }
8650 };
8651
8652 /* Macmini 3,1 */
8653 static const struct hda_verb alc885_macmini3_init_verbs[] = {
8654 /* DACs */
8655 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8656 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8657 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8658 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8659 /* Front mixer */
8660 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8661 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8662 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8663 /* Surround mixer */
8664 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8665 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8666 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8667 /* LFE mixer */
8668 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8669 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8670 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8671 /* HP mixer */
8672 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8673 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8674 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8675 /* Front Pin (0x0c) */
8676 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8677 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8678 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8679 /* LFE Pin (0x0e) */
8680 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8681 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8682 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8683 /* HP Pin (0x0f) */
8684 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8685 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8686 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8687 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8688 /* Line In pin */
8689 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8690 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8691
8692 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8693 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8694 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8695 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8696 { }
8697 };
8698
8699
8700 static const struct hda_verb alc885_mba21_init_verbs[] = {
8701 /*Internal and HP Speaker Mixer*/
8702 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8703 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8704 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8705 /*Internal Speaker Pin (0x0c)*/
8706 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8707 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8708 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8709 /* HP Pin: output 0 (0x0e) */
8710 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8711 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8712 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8713 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8714 /* Line in (is hp when jack connected)*/
8715 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8716 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8717
8718 { }
8719 };
8720
8721
8722 /* Macbook Pro rev3 */
8723 static const struct hda_verb alc885_mbp3_init_verbs[] = {
8724 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8725 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8726 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8727 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8728 /* Rear mixer */
8729 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8730 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8731 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8732 /* HP mixer */
8733 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8734 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8735 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8736 /* Front Pin: output 0 (0x0c) */
8737 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8738 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8739 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8740 /* HP Pin: output 0 (0x0e) */
8741 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8742 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8743 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
8744 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8745 /* Mic (rear) pin: input vref at 80% */
8746 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8747 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8748 /* Front Mic pin: input vref at 80% */
8749 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8750 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8751 /* Line In pin: use output 1 when in LineOut mode */
8752 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8753 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8754 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8755
8756 /* FIXME: use matrix-type input source selection */
8757 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8758 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8759 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8760 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8761 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8762 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8763 /* Input mixer2 */
8764 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8765 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8766 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8767 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8768 /* Input mixer3 */
8769 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8770 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8771 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8772 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8773 /* ADC1: mute amp left and right */
8774 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8775 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8776 /* ADC2: mute amp left and right */
8777 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8778 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8779 /* ADC3: mute amp left and right */
8780 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8781 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8782
8783 { }
8784 };
8785
8786 /* iMac 9,1 */
8787 static const struct hda_verb alc885_imac91_init_verbs[] = {
8788 /* Internal Speaker Pin (0x0c) */
8789 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8790 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8791 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8792 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8793 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8794 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8795 /* HP Pin: Rear */
8796 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8797 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8798 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8799 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8800 /* Line in Rear */
8801 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8802 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8803 /* Front Mic pin: input vref at 80% */
8804 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8805 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8806 /* Rear mixer */
8807 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8808 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8809 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8810 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8811 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8812 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8813 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8814 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8815 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8816 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8817 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8818 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8819 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8820 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8821 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8822 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8823 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8824 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8825 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8826 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8827 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8828 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8829 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8830 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8831 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8832 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8833 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8834 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8835 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8836 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8837 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8838 { }
8839 };
8840
8841 /* iMac 24 mixer. */
8842 static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
8843 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8844 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8845 { } /* end */
8846 };
8847
8848 /* iMac 24 init verbs. */
8849 static const struct hda_verb alc885_imac24_init_verbs[] = {
8850 /* Internal speakers: output 0 (0x0c) */
8851 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8852 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8853 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8854 /* Internal speakers: output 0 (0x0c) */
8855 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8856 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8857 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8858 /* Headphone: output 0 (0x0c) */
8859 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8860 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8861 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8862 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8863 /* Front Mic: input vref at 80% */
8864 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8865 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8866 { }
8867 };
8868
8869 /* Toggle speaker-output according to the hp-jack state */
8870 static void alc885_imac24_setup(struct hda_codec *codec)
8871 {
8872 struct alc_spec *spec = codec->spec;
8873
8874 spec->autocfg.hp_pins[0] = 0x14;
8875 spec->autocfg.speaker_pins[0] = 0x18;
8876 spec->autocfg.speaker_pins[1] = 0x1a;
8877 spec->automute = 1;
8878 spec->automute_mode = ALC_AUTOMUTE_AMP;
8879 }
8880
8881 #define alc885_mb5_setup alc885_imac24_setup
8882 #define alc885_macmini3_setup alc885_imac24_setup
8883
8884 /* Macbook Air 2,1 */
8885 static void alc885_mba21_setup(struct hda_codec *codec)
8886 {
8887 struct alc_spec *spec = codec->spec;
8888
8889 spec->autocfg.hp_pins[0] = 0x14;
8890 spec->autocfg.speaker_pins[0] = 0x18;
8891 spec->automute = 1;
8892 spec->automute_mode = ALC_AUTOMUTE_AMP;
8893 }
8894
8895
8896
8897 static void alc885_mbp3_setup(struct hda_codec *codec)
8898 {
8899 struct alc_spec *spec = codec->spec;
8900
8901 spec->autocfg.hp_pins[0] = 0x15;
8902 spec->autocfg.speaker_pins[0] = 0x14;
8903 spec->automute = 1;
8904 spec->automute_mode = ALC_AUTOMUTE_AMP;
8905 }
8906
8907 static void alc885_imac91_setup(struct hda_codec *codec)
8908 {
8909 struct alc_spec *spec = codec->spec;
8910
8911 spec->autocfg.hp_pins[0] = 0x14;
8912 spec->autocfg.speaker_pins[0] = 0x18;
8913 spec->autocfg.speaker_pins[1] = 0x1a;
8914 spec->automute = 1;
8915 spec->automute_mode = ALC_AUTOMUTE_AMP;
8916 }
8917
8918 static const struct hda_verb alc882_targa_verbs[] = {
8919 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8920 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8921
8922 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8923 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8924
8925 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8926 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8927 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8928
8929 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8930 { } /* end */
8931 };
8932
8933 /* toggle speaker-output according to the hp-jack state */
8934 static void alc882_targa_automute(struct hda_codec *codec)
8935 {
8936 struct alc_spec *spec = codec->spec;
8937 alc_hp_automute(codec);
8938 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8939 spec->jack_present ? 1 : 3);
8940 }
8941
8942 static void alc882_targa_setup(struct hda_codec *codec)
8943 {
8944 struct alc_spec *spec = codec->spec;
8945
8946 spec->autocfg.hp_pins[0] = 0x14;
8947 spec->autocfg.speaker_pins[0] = 0x1b;
8948 spec->automute = 1;
8949 spec->automute_mode = ALC_AUTOMUTE_AMP;
8950 }
8951
8952 static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8953 {
8954 if ((res >> 26) == ALC880_HP_EVENT)
8955 alc882_targa_automute(codec);
8956 }
8957
8958 static const struct hda_verb alc882_asus_a7j_verbs[] = {
8959 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8960 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8961
8962 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8963 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8964 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8965
8966 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8967 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8968 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8969
8970 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8971 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8972 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8973 { } /* end */
8974 };
8975
8976 static const struct hda_verb alc882_asus_a7m_verbs[] = {
8977 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8978 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8979
8980 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8981 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8982 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8983
8984 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8985 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8986 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8987
8988 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8989 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8990 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8991 { } /* end */
8992 };
8993
8994 static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8995 {
8996 unsigned int gpiostate, gpiomask, gpiodir;
8997
8998 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8999 AC_VERB_GET_GPIO_DATA, 0);
9000
9001 if (!muted)
9002 gpiostate |= (1 << pin);
9003 else
9004 gpiostate &= ~(1 << pin);
9005
9006 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
9007 AC_VERB_GET_GPIO_MASK, 0);
9008 gpiomask |= (1 << pin);
9009
9010 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
9011 AC_VERB_GET_GPIO_DIRECTION, 0);
9012 gpiodir |= (1 << pin);
9013
9014
9015 snd_hda_codec_write(codec, codec->afg, 0,
9016 AC_VERB_SET_GPIO_MASK, gpiomask);
9017 snd_hda_codec_write(codec, codec->afg, 0,
9018 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
9019
9020 msleep(1);
9021
9022 snd_hda_codec_write(codec, codec->afg, 0,
9023 AC_VERB_SET_GPIO_DATA, gpiostate);
9024 }
9025
9026 /* set up GPIO at initialization */
9027 static void alc885_macpro_init_hook(struct hda_codec *codec)
9028 {
9029 alc882_gpio_mute(codec, 0, 0);
9030 alc882_gpio_mute(codec, 1, 0);
9031 }
9032
9033 /* set up GPIO and update auto-muting at initialization */
9034 static void alc885_imac24_init_hook(struct hda_codec *codec)
9035 {
9036 alc885_macpro_init_hook(codec);
9037 alc_hp_automute(codec);
9038 }
9039
9040 /*
9041 * generic initialization of ADC, input mixers and output mixers
9042 */
9043 static const struct hda_verb alc883_auto_init_verbs[] = {
9044 /*
9045 * Unmute ADC0-2 and set the default input to mic-in
9046 */
9047 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
9048 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9049 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
9050 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9051
9052 /*
9053 * Set up output mixers (0x0c - 0x0f)
9054 */
9055 /* set vol=0 to output mixers */
9056 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9057 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9058 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9059 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
9060 /* set up input amps for analog loopback */
9061 /* Amp Indices: DAC = 0, mixer = 1 */
9062 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9063 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9064 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9065 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9066 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9067 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9068 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9069 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9070 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9071 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9072
9073 /* FIXME: use matrix-type input source selection */
9074 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
9075 /* Input mixer2 */
9076 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9077 /* Input mixer3 */
9078 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9079 { }
9080 };
9081
9082 /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
9083 static const struct hda_verb alc889A_mb31_ch2_init[] = {
9084 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9085 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9086 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9087 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9088 { } /* end */
9089 };
9090
9091 /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
9092 static const struct hda_verb alc889A_mb31_ch4_init[] = {
9093 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
9094 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9095 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9096 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9097 { } /* end */
9098 };
9099
9100 /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
9101 static const struct hda_verb alc889A_mb31_ch5_init[] = {
9102 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
9103 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
9104 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
9105 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
9106 { } /* end */
9107 };
9108
9109 /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
9110 static const struct hda_verb alc889A_mb31_ch6_init[] = {
9111 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
9112 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
9113 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
9114 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
9115 { } /* end */
9116 };
9117
9118 static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
9119 { 2, alc889A_mb31_ch2_init },
9120 { 4, alc889A_mb31_ch4_init },
9121 { 5, alc889A_mb31_ch5_init },
9122 { 6, alc889A_mb31_ch6_init },
9123 };
9124
9125 static const struct hda_verb alc883_medion_eapd_verbs[] = {
9126 /* eanable EAPD on medion laptop */
9127 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9128 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
9129 { }
9130 };
9131
9132 #define alc883_base_mixer alc882_base_mixer
9133
9134 static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
9135 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9136 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9137 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9138 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9139 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9140 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9141 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9142 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9143 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9144 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9145 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9146 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9147 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9148 { } /* end */
9149 };
9150
9151 static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
9152 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9153 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9154 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9155 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9156 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9157 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9158 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9159 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9160 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9161 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9162 { } /* end */
9163 };
9164
9165 static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
9166 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9167 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
9168 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9169 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9170 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9171 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9172 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9173 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9174 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9175 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9176 { } /* end */
9177 };
9178
9179 static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
9180 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9181 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9182 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9183 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9184 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9185 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9186 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9187 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9188 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9189 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9190 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9191 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9192 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9193 { } /* end */
9194 };
9195
9196 static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
9197 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9198 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9199 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9200 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9201 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9202 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9203 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9204 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9205 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9206 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9207 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9208 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9209 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9210 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9211 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9212 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9213 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9214 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9215 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9216 { } /* end */
9217 };
9218
9219 static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
9220 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9221 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9222 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9223 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9224 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9225 HDA_OUTPUT),
9226 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9227 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9228 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9229 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9230 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9231 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9232 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9233 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9234 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9235 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9236 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9237 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9238 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9239 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9240 { } /* end */
9241 };
9242
9243 static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
9244 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9245 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9246 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9247 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9248 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9249 HDA_OUTPUT),
9250 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9251 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9252 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9253 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9254 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9255 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9256 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9257 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9258 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
9259 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
9260 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9261 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9262 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9263 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9264 { } /* end */
9265 };
9266
9267 static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
9268 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9269 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9270 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9271 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9272 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9273 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9274 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9275 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9276 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9277 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9278 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9279 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9280 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9281 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9282 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9283 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9284 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9285 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9286 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9287 { } /* end */
9288 };
9289
9290 static const struct snd_kcontrol_new alc883_targa_mixer[] = {
9291 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9292 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9293 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9294 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9295 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9296 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9297 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9298 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9299 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9300 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9301 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9302 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9303 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9304 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9305 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9306 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9307 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9308 { } /* end */
9309 };
9310
9311 static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
9312 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9313 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9314 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9315 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9316 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9317 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9318 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9319 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9320 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9321 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9322 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9323 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9324 { } /* end */
9325 };
9326
9327 static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9328 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9329 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9330 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9331 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9332 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9333 { } /* end */
9334 };
9335
9336 static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9337 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9338 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9339 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9340 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9341 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9342 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9343 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9344 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9345 { } /* end */
9346 };
9347
9348 static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9349 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9350 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9351 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9352 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9353 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9354 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9355 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9356 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9357 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9358 { } /* end */
9359 };
9360
9361 static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9362 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9363 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9364 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9365 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9366 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9367 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9368 { } /* end */
9369 };
9370
9371 static const struct hda_verb alc883_medion_wim2160_verbs[] = {
9372 /* Unmute front mixer */
9373 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9374 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9375
9376 /* Set speaker pin to front mixer */
9377 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9378
9379 /* Init headphone pin */
9380 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9381 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9382 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9383 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9384
9385 { } /* end */
9386 };
9387
9388 /* toggle speaker-output according to the hp-jack state */
9389 static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9390 {
9391 struct alc_spec *spec = codec->spec;
9392
9393 spec->autocfg.hp_pins[0] = 0x1a;
9394 spec->autocfg.speaker_pins[0] = 0x15;
9395 spec->automute = 1;
9396 spec->automute_mode = ALC_AUTOMUTE_AMP;
9397 }
9398
9399 static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
9400 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9401 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9402 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9403 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9404 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9405 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9406 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9407 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9408 { } /* end */
9409 };
9410
9411 static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9412 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9413 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9414 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9415 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9416 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9417 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9418 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9419 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9420 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9421 { } /* end */
9422 };
9423
9424 static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9425 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9426 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9427 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9428 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9429 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9430 0x0d, 1, 0x0, HDA_OUTPUT),
9431 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9432 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9433 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9434 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9435 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9436 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9437 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9438 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9439 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9440 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9441 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9442 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9443 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9444 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9445 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9446 { } /* end */
9447 };
9448
9449 static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9450 /* Output mixers */
9451 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9452 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9453 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9454 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9455 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9456 HDA_OUTPUT),
9457 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9458 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9459 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9460 /* Output switches */
9461 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9462 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9463 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9464 /* Boost mixers */
9465 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9466 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
9467 /* Input mixers */
9468 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9469 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9470 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9471 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9472 { } /* end */
9473 };
9474
9475 static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9476 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9477 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9478 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9479 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9480 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9481 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9482 { } /* end */
9483 };
9484
9485 static const struct hda_bind_ctls alc883_bind_cap_vol = {
9486 .ops = &snd_hda_bind_vol,
9487 .values = {
9488 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9489 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9490 0
9491 },
9492 };
9493
9494 static const struct hda_bind_ctls alc883_bind_cap_switch = {
9495 .ops = &snd_hda_bind_sw,
9496 .values = {
9497 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9498 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9499 0
9500 },
9501 };
9502
9503 static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9504 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9505 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9506 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9507 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9508 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9509 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9510 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9511 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9512 { } /* end */
9513 };
9514
9515 static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9516 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9517 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9518 {
9519 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9520 /* .name = "Capture Source", */
9521 .name = "Input Source",
9522 .count = 1,
9523 .info = alc_mux_enum_info,
9524 .get = alc_mux_enum_get,
9525 .put = alc_mux_enum_put,
9526 },
9527 { } /* end */
9528 };
9529
9530 static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
9531 {
9532 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9533 .name = "Channel Mode",
9534 .info = alc_ch_mode_info,
9535 .get = alc_ch_mode_get,
9536 .put = alc_ch_mode_put,
9537 },
9538 { } /* end */
9539 };
9540
9541 /* toggle speaker-output according to the hp-jack state */
9542 static void alc883_mitac_setup(struct hda_codec *codec)
9543 {
9544 struct alc_spec *spec = codec->spec;
9545
9546 spec->autocfg.hp_pins[0] = 0x15;
9547 spec->autocfg.speaker_pins[0] = 0x14;
9548 spec->autocfg.speaker_pins[1] = 0x17;
9549 spec->automute = 1;
9550 spec->automute_mode = ALC_AUTOMUTE_AMP;
9551 }
9552
9553 static const struct hda_verb alc883_mitac_verbs[] = {
9554 /* HP */
9555 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9556 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9557 /* Subwoofer */
9558 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9559 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9560
9561 /* enable unsolicited event */
9562 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9563 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9564
9565 { } /* end */
9566 };
9567
9568 static const struct hda_verb alc883_clevo_m540r_verbs[] = {
9569 /* HP */
9570 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9571 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9572 /* Int speaker */
9573 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9574
9575 /* enable unsolicited event */
9576 /*
9577 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9578 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9579 */
9580
9581 { } /* end */
9582 };
9583
9584 static const struct hda_verb alc883_clevo_m720_verbs[] = {
9585 /* HP */
9586 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9587 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9588 /* Int speaker */
9589 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9590 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9591
9592 /* enable unsolicited event */
9593 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9594 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9595
9596 { } /* end */
9597 };
9598
9599 static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9600 /* HP */
9601 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9602 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9603 /* Subwoofer */
9604 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9605 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9606
9607 /* enable unsolicited event */
9608 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9609
9610 { } /* end */
9611 };
9612
9613 static const struct hda_verb alc883_targa_verbs[] = {
9614 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9615 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9616
9617 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9618 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9619
9620 /* Connect Line-Out side jack (SPDIF) to Side */
9621 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9622 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9623 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9624 /* Connect Mic jack to CLFE */
9625 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9626 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9627 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9628 /* Connect Line-in jack to Surround */
9629 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9630 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9631 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9632 /* Connect HP out jack to Front */
9633 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9634 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9635 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9636
9637 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9638
9639 { } /* end */
9640 };
9641
9642 static const struct hda_verb alc883_lenovo_101e_verbs[] = {
9643 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9644 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9645 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9646 { } /* end */
9647 };
9648
9649 static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9650 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9651 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9652 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9653 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9654 { } /* end */
9655 };
9656
9657 static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9658 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9659 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9660 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9661 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9662 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9663 { } /* end */
9664 };
9665
9666 static const struct hda_verb alc883_haier_w66_verbs[] = {
9667 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9668 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9669
9670 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9671
9672 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9673 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9674 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9675 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9676 { } /* end */
9677 };
9678
9679 static const struct hda_verb alc888_lenovo_sky_verbs[] = {
9680 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9681 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9682 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9683 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9684 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9685 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9686 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9687 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9688 { } /* end */
9689 };
9690
9691 static const struct hda_verb alc888_6st_dell_verbs[] = {
9692 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9693 { }
9694 };
9695
9696 static const struct hda_verb alc883_vaiott_verbs[] = {
9697 /* HP */
9698 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9699 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9700
9701 /* enable unsolicited event */
9702 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9703
9704 { } /* end */
9705 };
9706
9707 static void alc888_3st_hp_setup(struct hda_codec *codec)
9708 {
9709 struct alc_spec *spec = codec->spec;
9710
9711 spec->autocfg.hp_pins[0] = 0x1b;
9712 spec->autocfg.speaker_pins[0] = 0x14;
9713 spec->autocfg.speaker_pins[1] = 0x16;
9714 spec->autocfg.speaker_pins[2] = 0x18;
9715 spec->automute = 1;
9716 spec->automute_mode = ALC_AUTOMUTE_AMP;
9717 }
9718
9719 static const struct hda_verb alc888_3st_hp_verbs[] = {
9720 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
9721 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9722 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
9723 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9724 { } /* end */
9725 };
9726
9727 /*
9728 * 2ch mode
9729 */
9730 static const struct hda_verb alc888_3st_hp_2ch_init[] = {
9731 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9732 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9733 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9734 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9735 { } /* end */
9736 };
9737
9738 /*
9739 * 4ch mode
9740 */
9741 static const struct hda_verb alc888_3st_hp_4ch_init[] = {
9742 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9743 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9744 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9745 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9746 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9747 { } /* end */
9748 };
9749
9750 /*
9751 * 6ch mode
9752 */
9753 static const struct hda_verb alc888_3st_hp_6ch_init[] = {
9754 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9755 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9756 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
9757 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9758 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9759 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9760 { } /* end */
9761 };
9762
9763 static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
9764 { 2, alc888_3st_hp_2ch_init },
9765 { 4, alc888_3st_hp_4ch_init },
9766 { 6, alc888_3st_hp_6ch_init },
9767 };
9768
9769 static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
9770 {
9771 struct alc_spec *spec = codec->spec;
9772
9773 spec->autocfg.hp_pins[0] = 0x1b;
9774 spec->autocfg.line_out_pins[0] = 0x14;
9775 spec->autocfg.speaker_pins[0] = 0x15;
9776 spec->automute = 1;
9777 spec->automute_mode = ALC_AUTOMUTE_AMP;
9778 }
9779
9780 /* toggle speaker-output according to the hp-jack state */
9781 static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
9782 {
9783 struct alc_spec *spec = codec->spec;
9784
9785 spec->autocfg.hp_pins[0] = 0x14;
9786 spec->autocfg.speaker_pins[0] = 0x15;
9787 spec->automute = 1;
9788 spec->automute_mode = ALC_AUTOMUTE_AMP;
9789 }
9790
9791 /* toggle speaker-output according to the hp-jack state */
9792 #define alc883_targa_init_hook alc882_targa_init_hook
9793 #define alc883_targa_unsol_event alc882_targa_unsol_event
9794
9795 static void alc883_clevo_m720_setup(struct hda_codec *codec)
9796 {
9797 struct alc_spec *spec = codec->spec;
9798
9799 spec->autocfg.hp_pins[0] = 0x15;
9800 spec->autocfg.speaker_pins[0] = 0x14;
9801 spec->automute = 1;
9802 spec->automute_mode = ALC_AUTOMUTE_AMP;
9803 }
9804
9805 static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9806 {
9807 alc_hp_automute(codec);
9808 alc88x_simple_mic_automute(codec);
9809 }
9810
9811 static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
9812 unsigned int res)
9813 {
9814 switch (res >> 26) {
9815 case ALC880_MIC_EVENT:
9816 alc88x_simple_mic_automute(codec);
9817 break;
9818 default:
9819 alc_sku_unsol_event(codec, res);
9820 break;
9821 }
9822 }
9823
9824 /* toggle speaker-output according to the hp-jack state */
9825 static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
9826 {
9827 struct alc_spec *spec = codec->spec;
9828
9829 spec->autocfg.hp_pins[0] = 0x14;
9830 spec->autocfg.speaker_pins[0] = 0x15;
9831 spec->automute = 1;
9832 spec->automute_mode = ALC_AUTOMUTE_AMP;
9833 }
9834
9835 static void alc883_haier_w66_setup(struct hda_codec *codec)
9836 {
9837 struct alc_spec *spec = codec->spec;
9838
9839 spec->autocfg.hp_pins[0] = 0x1b;
9840 spec->autocfg.speaker_pins[0] = 0x14;
9841 spec->automute = 1;
9842 spec->automute_mode = ALC_AUTOMUTE_AMP;
9843 }
9844
9845 static void alc883_lenovo_101e_setup(struct hda_codec *codec)
9846 {
9847 struct alc_spec *spec = codec->spec;
9848
9849 spec->autocfg.hp_pins[0] = 0x1b;
9850 spec->autocfg.line_out_pins[0] = 0x14;
9851 spec->autocfg.speaker_pins[0] = 0x15;
9852 spec->automute = 1;
9853 spec->detect_line = 1;
9854 spec->automute_lines = 1;
9855 spec->automute_mode = ALC_AUTOMUTE_AMP;
9856 }
9857
9858 /* toggle speaker-output according to the hp-jack state */
9859 static void alc883_acer_aspire_setup(struct hda_codec *codec)
9860 {
9861 struct alc_spec *spec = codec->spec;
9862
9863 spec->autocfg.hp_pins[0] = 0x14;
9864 spec->autocfg.speaker_pins[0] = 0x15;
9865 spec->autocfg.speaker_pins[1] = 0x16;
9866 spec->automute = 1;
9867 spec->automute_mode = ALC_AUTOMUTE_AMP;
9868 }
9869
9870 static const struct hda_verb alc883_acer_eapd_verbs[] = {
9871 /* HP Pin: output 0 (0x0c) */
9872 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9873 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9874 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9875 /* Front Pin: output 0 (0x0c) */
9876 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9877 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9878 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9879 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9880 /* eanable EAPD on medion laptop */
9881 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9882 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9883 /* enable unsolicited event */
9884 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9885 { }
9886 };
9887
9888 static void alc888_6st_dell_setup(struct hda_codec *codec)
9889 {
9890 struct alc_spec *spec = codec->spec;
9891
9892 spec->autocfg.hp_pins[0] = 0x1b;
9893 spec->autocfg.speaker_pins[0] = 0x14;
9894 spec->autocfg.speaker_pins[1] = 0x15;
9895 spec->autocfg.speaker_pins[2] = 0x16;
9896 spec->autocfg.speaker_pins[3] = 0x17;
9897 spec->automute = 1;
9898 spec->automute_mode = ALC_AUTOMUTE_AMP;
9899 }
9900
9901 static void alc888_lenovo_sky_setup(struct hda_codec *codec)
9902 {
9903 struct alc_spec *spec = codec->spec;
9904
9905 spec->autocfg.hp_pins[0] = 0x1b;
9906 spec->autocfg.speaker_pins[0] = 0x14;
9907 spec->autocfg.speaker_pins[1] = 0x15;
9908 spec->autocfg.speaker_pins[2] = 0x16;
9909 spec->autocfg.speaker_pins[3] = 0x17;
9910 spec->autocfg.speaker_pins[4] = 0x1a;
9911 spec->automute = 1;
9912 spec->automute_mode = ALC_AUTOMUTE_AMP;
9913 }
9914
9915 static void alc883_vaiott_setup(struct hda_codec *codec)
9916 {
9917 struct alc_spec *spec = codec->spec;
9918
9919 spec->autocfg.hp_pins[0] = 0x15;
9920 spec->autocfg.speaker_pins[0] = 0x14;
9921 spec->autocfg.speaker_pins[1] = 0x17;
9922 spec->automute = 1;
9923 spec->automute_mode = ALC_AUTOMUTE_AMP;
9924 }
9925
9926 static const struct hda_verb alc888_asus_m90v_verbs[] = {
9927 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9928 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9929 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9930 /* enable unsolicited event */
9931 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9932 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9933 { } /* end */
9934 };
9935
9936 static void alc883_mode2_setup(struct hda_codec *codec)
9937 {
9938 struct alc_spec *spec = codec->spec;
9939
9940 spec->autocfg.hp_pins[0] = 0x1b;
9941 spec->autocfg.speaker_pins[0] = 0x14;
9942 spec->autocfg.speaker_pins[1] = 0x15;
9943 spec->autocfg.speaker_pins[2] = 0x16;
9944 spec->ext_mic.pin = 0x18;
9945 spec->int_mic.pin = 0x19;
9946 spec->ext_mic.mux_idx = 0;
9947 spec->int_mic.mux_idx = 1;
9948 spec->auto_mic = 1;
9949 spec->automute = 1;
9950 spec->automute_mode = ALC_AUTOMUTE_AMP;
9951 }
9952
9953 static const struct hda_verb alc888_asus_eee1601_verbs[] = {
9954 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9955 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9956 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9957 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9958 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9959 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9960 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9961 /* enable unsolicited event */
9962 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9963 { } /* end */
9964 };
9965
9966 static void alc883_eee1601_inithook(struct hda_codec *codec)
9967 {
9968 struct alc_spec *spec = codec->spec;
9969
9970 spec->autocfg.hp_pins[0] = 0x14;
9971 spec->autocfg.speaker_pins[0] = 0x1b;
9972 alc_hp_automute(codec);
9973 }
9974
9975 static const struct hda_verb alc889A_mb31_verbs[] = {
9976 /* Init rear pin (used as headphone output) */
9977 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9978 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9979 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9980 /* Init line pin (used as output in 4ch and 6ch mode) */
9981 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9982 /* Init line 2 pin (used as headphone out by default) */
9983 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9984 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9985 { } /* end */
9986 };
9987
9988 /* Mute speakers according to the headphone jack state */
9989 static void alc889A_mb31_automute(struct hda_codec *codec)
9990 {
9991 unsigned int present;
9992
9993 /* Mute only in 2ch or 4ch mode */
9994 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9995 == 0x00) {
9996 present = snd_hda_jack_detect(codec, 0x15);
9997 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9998 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9999 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
10000 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
10001 }
10002 }
10003
10004 static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
10005 {
10006 if ((res >> 26) == ALC880_HP_EVENT)
10007 alc889A_mb31_automute(codec);
10008 }
10009
10010
10011 #ifdef CONFIG_SND_HDA_POWER_SAVE
10012 #define alc882_loopbacks alc880_loopbacks
10013 #endif
10014
10015 /* pcm configuration: identical with ALC880 */
10016 #define alc882_pcm_analog_playback alc880_pcm_analog_playback
10017 #define alc882_pcm_analog_capture alc880_pcm_analog_capture
10018 #define alc882_pcm_digital_playback alc880_pcm_digital_playback
10019 #define alc882_pcm_digital_capture alc880_pcm_digital_capture
10020
10021 static const hda_nid_t alc883_slave_dig_outs[] = {
10022 ALC1200_DIGOUT_NID, 0,
10023 };
10024
10025 static const hda_nid_t alc1200_slave_dig_outs[] = {
10026 ALC883_DIGOUT_NID, 0,
10027 };
10028
10029 /*
10030 * configuration and preset
10031 */
10032 static const char * const alc882_models[ALC882_MODEL_LAST] = {
10033 [ALC882_3ST_DIG] = "3stack-dig",
10034 [ALC882_6ST_DIG] = "6stack-dig",
10035 [ALC882_ARIMA] = "arima",
10036 [ALC882_W2JC] = "w2jc",
10037 [ALC882_TARGA] = "targa",
10038 [ALC882_ASUS_A7J] = "asus-a7j",
10039 [ALC882_ASUS_A7M] = "asus-a7m",
10040 [ALC885_MACPRO] = "macpro",
10041 [ALC885_MB5] = "mb5",
10042 [ALC885_MACMINI3] = "macmini3",
10043 [ALC885_MBA21] = "mba21",
10044 [ALC885_MBP3] = "mbp3",
10045 [ALC885_IMAC24] = "imac24",
10046 [ALC885_IMAC91] = "imac91",
10047 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
10048 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
10049 [ALC883_3ST_6ch] = "3stack-6ch",
10050 [ALC883_6ST_DIG] = "alc883-6stack-dig",
10051 [ALC883_TARGA_DIG] = "targa-dig",
10052 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
10053 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
10054 [ALC883_ACER] = "acer",
10055 [ALC883_ACER_ASPIRE] = "acer-aspire",
10056 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
10057 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
10058 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
10059 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
10060 [ALC883_MEDION] = "medion",
10061 [ALC883_MEDION_WIM2160] = "medion-wim2160",
10062 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
10063 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
10064 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
10065 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
10066 [ALC888_LENOVO_SKY] = "lenovo-sky",
10067 [ALC883_HAIER_W66] = "haier-w66",
10068 [ALC888_3ST_HP] = "3stack-hp",
10069 [ALC888_6ST_DELL] = "6stack-dell",
10070 [ALC883_MITAC] = "mitac",
10071 [ALC883_CLEVO_M540R] = "clevo-m540r",
10072 [ALC883_CLEVO_M720] = "clevo-m720",
10073 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
10074 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
10075 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
10076 [ALC889A_INTEL] = "intel-alc889a",
10077 [ALC889_INTEL] = "intel-x58",
10078 [ALC1200_ASUS_P5Q] = "asus-p5q",
10079 [ALC889A_MB31] = "mb31",
10080 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
10081 [ALC882_AUTO] = "auto",
10082 };
10083
10084 static const struct snd_pci_quirk alc882_cfg_tbl[] = {
10085 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
10086
10087 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
10088 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
10089 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
10090 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
10091 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
10092 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
10093 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
10094 ALC888_ACER_ASPIRE_4930G),
10095 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
10096 ALC888_ACER_ASPIRE_4930G),
10097 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
10098 ALC888_ACER_ASPIRE_8930G),
10099 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
10100 ALC888_ACER_ASPIRE_8930G),
10101 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
10102 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
10103 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
10104 ALC888_ACER_ASPIRE_6530G),
10105 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
10106 ALC888_ACER_ASPIRE_6530G),
10107 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
10108 ALC888_ACER_ASPIRE_7730G),
10109 /* default Acer -- disabled as it causes more problems.
10110 * model=auto should work fine now
10111 */
10112 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
10113
10114 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
10115
10116 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
10117 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
10118 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
10119 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
10120 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
10121 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
10122
10123 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
10124 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
10125 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
10126 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
10127 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
10128 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
10129 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
10130 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
10131 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
10132 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
10133 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
10134
10135 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
10136 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
10137 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
10138 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
10139 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
10140 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
10141 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
10142 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
10143 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
10144
10145 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
10146 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
10147 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
10148 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
10149 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
10150 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
10151 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
10152 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
10153 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
10154 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
10155 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
10156 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
10157 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
10158 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
10159 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
10160 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
10161 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
10162 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
10163 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
10164 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
10165 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
10166 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
10167 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
10168 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
10169 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
10170 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
10171 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
10172 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
10173 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
10174 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
10175 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
10176
10177 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
10178 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
10179 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
10180 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
10181 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
10182 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
10183 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
10184 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
10185 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
10186 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
10187 ALC883_FUJITSU_PI2515),
10188 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
10189 ALC888_FUJITSU_XA3530),
10190 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
10191 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10192 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10193 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
10194 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
10195 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
10196 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
10197 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
10198
10199 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
10200 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
10201 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
10202 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
10203 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
10204 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
10205 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
10206
10207 {}
10208 };
10209
10210 /* codec SSID table for Intel Mac */
10211 static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
10212 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
10213 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
10214 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
10215 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
10216 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
10217 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
10218 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
10219 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
10220 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
10221 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
10222 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
10223 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
10224 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
10225 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
10226 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
10227 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
10228 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
10229 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
10230 * so apparently no perfect solution yet
10231 */
10232 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
10233 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
10234 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
10235 {} /* terminator */
10236 };
10237
10238 static const struct alc_config_preset alc882_presets[] = {
10239 [ALC882_3ST_DIG] = {
10240 .mixers = { alc882_base_mixer },
10241 .init_verbs = { alc882_base_init_verbs,
10242 alc882_adc1_init_verbs },
10243 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10244 .dac_nids = alc882_dac_nids,
10245 .dig_out_nid = ALC882_DIGOUT_NID,
10246 .dig_in_nid = ALC882_DIGIN_NID,
10247 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10248 .channel_mode = alc882_ch_modes,
10249 .need_dac_fix = 1,
10250 .input_mux = &alc882_capture_source,
10251 },
10252 [ALC882_6ST_DIG] = {
10253 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10254 .init_verbs = { alc882_base_init_verbs,
10255 alc882_adc1_init_verbs },
10256 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10257 .dac_nids = alc882_dac_nids,
10258 .dig_out_nid = ALC882_DIGOUT_NID,
10259 .dig_in_nid = ALC882_DIGIN_NID,
10260 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10261 .channel_mode = alc882_sixstack_modes,
10262 .input_mux = &alc882_capture_source,
10263 },
10264 [ALC882_ARIMA] = {
10265 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10266 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10267 alc882_eapd_verbs },
10268 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10269 .dac_nids = alc882_dac_nids,
10270 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10271 .channel_mode = alc882_sixstack_modes,
10272 .input_mux = &alc882_capture_source,
10273 },
10274 [ALC882_W2JC] = {
10275 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
10276 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10277 alc882_eapd_verbs, alc880_gpio1_init_verbs },
10278 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10279 .dac_nids = alc882_dac_nids,
10280 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10281 .channel_mode = alc880_threestack_modes,
10282 .need_dac_fix = 1,
10283 .input_mux = &alc882_capture_source,
10284 .dig_out_nid = ALC882_DIGOUT_NID,
10285 },
10286 [ALC885_MBA21] = {
10287 .mixers = { alc885_mba21_mixer },
10288 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10289 .num_dacs = 2,
10290 .dac_nids = alc882_dac_nids,
10291 .channel_mode = alc885_mba21_ch_modes,
10292 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10293 .input_mux = &alc882_capture_source,
10294 .unsol_event = alc_sku_unsol_event,
10295 .setup = alc885_mba21_setup,
10296 .init_hook = alc_hp_automute,
10297 },
10298 [ALC885_MBP3] = {
10299 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10300 .init_verbs = { alc885_mbp3_init_verbs,
10301 alc880_gpio1_init_verbs },
10302 .num_dacs = 2,
10303 .dac_nids = alc882_dac_nids,
10304 .hp_nid = 0x04,
10305 .channel_mode = alc885_mbp_4ch_modes,
10306 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
10307 .input_mux = &alc882_capture_source,
10308 .dig_out_nid = ALC882_DIGOUT_NID,
10309 .dig_in_nid = ALC882_DIGIN_NID,
10310 .unsol_event = alc_sku_unsol_event,
10311 .setup = alc885_mbp3_setup,
10312 .init_hook = alc_hp_automute,
10313 },
10314 [ALC885_MB5] = {
10315 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10316 .init_verbs = { alc885_mb5_init_verbs,
10317 alc880_gpio1_init_verbs },
10318 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10319 .dac_nids = alc882_dac_nids,
10320 .channel_mode = alc885_mb5_6ch_modes,
10321 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10322 .input_mux = &mb5_capture_source,
10323 .dig_out_nid = ALC882_DIGOUT_NID,
10324 .dig_in_nid = ALC882_DIGIN_NID,
10325 .unsol_event = alc_sku_unsol_event,
10326 .setup = alc885_mb5_setup,
10327 .init_hook = alc_hp_automute,
10328 },
10329 [ALC885_MACMINI3] = {
10330 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10331 .init_verbs = { alc885_macmini3_init_verbs,
10332 alc880_gpio1_init_verbs },
10333 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10334 .dac_nids = alc882_dac_nids,
10335 .channel_mode = alc885_macmini3_6ch_modes,
10336 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10337 .input_mux = &macmini3_capture_source,
10338 .dig_out_nid = ALC882_DIGOUT_NID,
10339 .dig_in_nid = ALC882_DIGIN_NID,
10340 .unsol_event = alc_sku_unsol_event,
10341 .setup = alc885_macmini3_setup,
10342 .init_hook = alc_hp_automute,
10343 },
10344 [ALC885_MACPRO] = {
10345 .mixers = { alc882_macpro_mixer },
10346 .init_verbs = { alc882_macpro_init_verbs },
10347 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10348 .dac_nids = alc882_dac_nids,
10349 .dig_out_nid = ALC882_DIGOUT_NID,
10350 .dig_in_nid = ALC882_DIGIN_NID,
10351 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10352 .channel_mode = alc882_ch_modes,
10353 .input_mux = &alc882_capture_source,
10354 .init_hook = alc885_macpro_init_hook,
10355 },
10356 [ALC885_IMAC24] = {
10357 .mixers = { alc885_imac24_mixer },
10358 .init_verbs = { alc885_imac24_init_verbs },
10359 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10360 .dac_nids = alc882_dac_nids,
10361 .dig_out_nid = ALC882_DIGOUT_NID,
10362 .dig_in_nid = ALC882_DIGIN_NID,
10363 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10364 .channel_mode = alc882_ch_modes,
10365 .input_mux = &alc882_capture_source,
10366 .unsol_event = alc_sku_unsol_event,
10367 .setup = alc885_imac24_setup,
10368 .init_hook = alc885_imac24_init_hook,
10369 },
10370 [ALC885_IMAC91] = {
10371 .mixers = {alc885_imac91_mixer},
10372 .init_verbs = { alc885_imac91_init_verbs,
10373 alc880_gpio1_init_verbs },
10374 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10375 .dac_nids = alc882_dac_nids,
10376 .channel_mode = alc885_mba21_ch_modes,
10377 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10378 .input_mux = &alc889A_imac91_capture_source,
10379 .dig_out_nid = ALC882_DIGOUT_NID,
10380 .dig_in_nid = ALC882_DIGIN_NID,
10381 .unsol_event = alc_sku_unsol_event,
10382 .setup = alc885_imac91_setup,
10383 .init_hook = alc_hp_automute,
10384 },
10385 [ALC882_TARGA] = {
10386 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
10387 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10388 alc880_gpio3_init_verbs, alc882_targa_verbs},
10389 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10390 .dac_nids = alc882_dac_nids,
10391 .dig_out_nid = ALC882_DIGOUT_NID,
10392 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10393 .adc_nids = alc882_adc_nids,
10394 .capsrc_nids = alc882_capsrc_nids,
10395 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10396 .channel_mode = alc882_3ST_6ch_modes,
10397 .need_dac_fix = 1,
10398 .input_mux = &alc882_capture_source,
10399 .unsol_event = alc_sku_unsol_event,
10400 .setup = alc882_targa_setup,
10401 .init_hook = alc882_targa_automute,
10402 },
10403 [ALC882_ASUS_A7J] = {
10404 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
10405 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10406 alc882_asus_a7j_verbs},
10407 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10408 .dac_nids = alc882_dac_nids,
10409 .dig_out_nid = ALC882_DIGOUT_NID,
10410 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10411 .adc_nids = alc882_adc_nids,
10412 .capsrc_nids = alc882_capsrc_nids,
10413 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10414 .channel_mode = alc882_3ST_6ch_modes,
10415 .need_dac_fix = 1,
10416 .input_mux = &alc882_capture_source,
10417 },
10418 [ALC882_ASUS_A7M] = {
10419 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
10420 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10421 alc882_eapd_verbs, alc880_gpio1_init_verbs,
10422 alc882_asus_a7m_verbs },
10423 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10424 .dac_nids = alc882_dac_nids,
10425 .dig_out_nid = ALC882_DIGOUT_NID,
10426 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10427 .channel_mode = alc880_threestack_modes,
10428 .need_dac_fix = 1,
10429 .input_mux = &alc882_capture_source,
10430 },
10431 [ALC883_3ST_2ch_DIG] = {
10432 .mixers = { alc883_3ST_2ch_mixer },
10433 .init_verbs = { alc883_init_verbs },
10434 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10435 .dac_nids = alc883_dac_nids,
10436 .dig_out_nid = ALC883_DIGOUT_NID,
10437 .dig_in_nid = ALC883_DIGIN_NID,
10438 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10439 .channel_mode = alc883_3ST_2ch_modes,
10440 .input_mux = &alc883_capture_source,
10441 },
10442 [ALC883_3ST_6ch_DIG] = {
10443 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10444 .init_verbs = { alc883_init_verbs },
10445 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10446 .dac_nids = alc883_dac_nids,
10447 .dig_out_nid = ALC883_DIGOUT_NID,
10448 .dig_in_nid = ALC883_DIGIN_NID,
10449 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10450 .channel_mode = alc883_3ST_6ch_modes,
10451 .need_dac_fix = 1,
10452 .input_mux = &alc883_capture_source,
10453 },
10454 [ALC883_3ST_6ch] = {
10455 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10456 .init_verbs = { alc883_init_verbs },
10457 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10458 .dac_nids = alc883_dac_nids,
10459 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10460 .channel_mode = alc883_3ST_6ch_modes,
10461 .need_dac_fix = 1,
10462 .input_mux = &alc883_capture_source,
10463 },
10464 [ALC883_3ST_6ch_INTEL] = {
10465 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10466 .init_verbs = { alc883_init_verbs },
10467 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10468 .dac_nids = alc883_dac_nids,
10469 .dig_out_nid = ALC883_DIGOUT_NID,
10470 .dig_in_nid = ALC883_DIGIN_NID,
10471 .slave_dig_outs = alc883_slave_dig_outs,
10472 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10473 .channel_mode = alc883_3ST_6ch_intel_modes,
10474 .need_dac_fix = 1,
10475 .input_mux = &alc883_3stack_6ch_intel,
10476 },
10477 [ALC889A_INTEL] = {
10478 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10479 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10480 alc_hp15_unsol_verbs },
10481 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10482 .dac_nids = alc883_dac_nids,
10483 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10484 .adc_nids = alc889_adc_nids,
10485 .dig_out_nid = ALC883_DIGOUT_NID,
10486 .dig_in_nid = ALC883_DIGIN_NID,
10487 .slave_dig_outs = alc883_slave_dig_outs,
10488 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10489 .channel_mode = alc889_8ch_intel_modes,
10490 .capsrc_nids = alc889_capsrc_nids,
10491 .input_mux = &alc889_capture_source,
10492 .setup = alc889_automute_setup,
10493 .init_hook = alc_hp_automute,
10494 .unsol_event = alc_sku_unsol_event,
10495 .need_dac_fix = 1,
10496 },
10497 [ALC889_INTEL] = {
10498 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10499 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
10500 alc889_eapd_verbs, alc_hp15_unsol_verbs},
10501 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10502 .dac_nids = alc883_dac_nids,
10503 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10504 .adc_nids = alc889_adc_nids,
10505 .dig_out_nid = ALC883_DIGOUT_NID,
10506 .dig_in_nid = ALC883_DIGIN_NID,
10507 .slave_dig_outs = alc883_slave_dig_outs,
10508 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10509 .channel_mode = alc889_8ch_intel_modes,
10510 .capsrc_nids = alc889_capsrc_nids,
10511 .input_mux = &alc889_capture_source,
10512 .setup = alc889_automute_setup,
10513 .init_hook = alc889_intel_init_hook,
10514 .unsol_event = alc_sku_unsol_event,
10515 .need_dac_fix = 1,
10516 },
10517 [ALC883_6ST_DIG] = {
10518 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10519 .init_verbs = { alc883_init_verbs },
10520 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10521 .dac_nids = alc883_dac_nids,
10522 .dig_out_nid = ALC883_DIGOUT_NID,
10523 .dig_in_nid = ALC883_DIGIN_NID,
10524 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10525 .channel_mode = alc883_sixstack_modes,
10526 .input_mux = &alc883_capture_source,
10527 },
10528 [ALC883_TARGA_DIG] = {
10529 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
10530 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10531 alc883_targa_verbs},
10532 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10533 .dac_nids = alc883_dac_nids,
10534 .dig_out_nid = ALC883_DIGOUT_NID,
10535 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10536 .channel_mode = alc883_3ST_6ch_modes,
10537 .need_dac_fix = 1,
10538 .input_mux = &alc883_capture_source,
10539 .unsol_event = alc883_targa_unsol_event,
10540 .setup = alc882_targa_setup,
10541 .init_hook = alc882_targa_automute,
10542 },
10543 [ALC883_TARGA_2ch_DIG] = {
10544 .mixers = { alc883_targa_2ch_mixer},
10545 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10546 alc883_targa_verbs},
10547 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10548 .dac_nids = alc883_dac_nids,
10549 .adc_nids = alc883_adc_nids_alt,
10550 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10551 .capsrc_nids = alc883_capsrc_nids,
10552 .dig_out_nid = ALC883_DIGOUT_NID,
10553 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10554 .channel_mode = alc883_3ST_2ch_modes,
10555 .input_mux = &alc883_capture_source,
10556 .unsol_event = alc883_targa_unsol_event,
10557 .setup = alc882_targa_setup,
10558 .init_hook = alc882_targa_automute,
10559 },
10560 [ALC883_TARGA_8ch_DIG] = {
10561 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10562 alc883_chmode_mixer },
10563 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10564 alc883_targa_verbs },
10565 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10566 .dac_nids = alc883_dac_nids,
10567 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10568 .adc_nids = alc883_adc_nids_rev,
10569 .capsrc_nids = alc883_capsrc_nids_rev,
10570 .dig_out_nid = ALC883_DIGOUT_NID,
10571 .dig_in_nid = ALC883_DIGIN_NID,
10572 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10573 .channel_mode = alc883_4ST_8ch_modes,
10574 .need_dac_fix = 1,
10575 .input_mux = &alc883_capture_source,
10576 .unsol_event = alc883_targa_unsol_event,
10577 .setup = alc882_targa_setup,
10578 .init_hook = alc882_targa_automute,
10579 },
10580 [ALC883_ACER] = {
10581 .mixers = { alc883_base_mixer },
10582 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10583 * and the headphone jack. Turn this on and rely on the
10584 * standard mute methods whenever the user wants to turn
10585 * these outputs off.
10586 */
10587 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10588 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10589 .dac_nids = alc883_dac_nids,
10590 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10591 .channel_mode = alc883_3ST_2ch_modes,
10592 .input_mux = &alc883_capture_source,
10593 },
10594 [ALC883_ACER_ASPIRE] = {
10595 .mixers = { alc883_acer_aspire_mixer },
10596 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
10597 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10598 .dac_nids = alc883_dac_nids,
10599 .dig_out_nid = ALC883_DIGOUT_NID,
10600 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10601 .channel_mode = alc883_3ST_2ch_modes,
10602 .input_mux = &alc883_capture_source,
10603 .unsol_event = alc_sku_unsol_event,
10604 .setup = alc883_acer_aspire_setup,
10605 .init_hook = alc_hp_automute,
10606 },
10607 [ALC888_ACER_ASPIRE_4930G] = {
10608 .mixers = { alc888_acer_aspire_4930g_mixer,
10609 alc883_chmode_mixer },
10610 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10611 alc888_acer_aspire_4930g_verbs },
10612 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10613 .dac_nids = alc883_dac_nids,
10614 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10615 .adc_nids = alc883_adc_nids_rev,
10616 .capsrc_nids = alc883_capsrc_nids_rev,
10617 .dig_out_nid = ALC883_DIGOUT_NID,
10618 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10619 .channel_mode = alc883_3ST_6ch_modes,
10620 .need_dac_fix = 1,
10621 .const_channel_count = 6,
10622 .num_mux_defs =
10623 ARRAY_SIZE(alc888_2_capture_sources),
10624 .input_mux = alc888_2_capture_sources,
10625 .unsol_event = alc_sku_unsol_event,
10626 .setup = alc888_acer_aspire_4930g_setup,
10627 .init_hook = alc_hp_automute,
10628 },
10629 [ALC888_ACER_ASPIRE_6530G] = {
10630 .mixers = { alc888_acer_aspire_6530_mixer },
10631 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10632 alc888_acer_aspire_6530g_verbs },
10633 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10634 .dac_nids = alc883_dac_nids,
10635 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10636 .adc_nids = alc883_adc_nids_rev,
10637 .capsrc_nids = alc883_capsrc_nids_rev,
10638 .dig_out_nid = ALC883_DIGOUT_NID,
10639 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10640 .channel_mode = alc883_3ST_2ch_modes,
10641 .num_mux_defs =
10642 ARRAY_SIZE(alc888_2_capture_sources),
10643 .input_mux = alc888_acer_aspire_6530_sources,
10644 .unsol_event = alc_sku_unsol_event,
10645 .setup = alc888_acer_aspire_6530g_setup,
10646 .init_hook = alc_hp_automute,
10647 },
10648 [ALC888_ACER_ASPIRE_8930G] = {
10649 .mixers = { alc889_acer_aspire_8930g_mixer,
10650 alc883_chmode_mixer },
10651 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10652 alc889_acer_aspire_8930g_verbs,
10653 alc889_eapd_verbs},
10654 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10655 .dac_nids = alc883_dac_nids,
10656 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10657 .adc_nids = alc889_adc_nids,
10658 .capsrc_nids = alc889_capsrc_nids,
10659 .dig_out_nid = ALC883_DIGOUT_NID,
10660 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10661 .channel_mode = alc883_3ST_6ch_modes,
10662 .need_dac_fix = 1,
10663 .const_channel_count = 6,
10664 .num_mux_defs =
10665 ARRAY_SIZE(alc889_capture_sources),
10666 .input_mux = alc889_capture_sources,
10667 .unsol_event = alc_sku_unsol_event,
10668 .setup = alc889_acer_aspire_8930g_setup,
10669 .init_hook = alc_hp_automute,
10670 #ifdef CONFIG_SND_HDA_POWER_SAVE
10671 .power_hook = alc_power_eapd,
10672 #endif
10673 },
10674 [ALC888_ACER_ASPIRE_7730G] = {
10675 .mixers = { alc883_3ST_6ch_mixer,
10676 alc883_chmode_mixer },
10677 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10678 alc888_acer_aspire_7730G_verbs },
10679 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10680 .dac_nids = alc883_dac_nids,
10681 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10682 .adc_nids = alc883_adc_nids_rev,
10683 .capsrc_nids = alc883_capsrc_nids_rev,
10684 .dig_out_nid = ALC883_DIGOUT_NID,
10685 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10686 .channel_mode = alc883_3ST_6ch_modes,
10687 .need_dac_fix = 1,
10688 .const_channel_count = 6,
10689 .input_mux = &alc883_capture_source,
10690 .unsol_event = alc_sku_unsol_event,
10691 .setup = alc888_acer_aspire_7730g_setup,
10692 .init_hook = alc_hp_automute,
10693 },
10694 [ALC883_MEDION] = {
10695 .mixers = { alc883_fivestack_mixer,
10696 alc883_chmode_mixer },
10697 .init_verbs = { alc883_init_verbs,
10698 alc883_medion_eapd_verbs },
10699 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10700 .dac_nids = alc883_dac_nids,
10701 .adc_nids = alc883_adc_nids_alt,
10702 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10703 .capsrc_nids = alc883_capsrc_nids,
10704 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10705 .channel_mode = alc883_sixstack_modes,
10706 .input_mux = &alc883_capture_source,
10707 },
10708 [ALC883_MEDION_WIM2160] = {
10709 .mixers = { alc883_medion_wim2160_mixer },
10710 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10711 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10712 .dac_nids = alc883_dac_nids,
10713 .dig_out_nid = ALC883_DIGOUT_NID,
10714 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10715 .adc_nids = alc883_adc_nids,
10716 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10717 .channel_mode = alc883_3ST_2ch_modes,
10718 .input_mux = &alc883_capture_source,
10719 .unsol_event = alc_sku_unsol_event,
10720 .setup = alc883_medion_wim2160_setup,
10721 .init_hook = alc_hp_automute,
10722 },
10723 [ALC883_LAPTOP_EAPD] = {
10724 .mixers = { alc883_base_mixer },
10725 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10726 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10727 .dac_nids = alc883_dac_nids,
10728 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10729 .channel_mode = alc883_3ST_2ch_modes,
10730 .input_mux = &alc883_capture_source,
10731 },
10732 [ALC883_CLEVO_M540R] = {
10733 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10734 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10735 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10736 .dac_nids = alc883_dac_nids,
10737 .dig_out_nid = ALC883_DIGOUT_NID,
10738 .dig_in_nid = ALC883_DIGIN_NID,
10739 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10740 .channel_mode = alc883_3ST_6ch_clevo_modes,
10741 .need_dac_fix = 1,
10742 .input_mux = &alc883_capture_source,
10743 /* This machine has the hardware HP auto-muting, thus
10744 * we need no software mute via unsol event
10745 */
10746 },
10747 [ALC883_CLEVO_M720] = {
10748 .mixers = { alc883_clevo_m720_mixer },
10749 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
10750 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10751 .dac_nids = alc883_dac_nids,
10752 .dig_out_nid = ALC883_DIGOUT_NID,
10753 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10754 .channel_mode = alc883_3ST_2ch_modes,
10755 .input_mux = &alc883_capture_source,
10756 .unsol_event = alc883_clevo_m720_unsol_event,
10757 .setup = alc883_clevo_m720_setup,
10758 .init_hook = alc883_clevo_m720_init_hook,
10759 },
10760 [ALC883_LENOVO_101E_2ch] = {
10761 .mixers = { alc883_lenovo_101e_2ch_mixer},
10762 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10763 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10764 .dac_nids = alc883_dac_nids,
10765 .adc_nids = alc883_adc_nids_alt,
10766 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10767 .capsrc_nids = alc883_capsrc_nids,
10768 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10769 .channel_mode = alc883_3ST_2ch_modes,
10770 .input_mux = &alc883_lenovo_101e_capture_source,
10771 .setup = alc883_lenovo_101e_setup,
10772 .unsol_event = alc_sku_unsol_event,
10773 .init_hook = alc_inithook,
10774 },
10775 [ALC883_LENOVO_NB0763] = {
10776 .mixers = { alc883_lenovo_nb0763_mixer },
10777 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10778 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10779 .dac_nids = alc883_dac_nids,
10780 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10781 .channel_mode = alc883_3ST_2ch_modes,
10782 .need_dac_fix = 1,
10783 .input_mux = &alc883_lenovo_nb0763_capture_source,
10784 .unsol_event = alc_sku_unsol_event,
10785 .setup = alc883_lenovo_nb0763_setup,
10786 .init_hook = alc_hp_automute,
10787 },
10788 [ALC888_LENOVO_MS7195_DIG] = {
10789 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10790 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10791 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10792 .dac_nids = alc883_dac_nids,
10793 .dig_out_nid = ALC883_DIGOUT_NID,
10794 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10795 .channel_mode = alc883_3ST_6ch_modes,
10796 .need_dac_fix = 1,
10797 .input_mux = &alc883_capture_source,
10798 .unsol_event = alc_sku_unsol_event,
10799 .setup = alc888_lenovo_ms7195_setup,
10800 .init_hook = alc_inithook,
10801 },
10802 [ALC883_HAIER_W66] = {
10803 .mixers = { alc883_targa_2ch_mixer},
10804 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10805 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10806 .dac_nids = alc883_dac_nids,
10807 .dig_out_nid = ALC883_DIGOUT_NID,
10808 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10809 .channel_mode = alc883_3ST_2ch_modes,
10810 .input_mux = &alc883_capture_source,
10811 .unsol_event = alc_sku_unsol_event,
10812 .setup = alc883_haier_w66_setup,
10813 .init_hook = alc_hp_automute,
10814 },
10815 [ALC888_3ST_HP] = {
10816 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10817 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
10818 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10819 .dac_nids = alc883_dac_nids,
10820 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10821 .channel_mode = alc888_3st_hp_modes,
10822 .need_dac_fix = 1,
10823 .input_mux = &alc883_capture_source,
10824 .unsol_event = alc_sku_unsol_event,
10825 .setup = alc888_3st_hp_setup,
10826 .init_hook = alc_hp_automute,
10827 },
10828 [ALC888_6ST_DELL] = {
10829 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10830 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10831 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10832 .dac_nids = alc883_dac_nids,
10833 .dig_out_nid = ALC883_DIGOUT_NID,
10834 .dig_in_nid = ALC883_DIGIN_NID,
10835 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10836 .channel_mode = alc883_sixstack_modes,
10837 .input_mux = &alc883_capture_source,
10838 .unsol_event = alc_sku_unsol_event,
10839 .setup = alc888_6st_dell_setup,
10840 .init_hook = alc_hp_automute,
10841 },
10842 [ALC883_MITAC] = {
10843 .mixers = { alc883_mitac_mixer },
10844 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10845 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10846 .dac_nids = alc883_dac_nids,
10847 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10848 .channel_mode = alc883_3ST_2ch_modes,
10849 .input_mux = &alc883_capture_source,
10850 .unsol_event = alc_sku_unsol_event,
10851 .setup = alc883_mitac_setup,
10852 .init_hook = alc_hp_automute,
10853 },
10854 [ALC883_FUJITSU_PI2515] = {
10855 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10856 .init_verbs = { alc883_init_verbs,
10857 alc883_2ch_fujitsu_pi2515_verbs},
10858 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10859 .dac_nids = alc883_dac_nids,
10860 .dig_out_nid = ALC883_DIGOUT_NID,
10861 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10862 .channel_mode = alc883_3ST_2ch_modes,
10863 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10864 .unsol_event = alc_sku_unsol_event,
10865 .setup = alc883_2ch_fujitsu_pi2515_setup,
10866 .init_hook = alc_hp_automute,
10867 },
10868 [ALC888_FUJITSU_XA3530] = {
10869 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10870 .init_verbs = { alc883_init_verbs,
10871 alc888_fujitsu_xa3530_verbs },
10872 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10873 .dac_nids = alc883_dac_nids,
10874 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10875 .adc_nids = alc883_adc_nids_rev,
10876 .capsrc_nids = alc883_capsrc_nids_rev,
10877 .dig_out_nid = ALC883_DIGOUT_NID,
10878 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10879 .channel_mode = alc888_4ST_8ch_intel_modes,
10880 .num_mux_defs =
10881 ARRAY_SIZE(alc888_2_capture_sources),
10882 .input_mux = alc888_2_capture_sources,
10883 .unsol_event = alc_sku_unsol_event,
10884 .setup = alc888_fujitsu_xa3530_setup,
10885 .init_hook = alc_hp_automute,
10886 },
10887 [ALC888_LENOVO_SKY] = {
10888 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10889 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10890 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10891 .dac_nids = alc883_dac_nids,
10892 .dig_out_nid = ALC883_DIGOUT_NID,
10893 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10894 .channel_mode = alc883_sixstack_modes,
10895 .need_dac_fix = 1,
10896 .input_mux = &alc883_lenovo_sky_capture_source,
10897 .unsol_event = alc_sku_unsol_event,
10898 .setup = alc888_lenovo_sky_setup,
10899 .init_hook = alc_hp_automute,
10900 },
10901 [ALC888_ASUS_M90V] = {
10902 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10903 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10904 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10905 .dac_nids = alc883_dac_nids,
10906 .dig_out_nid = ALC883_DIGOUT_NID,
10907 .dig_in_nid = ALC883_DIGIN_NID,
10908 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10909 .channel_mode = alc883_3ST_6ch_modes,
10910 .need_dac_fix = 1,
10911 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10912 .unsol_event = alc_sku_unsol_event,
10913 .setup = alc883_mode2_setup,
10914 .init_hook = alc_inithook,
10915 },
10916 [ALC888_ASUS_EEE1601] = {
10917 .mixers = { alc883_asus_eee1601_mixer },
10918 .cap_mixer = alc883_asus_eee1601_cap_mixer,
10919 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10920 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10921 .dac_nids = alc883_dac_nids,
10922 .dig_out_nid = ALC883_DIGOUT_NID,
10923 .dig_in_nid = ALC883_DIGIN_NID,
10924 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10925 .channel_mode = alc883_3ST_2ch_modes,
10926 .need_dac_fix = 1,
10927 .input_mux = &alc883_asus_eee1601_capture_source,
10928 .unsol_event = alc_sku_unsol_event,
10929 .init_hook = alc883_eee1601_inithook,
10930 },
10931 [ALC1200_ASUS_P5Q] = {
10932 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10933 .init_verbs = { alc883_init_verbs },
10934 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10935 .dac_nids = alc883_dac_nids,
10936 .dig_out_nid = ALC1200_DIGOUT_NID,
10937 .dig_in_nid = ALC883_DIGIN_NID,
10938 .slave_dig_outs = alc1200_slave_dig_outs,
10939 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10940 .channel_mode = alc883_sixstack_modes,
10941 .input_mux = &alc883_capture_source,
10942 },
10943 [ALC889A_MB31] = {
10944 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10945 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10946 alc880_gpio1_init_verbs },
10947 .adc_nids = alc883_adc_nids,
10948 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10949 .capsrc_nids = alc883_capsrc_nids,
10950 .dac_nids = alc883_dac_nids,
10951 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10952 .channel_mode = alc889A_mb31_6ch_modes,
10953 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10954 .input_mux = &alc889A_mb31_capture_source,
10955 .dig_out_nid = ALC883_DIGOUT_NID,
10956 .unsol_event = alc889A_mb31_unsol_event,
10957 .init_hook = alc889A_mb31_automute,
10958 },
10959 [ALC883_SONY_VAIO_TT] = {
10960 .mixers = { alc883_vaiott_mixer },
10961 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10962 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10963 .dac_nids = alc883_dac_nids,
10964 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10965 .channel_mode = alc883_3ST_2ch_modes,
10966 .input_mux = &alc883_capture_source,
10967 .unsol_event = alc_sku_unsol_event,
10968 .setup = alc883_vaiott_setup,
10969 .init_hook = alc_hp_automute,
10970 },
10971 };
10972
10973
10974 /*
10975 * Pin config fixes
10976 */
10977 enum {
10978 PINFIX_ABIT_AW9D_MAX,
10979 PINFIX_LENOVO_Y530,
10980 PINFIX_PB_M5210,
10981 PINFIX_ACER_ASPIRE_7736,
10982 };
10983
10984 static const struct alc_fixup alc882_fixups[] = {
10985 [PINFIX_ABIT_AW9D_MAX] = {
10986 .type = ALC_FIXUP_PINS,
10987 .v.pins = (const struct alc_pincfg[]) {
10988 { 0x15, 0x01080104 }, /* side */
10989 { 0x16, 0x01011012 }, /* rear */
10990 { 0x17, 0x01016011 }, /* clfe */
10991 { }
10992 }
10993 },
10994 [PINFIX_LENOVO_Y530] = {
10995 .type = ALC_FIXUP_PINS,
10996 .v.pins = (const struct alc_pincfg[]) {
10997 { 0x15, 0x99130112 }, /* rear int speakers */
10998 { 0x16, 0x99130111 }, /* subwoofer */
10999 { }
11000 }
11001 },
11002 [PINFIX_PB_M5210] = {
11003 .type = ALC_FIXUP_VERBS,
11004 .v.verbs = (const struct hda_verb[]) {
11005 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50 },
11006 {}
11007 }
11008 },
11009 [PINFIX_ACER_ASPIRE_7736] = {
11010 .type = ALC_FIXUP_SKU,
11011 .v.sku = ALC_FIXUP_SKU_IGNORE,
11012 },
11013 };
11014
11015 static const struct snd_pci_quirk alc882_fixup_tbl[] = {
11016 SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210),
11017 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530),
11018 SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX),
11019 SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736),
11020 {}
11021 };
11022
11023 /*
11024 * BIOS auto configuration
11025 */
11026 static int alc882_auto_create_input_ctls(struct hda_codec *codec,
11027 const struct auto_pin_cfg *cfg)
11028 {
11029 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x23, 0x22);
11030 }
11031
11032 static void alc882_auto_set_output_and_unmute(struct hda_codec *codec,
11033 hda_nid_t nid, int pin_type,
11034 hda_nid_t dac)
11035 {
11036 int idx;
11037
11038 /* set as output */
11039 alc_set_pin_output(codec, nid, pin_type);
11040
11041 if (dac == 0x25)
11042 idx = 4;
11043 else if (dac >= 0x02 && dac <= 0x05)
11044 idx = dac - 2;
11045 else
11046 return;
11047 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
11048 }
11049
11050 static void alc882_auto_init_multi_out(struct hda_codec *codec)
11051 {
11052 struct alc_spec *spec = codec->spec;
11053 int i;
11054
11055 for (i = 0; i <= HDA_SIDE; i++) {
11056 hda_nid_t nid = spec->autocfg.line_out_pins[i];
11057 int pin_type = get_pin_type(spec->autocfg.line_out_type);
11058 if (nid)
11059 alc882_auto_set_output_and_unmute(codec, nid, pin_type,
11060 spec->multiout.dac_nids[i]);
11061 }
11062 }
11063
11064 static void alc882_auto_init_hp_out(struct hda_codec *codec)
11065 {
11066 struct alc_spec *spec = codec->spec;
11067 hda_nid_t pin, dac;
11068 int i;
11069
11070 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT) {
11071 for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) {
11072 pin = spec->autocfg.hp_pins[i];
11073 if (!pin)
11074 break;
11075 dac = spec->multiout.hp_nid;
11076 if (!dac)
11077 dac = spec->multiout.dac_nids[0]; /* to front */
11078 alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
11079 }
11080 }
11081
11082 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT) {
11083 for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) {
11084 pin = spec->autocfg.speaker_pins[i];
11085 if (!pin)
11086 break;
11087 dac = spec->multiout.extra_out_nid[0];
11088 if (!dac)
11089 dac = spec->multiout.dac_nids[0]; /* to front */
11090 alc882_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
11091 }
11092 }
11093 }
11094
11095 static void alc882_auto_init_analog_input(struct hda_codec *codec)
11096 {
11097 struct alc_spec *spec = codec->spec;
11098 struct auto_pin_cfg *cfg = &spec->autocfg;
11099 int i;
11100
11101 for (i = 0; i < cfg->num_inputs; i++) {
11102 hda_nid_t nid = cfg->inputs[i].pin;
11103 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
11104 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
11105 snd_hda_codec_write(codec, nid, 0,
11106 AC_VERB_SET_AMP_GAIN_MUTE,
11107 AMP_OUT_MUTE);
11108 }
11109 }
11110
11111 static void alc882_auto_init_input_src(struct hda_codec *codec)
11112 {
11113 struct alc_spec *spec = codec->spec;
11114 int c;
11115
11116 for (c = 0; c < spec->num_adc_nids; c++) {
11117 hda_nid_t conn_list[HDA_MAX_NUM_INPUTS];
11118 hda_nid_t nid = spec->capsrc_nids[c];
11119 unsigned int mux_idx;
11120 const struct hda_input_mux *imux;
11121 int conns, mute, idx, item;
11122
11123 /* mute ADC */
11124 snd_hda_codec_write(codec, spec->adc_nids[c], 0,
11125 AC_VERB_SET_AMP_GAIN_MUTE,
11126 AMP_IN_MUTE(0));
11127
11128 conns = snd_hda_get_connections(codec, nid, conn_list,
11129 ARRAY_SIZE(conn_list));
11130 if (conns < 0)
11131 continue;
11132 mux_idx = c >= spec->num_mux_defs ? 0 : c;
11133 imux = &spec->input_mux[mux_idx];
11134 if (!imux->num_items && mux_idx > 0)
11135 imux = &spec->input_mux[0];
11136 for (idx = 0; idx < conns; idx++) {
11137 /* if the current connection is the selected one,
11138 * unmute it as default - otherwise mute it
11139 */
11140 mute = AMP_IN_MUTE(idx);
11141 for (item = 0; item < imux->num_items; item++) {
11142 if (imux->items[item].index == idx) {
11143 if (spec->cur_mux[c] == item)
11144 mute = AMP_IN_UNMUTE(idx);
11145 break;
11146 }
11147 }
11148 /* check if we have a selector or mixer
11149 * we could check for the widget type instead, but
11150 * just check for Amp-In presence (in case of mixer
11151 * without amp-in there is something wrong, this
11152 * function shouldn't be used or capsrc nid is wrong)
11153 */
11154 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP)
11155 snd_hda_codec_write(codec, nid, 0,
11156 AC_VERB_SET_AMP_GAIN_MUTE,
11157 mute);
11158 else if (mute != AMP_IN_MUTE(idx))
11159 snd_hda_codec_write(codec, nid, 0,
11160 AC_VERB_SET_CONNECT_SEL,
11161 idx);
11162 }
11163 }
11164 }
11165
11166 /* add mic boosts if needed */
11167 static int alc_auto_add_mic_boost(struct hda_codec *codec)
11168 {
11169 struct alc_spec *spec = codec->spec;
11170 struct auto_pin_cfg *cfg = &spec->autocfg;
11171 int i, err;
11172 int type_idx = 0;
11173 hda_nid_t nid;
11174 const char *prev_label = NULL;
11175
11176 for (i = 0; i < cfg->num_inputs; i++) {
11177 if (cfg->inputs[i].type > AUTO_PIN_MIC)
11178 break;
11179 nid = cfg->inputs[i].pin;
11180 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
11181 const char *label;
11182 char boost_label[32];
11183
11184 label = hda_get_autocfg_input_label(codec, cfg, i);
11185 if (prev_label && !strcmp(label, prev_label))
11186 type_idx++;
11187 else
11188 type_idx = 0;
11189 prev_label = label;
11190
11191 snprintf(boost_label, sizeof(boost_label),
11192 "%s Boost Volume", label);
11193 err = add_control(spec, ALC_CTL_WIDGET_VOL,
11194 boost_label, type_idx,
11195 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
11196 if (err < 0)
11197 return err;
11198 }
11199 }
11200 return 0;
11201 }
11202
11203 /* almost identical with ALC880 parser... */
11204 static int alc882_parse_auto_config(struct hda_codec *codec)
11205 {
11206 struct alc_spec *spec = codec->spec;
11207 static const hda_nid_t alc882_ignore[] = { 0x1d, 0 };
11208 int err;
11209
11210 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
11211 alc882_ignore);
11212 if (err < 0)
11213 return err;
11214 if (!spec->autocfg.line_outs)
11215 return 0; /* can't find valid BIOS pin config */
11216
11217 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
11218 if (err < 0)
11219 return err;
11220 err = alc_auto_add_multi_channel_mode(codec);
11221 if (err < 0)
11222 return err;
11223 err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg);
11224 if (err < 0)
11225 return err;
11226 err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0],
11227 "Headphone");
11228 if (err < 0)
11229 return err;
11230 err = alc880_auto_create_extra_out(spec,
11231 spec->autocfg.speaker_pins[0],
11232 "Speaker");
11233 if (err < 0)
11234 return err;
11235 err = alc882_auto_create_input_ctls(codec, &spec->autocfg);
11236 if (err < 0)
11237 return err;
11238
11239 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
11240
11241 alc_auto_parse_digital(codec);
11242
11243 if (spec->kctls.list)
11244 add_mixer(spec, spec->kctls.list);
11245
11246 add_verb(spec, alc883_auto_init_verbs);
11247 /* if ADC 0x07 is available, initialize it, too */
11248 if (get_wcaps_type(get_wcaps(codec, 0x07)) == AC_WID_AUD_IN)
11249 add_verb(spec, alc882_adc1_init_verbs);
11250
11251 spec->num_mux_defs = 1;
11252 spec->input_mux = &spec->private_imux[0];
11253
11254 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
11255
11256 err = alc_auto_add_mic_boost(codec);
11257 if (err < 0)
11258 return err;
11259
11260 return 1; /* config found */
11261 }
11262
11263 /* additional initialization for auto-configuration model */
11264 static void alc882_auto_init(struct hda_codec *codec)
11265 {
11266 struct alc_spec *spec = codec->spec;
11267 alc882_auto_init_multi_out(codec);
11268 alc882_auto_init_hp_out(codec);
11269 alc882_auto_init_analog_input(codec);
11270 alc882_auto_init_input_src(codec);
11271 alc_auto_init_digital(codec);
11272 if (spec->unsol_event)
11273 alc_inithook(codec);
11274 }
11275
11276 static int patch_alc882(struct hda_codec *codec)
11277 {
11278 struct alc_spec *spec;
11279 int err, board_config;
11280
11281 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
11282 if (spec == NULL)
11283 return -ENOMEM;
11284
11285 codec->spec = spec;
11286
11287 switch (codec->vendor_id) {
11288 case 0x10ec0882:
11289 case 0x10ec0885:
11290 break;
11291 default:
11292 /* ALC883 and variants */
11293 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
11294 break;
11295 }
11296
11297 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST,
11298 alc882_models,
11299 alc882_cfg_tbl);
11300
11301 if (board_config < 0 || board_config >= ALC882_MODEL_LAST)
11302 board_config = snd_hda_check_board_codec_sid_config(codec,
11303 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
11304
11305 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) {
11306 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
11307 codec->chip_name);
11308 board_config = ALC882_AUTO;
11309 }
11310
11311 if (board_config == ALC882_AUTO) {
11312 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11313 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11314 }
11315
11316 alc_auto_parse_customize_define(codec);
11317
11318 if (board_config == ALC882_AUTO) {
11319 /* automatic parse from the BIOS config */
11320 err = alc882_parse_auto_config(codec);
11321 if (err < 0) {
11322 alc_free(codec);
11323 return err;
11324 } else if (!err) {
11325 printk(KERN_INFO
11326 "hda_codec: Cannot set up configuration "
11327 "from BIOS. Using base mode...\n");
11328 board_config = ALC882_3ST_DIG;
11329 }
11330 }
11331
11332 if (has_cdefine_beep(codec)) {
11333 err = snd_hda_attach_beep_device(codec, 0x1);
11334 if (err < 0) {
11335 alc_free(codec);
11336 return err;
11337 }
11338 }
11339
11340 if (board_config != ALC882_AUTO)
11341 setup_preset(codec, &alc882_presets[board_config]);
11342
11343 spec->stream_analog_playback = &alc882_pcm_analog_playback;
11344 spec->stream_analog_capture = &alc882_pcm_analog_capture;
11345 /* FIXME: setup DAC5 */
11346 /*spec->stream_analog_alt_playback = &alc880_pcm_analog_alt_playback;*/
11347 spec->stream_analog_alt_capture = &alc880_pcm_analog_alt_capture;
11348
11349 spec->stream_digital_playback = &alc882_pcm_digital_playback;
11350 spec->stream_digital_capture = &alc882_pcm_digital_capture;
11351
11352 if (!spec->adc_nids && spec->input_mux) {
11353 int i, j;
11354 spec->num_adc_nids = 0;
11355 for (i = 0; i < ARRAY_SIZE(alc882_adc_nids); i++) {
11356 const struct hda_input_mux *imux = spec->input_mux;
11357 hda_nid_t cap;
11358 hda_nid_t items[16];
11359 hda_nid_t nid = alc882_adc_nids[i];
11360 unsigned int wcap = get_wcaps(codec, nid);
11361 /* get type */
11362 wcap = get_wcaps_type(wcap);
11363 if (wcap != AC_WID_AUD_IN)
11364 continue;
11365 spec->private_adc_nids[spec->num_adc_nids] = nid;
11366 err = snd_hda_get_connections(codec, nid, &cap, 1);
11367 if (err < 0)
11368 continue;
11369 err = snd_hda_get_connections(codec, cap, items,
11370 ARRAY_SIZE(items));
11371 if (err < 0)
11372 continue;
11373 for (j = 0; j < imux->num_items; j++)
11374 if (imux->items[j].index >= err)
11375 break;
11376 if (j < imux->num_items)
11377 continue;
11378 spec->private_capsrc_nids[spec->num_adc_nids] = cap;
11379 spec->num_adc_nids++;
11380 }
11381 spec->adc_nids = spec->private_adc_nids;
11382 spec->capsrc_nids = spec->private_capsrc_nids;
11383 }
11384
11385 set_capture_mixer(codec);
11386
11387 if (has_cdefine_beep(codec))
11388 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
11389
11390 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
11391
11392 spec->vmaster_nid = 0x0c;
11393
11394 codec->patch_ops = alc_patch_ops;
11395 if (board_config == ALC882_AUTO)
11396 spec->init_hook = alc882_auto_init;
11397
11398 alc_init_jacks(codec);
11399 #ifdef CONFIG_SND_HDA_POWER_SAVE
11400 if (!spec->loopback.amplist)
11401 spec->loopback.amplist = alc882_loopbacks;
11402 #endif
11403
11404 return 0;
11405 }
11406
11407
11408 /*
11409 * ALC262 support
11410 */
11411
11412 #define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11413 #define ALC262_DIGIN_NID ALC880_DIGIN_NID
11414
11415 #define alc262_dac_nids alc260_dac_nids
11416 #define alc262_adc_nids alc882_adc_nids
11417 #define alc262_adc_nids_alt alc882_adc_nids_alt
11418 #define alc262_capsrc_nids alc882_capsrc_nids
11419 #define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
11420
11421 #define alc262_modes alc260_modes
11422 #define alc262_capture_source alc882_capture_source
11423
11424 static const hda_nid_t alc262_dmic_adc_nids[1] = {
11425 /* ADC0 */
11426 0x09
11427 };
11428
11429 static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11430
11431 static const struct snd_kcontrol_new alc262_base_mixer[] = {
11432 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11433 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11434 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11435 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11436 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11437 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11438 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11439 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11440 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11441 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11442 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11443 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11444 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11445 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11446 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11447 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11448 { } /* end */
11449 };
11450
11451 /* update HP, line and mono-out pins according to the master switch */
11452 #define alc262_hp_master_update alc260_hp_master_update
11453
11454 static void alc262_hp_bpc_setup(struct hda_codec *codec)
11455 {
11456 struct alc_spec *spec = codec->spec;
11457
11458 spec->autocfg.hp_pins[0] = 0x1b;
11459 spec->autocfg.speaker_pins[0] = 0x16;
11460 spec->automute = 1;
11461 spec->automute_mode = ALC_AUTOMUTE_PIN;
11462 }
11463
11464 static void alc262_hp_wildwest_setup(struct hda_codec *codec)
11465 {
11466 struct alc_spec *spec = codec->spec;
11467
11468 spec->autocfg.hp_pins[0] = 0x15;
11469 spec->autocfg.speaker_pins[0] = 0x16;
11470 spec->automute = 1;
11471 spec->automute_mode = ALC_AUTOMUTE_PIN;
11472 }
11473
11474 #define alc262_hp_master_sw_get alc260_hp_master_sw_get
11475 #define alc262_hp_master_sw_put alc260_hp_master_sw_put
11476
11477 #define ALC262_HP_MASTER_SWITCH \
11478 { \
11479 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11480 .name = "Master Playback Switch", \
11481 .info = snd_ctl_boolean_mono_info, \
11482 .get = alc262_hp_master_sw_get, \
11483 .put = alc262_hp_master_sw_put, \
11484 }, \
11485 { \
11486 .iface = NID_MAPPING, \
11487 .name = "Master Playback Switch", \
11488 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
11489 }
11490
11491
11492 static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
11493 ALC262_HP_MASTER_SWITCH,
11494 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11495 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11496 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11497 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11498 HDA_OUTPUT),
11499 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11500 HDA_OUTPUT),
11501 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11502 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11503 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11504 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11505 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11506 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11507 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11508 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11509 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11510 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11511 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11512 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11513 { } /* end */
11514 };
11515
11516 static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11517 ALC262_HP_MASTER_SWITCH,
11518 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11519 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11520 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11521 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11522 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11523 HDA_OUTPUT),
11524 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11525 HDA_OUTPUT),
11526 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11527 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
11528 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
11529 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11530 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11531 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11532 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11533 { } /* end */
11534 };
11535
11536 static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11537 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11538 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11539 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
11540 { } /* end */
11541 };
11542
11543 /* mute/unmute internal speaker according to the hp jack and mute state */
11544 static void alc262_hp_t5735_setup(struct hda_codec *codec)
11545 {
11546 struct alc_spec *spec = codec->spec;
11547
11548 spec->autocfg.hp_pins[0] = 0x15;
11549 spec->autocfg.speaker_pins[0] = 0x14;
11550 spec->automute = 1;
11551 spec->automute_mode = ALC_AUTOMUTE_PIN;
11552 }
11553
11554 static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
11555 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11556 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11557 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11558 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11559 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11560 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11561 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11562 { } /* end */
11563 };
11564
11565 static const struct hda_verb alc262_hp_t5735_verbs[] = {
11566 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11567 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11568
11569 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11570 { }
11571 };
11572
11573 static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
11574 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11575 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11576 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11577 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
11578 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11579 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11580 { } /* end */
11581 };
11582
11583 static const struct hda_verb alc262_hp_rp5700_verbs[] = {
11584 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11585 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11586 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11587 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11588 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11589 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11590 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11591 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11592 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11593 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11594 {}
11595 };
11596
11597 static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
11598 .num_items = 1,
11599 .items = {
11600 { "Line", 0x1 },
11601 },
11602 };
11603
11604 /* bind hp and internal speaker mute (with plug check) as master switch */
11605 #define alc262_hippo_master_update alc262_hp_master_update
11606 #define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11607 #define alc262_hippo_master_sw_put alc262_hp_master_sw_put
11608
11609 #define ALC262_HIPPO_MASTER_SWITCH \
11610 { \
11611 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11612 .name = "Master Playback Switch", \
11613 .info = snd_ctl_boolean_mono_info, \
11614 .get = alc262_hippo_master_sw_get, \
11615 .put = alc262_hippo_master_sw_put, \
11616 }, \
11617 { \
11618 .iface = NID_MAPPING, \
11619 .name = "Master Playback Switch", \
11620 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11621 (SUBDEV_SPEAKER(0) << 16), \
11622 }
11623
11624 static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
11625 ALC262_HIPPO_MASTER_SWITCH,
11626 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11627 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11628 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11629 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11630 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11631 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11632 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11633 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11634 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11635 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11636 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11637 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11638 { } /* end */
11639 };
11640
11641 static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11642 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11643 ALC262_HIPPO_MASTER_SWITCH,
11644 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11645 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11646 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11647 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11648 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11649 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11650 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11651 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11652 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11653 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11654 { } /* end */
11655 };
11656
11657 /* mute/unmute internal speaker according to the hp jack and mute state */
11658 static void alc262_hippo_setup(struct hda_codec *codec)
11659 {
11660 struct alc_spec *spec = codec->spec;
11661
11662 spec->autocfg.hp_pins[0] = 0x15;
11663 spec->autocfg.speaker_pins[0] = 0x14;
11664 spec->automute = 1;
11665 spec->automute_mode = ALC_AUTOMUTE_AMP;
11666 }
11667
11668 static void alc262_hippo1_setup(struct hda_codec *codec)
11669 {
11670 struct alc_spec *spec = codec->spec;
11671
11672 spec->autocfg.hp_pins[0] = 0x1b;
11673 spec->autocfg.speaker_pins[0] = 0x14;
11674 spec->automute = 1;
11675 spec->automute_mode = ALC_AUTOMUTE_AMP;
11676 }
11677
11678
11679 static const struct snd_kcontrol_new alc262_sony_mixer[] = {
11680 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11681 ALC262_HIPPO_MASTER_SWITCH,
11682 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11683 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11684 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11685 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11686 { } /* end */
11687 };
11688
11689 static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
11690 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11691 ALC262_HIPPO_MASTER_SWITCH,
11692 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11693 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11694 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11695 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11696 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11697 { } /* end */
11698 };
11699
11700 static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
11701 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11702 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11703 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11704 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11705 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11706 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11707 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11708 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11709 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11710 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11711 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11712 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11713 { } /* end */
11714 };
11715
11716 static const struct hda_verb alc262_tyan_verbs[] = {
11717 /* Headphone automute */
11718 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11719 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11720 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11721
11722 /* P11 AUX_IN, white 4-pin connector */
11723 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11724 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11725 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11726 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11727
11728 {}
11729 };
11730
11731 /* unsolicited event for HP jack sensing */
11732 static void alc262_tyan_setup(struct hda_codec *codec)
11733 {
11734 struct alc_spec *spec = codec->spec;
11735
11736 spec->autocfg.hp_pins[0] = 0x1b;
11737 spec->autocfg.speaker_pins[0] = 0x15;
11738 spec->automute = 1;
11739 spec->automute_mode = ALC_AUTOMUTE_AMP;
11740 }
11741
11742
11743 #define alc262_capture_mixer alc882_capture_mixer
11744 #define alc262_capture_alt_mixer alc882_capture_alt_mixer
11745
11746 /*
11747 * generic initialization of ADC, input mixers and output mixers
11748 */
11749 static const struct hda_verb alc262_init_verbs[] = {
11750 /*
11751 * Unmute ADC0-2 and set the default input to mic-in
11752 */
11753 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11754 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11755 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11756 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11757 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11758 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11759
11760 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11761 * mixer widget
11762 * Note: PASD motherboards uses the Line In 2 as the input for
11763 * front panel mic (mic 2)
11764 */
11765 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11766 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11767 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11768 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11769 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11770 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11771
11772 /*
11773 * Set up output mixers (0x0c - 0x0e)
11774 */
11775 /* set vol=0 to output mixers */
11776 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11777 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11778 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11779 /* set up input amps for analog loopback */
11780 /* Amp Indices: DAC = 0, mixer = 1 */
11781 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11782 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11783 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11784 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11785 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11786 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11787
11788 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11789 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11790 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11791 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11792 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11793 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11794
11795 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11796 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11797 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11798 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11799 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11800
11801 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11802 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11803
11804 /* FIXME: use matrix-type input source selection */
11805 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11806 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11807 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11808 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11809 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11810 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11811 /* Input mixer2 */
11812 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11813 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11814 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11815 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11816 /* Input mixer3 */
11817 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11818 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11819 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11820 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11821
11822 { }
11823 };
11824
11825 static const struct hda_verb alc262_eapd_verbs[] = {
11826 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11827 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11828 { }
11829 };
11830
11831 static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
11832 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11833 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11834 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11835
11836 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11837 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11838 {}
11839 };
11840
11841 static const struct hda_verb alc262_sony_unsol_verbs[] = {
11842 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11843 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11844 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11845
11846 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11847 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11848 {}
11849 };
11850
11851 static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11852 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11853 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11854 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11855 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11856 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11857 { } /* end */
11858 };
11859
11860 static const struct hda_verb alc262_toshiba_s06_verbs[] = {
11861 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11862 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11863 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11864 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11865 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11866 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11867 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11868 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11869 {}
11870 };
11871
11872 static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11873 {
11874 struct alc_spec *spec = codec->spec;
11875
11876 spec->autocfg.hp_pins[0] = 0x15;
11877 spec->autocfg.speaker_pins[0] = 0x14;
11878 spec->ext_mic.pin = 0x18;
11879 spec->ext_mic.mux_idx = 0;
11880 spec->int_mic.pin = 0x12;
11881 spec->int_mic.mux_idx = 9;
11882 spec->auto_mic = 1;
11883 spec->automute = 1;
11884 spec->automute_mode = ALC_AUTOMUTE_PIN;
11885 }
11886
11887 /*
11888 * nec model
11889 * 0x15 = headphone
11890 * 0x16 = internal speaker
11891 * 0x18 = external mic
11892 */
11893
11894 static const struct snd_kcontrol_new alc262_nec_mixer[] = {
11895 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11896 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11897
11898 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11899 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11900 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11901
11902 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11903 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11904 { } /* end */
11905 };
11906
11907 static const struct hda_verb alc262_nec_verbs[] = {
11908 /* Unmute Speaker */
11909 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11910
11911 /* Headphone */
11912 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11913 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11914
11915 /* External mic to headphone */
11916 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11917 /* External mic to speaker */
11918 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11919 {}
11920 };
11921
11922 /*
11923 * fujitsu model
11924 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11925 * 0x1b = port replicator headphone out
11926 */
11927
11928 #define ALC_HP_EVENT ALC880_HP_EVENT
11929
11930 static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11931 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11932 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11933 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11934 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11935 {}
11936 };
11937
11938 static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11939 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11940 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11941 {}
11942 };
11943
11944 static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11945 /* Front Mic pin: input vref at 50% */
11946 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11947 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11948 {}
11949 };
11950
11951 static const struct hda_input_mux alc262_fujitsu_capture_source = {
11952 .num_items = 3,
11953 .items = {
11954 { "Mic", 0x0 },
11955 { "Internal Mic", 0x1 },
11956 { "CD", 0x4 },
11957 },
11958 };
11959
11960 static const struct hda_input_mux alc262_HP_capture_source = {
11961 .num_items = 5,
11962 .items = {
11963 { "Mic", 0x0 },
11964 { "Front Mic", 0x1 },
11965 { "Line", 0x2 },
11966 { "CD", 0x4 },
11967 { "AUX IN", 0x6 },
11968 },
11969 };
11970
11971 static const struct hda_input_mux alc262_HP_D7000_capture_source = {
11972 .num_items = 4,
11973 .items = {
11974 { "Mic", 0x0 },
11975 { "Front Mic", 0x2 },
11976 { "Line", 0x1 },
11977 { "CD", 0x4 },
11978 },
11979 };
11980
11981 static void alc262_fujitsu_setup(struct hda_codec *codec)
11982 {
11983 struct alc_spec *spec = codec->spec;
11984
11985 spec->autocfg.hp_pins[0] = 0x14;
11986 spec->autocfg.hp_pins[1] = 0x1b;
11987 spec->autocfg.speaker_pins[0] = 0x15;
11988 spec->automute = 1;
11989 spec->automute_mode = ALC_AUTOMUTE_AMP;
11990 }
11991
11992 /* bind volumes of both NID 0x0c and 0x0d */
11993 static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11994 .ops = &snd_hda_bind_vol,
11995 .values = {
11996 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11997 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11998 0
11999 },
12000 };
12001
12002 static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
12003 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12004 {
12005 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12006 .name = "Master Playback Switch",
12007 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12008 .info = snd_ctl_boolean_mono_info,
12009 .get = alc262_hp_master_sw_get,
12010 .put = alc262_hp_master_sw_put,
12011 },
12012 {
12013 .iface = NID_MAPPING,
12014 .name = "Master Playback Switch",
12015 .private_value = 0x1b,
12016 },
12017 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12018 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12019 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12020 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12021 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12022 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12023 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12024 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12025 { } /* end */
12026 };
12027
12028 static void alc262_lenovo_3000_setup(struct hda_codec *codec)
12029 {
12030 struct alc_spec *spec = codec->spec;
12031
12032 spec->autocfg.hp_pins[0] = 0x1b;
12033 spec->autocfg.speaker_pins[0] = 0x14;
12034 spec->autocfg.speaker_pins[1] = 0x16;
12035 spec->automute = 1;
12036 spec->automute_mode = ALC_AUTOMUTE_AMP;
12037 }
12038
12039 static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
12040 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12041 {
12042 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12043 .name = "Master Playback Switch",
12044 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
12045 .info = snd_ctl_boolean_mono_info,
12046 .get = alc262_hp_master_sw_get,
12047 .put = alc262_hp_master_sw_put,
12048 },
12049 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
12050 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
12051 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12052 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12053 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12054 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12055 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
12056 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
12057 { } /* end */
12058 };
12059
12060 static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
12061 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
12062 ALC262_HIPPO_MASTER_SWITCH,
12063 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
12064 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
12065 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12066 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12067 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12068 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
12069 { } /* end */
12070 };
12071
12072 /* additional init verbs for Benq laptops */
12073 static const struct hda_verb alc262_EAPD_verbs[] = {
12074 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12075 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
12076 {}
12077 };
12078
12079 static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
12080 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12081 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12082
12083 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
12084 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
12085 {}
12086 };
12087
12088 /* Samsung Q1 Ultra Vista model setup */
12089 static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
12090 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
12091 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
12092 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
12093 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
12094 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
12095 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
12096 { } /* end */
12097 };
12098
12099 static const struct hda_verb alc262_ultra_verbs[] = {
12100 /* output mixer */
12101 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12102 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12103 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12104 /* speaker */
12105 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12106 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12107 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12108 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
12109 /* HP */
12110 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12111 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12112 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12113 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12114 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12115 /* internal mic */
12116 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12117 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12118 /* ADC, choose mic */
12119 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12120 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12121 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12122 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12123 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12124 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12125 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12126 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12127 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12128 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
12129 {}
12130 };
12131
12132 /* mute/unmute internal speaker according to the hp jack and mute state */
12133 static void alc262_ultra_automute(struct hda_codec *codec)
12134 {
12135 struct alc_spec *spec = codec->spec;
12136 unsigned int mute;
12137
12138 mute = 0;
12139 /* auto-mute only when HP is used as HP */
12140 if (!spec->cur_mux[0]) {
12141 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
12142 if (spec->jack_present)
12143 mute = HDA_AMP_MUTE;
12144 }
12145 /* mute/unmute internal speaker */
12146 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
12147 HDA_AMP_MUTE, mute);
12148 /* mute/unmute HP */
12149 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
12150 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
12151 }
12152
12153 /* unsolicited event for HP jack sensing */
12154 static void alc262_ultra_unsol_event(struct hda_codec *codec,
12155 unsigned int res)
12156 {
12157 if ((res >> 26) != ALC880_HP_EVENT)
12158 return;
12159 alc262_ultra_automute(codec);
12160 }
12161
12162 static const struct hda_input_mux alc262_ultra_capture_source = {
12163 .num_items = 2,
12164 .items = {
12165 { "Mic", 0x1 },
12166 { "Headphone", 0x7 },
12167 },
12168 };
12169
12170 static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
12171 struct snd_ctl_elem_value *ucontrol)
12172 {
12173 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
12174 struct alc_spec *spec = codec->spec;
12175 int ret;
12176
12177 ret = alc_mux_enum_put(kcontrol, ucontrol);
12178 if (!ret)
12179 return 0;
12180 /* reprogram the HP pin as mic or HP according to the input source */
12181 snd_hda_codec_write_cache(codec, 0x15, 0,
12182 AC_VERB_SET_PIN_WIDGET_CONTROL,
12183 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
12184 alc262_ultra_automute(codec); /* mute/unmute HP */
12185 return ret;
12186 }
12187
12188 static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
12189 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
12190 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
12191 {
12192 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12193 .name = "Capture Source",
12194 .info = alc_mux_enum_info,
12195 .get = alc_mux_enum_get,
12196 .put = alc262_ultra_mux_enum_put,
12197 },
12198 {
12199 .iface = NID_MAPPING,
12200 .name = "Capture Source",
12201 .private_value = 0x15,
12202 },
12203 { } /* end */
12204 };
12205
12206 /* We use two mixers depending on the output pin; 0x16 is a mono output
12207 * and thus it's bound with a different mixer.
12208 * This function returns which mixer amp should be used.
12209 */
12210 static int alc262_check_volbit(hda_nid_t nid)
12211 {
12212 if (!nid)
12213 return 0;
12214 else if (nid == 0x16)
12215 return 2;
12216 else
12217 return 1;
12218 }
12219
12220 static int alc262_add_out_vol_ctl(struct alc_spec *spec, hda_nid_t nid,
12221 const char *pfx, int *vbits, int idx)
12222 {
12223 unsigned long val;
12224 int vbit;
12225
12226 vbit = alc262_check_volbit(nid);
12227 if (!vbit)
12228 return 0;
12229 if (*vbits & vbit) /* a volume control for this mixer already there */
12230 return 0;
12231 *vbits |= vbit;
12232 if (vbit == 2)
12233 val = HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT);
12234 else
12235 val = HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT);
12236 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx, val);
12237 }
12238
12239 static int alc262_add_out_sw_ctl(struct alc_spec *spec, hda_nid_t nid,
12240 const char *pfx, int idx)
12241 {
12242 unsigned long val;
12243
12244 if (!nid)
12245 return 0;
12246 if (nid == 0x16)
12247 val = HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT);
12248 else
12249 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
12250 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx, val);
12251 }
12252
12253 /* add playback controls from the parsed DAC table */
12254 static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
12255 const struct auto_pin_cfg *cfg)
12256 {
12257 const char *pfx;
12258 int vbits;
12259 int i, err;
12260
12261 spec->multiout.num_dacs = 1; /* only use one dac */
12262 spec->multiout.dac_nids = spec->private_dac_nids;
12263 spec->private_dac_nids[0] = 2;
12264
12265 pfx = alc_get_line_out_pfx(spec, true);
12266 if (!pfx)
12267 pfx = "Front";
12268 for (i = 0; i < 2; i++) {
12269 err = alc262_add_out_sw_ctl(spec, cfg->line_out_pins[i], pfx, i);
12270 if (err < 0)
12271 return err;
12272 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12273 err = alc262_add_out_sw_ctl(spec, cfg->speaker_pins[i],
12274 "Speaker", i);
12275 if (err < 0)
12276 return err;
12277 }
12278 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12279 err = alc262_add_out_sw_ctl(spec, cfg->hp_pins[i],
12280 "Headphone", i);
12281 if (err < 0)
12282 return err;
12283 }
12284 }
12285
12286 vbits = alc262_check_volbit(cfg->line_out_pins[0]) |
12287 alc262_check_volbit(cfg->speaker_pins[0]) |
12288 alc262_check_volbit(cfg->hp_pins[0]);
12289 if (vbits == 1 || vbits == 2)
12290 pfx = "Master"; /* only one mixer is used */
12291 vbits = 0;
12292 for (i = 0; i < 2; i++) {
12293 err = alc262_add_out_vol_ctl(spec, cfg->line_out_pins[i], pfx,
12294 &vbits, i);
12295 if (err < 0)
12296 return err;
12297 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
12298 err = alc262_add_out_vol_ctl(spec, cfg->speaker_pins[i],
12299 "Speaker", &vbits, i);
12300 if (err < 0)
12301 return err;
12302 }
12303 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
12304 err = alc262_add_out_vol_ctl(spec, cfg->hp_pins[i],
12305 "Headphone", &vbits, i);
12306 if (err < 0)
12307 return err;
12308 }
12309 }
12310 return 0;
12311 }
12312
12313 #define alc262_auto_create_input_ctls \
12314 alc882_auto_create_input_ctls
12315
12316 /*
12317 * generic initialization of ADC, input mixers and output mixers
12318 */
12319 static const struct hda_verb alc262_volume_init_verbs[] = {
12320 /*
12321 * Unmute ADC0-2 and set the default input to mic-in
12322 */
12323 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12324 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12325 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12326 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12327 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12328 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12329
12330 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12331 * mixer widget
12332 * Note: PASD motherboards uses the Line In 2 as the input for
12333 * front panel mic (mic 2)
12334 */
12335 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12336 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12337 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12338 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12339 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12340 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12341
12342 /*
12343 * Set up output mixers (0x0c - 0x0f)
12344 */
12345 /* set vol=0 to output mixers */
12346 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12347 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12348 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12349
12350 /* set up input amps for analog loopback */
12351 /* Amp Indices: DAC = 0, mixer = 1 */
12352 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12353 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12354 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12355 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12356 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12357 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12358
12359 /* FIXME: use matrix-type input source selection */
12360 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12361 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12362 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12363 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12364 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12365 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12366 /* Input mixer2 */
12367 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12368 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12369 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12370 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12371 /* Input mixer3 */
12372 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12373 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12374 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12375 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12376
12377 { }
12378 };
12379
12380 static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
12381 /*
12382 * Unmute ADC0-2 and set the default input to mic-in
12383 */
12384 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12385 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12386 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12387 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12388 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12389 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12390
12391 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12392 * mixer widget
12393 * Note: PASD motherboards uses the Line In 2 as the input for
12394 * front panel mic (mic 2)
12395 */
12396 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12397 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12398 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12399 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12400 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12401 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12402 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12403 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12404
12405 /*
12406 * Set up output mixers (0x0c - 0x0e)
12407 */
12408 /* set vol=0 to output mixers */
12409 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12410 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12411 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12412
12413 /* set up input amps for analog loopback */
12414 /* Amp Indices: DAC = 0, mixer = 1 */
12415 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12416 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12417 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12418 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12419 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12420 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12421
12422 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12423 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12424 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12425
12426 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12427 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12428
12429 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12430 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12431
12432 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12433 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12434 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12435 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12436 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12437
12438 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12439 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12440 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12441 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12442 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12443 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12444
12445
12446 /* FIXME: use matrix-type input source selection */
12447 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12448 /* Input mixer1: only unmute Mic */
12449 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12450 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12451 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12452 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12453 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12454 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12455 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12456 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12457 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12458 /* Input mixer2 */
12459 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12460 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12461 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12462 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12463 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12464 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12465 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12466 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12467 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12468 /* Input mixer3 */
12469 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12470 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12471 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12472 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12473 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12474 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12475 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12476 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12477 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12478
12479 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12480
12481 { }
12482 };
12483
12484 static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12485 /*
12486 * Unmute ADC0-2 and set the default input to mic-in
12487 */
12488 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12489 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12490 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12491 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12492 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12493 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12494
12495 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12496 * mixer widget
12497 * Note: PASD motherboards uses the Line In 2 as the input for front
12498 * panel mic (mic 2)
12499 */
12500 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12501 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12502 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12503 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12504 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12505 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12506 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12507 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12508 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12509 /*
12510 * Set up output mixers (0x0c - 0x0e)
12511 */
12512 /* set vol=0 to output mixers */
12513 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12514 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12515 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12516
12517 /* set up input amps for analog loopback */
12518 /* Amp Indices: DAC = 0, mixer = 1 */
12519 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12520 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12521 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12522 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12523 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12524 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12525
12526
12527 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12528 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12529 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12530 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12531 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12532 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12533 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12534
12535 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12536 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12537
12538 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12539 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12540
12541 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12542 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12543 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12544 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12545 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12546 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12547
12548 /* FIXME: use matrix-type input source selection */
12549 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12550 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12551 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12552 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12553 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12554 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12555 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12556 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12557 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12558 /* Input mixer2 */
12559 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12560 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12561 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12562 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12563 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12564 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12565 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12566 /* Input mixer3 */
12567 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12568 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12569 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12570 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12571 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12572 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12573 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12574
12575 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12576
12577 { }
12578 };
12579
12580 static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12581
12582 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12583 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12584 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12585
12586 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12587 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12588 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12589 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12590
12591 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12592 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12593 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12594 {}
12595 };
12596
12597 /*
12598 * Pin config fixes
12599 */
12600 enum {
12601 PINFIX_FSC_H270,
12602 };
12603
12604 static const struct alc_fixup alc262_fixups[] = {
12605 [PINFIX_FSC_H270] = {
12606 .type = ALC_FIXUP_PINS,
12607 .v.pins = (const struct alc_pincfg[]) {
12608 { 0x14, 0x99130110 }, /* speaker */
12609 { 0x15, 0x0221142f }, /* front HP */
12610 { 0x1b, 0x0121141f }, /* rear HP */
12611 { }
12612 }
12613 },
12614 };
12615
12616 static const struct snd_pci_quirk alc262_fixup_tbl[] = {
12617 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12618 {}
12619 };
12620
12621
12622 #ifdef CONFIG_SND_HDA_POWER_SAVE
12623 #define alc262_loopbacks alc880_loopbacks
12624 #endif
12625
12626 /* pcm configuration: identical with ALC880 */
12627 #define alc262_pcm_analog_playback alc880_pcm_analog_playback
12628 #define alc262_pcm_analog_capture alc880_pcm_analog_capture
12629 #define alc262_pcm_digital_playback alc880_pcm_digital_playback
12630 #define alc262_pcm_digital_capture alc880_pcm_digital_capture
12631
12632 /*
12633 * BIOS auto configuration
12634 */
12635 static int alc262_parse_auto_config(struct hda_codec *codec)
12636 {
12637 struct alc_spec *spec = codec->spec;
12638 int err;
12639 static const hda_nid_t alc262_ignore[] = { 0x1d, 0 };
12640
12641 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
12642 alc262_ignore);
12643 if (err < 0)
12644 return err;
12645 if (!spec->autocfg.line_outs) {
12646 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
12647 spec->multiout.max_channels = 2;
12648 spec->no_analog = 1;
12649 goto dig_only;
12650 }
12651 return 0; /* can't find valid BIOS pin config */
12652 }
12653 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
12654 if (err < 0)
12655 return err;
12656 err = alc262_auto_create_input_ctls(codec, &spec->autocfg);
12657 if (err < 0)
12658 return err;
12659
12660 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
12661
12662 dig_only:
12663 alc_auto_parse_digital(codec);
12664
12665 if (spec->kctls.list)
12666 add_mixer(spec, spec->kctls.list);
12667
12668 add_verb(spec, alc262_volume_init_verbs);
12669 spec->num_mux_defs = 1;
12670 spec->input_mux = &spec->private_imux[0];
12671
12672 err = alc_auto_add_mic_boost(codec);
12673 if (err < 0)
12674 return err;
12675
12676 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
12677
12678 return 1;
12679 }
12680
12681 #define alc262_auto_init_multi_out alc882_auto_init_multi_out
12682 #define alc262_auto_init_hp_out alc882_auto_init_hp_out
12683 #define alc262_auto_init_analog_input alc882_auto_init_analog_input
12684 #define alc262_auto_init_input_src alc882_auto_init_input_src
12685
12686
12687 /* init callback for auto-configuration model -- overriding the default init */
12688 static void alc262_auto_init(struct hda_codec *codec)
12689 {
12690 struct alc_spec *spec = codec->spec;
12691 alc262_auto_init_multi_out(codec);
12692 alc262_auto_init_hp_out(codec);
12693 alc262_auto_init_analog_input(codec);
12694 alc262_auto_init_input_src(codec);
12695 alc_auto_init_digital(codec);
12696 if (spec->unsol_event)
12697 alc_inithook(codec);
12698 }
12699
12700 /*
12701 * configuration and preset
12702 */
12703 static const char * const alc262_models[ALC262_MODEL_LAST] = {
12704 [ALC262_BASIC] = "basic",
12705 [ALC262_HIPPO] = "hippo",
12706 [ALC262_HIPPO_1] = "hippo_1",
12707 [ALC262_FUJITSU] = "fujitsu",
12708 [ALC262_HP_BPC] = "hp-bpc",
12709 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
12710 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
12711 [ALC262_HP_RP5700] = "hp-rp5700",
12712 [ALC262_BENQ_ED8] = "benq",
12713 [ALC262_BENQ_T31] = "benq-t31",
12714 [ALC262_SONY_ASSAMD] = "sony-assamd",
12715 [ALC262_TOSHIBA_S06] = "toshiba-s06",
12716 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
12717 [ALC262_ULTRA] = "ultra",
12718 [ALC262_LENOVO_3000] = "lenovo-3000",
12719 [ALC262_NEC] = "nec",
12720 [ALC262_TYAN] = "tyan",
12721 [ALC262_AUTO] = "auto",
12722 };
12723
12724 static const struct snd_pci_quirk alc262_cfg_tbl[] = {
12725 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
12726 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
12727 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12728 ALC262_HP_BPC),
12729 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12730 ALC262_HP_BPC),
12731 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12732 ALC262_HP_BPC),
12733 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12734 ALC262_HP_BPC),
12735 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
12736 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
12737 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
12738 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
12739 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
12740 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
12741 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
12742 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
12743 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12744 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12745 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
12746 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12747 ALC262_HP_TC_T5735),
12748 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
12749 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12750 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
12751 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12752 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
12753 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
12754 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12755 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
12756 #if 0 /* disable the quirk since model=auto works better in recent versions */
12757 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12758 ALC262_SONY_ASSAMD),
12759 #endif
12760 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
12761 ALC262_TOSHIBA_RX1),
12762 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
12763 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
12764 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
12765 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
12766 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12767 ALC262_ULTRA),
12768 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
12769 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
12770 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12771 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12772 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
12773 {}
12774 };
12775
12776 static const struct alc_config_preset alc262_presets[] = {
12777 [ALC262_BASIC] = {
12778 .mixers = { alc262_base_mixer },
12779 .init_verbs = { alc262_init_verbs },
12780 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12781 .dac_nids = alc262_dac_nids,
12782 .hp_nid = 0x03,
12783 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12784 .channel_mode = alc262_modes,
12785 .input_mux = &alc262_capture_source,
12786 },
12787 [ALC262_HIPPO] = {
12788 .mixers = { alc262_hippo_mixer },
12789 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
12790 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12791 .dac_nids = alc262_dac_nids,
12792 .hp_nid = 0x03,
12793 .dig_out_nid = ALC262_DIGOUT_NID,
12794 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12795 .channel_mode = alc262_modes,
12796 .input_mux = &alc262_capture_source,
12797 .unsol_event = alc_sku_unsol_event,
12798 .setup = alc262_hippo_setup,
12799 .init_hook = alc_inithook,
12800 },
12801 [ALC262_HIPPO_1] = {
12802 .mixers = { alc262_hippo1_mixer },
12803 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12804 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12805 .dac_nids = alc262_dac_nids,
12806 .hp_nid = 0x02,
12807 .dig_out_nid = ALC262_DIGOUT_NID,
12808 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12809 .channel_mode = alc262_modes,
12810 .input_mux = &alc262_capture_source,
12811 .unsol_event = alc_sku_unsol_event,
12812 .setup = alc262_hippo1_setup,
12813 .init_hook = alc_inithook,
12814 },
12815 [ALC262_FUJITSU] = {
12816 .mixers = { alc262_fujitsu_mixer },
12817 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12818 alc262_fujitsu_unsol_verbs },
12819 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12820 .dac_nids = alc262_dac_nids,
12821 .hp_nid = 0x03,
12822 .dig_out_nid = ALC262_DIGOUT_NID,
12823 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12824 .channel_mode = alc262_modes,
12825 .input_mux = &alc262_fujitsu_capture_source,
12826 .unsol_event = alc_sku_unsol_event,
12827 .setup = alc262_fujitsu_setup,
12828 .init_hook = alc_inithook,
12829 },
12830 [ALC262_HP_BPC] = {
12831 .mixers = { alc262_HP_BPC_mixer },
12832 .init_verbs = { alc262_HP_BPC_init_verbs },
12833 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12834 .dac_nids = alc262_dac_nids,
12835 .hp_nid = 0x03,
12836 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12837 .channel_mode = alc262_modes,
12838 .input_mux = &alc262_HP_capture_source,
12839 .unsol_event = alc_sku_unsol_event,
12840 .setup = alc262_hp_bpc_setup,
12841 .init_hook = alc_inithook,
12842 },
12843 [ALC262_HP_BPC_D7000_WF] = {
12844 .mixers = { alc262_HP_BPC_WildWest_mixer },
12845 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12846 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12847 .dac_nids = alc262_dac_nids,
12848 .hp_nid = 0x03,
12849 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12850 .channel_mode = alc262_modes,
12851 .input_mux = &alc262_HP_D7000_capture_source,
12852 .unsol_event = alc_sku_unsol_event,
12853 .setup = alc262_hp_wildwest_setup,
12854 .init_hook = alc_inithook,
12855 },
12856 [ALC262_HP_BPC_D7000_WL] = {
12857 .mixers = { alc262_HP_BPC_WildWest_mixer,
12858 alc262_HP_BPC_WildWest_option_mixer },
12859 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12860 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12861 .dac_nids = alc262_dac_nids,
12862 .hp_nid = 0x03,
12863 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12864 .channel_mode = alc262_modes,
12865 .input_mux = &alc262_HP_D7000_capture_source,
12866 .unsol_event = alc_sku_unsol_event,
12867 .setup = alc262_hp_wildwest_setup,
12868 .init_hook = alc_inithook,
12869 },
12870 [ALC262_HP_TC_T5735] = {
12871 .mixers = { alc262_hp_t5735_mixer },
12872 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12873 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12874 .dac_nids = alc262_dac_nids,
12875 .hp_nid = 0x03,
12876 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12877 .channel_mode = alc262_modes,
12878 .input_mux = &alc262_capture_source,
12879 .unsol_event = alc_sku_unsol_event,
12880 .setup = alc262_hp_t5735_setup,
12881 .init_hook = alc_inithook,
12882 },
12883 [ALC262_HP_RP5700] = {
12884 .mixers = { alc262_hp_rp5700_mixer },
12885 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12886 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12887 .dac_nids = alc262_dac_nids,
12888 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12889 .channel_mode = alc262_modes,
12890 .input_mux = &alc262_hp_rp5700_capture_source,
12891 },
12892 [ALC262_BENQ_ED8] = {
12893 .mixers = { alc262_base_mixer },
12894 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12895 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12896 .dac_nids = alc262_dac_nids,
12897 .hp_nid = 0x03,
12898 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12899 .channel_mode = alc262_modes,
12900 .input_mux = &alc262_capture_source,
12901 },
12902 [ALC262_SONY_ASSAMD] = {
12903 .mixers = { alc262_sony_mixer },
12904 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12905 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12906 .dac_nids = alc262_dac_nids,
12907 .hp_nid = 0x02,
12908 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12909 .channel_mode = alc262_modes,
12910 .input_mux = &alc262_capture_source,
12911 .unsol_event = alc_sku_unsol_event,
12912 .setup = alc262_hippo_setup,
12913 .init_hook = alc_inithook,
12914 },
12915 [ALC262_BENQ_T31] = {
12916 .mixers = { alc262_benq_t31_mixer },
12917 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12918 alc_hp15_unsol_verbs },
12919 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12920 .dac_nids = alc262_dac_nids,
12921 .hp_nid = 0x03,
12922 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12923 .channel_mode = alc262_modes,
12924 .input_mux = &alc262_capture_source,
12925 .unsol_event = alc_sku_unsol_event,
12926 .setup = alc262_hippo_setup,
12927 .init_hook = alc_inithook,
12928 },
12929 [ALC262_ULTRA] = {
12930 .mixers = { alc262_ultra_mixer },
12931 .cap_mixer = alc262_ultra_capture_mixer,
12932 .init_verbs = { alc262_ultra_verbs },
12933 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12934 .dac_nids = alc262_dac_nids,
12935 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12936 .channel_mode = alc262_modes,
12937 .input_mux = &alc262_ultra_capture_source,
12938 .adc_nids = alc262_adc_nids, /* ADC0 */
12939 .capsrc_nids = alc262_capsrc_nids,
12940 .num_adc_nids = 1, /* single ADC */
12941 .unsol_event = alc262_ultra_unsol_event,
12942 .init_hook = alc262_ultra_automute,
12943 },
12944 [ALC262_LENOVO_3000] = {
12945 .mixers = { alc262_lenovo_3000_mixer },
12946 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12947 alc262_lenovo_3000_unsol_verbs,
12948 alc262_lenovo_3000_init_verbs },
12949 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12950 .dac_nids = alc262_dac_nids,
12951 .hp_nid = 0x03,
12952 .dig_out_nid = ALC262_DIGOUT_NID,
12953 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12954 .channel_mode = alc262_modes,
12955 .input_mux = &alc262_fujitsu_capture_source,
12956 .unsol_event = alc_sku_unsol_event,
12957 .setup = alc262_lenovo_3000_setup,
12958 .init_hook = alc_inithook,
12959 },
12960 [ALC262_NEC] = {
12961 .mixers = { alc262_nec_mixer },
12962 .init_verbs = { alc262_nec_verbs },
12963 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12964 .dac_nids = alc262_dac_nids,
12965 .hp_nid = 0x03,
12966 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12967 .channel_mode = alc262_modes,
12968 .input_mux = &alc262_capture_source,
12969 },
12970 [ALC262_TOSHIBA_S06] = {
12971 .mixers = { alc262_toshiba_s06_mixer },
12972 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12973 alc262_eapd_verbs },
12974 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12975 .capsrc_nids = alc262_dmic_capsrc_nids,
12976 .dac_nids = alc262_dac_nids,
12977 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
12978 .num_adc_nids = 1, /* single ADC */
12979 .dig_out_nid = ALC262_DIGOUT_NID,
12980 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12981 .channel_mode = alc262_modes,
12982 .unsol_event = alc_sku_unsol_event,
12983 .setup = alc262_toshiba_s06_setup,
12984 .init_hook = alc_inithook,
12985 },
12986 [ALC262_TOSHIBA_RX1] = {
12987 .mixers = { alc262_toshiba_rx1_mixer },
12988 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12989 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12990 .dac_nids = alc262_dac_nids,
12991 .hp_nid = 0x03,
12992 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12993 .channel_mode = alc262_modes,
12994 .input_mux = &alc262_capture_source,
12995 .unsol_event = alc_sku_unsol_event,
12996 .setup = alc262_hippo_setup,
12997 .init_hook = alc_inithook,
12998 },
12999 [ALC262_TYAN] = {
13000 .mixers = { alc262_tyan_mixer },
13001 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
13002 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
13003 .dac_nids = alc262_dac_nids,
13004 .hp_nid = 0x02,
13005 .dig_out_nid = ALC262_DIGOUT_NID,
13006 .num_channel_mode = ARRAY_SIZE(alc262_modes),
13007 .channel_mode = alc262_modes,
13008 .input_mux = &alc262_capture_source,
13009 .unsol_event = alc_sku_unsol_event,
13010 .setup = alc262_tyan_setup,
13011 .init_hook = alc_hp_automute,
13012 },
13013 };
13014
13015 static int patch_alc262(struct hda_codec *codec)
13016 {
13017 struct alc_spec *spec;
13018 int board_config;
13019 int err;
13020
13021 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
13022 if (spec == NULL)
13023 return -ENOMEM;
13024
13025 codec->spec = spec;
13026 #if 0
13027 /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is
13028 * under-run
13029 */
13030 {
13031 int tmp;
13032 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
13033 tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0);
13034 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7);
13035 snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, tmp | 0x80);
13036 }
13037 #endif
13038 alc_auto_parse_customize_define(codec);
13039
13040 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
13041
13042 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST,
13043 alc262_models,
13044 alc262_cfg_tbl);
13045
13046 if (board_config < 0) {
13047 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13048 codec->chip_name);
13049 board_config = ALC262_AUTO;
13050 }
13051
13052 if (board_config == ALC262_AUTO) {
13053 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
13054 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
13055 }
13056
13057 if (board_config == ALC262_AUTO) {
13058 /* automatic parse from the BIOS config */
13059 err = alc262_parse_auto_config(codec);
13060 if (err < 0) {
13061 alc_free(codec);
13062 return err;
13063 } else if (!err) {
13064 printk(KERN_INFO
13065 "hda_codec: Cannot set up configuration "
13066 "from BIOS. Using base mode...\n");
13067 board_config = ALC262_BASIC;
13068 }
13069 }
13070
13071 if (!spec->no_analog && has_cdefine_beep(codec)) {
13072 err = snd_hda_attach_beep_device(codec, 0x1);
13073 if (err < 0) {
13074 alc_free(codec);
13075 return err;
13076 }
13077 }
13078
13079 if (board_config != ALC262_AUTO)
13080 setup_preset(codec, &alc262_presets[board_config]);
13081
13082 spec->stream_analog_playback = &alc262_pcm_analog_playback;
13083 spec->stream_analog_capture = &alc262_pcm_analog_capture;
13084
13085 spec->stream_digital_playback = &alc262_pcm_digital_playback;
13086 spec->stream_digital_capture = &alc262_pcm_digital_capture;
13087
13088 if (!spec->adc_nids && spec->input_mux) {
13089 int i;
13090 /* check whether the digital-mic has to be supported */
13091 for (i = 0; i < spec->input_mux->num_items; i++) {
13092 if (spec->input_mux->items[i].index >= 9)
13093 break;
13094 }
13095 if (i < spec->input_mux->num_items) {
13096 /* use only ADC0 */
13097 spec->adc_nids = alc262_dmic_adc_nids;
13098 spec->num_adc_nids = 1;
13099 spec->capsrc_nids = alc262_dmic_capsrc_nids;
13100 } else {
13101 /* all analog inputs */
13102 /* check whether NID 0x07 is valid */
13103 unsigned int wcap = get_wcaps(codec, 0x07);
13104
13105 /* get type */
13106 wcap = get_wcaps_type(wcap);
13107 if (wcap != AC_WID_AUD_IN) {
13108 spec->adc_nids = alc262_adc_nids_alt;
13109 spec->num_adc_nids =
13110 ARRAY_SIZE(alc262_adc_nids_alt);
13111 spec->capsrc_nids = alc262_capsrc_nids_alt;
13112 } else {
13113 spec->adc_nids = alc262_adc_nids;
13114 spec->num_adc_nids =
13115 ARRAY_SIZE(alc262_adc_nids);
13116 spec->capsrc_nids = alc262_capsrc_nids;
13117 }
13118 }
13119 }
13120 if (!spec->cap_mixer && !spec->no_analog)
13121 set_capture_mixer(codec);
13122 if (!spec->no_analog && has_cdefine_beep(codec))
13123 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
13124
13125 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
13126
13127 spec->vmaster_nid = 0x0c;
13128
13129 codec->patch_ops = alc_patch_ops;
13130 if (board_config == ALC262_AUTO)
13131 spec->init_hook = alc262_auto_init;
13132 spec->shutup = alc_eapd_shutup;
13133
13134 alc_init_jacks(codec);
13135 #ifdef CONFIG_SND_HDA_POWER_SAVE
13136 if (!spec->loopback.amplist)
13137 spec->loopback.amplist = alc262_loopbacks;
13138 #endif
13139
13140 return 0;
13141 }
13142
13143 /*
13144 * ALC268 channel source setting (2 channel)
13145 */
13146 #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
13147 #define alc268_modes alc260_modes
13148
13149 static const hda_nid_t alc268_dac_nids[2] = {
13150 /* front, hp */
13151 0x02, 0x03
13152 };
13153
13154 static const hda_nid_t alc268_adc_nids[2] = {
13155 /* ADC0-1 */
13156 0x08, 0x07
13157 };
13158
13159 static const hda_nid_t alc268_adc_nids_alt[1] = {
13160 /* ADC0 */
13161 0x08
13162 };
13163
13164 static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
13165
13166 static const struct snd_kcontrol_new alc268_base_mixer[] = {
13167 /* output mixer control */
13168 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13169 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13170 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13171 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13172 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13173 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13174 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13175 { }
13176 };
13177
13178 static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
13179 /* output mixer control */
13180 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13181 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13182 ALC262_HIPPO_MASTER_SWITCH,
13183 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13184 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13185 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13186 { }
13187 };
13188
13189 /* bind Beep switches of both NID 0x0f and 0x10 */
13190 static const struct hda_bind_ctls alc268_bind_beep_sw = {
13191 .ops = &snd_hda_bind_sw,
13192 .values = {
13193 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
13194 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
13195 0
13196 },
13197 };
13198
13199 static const struct snd_kcontrol_new alc268_beep_mixer[] = {
13200 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
13201 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
13202 { }
13203 };
13204
13205 static const struct hda_verb alc268_eapd_verbs[] = {
13206 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
13207 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
13208 { }
13209 };
13210
13211 /* Toshiba specific */
13212 static const struct hda_verb alc268_toshiba_verbs[] = {
13213 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13214 { } /* end */
13215 };
13216
13217 /* Acer specific */
13218 /* bind volumes of both NID 0x02 and 0x03 */
13219 static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
13220 .ops = &snd_hda_bind_vol,
13221 .values = {
13222 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
13223 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
13224 0
13225 },
13226 };
13227
13228 static void alc268_acer_setup(struct hda_codec *codec)
13229 {
13230 struct alc_spec *spec = codec->spec;
13231
13232 spec->autocfg.hp_pins[0] = 0x14;
13233 spec->autocfg.speaker_pins[0] = 0x15;
13234 spec->automute = 1;
13235 spec->automute_mode = ALC_AUTOMUTE_AMP;
13236 }
13237
13238 #define alc268_acer_master_sw_get alc262_hp_master_sw_get
13239 #define alc268_acer_master_sw_put alc262_hp_master_sw_put
13240
13241 static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
13242 /* output mixer control */
13243 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13244 {
13245 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13246 .name = "Master Playback Switch",
13247 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
13248 .info = snd_ctl_boolean_mono_info,
13249 .get = alc268_acer_master_sw_get,
13250 .put = alc268_acer_master_sw_put,
13251 },
13252 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
13253 { }
13254 };
13255
13256 static const struct snd_kcontrol_new alc268_acer_mixer[] = {
13257 /* output mixer control */
13258 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13259 {
13260 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13261 .name = "Master Playback Switch",
13262 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13263 .info = snd_ctl_boolean_mono_info,
13264 .get = alc268_acer_master_sw_get,
13265 .put = alc268_acer_master_sw_put,
13266 },
13267 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13268 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13269 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13270 { }
13271 };
13272
13273 static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
13274 /* output mixer control */
13275 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13276 {
13277 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13278 .name = "Master Playback Switch",
13279 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
13280 .info = snd_ctl_boolean_mono_info,
13281 .get = alc268_acer_master_sw_get,
13282 .put = alc268_acer_master_sw_put,
13283 },
13284 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13285 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
13286 { }
13287 };
13288
13289 static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
13290 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13291 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13292 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13293 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13294 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
13295 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
13296 { }
13297 };
13298
13299 static const struct hda_verb alc268_acer_verbs[] = {
13300 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
13301 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13302 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13303 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
13304 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13305 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
13306 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13307 { }
13308 };
13309
13310 /* unsolicited event for HP jack sensing */
13311 #define alc268_toshiba_setup alc262_hippo_setup
13312
13313 static void alc268_acer_lc_setup(struct hda_codec *codec)
13314 {
13315 struct alc_spec *spec = codec->spec;
13316 spec->autocfg.hp_pins[0] = 0x15;
13317 spec->autocfg.speaker_pins[0] = 0x14;
13318 spec->automute = 1;
13319 spec->automute_mode = ALC_AUTOMUTE_AMP;
13320 spec->ext_mic.pin = 0x18;
13321 spec->ext_mic.mux_idx = 0;
13322 spec->int_mic.pin = 0x12;
13323 spec->int_mic.mux_idx = 6;
13324 spec->auto_mic = 1;
13325 }
13326
13327 static const struct snd_kcontrol_new alc268_dell_mixer[] = {
13328 /* output mixer control */
13329 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13330 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13331 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13332 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13333 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13334 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13335 { }
13336 };
13337
13338 static const struct hda_verb alc268_dell_verbs[] = {
13339 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13340 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13341 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13342 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13343 { }
13344 };
13345
13346 /* mute/unmute internal speaker according to the hp jack and mute state */
13347 static void alc268_dell_setup(struct hda_codec *codec)
13348 {
13349 struct alc_spec *spec = codec->spec;
13350
13351 spec->autocfg.hp_pins[0] = 0x15;
13352 spec->autocfg.speaker_pins[0] = 0x14;
13353 spec->ext_mic.pin = 0x18;
13354 spec->ext_mic.mux_idx = 0;
13355 spec->int_mic.pin = 0x19;
13356 spec->int_mic.mux_idx = 1;
13357 spec->auto_mic = 1;
13358 spec->automute = 1;
13359 spec->automute_mode = ALC_AUTOMUTE_PIN;
13360 }
13361
13362 static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
13363 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
13364 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13365 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
13366 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13367 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13368 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
13369 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13370 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13371 { }
13372 };
13373
13374 static const struct hda_verb alc267_quanta_il1_verbs[] = {
13375 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13376 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
13377 { }
13378 };
13379
13380 static void alc267_quanta_il1_setup(struct hda_codec *codec)
13381 {
13382 struct alc_spec *spec = codec->spec;
13383 spec->autocfg.hp_pins[0] = 0x15;
13384 spec->autocfg.speaker_pins[0] = 0x14;
13385 spec->ext_mic.pin = 0x18;
13386 spec->ext_mic.mux_idx = 0;
13387 spec->int_mic.pin = 0x19;
13388 spec->int_mic.mux_idx = 1;
13389 spec->auto_mic = 1;
13390 spec->automute = 1;
13391 spec->automute_mode = ALC_AUTOMUTE_PIN;
13392 }
13393
13394 /*
13395 * generic initialization of ADC, input mixers and output mixers
13396 */
13397 static const struct hda_verb alc268_base_init_verbs[] = {
13398 /* Unmute DAC0-1 and set vol = 0 */
13399 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13400 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13401
13402 /*
13403 * Set up output mixers (0x0c - 0x0e)
13404 */
13405 /* set vol=0 to output mixers */
13406 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13407 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
13408
13409 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13410 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13411
13412 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13413 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
13414 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
13415 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13416 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13417 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13418 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13419 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13420
13421 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13422 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13423 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13424 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13425 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13426
13427 /* set PCBEEP vol = 0, mute connections */
13428 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13429 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13430 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13431
13432 /* Unmute Selector 23h,24h and set the default input to mic-in */
13433
13434 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
13435 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13436 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
13437 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13438
13439 { }
13440 };
13441
13442 /*
13443 * generic initialization of ADC, input mixers and output mixers
13444 */
13445 static const struct hda_verb alc268_volume_init_verbs[] = {
13446 /* set output DAC */
13447 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13448 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13449
13450 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13451 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13452 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13453 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13454 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13455
13456 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13457 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13458 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13459
13460 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13461 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13462
13463 /* set PCBEEP vol = 0, mute connections */
13464 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13465 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13466 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13467
13468 { }
13469 };
13470
13471 static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13472 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13473 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13474 { } /* end */
13475 };
13476
13477 static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13478 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13479 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13480 _DEFINE_CAPSRC(1),
13481 { } /* end */
13482 };
13483
13484 static const struct snd_kcontrol_new alc268_capture_mixer[] = {
13485 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13486 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13487 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13488 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
13489 _DEFINE_CAPSRC(2),
13490 { } /* end */
13491 };
13492
13493 static const struct hda_input_mux alc268_capture_source = {
13494 .num_items = 4,
13495 .items = {
13496 { "Mic", 0x0 },
13497 { "Front Mic", 0x1 },
13498 { "Line", 0x2 },
13499 { "CD", 0x3 },
13500 },
13501 };
13502
13503 static const struct hda_input_mux alc268_acer_capture_source = {
13504 .num_items = 3,
13505 .items = {
13506 { "Mic", 0x0 },
13507 { "Internal Mic", 0x1 },
13508 { "Line", 0x2 },
13509 },
13510 };
13511
13512 static const struct hda_input_mux alc268_acer_dmic_capture_source = {
13513 .num_items = 3,
13514 .items = {
13515 { "Mic", 0x0 },
13516 { "Internal Mic", 0x6 },
13517 { "Line", 0x2 },
13518 },
13519 };
13520
13521 #ifdef CONFIG_SND_DEBUG
13522 static const struct snd_kcontrol_new alc268_test_mixer[] = {
13523 /* Volume widgets */
13524 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13525 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13526 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13527 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13528 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13529 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13530 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13531 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13532 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13533 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13534 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13535 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13536 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
13537 /* The below appears problematic on some hardwares */
13538 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
13539 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13540 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13541 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13542 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13543
13544 /* Modes for retasking pin widgets */
13545 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13546 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13547 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13548 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13549
13550 /* Controls for GPIO pins, assuming they are configured as outputs */
13551 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13552 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13553 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13554 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13555
13556 /* Switches to allow the digital SPDIF output pin to be enabled.
13557 * The ALC268 does not have an SPDIF input.
13558 */
13559 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13560
13561 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13562 * this output to turn on an external amplifier.
13563 */
13564 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13565 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13566
13567 { } /* end */
13568 };
13569 #endif
13570
13571 /* create input playback/capture controls for the given pin */
13572 static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13573 const char *ctlname, int idx)
13574 {
13575 hda_nid_t dac;
13576 int err;
13577
13578 switch (nid) {
13579 case 0x14:
13580 case 0x16:
13581 dac = 0x02;
13582 break;
13583 case 0x15:
13584 case 0x1a: /* ALC259/269 only */
13585 case 0x1b: /* ALC259/269 only */
13586 case 0x21: /* ALC269vb has this pin, too */
13587 dac = 0x03;
13588 break;
13589 default:
13590 snd_printd(KERN_WARNING "hda_codec: "
13591 "ignoring pin 0x%x as unknown\n", nid);
13592 return 0;
13593 }
13594 if (spec->multiout.dac_nids[0] != dac &&
13595 spec->multiout.dac_nids[1] != dac) {
13596 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
13597 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
13598 HDA_OUTPUT));
13599 if (err < 0)
13600 return err;
13601 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
13602 }
13603
13604 if (nid != 0x16)
13605 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13606 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
13607 else /* mono */
13608 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
13609 HDA_COMPOSE_AMP_VAL(nid, 2, idx, HDA_OUTPUT));
13610 if (err < 0)
13611 return err;
13612 return 0;
13613 }
13614
13615 /* add playback controls from the parsed DAC table */
13616 static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec,
13617 const struct auto_pin_cfg *cfg)
13618 {
13619 hda_nid_t nid;
13620 int err;
13621
13622 spec->multiout.dac_nids = spec->private_dac_nids;
13623
13624 nid = cfg->line_out_pins[0];
13625 if (nid) {
13626 const char *name;
13627 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
13628 name = "Speaker";
13629 else
13630 name = "Front";
13631 err = alc268_new_analog_output(spec, nid, name, 0);
13632 if (err < 0)
13633 return err;
13634 }
13635
13636 nid = cfg->speaker_pins[0];
13637 if (nid == 0x1d) {
13638 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, "Speaker",
13639 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
13640 if (err < 0)
13641 return err;
13642 } else if (nid) {
13643 err = alc268_new_analog_output(spec, nid, "Speaker", 0);
13644 if (err < 0)
13645 return err;
13646 }
13647 nid = cfg->hp_pins[0];
13648 if (nid) {
13649 err = alc268_new_analog_output(spec, nid, "Headphone", 0);
13650 if (err < 0)
13651 return err;
13652 }
13653
13654 nid = cfg->line_out_pins[1] | cfg->line_out_pins[2];
13655 if (nid == 0x16) {
13656 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, "Mono",
13657 HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT));
13658 if (err < 0)
13659 return err;
13660 }
13661 return 0;
13662 }
13663
13664 /* create playback/capture controls for input pins */
13665 static int alc268_auto_create_input_ctls(struct hda_codec *codec,
13666 const struct auto_pin_cfg *cfg)
13667 {
13668 return alc_auto_create_input_ctls(codec, cfg, 0, 0x23, 0x24);
13669 }
13670
13671 static void alc268_auto_set_output_and_unmute(struct hda_codec *codec,
13672 hda_nid_t nid, int pin_type)
13673 {
13674 int idx;
13675
13676 alc_set_pin_output(codec, nid, pin_type);
13677 if (nid == 0x14 || nid == 0x16)
13678 idx = 0;
13679 else
13680 idx = 1;
13681 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx);
13682 }
13683
13684 static void alc268_auto_init_multi_out(struct hda_codec *codec)
13685 {
13686 struct alc_spec *spec = codec->spec;
13687 int i;
13688
13689 for (i = 0; i < spec->autocfg.line_outs; i++) {
13690 hda_nid_t nid = spec->autocfg.line_out_pins[i];
13691 int pin_type = get_pin_type(spec->autocfg.line_out_type);
13692 alc268_auto_set_output_and_unmute(codec, nid, pin_type);
13693 }
13694 }
13695
13696 static void alc268_auto_init_hp_out(struct hda_codec *codec)
13697 {
13698 struct alc_spec *spec = codec->spec;
13699 hda_nid_t pin;
13700 int i;
13701
13702 for (i = 0; i < spec->autocfg.hp_outs; i++) {
13703 pin = spec->autocfg.hp_pins[i];
13704 alc268_auto_set_output_and_unmute(codec, pin, PIN_HP);
13705 }
13706 for (i = 0; i < spec->autocfg.speaker_outs; i++) {
13707 pin = spec->autocfg.speaker_pins[i];
13708 alc268_auto_set_output_and_unmute(codec, pin, PIN_OUT);
13709 }
13710 if (spec->autocfg.mono_out_pin)
13711 snd_hda_codec_write(codec, spec->autocfg.mono_out_pin, 0,
13712 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13713 }
13714
13715 static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13716 {
13717 struct alc_spec *spec = codec->spec;
13718 hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0];
13719 hda_nid_t hp_nid = spec->autocfg.hp_pins[0];
13720 hda_nid_t line_nid = spec->autocfg.line_out_pins[0];
13721 unsigned int dac_vol1, dac_vol2;
13722
13723 if (line_nid == 0x1d || speaker_nid == 0x1d) {
13724 snd_hda_codec_write(codec, speaker_nid, 0,
13725 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
13726 /* mute mixer inputs from 0x1d */
13727 snd_hda_codec_write(codec, 0x0f, 0,
13728 AC_VERB_SET_AMP_GAIN_MUTE,
13729 AMP_IN_UNMUTE(1));
13730 snd_hda_codec_write(codec, 0x10, 0,
13731 AC_VERB_SET_AMP_GAIN_MUTE,
13732 AMP_IN_UNMUTE(1));
13733 } else {
13734 /* unmute mixer inputs from 0x1d */
13735 snd_hda_codec_write(codec, 0x0f, 0,
13736 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13737 snd_hda_codec_write(codec, 0x10, 0,
13738 AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1));
13739 }
13740
13741 dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */
13742 if (line_nid == 0x14)
13743 dac_vol2 = AMP_OUT_ZERO;
13744 else if (line_nid == 0x15)
13745 dac_vol1 = AMP_OUT_ZERO;
13746 if (hp_nid == 0x14)
13747 dac_vol2 = AMP_OUT_ZERO;
13748 else if (hp_nid == 0x15)
13749 dac_vol1 = AMP_OUT_ZERO;
13750 if (line_nid != 0x16 || hp_nid != 0x16 ||
13751 spec->autocfg.line_out_pins[1] != 0x16 ||
13752 spec->autocfg.line_out_pins[2] != 0x16)
13753 dac_vol1 = dac_vol2 = AMP_OUT_ZERO;
13754
13755 snd_hda_codec_write(codec, 0x02, 0,
13756 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol1);
13757 snd_hda_codec_write(codec, 0x03, 0,
13758 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13759 }
13760
13761 /* pcm configuration: identical with ALC880 */
13762 #define alc268_pcm_analog_playback alc880_pcm_analog_playback
13763 #define alc268_pcm_analog_capture alc880_pcm_analog_capture
13764 #define alc268_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
13765 #define alc268_pcm_digital_playback alc880_pcm_digital_playback
13766
13767 /*
13768 * BIOS auto configuration
13769 */
13770 static int alc268_parse_auto_config(struct hda_codec *codec)
13771 {
13772 struct alc_spec *spec = codec->spec;
13773 int err;
13774 static const hda_nid_t alc268_ignore[] = { 0 };
13775
13776 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
13777 alc268_ignore);
13778 if (err < 0)
13779 return err;
13780 if (!spec->autocfg.line_outs) {
13781 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
13782 spec->multiout.max_channels = 2;
13783 spec->no_analog = 1;
13784 goto dig_only;
13785 }
13786 return 0; /* can't find valid BIOS pin config */
13787 }
13788 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg);
13789 if (err < 0)
13790 return err;
13791 err = alc268_auto_create_input_ctls(codec, &spec->autocfg);
13792 if (err < 0)
13793 return err;
13794
13795 spec->multiout.max_channels = 2;
13796
13797 dig_only:
13798 /* digital only support output */
13799 alc_auto_parse_digital(codec);
13800 if (spec->kctls.list)
13801 add_mixer(spec, spec->kctls.list);
13802
13803 if (!spec->no_analog && spec->autocfg.speaker_pins[0] != 0x1d)
13804 add_mixer(spec, alc268_beep_mixer);
13805
13806 add_verb(spec, alc268_volume_init_verbs);
13807 spec->num_mux_defs = 2;
13808 spec->input_mux = &spec->private_imux[0];
13809
13810 err = alc_auto_add_mic_boost(codec);
13811 if (err < 0)
13812 return err;
13813
13814 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
13815
13816 return 1;
13817 }
13818
13819 #define alc268_auto_init_analog_input alc882_auto_init_analog_input
13820 #define alc268_auto_init_input_src alc882_auto_init_input_src
13821
13822 /* init callback for auto-configuration model -- overriding the default init */
13823 static void alc268_auto_init(struct hda_codec *codec)
13824 {
13825 struct alc_spec *spec = codec->spec;
13826 alc268_auto_init_multi_out(codec);
13827 alc268_auto_init_hp_out(codec);
13828 alc268_auto_init_mono_speaker_out(codec);
13829 alc268_auto_init_analog_input(codec);
13830 alc268_auto_init_input_src(codec);
13831 alc_auto_init_digital(codec);
13832 if (spec->unsol_event)
13833 alc_inithook(codec);
13834 }
13835
13836 /*
13837 * configuration and preset
13838 */
13839 static const char * const alc268_models[ALC268_MODEL_LAST] = {
13840 [ALC267_QUANTA_IL1] = "quanta-il1",
13841 [ALC268_3ST] = "3stack",
13842 [ALC268_TOSHIBA] = "toshiba",
13843 [ALC268_ACER] = "acer",
13844 [ALC268_ACER_DMIC] = "acer-dmic",
13845 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
13846 [ALC268_DELL] = "dell",
13847 [ALC268_ZEPTO] = "zepto",
13848 #ifdef CONFIG_SND_DEBUG
13849 [ALC268_TEST] = "test",
13850 #endif
13851 [ALC268_AUTO] = "auto",
13852 };
13853
13854 static const struct snd_pci_quirk alc268_cfg_tbl[] = {
13855 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
13856 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
13857 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
13858 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
13859 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
13860 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13861 ALC268_ACER_ASPIRE_ONE),
13862 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
13863 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO),
13864 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13865 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
13866 /* almost compatible with toshiba but with optional digital outs;
13867 * auto-probing seems working fine
13868 */
13869 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
13870 ALC268_AUTO),
13871 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
13872 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
13873 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
13874 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
13875 {}
13876 };
13877
13878 /* Toshiba laptops have no unique PCI SSID but only codec SSID */
13879 static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13880 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13881 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13882 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13883 ALC268_TOSHIBA),
13884 {}
13885 };
13886
13887 static const struct alc_config_preset alc268_presets[] = {
13888 [ALC267_QUANTA_IL1] = {
13889 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13890 alc268_capture_nosrc_mixer },
13891 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13892 alc267_quanta_il1_verbs },
13893 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13894 .dac_nids = alc268_dac_nids,
13895 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13896 .adc_nids = alc268_adc_nids_alt,
13897 .hp_nid = 0x03,
13898 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13899 .channel_mode = alc268_modes,
13900 .unsol_event = alc_sku_unsol_event,
13901 .setup = alc267_quanta_il1_setup,
13902 .init_hook = alc_inithook,
13903 },
13904 [ALC268_3ST] = {
13905 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13906 alc268_beep_mixer },
13907 .init_verbs = { alc268_base_init_verbs },
13908 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13909 .dac_nids = alc268_dac_nids,
13910 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13911 .adc_nids = alc268_adc_nids_alt,
13912 .capsrc_nids = alc268_capsrc_nids,
13913 .hp_nid = 0x03,
13914 .dig_out_nid = ALC268_DIGOUT_NID,
13915 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13916 .channel_mode = alc268_modes,
13917 .input_mux = &alc268_capture_source,
13918 },
13919 [ALC268_TOSHIBA] = {
13920 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
13921 alc268_beep_mixer },
13922 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13923 alc268_toshiba_verbs },
13924 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13925 .dac_nids = alc268_dac_nids,
13926 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13927 .adc_nids = alc268_adc_nids_alt,
13928 .capsrc_nids = alc268_capsrc_nids,
13929 .hp_nid = 0x03,
13930 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13931 .channel_mode = alc268_modes,
13932 .input_mux = &alc268_capture_source,
13933 .unsol_event = alc_sku_unsol_event,
13934 .setup = alc268_toshiba_setup,
13935 .init_hook = alc_inithook,
13936 },
13937 [ALC268_ACER] = {
13938 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
13939 alc268_beep_mixer },
13940 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13941 alc268_acer_verbs },
13942 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13943 .dac_nids = alc268_dac_nids,
13944 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13945 .adc_nids = alc268_adc_nids_alt,
13946 .capsrc_nids = alc268_capsrc_nids,
13947 .hp_nid = 0x02,
13948 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13949 .channel_mode = alc268_modes,
13950 .input_mux = &alc268_acer_capture_source,
13951 .unsol_event = alc_sku_unsol_event,
13952 .setup = alc268_acer_setup,
13953 .init_hook = alc_inithook,
13954 },
13955 [ALC268_ACER_DMIC] = {
13956 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13957 alc268_beep_mixer },
13958 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13959 alc268_acer_verbs },
13960 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13961 .dac_nids = alc268_dac_nids,
13962 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13963 .adc_nids = alc268_adc_nids_alt,
13964 .capsrc_nids = alc268_capsrc_nids,
13965 .hp_nid = 0x02,
13966 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13967 .channel_mode = alc268_modes,
13968 .input_mux = &alc268_acer_dmic_capture_source,
13969 .unsol_event = alc_sku_unsol_event,
13970 .setup = alc268_acer_setup,
13971 .init_hook = alc_inithook,
13972 },
13973 [ALC268_ACER_ASPIRE_ONE] = {
13974 .mixers = { alc268_acer_aspire_one_mixer,
13975 alc268_beep_mixer,
13976 alc268_capture_nosrc_mixer },
13977 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13978 alc268_acer_aspire_one_verbs },
13979 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13980 .dac_nids = alc268_dac_nids,
13981 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13982 .adc_nids = alc268_adc_nids_alt,
13983 .capsrc_nids = alc268_capsrc_nids,
13984 .hp_nid = 0x03,
13985 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13986 .channel_mode = alc268_modes,
13987 .unsol_event = alc_sku_unsol_event,
13988 .setup = alc268_acer_lc_setup,
13989 .init_hook = alc_inithook,
13990 },
13991 [ALC268_DELL] = {
13992 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13993 alc268_capture_nosrc_mixer },
13994 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13995 alc268_dell_verbs },
13996 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13997 .dac_nids = alc268_dac_nids,
13998 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13999 .adc_nids = alc268_adc_nids_alt,
14000 .capsrc_nids = alc268_capsrc_nids,
14001 .hp_nid = 0x02,
14002 .num_channel_mode = ARRAY_SIZE(alc268_modes),
14003 .channel_mode = alc268_modes,
14004 .unsol_event = alc_sku_unsol_event,
14005 .setup = alc268_dell_setup,
14006 .init_hook = alc_inithook,
14007 },
14008 [ALC268_ZEPTO] = {
14009 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
14010 alc268_beep_mixer },
14011 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14012 alc268_toshiba_verbs },
14013 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
14014 .dac_nids = alc268_dac_nids,
14015 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14016 .adc_nids = alc268_adc_nids_alt,
14017 .capsrc_nids = alc268_capsrc_nids,
14018 .hp_nid = 0x03,
14019 .dig_out_nid = ALC268_DIGOUT_NID,
14020 .num_channel_mode = ARRAY_SIZE(alc268_modes),
14021 .channel_mode = alc268_modes,
14022 .input_mux = &alc268_capture_source,
14023 .unsol_event = alc_sku_unsol_event,
14024 .setup = alc268_toshiba_setup,
14025 .init_hook = alc_inithook,
14026 },
14027 #ifdef CONFIG_SND_DEBUG
14028 [ALC268_TEST] = {
14029 .mixers = { alc268_test_mixer, alc268_capture_mixer },
14030 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
14031 alc268_volume_init_verbs },
14032 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
14033 .dac_nids = alc268_dac_nids,
14034 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
14035 .adc_nids = alc268_adc_nids_alt,
14036 .capsrc_nids = alc268_capsrc_nids,
14037 .hp_nid = 0x03,
14038 .dig_out_nid = ALC268_DIGOUT_NID,
14039 .num_channel_mode = ARRAY_SIZE(alc268_modes),
14040 .channel_mode = alc268_modes,
14041 .input_mux = &alc268_capture_source,
14042 },
14043 #endif
14044 };
14045
14046 static int patch_alc268(struct hda_codec *codec)
14047 {
14048 struct alc_spec *spec;
14049 int board_config;
14050 int i, has_beep, err;
14051
14052 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
14053 if (spec == NULL)
14054 return -ENOMEM;
14055
14056 codec->spec = spec;
14057
14058 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST,
14059 alc268_models,
14060 alc268_cfg_tbl);
14061
14062 if (board_config < 0 || board_config >= ALC268_MODEL_LAST)
14063 board_config = snd_hda_check_board_codec_sid_config(codec,
14064 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
14065
14066 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) {
14067 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14068 codec->chip_name);
14069 board_config = ALC268_AUTO;
14070 }
14071
14072 if (board_config == ALC268_AUTO) {
14073 /* automatic parse from the BIOS config */
14074 err = alc268_parse_auto_config(codec);
14075 if (err < 0) {
14076 alc_free(codec);
14077 return err;
14078 } else if (!err) {
14079 printk(KERN_INFO
14080 "hda_codec: Cannot set up configuration "
14081 "from BIOS. Using base mode...\n");
14082 board_config = ALC268_3ST;
14083 }
14084 }
14085
14086 if (board_config != ALC268_AUTO)
14087 setup_preset(codec, &alc268_presets[board_config]);
14088
14089 spec->stream_analog_playback = &alc268_pcm_analog_playback;
14090 spec->stream_analog_capture = &alc268_pcm_analog_capture;
14091 spec->stream_analog_alt_capture = &alc268_pcm_analog_alt_capture;
14092
14093 spec->stream_digital_playback = &alc268_pcm_digital_playback;
14094
14095 has_beep = 0;
14096 for (i = 0; i < spec->num_mixers; i++) {
14097 if (spec->mixers[i] == alc268_beep_mixer) {
14098 has_beep = 1;
14099 break;
14100 }
14101 }
14102
14103 if (has_beep) {
14104 err = snd_hda_attach_beep_device(codec, 0x1);
14105 if (err < 0) {
14106 alc_free(codec);
14107 return err;
14108 }
14109 if (!query_amp_caps(codec, 0x1d, HDA_INPUT))
14110 /* override the amp caps for beep generator */
14111 snd_hda_override_amp_caps(codec, 0x1d, HDA_INPUT,
14112 (0x0c << AC_AMPCAP_OFFSET_SHIFT) |
14113 (0x0c << AC_AMPCAP_NUM_STEPS_SHIFT) |
14114 (0x07 << AC_AMPCAP_STEP_SIZE_SHIFT) |
14115 (0 << AC_AMPCAP_MUTE_SHIFT));
14116 }
14117
14118 if (!spec->no_analog && !spec->adc_nids && spec->input_mux) {
14119 /* check whether NID 0x07 is valid */
14120 unsigned int wcap = get_wcaps(codec, 0x07);
14121
14122 spec->capsrc_nids = alc268_capsrc_nids;
14123 /* get type */
14124 wcap = get_wcaps_type(wcap);
14125 if (spec->auto_mic ||
14126 wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) {
14127 spec->adc_nids = alc268_adc_nids_alt;
14128 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt);
14129 if (spec->auto_mic)
14130 fixup_automic_adc(codec);
14131 if (spec->auto_mic || spec->input_mux->num_items == 1)
14132 add_mixer(spec, alc268_capture_nosrc_mixer);
14133 else
14134 add_mixer(spec, alc268_capture_alt_mixer);
14135 } else {
14136 spec->adc_nids = alc268_adc_nids;
14137 spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids);
14138 add_mixer(spec, alc268_capture_mixer);
14139 }
14140 }
14141
14142 spec->vmaster_nid = 0x02;
14143
14144 codec->patch_ops = alc_patch_ops;
14145 if (board_config == ALC268_AUTO)
14146 spec->init_hook = alc268_auto_init;
14147 spec->shutup = alc_eapd_shutup;
14148
14149 alc_init_jacks(codec);
14150
14151 return 0;
14152 }
14153
14154 /*
14155 * ALC269 channel source setting (2 channel)
14156 */
14157 #define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
14158
14159 #define alc269_dac_nids alc260_dac_nids
14160
14161 static const hda_nid_t alc269_adc_nids[1] = {
14162 /* ADC1 */
14163 0x08,
14164 };
14165
14166 static const hda_nid_t alc269_capsrc_nids[1] = {
14167 0x23,
14168 };
14169
14170 static const hda_nid_t alc269vb_adc_nids[1] = {
14171 /* ADC1 */
14172 0x09,
14173 };
14174
14175 static const hda_nid_t alc269vb_capsrc_nids[1] = {
14176 0x22,
14177 };
14178
14179 static const hda_nid_t alc269_adc_candidates[] = {
14180 0x08, 0x09, 0x07, 0x11,
14181 };
14182
14183 #define alc269_modes alc260_modes
14184 #define alc269_capture_source alc880_lg_lw_capture_source
14185
14186 static const struct snd_kcontrol_new alc269_base_mixer[] = {
14187 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14188 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14189 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
14190 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
14191 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14192 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14193 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14194 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14195 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14196 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
14197 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14198 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
14199 { } /* end */
14200 };
14201
14202 static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
14203 /* output mixer control */
14204 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14205 {
14206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14207 .name = "Master Playback Switch",
14208 .subdevice = HDA_SUBDEV_AMP_FLAG,
14209 .info = snd_hda_mixer_amp_switch_info,
14210 .get = snd_hda_mixer_amp_switch_get,
14211 .put = alc268_acer_master_sw_put,
14212 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14213 },
14214 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14215 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14216 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14217 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14218 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14219 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14220 { }
14221 };
14222
14223 static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
14224 /* output mixer control */
14225 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
14226 {
14227 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14228 .name = "Master Playback Switch",
14229 .subdevice = HDA_SUBDEV_AMP_FLAG,
14230 .info = snd_hda_mixer_amp_switch_info,
14231 .get = snd_hda_mixer_amp_switch_get,
14232 .put = alc268_acer_master_sw_put,
14233 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
14234 },
14235 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
14236 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
14237 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14238 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
14239 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
14240 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14241 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
14242 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
14243 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
14244 { }
14245 };
14246
14247 static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
14248 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14249 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14250 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
14251 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14252 { } /* end */
14253 };
14254
14255 static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
14256 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
14257 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14258 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
14259 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
14260 { } /* end */
14261 };
14262
14263 static const struct snd_kcontrol_new alc269_asus_mixer[] = {
14264 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
14265 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
14266 { } /* end */
14267 };
14268
14269 /* capture mixer elements */
14270 static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
14271 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14272 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14273 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14274 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14275 { } /* end */
14276 };
14277
14278 static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
14279 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
14280 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
14281 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14282 { } /* end */
14283 };
14284
14285 static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
14286 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14287 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14288 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14289 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
14290 { } /* end */
14291 };
14292
14293 static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
14294 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
14295 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
14296 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
14297 { } /* end */
14298 };
14299
14300 /* FSC amilo */
14301 #define alc269_fujitsu_mixer alc269_laptop_mixer
14302
14303 static const struct hda_verb alc269_quanta_fl1_verbs[] = {
14304 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14305 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14306 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14307 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14308 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14309 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14310 { }
14311 };
14312
14313 static const struct hda_verb alc269_lifebook_verbs[] = {
14314 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14315 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
14316 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14317 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14318 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14319 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14320 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14321 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
14322 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14323 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14324 { }
14325 };
14326
14327 /* toggle speaker-output according to the hp-jack state */
14328 static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
14329 {
14330 alc_hp_automute(codec);
14331
14332 snd_hda_codec_write(codec, 0x20, 0,
14333 AC_VERB_SET_COEF_INDEX, 0x0c);
14334 snd_hda_codec_write(codec, 0x20, 0,
14335 AC_VERB_SET_PROC_COEF, 0x680);
14336
14337 snd_hda_codec_write(codec, 0x20, 0,
14338 AC_VERB_SET_COEF_INDEX, 0x0c);
14339 snd_hda_codec_write(codec, 0x20, 0,
14340 AC_VERB_SET_PROC_COEF, 0x480);
14341 }
14342
14343 #define alc269_lifebook_speaker_automute \
14344 alc269_quanta_fl1_speaker_automute
14345
14346 static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
14347 {
14348 unsigned int present_laptop;
14349 unsigned int present_dock;
14350
14351 present_laptop = snd_hda_jack_detect(codec, 0x18);
14352 present_dock = snd_hda_jack_detect(codec, 0x1b);
14353
14354 /* Laptop mic port overrides dock mic port, design decision */
14355 if (present_dock)
14356 snd_hda_codec_write(codec, 0x23, 0,
14357 AC_VERB_SET_CONNECT_SEL, 0x3);
14358 if (present_laptop)
14359 snd_hda_codec_write(codec, 0x23, 0,
14360 AC_VERB_SET_CONNECT_SEL, 0x0);
14361 if (!present_dock && !present_laptop)
14362 snd_hda_codec_write(codec, 0x23, 0,
14363 AC_VERB_SET_CONNECT_SEL, 0x1);
14364 }
14365
14366 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
14367 unsigned int res)
14368 {
14369 switch (res >> 26) {
14370 case ALC880_HP_EVENT:
14371 alc269_quanta_fl1_speaker_automute(codec);
14372 break;
14373 case ALC880_MIC_EVENT:
14374 alc_mic_automute(codec);
14375 break;
14376 }
14377 }
14378
14379 static void alc269_lifebook_unsol_event(struct hda_codec *codec,
14380 unsigned int res)
14381 {
14382 if ((res >> 26) == ALC880_HP_EVENT)
14383 alc269_lifebook_speaker_automute(codec);
14384 if ((res >> 26) == ALC880_MIC_EVENT)
14385 alc269_lifebook_mic_autoswitch(codec);
14386 }
14387
14388 static void alc269_quanta_fl1_setup(struct hda_codec *codec)
14389 {
14390 struct alc_spec *spec = codec->spec;
14391 spec->autocfg.hp_pins[0] = 0x15;
14392 spec->autocfg.speaker_pins[0] = 0x14;
14393 spec->automute_mixer_nid[0] = 0x0c;
14394 spec->automute = 1;
14395 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14396 spec->ext_mic.pin = 0x18;
14397 spec->ext_mic.mux_idx = 0;
14398 spec->int_mic.pin = 0x19;
14399 spec->int_mic.mux_idx = 1;
14400 spec->auto_mic = 1;
14401 }
14402
14403 static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
14404 {
14405 alc269_quanta_fl1_speaker_automute(codec);
14406 alc_mic_automute(codec);
14407 }
14408
14409 static void alc269_lifebook_setup(struct hda_codec *codec)
14410 {
14411 struct alc_spec *spec = codec->spec;
14412 spec->autocfg.hp_pins[0] = 0x15;
14413 spec->autocfg.hp_pins[1] = 0x1a;
14414 spec->autocfg.speaker_pins[0] = 0x14;
14415 spec->automute_mixer_nid[0] = 0x0c;
14416 spec->automute = 1;
14417 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14418 }
14419
14420 static void alc269_lifebook_init_hook(struct hda_codec *codec)
14421 {
14422 alc269_lifebook_speaker_automute(codec);
14423 alc269_lifebook_mic_autoswitch(codec);
14424 }
14425
14426 static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
14427 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14428 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
14429 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14430 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14431 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14432 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14433 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14434 {}
14435 };
14436
14437 static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
14438 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
14439 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
14440 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14441 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
14442 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14443 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14444 {}
14445 };
14446
14447 static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
14448 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14449 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
14450 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14451 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14452 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14453 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14454 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14455 {}
14456 };
14457
14458 static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
14459 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
14460 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
14461 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
14462 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
14463 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14464 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14465 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14466 {}
14467 };
14468
14469 static const struct hda_verb alc271_acer_dmic_verbs[] = {
14470 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14471 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14472 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14473 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14474 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14475 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14476 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14477 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14478 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14479 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14480 { }
14481 };
14482
14483 static void alc269_laptop_amic_setup(struct hda_codec *codec)
14484 {
14485 struct alc_spec *spec = codec->spec;
14486 spec->autocfg.hp_pins[0] = 0x15;
14487 spec->autocfg.speaker_pins[0] = 0x14;
14488 spec->automute_mixer_nid[0] = 0x0c;
14489 spec->automute = 1;
14490 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14491 spec->ext_mic.pin = 0x18;
14492 spec->ext_mic.mux_idx = 0;
14493 spec->int_mic.pin = 0x19;
14494 spec->int_mic.mux_idx = 1;
14495 spec->auto_mic = 1;
14496 }
14497
14498 static void alc269_laptop_dmic_setup(struct hda_codec *codec)
14499 {
14500 struct alc_spec *spec = codec->spec;
14501 spec->autocfg.hp_pins[0] = 0x15;
14502 spec->autocfg.speaker_pins[0] = 0x14;
14503 spec->automute_mixer_nid[0] = 0x0c;
14504 spec->automute = 1;
14505 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14506 spec->ext_mic.pin = 0x18;
14507 spec->ext_mic.mux_idx = 0;
14508 spec->int_mic.pin = 0x12;
14509 spec->int_mic.mux_idx = 5;
14510 spec->auto_mic = 1;
14511 }
14512
14513 static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
14514 {
14515 struct alc_spec *spec = codec->spec;
14516 spec->autocfg.hp_pins[0] = 0x21;
14517 spec->autocfg.speaker_pins[0] = 0x14;
14518 spec->automute_mixer_nid[0] = 0x0c;
14519 spec->automute = 1;
14520 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14521 spec->ext_mic.pin = 0x18;
14522 spec->ext_mic.mux_idx = 0;
14523 spec->int_mic.pin = 0x19;
14524 spec->int_mic.mux_idx = 1;
14525 spec->auto_mic = 1;
14526 }
14527
14528 static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14529 {
14530 struct alc_spec *spec = codec->spec;
14531 spec->autocfg.hp_pins[0] = 0x21;
14532 spec->autocfg.speaker_pins[0] = 0x14;
14533 spec->automute_mixer_nid[0] = 0x0c;
14534 spec->automute = 1;
14535 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14536 spec->ext_mic.pin = 0x18;
14537 spec->ext_mic.mux_idx = 0;
14538 spec->int_mic.pin = 0x12;
14539 spec->int_mic.mux_idx = 6;
14540 spec->auto_mic = 1;
14541 }
14542
14543 /*
14544 * generic initialization of ADC, input mixers and output mixers
14545 */
14546 static const struct hda_verb alc269_init_verbs[] = {
14547 /*
14548 * Unmute ADC0 and set the default input to mic-in
14549 */
14550 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14551
14552 /*
14553 * Set up output mixers (0x02 - 0x03)
14554 */
14555 /* set vol=0 to output mixers */
14556 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14557 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14558
14559 /* set up input amps for analog loopback */
14560 /* Amp Indices: DAC = 0, mixer = 1 */
14561 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14562 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14563 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14564 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14565 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14566 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14567
14568 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14569 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14570 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14571 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14572 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14573 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14574 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14575
14576 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14577 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14578
14579 /* FIXME: use Mux-type input source selection */
14580 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14581 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14582 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
14583
14584 /* set EAPD */
14585 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14586 { }
14587 };
14588
14589 static const struct hda_verb alc269vb_init_verbs[] = {
14590 /*
14591 * Unmute ADC0 and set the default input to mic-in
14592 */
14593 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14594
14595 /*
14596 * Set up output mixers (0x02 - 0x03)
14597 */
14598 /* set vol=0 to output mixers */
14599 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14600 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14601
14602 /* set up input amps for analog loopback */
14603 /* Amp Indices: DAC = 0, mixer = 1 */
14604 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14605 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14606 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14607 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14608 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14609 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14610
14611 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14612 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14613 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14614 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14615 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14616 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14617 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14618
14619 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14620 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14621
14622 /* FIXME: use Mux-type input source selection */
14623 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14624 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14625 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
14626
14627 /* set EAPD */
14628 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14629 { }
14630 };
14631
14632 #define alc269_auto_create_multi_out_ctls \
14633 alc268_auto_create_multi_out_ctls
14634 #define alc269_auto_create_input_ctls \
14635 alc268_auto_create_input_ctls
14636
14637 #ifdef CONFIG_SND_HDA_POWER_SAVE
14638 #define alc269_loopbacks alc880_loopbacks
14639 #endif
14640
14641 /* pcm configuration: identical with ALC880 */
14642 #define alc269_pcm_analog_playback alc880_pcm_analog_playback
14643 #define alc269_pcm_analog_capture alc880_pcm_analog_capture
14644 #define alc269_pcm_digital_playback alc880_pcm_digital_playback
14645 #define alc269_pcm_digital_capture alc880_pcm_digital_capture
14646
14647 static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = {
14648 .substreams = 1,
14649 .channels_min = 2,
14650 .channels_max = 8,
14651 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14652 /* NID is set in alc_build_pcms */
14653 .ops = {
14654 .open = alc880_playback_pcm_open,
14655 .prepare = alc880_playback_pcm_prepare,
14656 .cleanup = alc880_playback_pcm_cleanup
14657 },
14658 };
14659
14660 static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = {
14661 .substreams = 1,
14662 .channels_min = 2,
14663 .channels_max = 2,
14664 .rates = SNDRV_PCM_RATE_44100, /* fixed rate */
14665 /* NID is set in alc_build_pcms */
14666 };
14667
14668 #ifdef CONFIG_SND_HDA_POWER_SAVE
14669 static int alc269_mic2_for_mute_led(struct hda_codec *codec)
14670 {
14671 switch (codec->subsystem_id) {
14672 case 0x103c1586:
14673 return 1;
14674 }
14675 return 0;
14676 }
14677
14678 static int alc269_mic2_mute_check_ps(struct hda_codec *codec, hda_nid_t nid)
14679 {
14680 /* update mute-LED according to the speaker mute state */
14681 if (nid == 0x01 || nid == 0x14) {
14682 int pinval;
14683 if (snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0) &
14684 HDA_AMP_MUTE)
14685 pinval = 0x24;
14686 else
14687 pinval = 0x20;
14688 /* mic2 vref pin is used for mute LED control */
14689 snd_hda_codec_update_cache(codec, 0x19, 0,
14690 AC_VERB_SET_PIN_WIDGET_CONTROL,
14691 pinval);
14692 }
14693 return alc_check_power_status(codec, nid);
14694 }
14695 #endif /* CONFIG_SND_HDA_POWER_SAVE */
14696
14697 static int alc275_setup_dual_adc(struct hda_codec *codec)
14698 {
14699 struct alc_spec *spec = codec->spec;
14700
14701 if (codec->vendor_id != 0x10ec0275 || !spec->auto_mic)
14702 return 0;
14703 if ((spec->ext_mic.pin >= 0x18 && spec->int_mic.pin <= 0x13) ||
14704 (spec->ext_mic.pin <= 0x12 && spec->int_mic.pin >= 0x18)) {
14705 if (spec->ext_mic.pin <= 0x12) {
14706 spec->private_adc_nids[0] = 0x08;
14707 spec->private_adc_nids[1] = 0x11;
14708 spec->private_capsrc_nids[0] = 0x23;
14709 spec->private_capsrc_nids[1] = 0x22;
14710 } else {
14711 spec->private_adc_nids[0] = 0x11;
14712 spec->private_adc_nids[1] = 0x08;
14713 spec->private_capsrc_nids[0] = 0x22;
14714 spec->private_capsrc_nids[1] = 0x23;
14715 }
14716 spec->adc_nids = spec->private_adc_nids;
14717 spec->capsrc_nids = spec->private_capsrc_nids;
14718 spec->num_adc_nids = 2;
14719 spec->dual_adc_switch = 1;
14720 snd_printdd("realtek: enabling dual ADC switchg (%02x:%02x)\n",
14721 spec->adc_nids[0], spec->adc_nids[1]);
14722 return 1;
14723 }
14724 return 0;
14725 }
14726
14727 /* different alc269-variants */
14728 enum {
14729 ALC269_TYPE_NORMAL,
14730 ALC269_TYPE_ALC258,
14731 ALC269_TYPE_ALC259,
14732 ALC269_TYPE_ALC269VB,
14733 ALC269_TYPE_ALC270,
14734 ALC269_TYPE_ALC271X,
14735 };
14736
14737 /*
14738 * BIOS auto configuration
14739 */
14740 static int alc269_parse_auto_config(struct hda_codec *codec)
14741 {
14742 struct alc_spec *spec = codec->spec;
14743 int err;
14744 static const hda_nid_t alc269_ignore[] = { 0x1d, 0 };
14745
14746 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
14747 alc269_ignore);
14748 if (err < 0)
14749 return err;
14750
14751 err = alc269_auto_create_multi_out_ctls(spec, &spec->autocfg);
14752 if (err < 0)
14753 return err;
14754 if (spec->codec_variant == ALC269_TYPE_NORMAL)
14755 err = alc269_auto_create_input_ctls(codec, &spec->autocfg);
14756 else
14757 err = alc_auto_create_input_ctls(codec, &spec->autocfg, 0,
14758 0x22, 0);
14759 if (err < 0)
14760 return err;
14761
14762 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
14763
14764 alc_auto_parse_digital(codec);
14765
14766 if (spec->kctls.list)
14767 add_mixer(spec, spec->kctls.list);
14768
14769 if (spec->codec_variant != ALC269_TYPE_NORMAL) {
14770 add_verb(spec, alc269vb_init_verbs);
14771 alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21);
14772 } else {
14773 add_verb(spec, alc269_init_verbs);
14774 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
14775 }
14776
14777 spec->num_mux_defs = 1;
14778 spec->input_mux = &spec->private_imux[0];
14779
14780 if (!alc275_setup_dual_adc(codec))
14781 fillup_priv_adc_nids(codec, alc269_adc_candidates,
14782 sizeof(alc269_adc_candidates));
14783
14784 err = alc_auto_add_mic_boost(codec);
14785 if (err < 0)
14786 return err;
14787
14788 if (!spec->cap_mixer && !spec->no_analog)
14789 set_capture_mixer(codec);
14790
14791 return 1;
14792 }
14793
14794 #define alc269_auto_init_multi_out alc268_auto_init_multi_out
14795 #define alc269_auto_init_hp_out alc268_auto_init_hp_out
14796 #define alc269_auto_init_analog_input alc882_auto_init_analog_input
14797 #define alc269_auto_init_input_src alc882_auto_init_input_src
14798
14799
14800 /* init callback for auto-configuration model -- overriding the default init */
14801 static void alc269_auto_init(struct hda_codec *codec)
14802 {
14803 struct alc_spec *spec = codec->spec;
14804 alc269_auto_init_multi_out(codec);
14805 alc269_auto_init_hp_out(codec);
14806 alc269_auto_init_analog_input(codec);
14807 if (!spec->dual_adc_switch)
14808 alc269_auto_init_input_src(codec);
14809 alc_auto_init_digital(codec);
14810 if (spec->unsol_event)
14811 alc_inithook(codec);
14812 }
14813
14814 static void alc269_toggle_power_output(struct hda_codec *codec, int power_up)
14815 {
14816 int val = alc_read_coef_idx(codec, 0x04);
14817 if (power_up)
14818 val |= 1 << 11;
14819 else
14820 val &= ~(1 << 11);
14821 alc_write_coef_idx(codec, 0x04, val);
14822 }
14823
14824 static void alc269_shutup(struct hda_codec *codec)
14825 {
14826 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017)
14827 alc269_toggle_power_output(codec, 0);
14828 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14829 alc269_toggle_power_output(codec, 0);
14830 msleep(150);
14831 }
14832 }
14833
14834 #ifdef SND_HDA_NEEDS_RESUME
14835 static int alc269_resume(struct hda_codec *codec)
14836 {
14837 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
14838 alc269_toggle_power_output(codec, 0);
14839 msleep(150);
14840 }
14841
14842 codec->patch_ops.init(codec);
14843
14844 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
14845 alc269_toggle_power_output(codec, 1);
14846 msleep(200);
14847 }
14848
14849 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018)
14850 alc269_toggle_power_output(codec, 1);
14851
14852 snd_hda_codec_resume_amp(codec);
14853 snd_hda_codec_resume_cache(codec);
14854 hda_call_check_power_status(codec, 0x01);
14855 return 0;
14856 }
14857 #endif /* SND_HDA_NEEDS_RESUME */
14858
14859 static void alc269_fixup_hweq(struct hda_codec *codec,
14860 const struct alc_fixup *fix, int action)
14861 {
14862 int coef;
14863
14864 if (action != ALC_FIXUP_ACT_INIT)
14865 return;
14866 coef = alc_read_coef_idx(codec, 0x1e);
14867 alc_write_coef_idx(codec, 0x1e, coef | 0x80);
14868 }
14869
14870 static void alc271_fixup_dmic(struct hda_codec *codec,
14871 const struct alc_fixup *fix, int action)
14872 {
14873 static const struct hda_verb verbs[] = {
14874 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14875 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14876 {}
14877 };
14878 unsigned int cfg;
14879
14880 if (strcmp(codec->chip_name, "ALC271X"))
14881 return;
14882 cfg = snd_hda_codec_get_pincfg(codec, 0x12);
14883 if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED)
14884 snd_hda_sequence_write(codec, verbs);
14885 }
14886
14887 enum {
14888 ALC269_FIXUP_SONY_VAIO,
14889 ALC275_FIXUP_SONY_VAIO_GPIO2,
14890 ALC269_FIXUP_DELL_M101Z,
14891 ALC269_FIXUP_SKU_IGNORE,
14892 ALC269_FIXUP_ASUS_G73JW,
14893 ALC269_FIXUP_LENOVO_EAPD,
14894 ALC275_FIXUP_SONY_HWEQ,
14895 ALC271_FIXUP_DMIC,
14896 };
14897
14898 static const struct alc_fixup alc269_fixups[] = {
14899 [ALC269_FIXUP_SONY_VAIO] = {
14900 .type = ALC_FIXUP_VERBS,
14901 .v.verbs = (const struct hda_verb[]) {
14902 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD},
14903 {}
14904 }
14905 },
14906 [ALC275_FIXUP_SONY_VAIO_GPIO2] = {
14907 .type = ALC_FIXUP_VERBS,
14908 .v.verbs = (const struct hda_verb[]) {
14909 {0x01, AC_VERB_SET_GPIO_MASK, 0x04},
14910 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04},
14911 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
14912 { }
14913 },
14914 .chained = true,
14915 .chain_id = ALC269_FIXUP_SONY_VAIO
14916 },
14917 [ALC269_FIXUP_DELL_M101Z] = {
14918 .type = ALC_FIXUP_VERBS,
14919 .v.verbs = (const struct hda_verb[]) {
14920 /* Enables internal speaker */
14921 {0x20, AC_VERB_SET_COEF_INDEX, 13},
14922 {0x20, AC_VERB_SET_PROC_COEF, 0x4040},
14923 {}
14924 }
14925 },
14926 [ALC269_FIXUP_SKU_IGNORE] = {
14927 .type = ALC_FIXUP_SKU,
14928 .v.sku = ALC_FIXUP_SKU_IGNORE,
14929 },
14930 [ALC269_FIXUP_ASUS_G73JW] = {
14931 .type = ALC_FIXUP_PINS,
14932 .v.pins = (const struct alc_pincfg[]) {
14933 { 0x17, 0x99130111 }, /* subwoofer */
14934 { }
14935 }
14936 },
14937 [ALC269_FIXUP_LENOVO_EAPD] = {
14938 .type = ALC_FIXUP_VERBS,
14939 .v.verbs = (const struct hda_verb[]) {
14940 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
14941 {}
14942 }
14943 },
14944 [ALC275_FIXUP_SONY_HWEQ] = {
14945 .type = ALC_FIXUP_FUNC,
14946 .v.func = alc269_fixup_hweq,
14947 .chained = true,
14948 .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2
14949 },
14950 [ALC271_FIXUP_DMIC] = {
14951 .type = ALC_FIXUP_FUNC,
14952 .v.func = alc271_fixup_dmic,
14953 },
14954 };
14955
14956 static const struct snd_pci_quirk alc269_fixup_tbl[] = {
14957 SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2),
14958 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14959 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
14960 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
14961 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
14962 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
14963 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
14964 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
14965 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
14966 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
14967 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
14968 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
14969 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
14970 {}
14971 };
14972
14973
14974 /*
14975 * configuration and preset
14976 */
14977 static const char * const alc269_models[ALC269_MODEL_LAST] = {
14978 [ALC269_BASIC] = "basic",
14979 [ALC269_QUANTA_FL1] = "quanta",
14980 [ALC269_AMIC] = "laptop-amic",
14981 [ALC269_DMIC] = "laptop-dmic",
14982 [ALC269_FUJITSU] = "fujitsu",
14983 [ALC269_LIFEBOOK] = "lifebook",
14984 [ALC269_AUTO] = "auto",
14985 };
14986
14987 static const struct snd_pci_quirk alc269_cfg_tbl[] = {
14988 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
14989 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
14990 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
14991 ALC269_AMIC),
14992 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14993 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14994 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14995 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14996 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14997 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14998 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14999 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
15000 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
15001 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
15002 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
15003 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
15004 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
15005 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
15006 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
15007 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
15008 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
15009 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
15010 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
15011 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
15012 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
15013 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
15014 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
15015 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
15016 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
15017 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
15018 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
15019 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
15020 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
15021 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
15022 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
15023 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
15024 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
15025 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
15026 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
15027 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
15028 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
15029 ALC269_DMIC),
15030 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
15031 ALC269_DMIC),
15032 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
15033 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
15034 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
15035 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
15036 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
15037 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
15038 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
15039 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
15040 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
15041 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
15042 {}
15043 };
15044
15045 static const struct alc_config_preset alc269_presets[] = {
15046 [ALC269_BASIC] = {
15047 .mixers = { alc269_base_mixer },
15048 .init_verbs = { alc269_init_verbs },
15049 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15050 .dac_nids = alc269_dac_nids,
15051 .hp_nid = 0x03,
15052 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15053 .channel_mode = alc269_modes,
15054 .input_mux = &alc269_capture_source,
15055 },
15056 [ALC269_QUANTA_FL1] = {
15057 .mixers = { alc269_quanta_fl1_mixer },
15058 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
15059 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15060 .dac_nids = alc269_dac_nids,
15061 .hp_nid = 0x03,
15062 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15063 .channel_mode = alc269_modes,
15064 .input_mux = &alc269_capture_source,
15065 .unsol_event = alc269_quanta_fl1_unsol_event,
15066 .setup = alc269_quanta_fl1_setup,
15067 .init_hook = alc269_quanta_fl1_init_hook,
15068 },
15069 [ALC269_AMIC] = {
15070 .mixers = { alc269_laptop_mixer },
15071 .cap_mixer = alc269_laptop_analog_capture_mixer,
15072 .init_verbs = { alc269_init_verbs,
15073 alc269_laptop_amic_init_verbs },
15074 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15075 .dac_nids = alc269_dac_nids,
15076 .hp_nid = 0x03,
15077 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15078 .channel_mode = alc269_modes,
15079 .unsol_event = alc_sku_unsol_event,
15080 .setup = alc269_laptop_amic_setup,
15081 .init_hook = alc_inithook,
15082 },
15083 [ALC269_DMIC] = {
15084 .mixers = { alc269_laptop_mixer },
15085 .cap_mixer = alc269_laptop_digital_capture_mixer,
15086 .init_verbs = { alc269_init_verbs,
15087 alc269_laptop_dmic_init_verbs },
15088 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15089 .dac_nids = alc269_dac_nids,
15090 .hp_nid = 0x03,
15091 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15092 .channel_mode = alc269_modes,
15093 .unsol_event = alc_sku_unsol_event,
15094 .setup = alc269_laptop_dmic_setup,
15095 .init_hook = alc_inithook,
15096 },
15097 [ALC269VB_AMIC] = {
15098 .mixers = { alc269vb_laptop_mixer },
15099 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
15100 .init_verbs = { alc269vb_init_verbs,
15101 alc269vb_laptop_amic_init_verbs },
15102 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15103 .dac_nids = alc269_dac_nids,
15104 .hp_nid = 0x03,
15105 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15106 .channel_mode = alc269_modes,
15107 .unsol_event = alc_sku_unsol_event,
15108 .setup = alc269vb_laptop_amic_setup,
15109 .init_hook = alc_inithook,
15110 },
15111 [ALC269VB_DMIC] = {
15112 .mixers = { alc269vb_laptop_mixer },
15113 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15114 .init_verbs = { alc269vb_init_verbs,
15115 alc269vb_laptop_dmic_init_verbs },
15116 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15117 .dac_nids = alc269_dac_nids,
15118 .hp_nid = 0x03,
15119 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15120 .channel_mode = alc269_modes,
15121 .unsol_event = alc_sku_unsol_event,
15122 .setup = alc269vb_laptop_dmic_setup,
15123 .init_hook = alc_inithook,
15124 },
15125 [ALC269_FUJITSU] = {
15126 .mixers = { alc269_fujitsu_mixer },
15127 .cap_mixer = alc269_laptop_digital_capture_mixer,
15128 .init_verbs = { alc269_init_verbs,
15129 alc269_laptop_dmic_init_verbs },
15130 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15131 .dac_nids = alc269_dac_nids,
15132 .hp_nid = 0x03,
15133 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15134 .channel_mode = alc269_modes,
15135 .unsol_event = alc_sku_unsol_event,
15136 .setup = alc269_laptop_dmic_setup,
15137 .init_hook = alc_inithook,
15138 },
15139 [ALC269_LIFEBOOK] = {
15140 .mixers = { alc269_lifebook_mixer },
15141 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
15142 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15143 .dac_nids = alc269_dac_nids,
15144 .hp_nid = 0x03,
15145 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15146 .channel_mode = alc269_modes,
15147 .input_mux = &alc269_capture_source,
15148 .unsol_event = alc269_lifebook_unsol_event,
15149 .setup = alc269_lifebook_setup,
15150 .init_hook = alc269_lifebook_init_hook,
15151 },
15152 [ALC271_ACER] = {
15153 .mixers = { alc269_asus_mixer },
15154 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
15155 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
15156 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
15157 .dac_nids = alc269_dac_nids,
15158 .adc_nids = alc262_dmic_adc_nids,
15159 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
15160 .capsrc_nids = alc262_dmic_capsrc_nids,
15161 .num_channel_mode = ARRAY_SIZE(alc269_modes),
15162 .channel_mode = alc269_modes,
15163 .input_mux = &alc269_capture_source,
15164 .dig_out_nid = ALC880_DIGOUT_NID,
15165 .unsol_event = alc_sku_unsol_event,
15166 .setup = alc269vb_laptop_dmic_setup,
15167 .init_hook = alc_inithook,
15168 },
15169 };
15170
15171 static int alc269_fill_coef(struct hda_codec *codec)
15172 {
15173 int val;
15174
15175 if ((alc_read_coef_idx(codec, 0) & 0x00ff) < 0x015) {
15176 alc_write_coef_idx(codec, 0xf, 0x960b);
15177 alc_write_coef_idx(codec, 0xe, 0x8817);
15178 }
15179
15180 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x016) {
15181 alc_write_coef_idx(codec, 0xf, 0x960b);
15182 alc_write_coef_idx(codec, 0xe, 0x8814);
15183 }
15184
15185 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) {
15186 val = alc_read_coef_idx(codec, 0x04);
15187 /* Power up output pin */
15188 alc_write_coef_idx(codec, 0x04, val | (1<<11));
15189 }
15190
15191 if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) {
15192 val = alc_read_coef_idx(codec, 0xd);
15193 if ((val & 0x0c00) >> 10 != 0x1) {
15194 /* Capless ramp up clock control */
15195 alc_write_coef_idx(codec, 0xd, val | (1<<10));
15196 }
15197 val = alc_read_coef_idx(codec, 0x17);
15198 if ((val & 0x01c0) >> 6 != 0x4) {
15199 /* Class D power on reset */
15200 alc_write_coef_idx(codec, 0x17, val | (1<<7));
15201 }
15202 }
15203
15204 val = alc_read_coef_idx(codec, 0xd); /* Class D */
15205 alc_write_coef_idx(codec, 0xd, val | (1<<14));
15206
15207 val = alc_read_coef_idx(codec, 0x4); /* HP */
15208 alc_write_coef_idx(codec, 0x4, val | (1<<11));
15209
15210 return 0;
15211 }
15212
15213 static int patch_alc269(struct hda_codec *codec)
15214 {
15215 struct alc_spec *spec;
15216 int board_config, coef;
15217 int err;
15218
15219 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
15220 if (spec == NULL)
15221 return -ENOMEM;
15222
15223 codec->spec = spec;
15224
15225 alc_auto_parse_customize_define(codec);
15226
15227 if (codec->vendor_id == 0x10ec0269) {
15228 coef = alc_read_coef_idx(codec, 0);
15229 if ((coef & 0x00f0) == 0x0010) {
15230 if (codec->bus->pci->subsystem_vendor == 0x1025 &&
15231 spec->cdefine.platform_type == 1) {
15232 alc_codec_rename(codec, "ALC271X");
15233 spec->codec_variant = ALC269_TYPE_ALC271X;
15234 } else if ((coef & 0xf000) == 0x1000) {
15235 spec->codec_variant = ALC269_TYPE_ALC270;
15236 } else if ((coef & 0xf000) == 0x2000) {
15237 alc_codec_rename(codec, "ALC259");
15238 spec->codec_variant = ALC269_TYPE_ALC259;
15239 } else if ((coef & 0xf000) == 0x3000) {
15240 alc_codec_rename(codec, "ALC258");
15241 spec->codec_variant = ALC269_TYPE_ALC258;
15242 } else {
15243 alc_codec_rename(codec, "ALC269VB");
15244 spec->codec_variant = ALC269_TYPE_ALC269VB;
15245 }
15246 } else
15247 alc_fix_pll_init(codec, 0x20, 0x04, 15);
15248 alc269_fill_coef(codec);
15249 }
15250
15251 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST,
15252 alc269_models,
15253 alc269_cfg_tbl);
15254
15255 if (board_config < 0) {
15256 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15257 codec->chip_name);
15258 board_config = ALC269_AUTO;
15259 }
15260
15261 if (board_config == ALC269_AUTO) {
15262 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
15263 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15264 }
15265
15266 if (board_config == ALC269_AUTO) {
15267 /* automatic parse from the BIOS config */
15268 err = alc269_parse_auto_config(codec);
15269 if (err < 0) {
15270 alc_free(codec);
15271 return err;
15272 } else if (!err) {
15273 printk(KERN_INFO
15274 "hda_codec: Cannot set up configuration "
15275 "from BIOS. Using base mode...\n");
15276 board_config = ALC269_BASIC;
15277 }
15278 }
15279
15280 if (has_cdefine_beep(codec)) {
15281 err = snd_hda_attach_beep_device(codec, 0x1);
15282 if (err < 0) {
15283 alc_free(codec);
15284 return err;
15285 }
15286 }
15287
15288 if (board_config != ALC269_AUTO)
15289 setup_preset(codec, &alc269_presets[board_config]);
15290
15291 if (board_config == ALC269_QUANTA_FL1) {
15292 /* Due to a hardware problem on Lenovo Ideadpad, we need to
15293 * fix the sample rate of analog I/O to 44.1kHz
15294 */
15295 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
15296 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
15297 } else if (spec->dual_adc_switch) {
15298 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15299 /* switch ADC dynamically */
15300 spec->stream_analog_capture = &dualmic_pcm_analog_capture;
15301 } else {
15302 spec->stream_analog_playback = &alc269_pcm_analog_playback;
15303 spec->stream_analog_capture = &alc269_pcm_analog_capture;
15304 }
15305 spec->stream_digital_playback = &alc269_pcm_digital_playback;
15306 spec->stream_digital_capture = &alc269_pcm_digital_capture;
15307
15308 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
15309 if (spec->codec_variant == ALC269_TYPE_NORMAL) {
15310 spec->adc_nids = alc269_adc_nids;
15311 spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids);
15312 spec->capsrc_nids = alc269_capsrc_nids;
15313 } else {
15314 spec->adc_nids = alc269vb_adc_nids;
15315 spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids);
15316 spec->capsrc_nids = alc269vb_capsrc_nids;
15317 }
15318 }
15319
15320 if (!spec->cap_mixer)
15321 set_capture_mixer(codec);
15322 if (has_cdefine_beep(codec))
15323 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
15324
15325 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
15326
15327 spec->vmaster_nid = 0x02;
15328
15329 codec->patch_ops = alc_patch_ops;
15330 #ifdef SND_HDA_NEEDS_RESUME
15331 codec->patch_ops.resume = alc269_resume;
15332 #endif
15333 if (board_config == ALC269_AUTO)
15334 spec->init_hook = alc269_auto_init;
15335 spec->shutup = alc269_shutup;
15336
15337 alc_init_jacks(codec);
15338 #ifdef CONFIG_SND_HDA_POWER_SAVE
15339 if (!spec->loopback.amplist)
15340 spec->loopback.amplist = alc269_loopbacks;
15341 if (alc269_mic2_for_mute_led(codec))
15342 codec->patch_ops.check_power_status = alc269_mic2_mute_check_ps;
15343 #endif
15344
15345 return 0;
15346 }
15347
15348 /*
15349 * ALC861 channel source setting (2/6 channel selection for 3-stack)
15350 */
15351
15352 /*
15353 * set the path ways for 2 channel output
15354 * need to set the codec line out and mic 1 pin widgets to inputs
15355 */
15356 static const struct hda_verb alc861_threestack_ch2_init[] = {
15357 /* set pin widget 1Ah (line in) for input */
15358 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15359 /* set pin widget 18h (mic1/2) for input, for mic also enable
15360 * the vref
15361 */
15362 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15363
15364 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15365 #if 0
15366 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15367 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15368 #endif
15369 { } /* end */
15370 };
15371 /*
15372 * 6ch mode
15373 * need to set the codec line out and mic 1 pin widgets to outputs
15374 */
15375 static const struct hda_verb alc861_threestack_ch6_init[] = {
15376 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15377 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15378 /* set pin widget 18h (mic1) for output (CLFE)*/
15379 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15380
15381 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15382 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15383
15384 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15385 #if 0
15386 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15387 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15388 #endif
15389 { } /* end */
15390 };
15391
15392 static const struct hda_channel_mode alc861_threestack_modes[2] = {
15393 { 2, alc861_threestack_ch2_init },
15394 { 6, alc861_threestack_ch6_init },
15395 };
15396 /* Set mic1 as input and unmute the mixer */
15397 static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
15398 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15399 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15400 { } /* end */
15401 };
15402 /* Set mic1 as output and mute mixer */
15403 static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
15404 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15405 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15406 { } /* end */
15407 };
15408
15409 static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
15410 { 2, alc861_uniwill_m31_ch2_init },
15411 { 4, alc861_uniwill_m31_ch4_init },
15412 };
15413
15414 /* Set mic1 and line-in as input and unmute the mixer */
15415 static const struct hda_verb alc861_asus_ch2_init[] = {
15416 /* set pin widget 1Ah (line in) for input */
15417 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15418 /* set pin widget 18h (mic1/2) for input, for mic also enable
15419 * the vref
15420 */
15421 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15422
15423 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
15424 #if 0
15425 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
15426 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
15427 #endif
15428 { } /* end */
15429 };
15430 /* Set mic1 nad line-in as output and mute mixer */
15431 static const struct hda_verb alc861_asus_ch6_init[] = {
15432 /* set pin widget 1Ah (line in) for output (Back Surround)*/
15433 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15434 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15435 /* set pin widget 18h (mic1) for output (CLFE)*/
15436 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15437 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
15438 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
15439 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
15440
15441 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
15442 #if 0
15443 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
15444 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
15445 #endif
15446 { } /* end */
15447 };
15448
15449 static const struct hda_channel_mode alc861_asus_modes[2] = {
15450 { 2, alc861_asus_ch2_init },
15451 { 6, alc861_asus_ch6_init },
15452 };
15453
15454 /* patch-ALC861 */
15455
15456 static const struct snd_kcontrol_new alc861_base_mixer[] = {
15457 /* output mixer control */
15458 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15459 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15460 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15461 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15462 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15463
15464 /*Input mixer control */
15465 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15466 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15467 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15468 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15469 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15470 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15471 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15472 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15473 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15474 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15475
15476 { } /* end */
15477 };
15478
15479 static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
15480 /* output mixer control */
15481 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15482 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15483 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15484 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15485 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15486
15487 /* Input mixer control */
15488 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15489 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15490 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15491 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15492 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15493 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15494 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15495 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15496 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15497 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15498
15499 {
15500 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15501 .name = "Channel Mode",
15502 .info = alc_ch_mode_info,
15503 .get = alc_ch_mode_get,
15504 .put = alc_ch_mode_put,
15505 .private_value = ARRAY_SIZE(alc861_threestack_modes),
15506 },
15507 { } /* end */
15508 };
15509
15510 static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
15511 /* output mixer control */
15512 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15513 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15514 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15515
15516 { } /* end */
15517 };
15518
15519 static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
15520 /* output mixer control */
15521 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15522 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15523 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15524 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15525 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
15526
15527 /* Input mixer control */
15528 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15529 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
15530 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15531 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15532 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15533 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15534 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15535 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15536 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15537 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15538
15539 {
15540 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15541 .name = "Channel Mode",
15542 .info = alc_ch_mode_info,
15543 .get = alc_ch_mode_get,
15544 .put = alc_ch_mode_put,
15545 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15546 },
15547 { } /* end */
15548 };
15549
15550 static const struct snd_kcontrol_new alc861_asus_mixer[] = {
15551 /* output mixer control */
15552 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15553 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15554 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15555 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15556 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15557
15558 /* Input mixer control */
15559 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15560 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15561 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15562 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15563 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15564 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15565 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15566 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15567 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15568 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15569
15570 {
15571 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15572 .name = "Channel Mode",
15573 .info = alc_ch_mode_info,
15574 .get = alc_ch_mode_get,
15575 .put = alc_ch_mode_put,
15576 .private_value = ARRAY_SIZE(alc861_asus_modes),
15577 },
15578 { }
15579 };
15580
15581 /* additional mixer */
15582 static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
15583 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15584 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15585 { }
15586 };
15587
15588 /*
15589 * generic initialization of ADC, input mixers and output mixers
15590 */
15591 static const struct hda_verb alc861_base_init_verbs[] = {
15592 /*
15593 * Unmute ADC0 and set the default input to mic-in
15594 */
15595 /* port-A for surround (rear panel) */
15596 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15597 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15598 /* port-B for mic-in (rear panel) with vref */
15599 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15600 /* port-C for line-in (rear panel) */
15601 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15602 /* port-D for Front */
15603 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15604 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15605 /* port-E for HP out (front panel) */
15606 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15607 /* route front PCM to HP */
15608 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15609 /* port-F for mic-in (front panel) with vref */
15610 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15611 /* port-G for CLFE (rear panel) */
15612 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15613 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15614 /* port-H for side (rear panel) */
15615 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15616 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15617 /* CD-in */
15618 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15619 /* route front mic to ADC1*/
15620 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15621 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15622
15623 /* Unmute DAC0~3 & spdif out*/
15624 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15625 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15626 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15627 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15628 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15629
15630 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15631 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15632 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15633 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15634 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15635
15636 /* Unmute Stereo Mixer 15 */
15637 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15638 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15639 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15640 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15641
15642 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15643 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15644 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15645 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15646 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15647 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15648 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15649 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15650 /* hp used DAC 3 (Front) */
15651 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15652 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15653
15654 { }
15655 };
15656
15657 static const struct hda_verb alc861_threestack_init_verbs[] = {
15658 /*
15659 * Unmute ADC0 and set the default input to mic-in
15660 */
15661 /* port-A for surround (rear panel) */
15662 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15663 /* port-B for mic-in (rear panel) with vref */
15664 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15665 /* port-C for line-in (rear panel) */
15666 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15667 /* port-D for Front */
15668 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15669 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15670 /* port-E for HP out (front panel) */
15671 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15672 /* route front PCM to HP */
15673 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15674 /* port-F for mic-in (front panel) with vref */
15675 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15676 /* port-G for CLFE (rear panel) */
15677 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15678 /* port-H for side (rear panel) */
15679 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15680 /* CD-in */
15681 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15682 /* route front mic to ADC1*/
15683 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15684 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15685 /* Unmute DAC0~3 & spdif out*/
15686 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15687 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15688 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15689 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15690 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15691
15692 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15693 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15694 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15695 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15696 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15697
15698 /* Unmute Stereo Mixer 15 */
15699 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15700 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15701 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15702 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15703
15704 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15705 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15706 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15707 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15708 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15709 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15710 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15711 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15712 /* hp used DAC 3 (Front) */
15713 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15714 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15715 { }
15716 };
15717
15718 static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15719 /*
15720 * Unmute ADC0 and set the default input to mic-in
15721 */
15722 /* port-A for surround (rear panel) */
15723 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15724 /* port-B for mic-in (rear panel) with vref */
15725 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15726 /* port-C for line-in (rear panel) */
15727 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15728 /* port-D for Front */
15729 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15730 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15731 /* port-E for HP out (front panel) */
15732 /* this has to be set to VREF80 */
15733 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15734 /* route front PCM to HP */
15735 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15736 /* port-F for mic-in (front panel) with vref */
15737 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15738 /* port-G for CLFE (rear panel) */
15739 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15740 /* port-H for side (rear panel) */
15741 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15742 /* CD-in */
15743 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15744 /* route front mic to ADC1*/
15745 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15746 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15747 /* Unmute DAC0~3 & spdif out*/
15748 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15749 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15750 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15751 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15752 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15753
15754 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15755 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15756 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15757 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15758 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15759
15760 /* Unmute Stereo Mixer 15 */
15761 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15762 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15763 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15764 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15765
15766 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15767 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15768 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15769 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15770 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15771 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15772 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15773 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15774 /* hp used DAC 3 (Front) */
15775 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15776 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15777 { }
15778 };
15779
15780 static const struct hda_verb alc861_asus_init_verbs[] = {
15781 /*
15782 * Unmute ADC0 and set the default input to mic-in
15783 */
15784 /* port-A for surround (rear panel)
15785 * according to codec#0 this is the HP jack
15786 */
15787 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15788 /* route front PCM to HP */
15789 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15790 /* port-B for mic-in (rear panel) with vref */
15791 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15792 /* port-C for line-in (rear panel) */
15793 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15794 /* port-D for Front */
15795 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15796 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15797 /* port-E for HP out (front panel) */
15798 /* this has to be set to VREF80 */
15799 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15800 /* route front PCM to HP */
15801 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15802 /* port-F for mic-in (front panel) with vref */
15803 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15804 /* port-G for CLFE (rear panel) */
15805 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15806 /* port-H for side (rear panel) */
15807 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15808 /* CD-in */
15809 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15810 /* route front mic to ADC1*/
15811 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15812 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15813 /* Unmute DAC0~3 & spdif out*/
15814 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15815 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15816 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15817 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15818 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15819 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15820 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15821 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15822 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15823 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15824
15825 /* Unmute Stereo Mixer 15 */
15826 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15827 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15828 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15829 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15830
15831 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15832 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15833 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15834 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15835 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15836 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15837 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15838 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15839 /* hp used DAC 3 (Front) */
15840 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15841 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15842 { }
15843 };
15844
15845 /* additional init verbs for ASUS laptops */
15846 static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
15847 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15848 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15849 { }
15850 };
15851
15852 /*
15853 * generic initialization of ADC, input mixers and output mixers
15854 */
15855 static const struct hda_verb alc861_auto_init_verbs[] = {
15856 /*
15857 * Unmute ADC0 and set the default input to mic-in
15858 */
15859 /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */
15860 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15861
15862 /* Unmute DAC0~3 & spdif out*/
15863 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15864 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15865 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15866 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
15867 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15868
15869 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15870 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15871 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15872 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15873 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15874
15875 /* Unmute Stereo Mixer 15 */
15876 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15877 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15878 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15879 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c},
15880
15881 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15882 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15883 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15884 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15885 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15886 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15887 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15888 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15889
15890 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15891 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15892 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15893 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15894 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
15895 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
15896 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
15897 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
15898
15899 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */
15900
15901 { }
15902 };
15903
15904 static const struct hda_verb alc861_toshiba_init_verbs[] = {
15905 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15906
15907 { }
15908 };
15909
15910 /* toggle speaker-output according to the hp-jack state */
15911 static void alc861_toshiba_automute(struct hda_codec *codec)
15912 {
15913 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
15914
15915 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15916 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15917 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15918 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
15919 }
15920
15921 static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15922 unsigned int res)
15923 {
15924 if ((res >> 26) == ALC880_HP_EVENT)
15925 alc861_toshiba_automute(codec);
15926 }
15927
15928 /* pcm configuration: identical with ALC880 */
15929 #define alc861_pcm_analog_playback alc880_pcm_analog_playback
15930 #define alc861_pcm_analog_capture alc880_pcm_analog_capture
15931 #define alc861_pcm_digital_playback alc880_pcm_digital_playback
15932 #define alc861_pcm_digital_capture alc880_pcm_digital_capture
15933
15934
15935 #define ALC861_DIGOUT_NID 0x07
15936
15937 static const struct hda_channel_mode alc861_8ch_modes[1] = {
15938 { 8, NULL }
15939 };
15940
15941 static const hda_nid_t alc861_dac_nids[4] = {
15942 /* front, surround, clfe, side */
15943 0x03, 0x06, 0x05, 0x04
15944 };
15945
15946 static const hda_nid_t alc660_dac_nids[3] = {
15947 /* front, clfe, surround */
15948 0x03, 0x05, 0x06
15949 };
15950
15951 static const hda_nid_t alc861_adc_nids[1] = {
15952 /* ADC0-2 */
15953 0x08,
15954 };
15955
15956 static const struct hda_input_mux alc861_capture_source = {
15957 .num_items = 5,
15958 .items = {
15959 { "Mic", 0x0 },
15960 { "Front Mic", 0x3 },
15961 { "Line", 0x1 },
15962 { "CD", 0x4 },
15963 { "Mixer", 0x5 },
15964 },
15965 };
15966
15967 static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15968 {
15969 struct alc_spec *spec = codec->spec;
15970 hda_nid_t mix, srcs[5];
15971 int i, j, num;
15972
15973 if (snd_hda_get_connections(codec, pin, &mix, 1) != 1)
15974 return 0;
15975 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
15976 if (num < 0)
15977 return 0;
15978 for (i = 0; i < num; i++) {
15979 unsigned int type;
15980 type = get_wcaps_type(get_wcaps(codec, srcs[i]));
15981 if (type != AC_WID_AUD_OUT)
15982 continue;
15983 for (j = 0; j < spec->multiout.num_dacs; j++)
15984 if (spec->multiout.dac_nids[j] == srcs[i])
15985 break;
15986 if (j >= spec->multiout.num_dacs)
15987 return srcs[i];
15988 }
15989 return 0;
15990 }
15991
15992 /* fill in the dac_nids table from the parsed pin configuration */
15993 static int alc861_auto_fill_dac_nids(struct hda_codec *codec,
15994 const struct auto_pin_cfg *cfg)
15995 {
15996 struct alc_spec *spec = codec->spec;
15997 int i;
15998 hda_nid_t nid, dac;
15999
16000 spec->multiout.dac_nids = spec->private_dac_nids;
16001 for (i = 0; i < cfg->line_outs; i++) {
16002 nid = cfg->line_out_pins[i];
16003 dac = alc861_look_for_dac(codec, nid);
16004 if (!dac)
16005 continue;
16006 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
16007 }
16008 return 0;
16009 }
16010
16011 static int __alc861_create_out_sw(struct hda_codec *codec, const char *pfx,
16012 hda_nid_t nid, int idx, unsigned int chs)
16013 {
16014 return __add_pb_sw_ctrl(codec->spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
16015 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
16016 }
16017
16018 #define alc861_create_out_sw(codec, pfx, nid, chs) \
16019 __alc861_create_out_sw(codec, pfx, nid, 0, chs)
16020
16021 /* add playback controls from the parsed DAC table */
16022 static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec,
16023 const struct auto_pin_cfg *cfg)
16024 {
16025 struct alc_spec *spec = codec->spec;
16026 static const char * const chname[4] = {
16027 "Front", "Surround", NULL /*CLFE*/, "Side"
16028 };
16029 const char *pfx = alc_get_line_out_pfx(spec, true);
16030 hda_nid_t nid;
16031 int i, err, noutputs;
16032
16033 noutputs = cfg->line_outs;
16034 if (spec->multi_ios > 0)
16035 noutputs += spec->multi_ios;
16036
16037 for (i = 0; i < noutputs; i++) {
16038 nid = spec->multiout.dac_nids[i];
16039 if (!nid)
16040 continue;
16041 if (!pfx && i == 2) {
16042 /* Center/LFE */
16043 err = alc861_create_out_sw(codec, "Center", nid, 1);
16044 if (err < 0)
16045 return err;
16046 err = alc861_create_out_sw(codec, "LFE", nid, 2);
16047 if (err < 0)
16048 return err;
16049 } else {
16050 const char *name = pfx;
16051 int index = i;
16052 if (!name) {
16053 name = chname[i];
16054 index = 0;
16055 }
16056 err = __alc861_create_out_sw(codec, name, nid, index, 3);
16057 if (err < 0)
16058 return err;
16059 }
16060 }
16061 return 0;
16062 }
16063
16064 static int alc861_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin)
16065 {
16066 struct alc_spec *spec = codec->spec;
16067 int err;
16068 hda_nid_t nid;
16069
16070 if (!pin)
16071 return 0;
16072
16073 if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) {
16074 nid = alc861_look_for_dac(codec, pin);
16075 if (nid) {
16076 err = alc861_create_out_sw(codec, "Headphone", nid, 3);
16077 if (err < 0)
16078 return err;
16079 spec->multiout.hp_nid = nid;
16080 }
16081 }
16082 return 0;
16083 }
16084
16085 /* create playback/capture controls for input pins */
16086 static int alc861_auto_create_input_ctls(struct hda_codec *codec,
16087 const struct auto_pin_cfg *cfg)
16088 {
16089 return alc_auto_create_input_ctls(codec, cfg, 0x15, 0x08, 0);
16090 }
16091
16092 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec,
16093 hda_nid_t nid,
16094 int pin_type, hda_nid_t dac)
16095 {
16096 hda_nid_t mix, srcs[5];
16097 int i, num;
16098
16099 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
16100 pin_type);
16101 snd_hda_codec_write(codec, dac, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16102 AMP_OUT_UNMUTE);
16103 if (snd_hda_get_connections(codec, nid, &mix, 1) != 1)
16104 return;
16105 num = snd_hda_get_connections(codec, mix, srcs, ARRAY_SIZE(srcs));
16106 if (num < 0)
16107 return;
16108 for (i = 0; i < num; i++) {
16109 unsigned int mute;
16110 if (srcs[i] == dac || srcs[i] == 0x15)
16111 mute = AMP_IN_UNMUTE(i);
16112 else
16113 mute = AMP_IN_MUTE(i);
16114 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
16115 mute);
16116 }
16117 }
16118
16119 static void alc861_auto_init_multi_out(struct hda_codec *codec)
16120 {
16121 struct alc_spec *spec = codec->spec;
16122 int i;
16123
16124 for (i = 0; i < spec->autocfg.line_outs; i++) {
16125 hda_nid_t nid = spec->autocfg.line_out_pins[i];
16126 int pin_type = get_pin_type(spec->autocfg.line_out_type);
16127 if (nid)
16128 alc861_auto_set_output_and_unmute(codec, nid, pin_type,
16129 spec->multiout.dac_nids[i]);
16130 }
16131 }
16132
16133 static void alc861_auto_init_hp_out(struct hda_codec *codec)
16134 {
16135 struct alc_spec *spec = codec->spec;
16136
16137 if (spec->autocfg.hp_outs)
16138 alc861_auto_set_output_and_unmute(codec,
16139 spec->autocfg.hp_pins[0],
16140 PIN_HP,
16141 spec->multiout.hp_nid);
16142 if (spec->autocfg.speaker_outs)
16143 alc861_auto_set_output_and_unmute(codec,
16144 spec->autocfg.speaker_pins[0],
16145 PIN_OUT,
16146 spec->multiout.dac_nids[0]);
16147 }
16148
16149 static void alc861_auto_init_analog_input(struct hda_codec *codec)
16150 {
16151 struct alc_spec *spec = codec->spec;
16152 struct auto_pin_cfg *cfg = &spec->autocfg;
16153 int i;
16154
16155 for (i = 0; i < cfg->num_inputs; i++) {
16156 hda_nid_t nid = cfg->inputs[i].pin;
16157 if (nid >= 0x0c && nid <= 0x11)
16158 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
16159 }
16160 }
16161
16162 /* parse the BIOS configuration and set up the alc_spec */
16163 /* return 1 if successful, 0 if the proper config is not found,
16164 * or a negative error code
16165 */
16166 static int alc861_parse_auto_config(struct hda_codec *codec)
16167 {
16168 struct alc_spec *spec = codec->spec;
16169 int err;
16170 static const hda_nid_t alc861_ignore[] = { 0x1d, 0 };
16171
16172 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
16173 alc861_ignore);
16174 if (err < 0)
16175 return err;
16176 if (!spec->autocfg.line_outs)
16177 return 0; /* can't find valid BIOS pin config */
16178
16179 err = alc861_auto_fill_dac_nids(codec, &spec->autocfg);
16180 if (err < 0)
16181 return err;
16182 err = alc_auto_add_multi_channel_mode(codec);
16183 if (err < 0)
16184 return err;
16185 err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg);
16186 if (err < 0)
16187 return err;
16188 err = alc861_auto_create_hp_ctls(codec, spec->autocfg.hp_pins[0]);
16189 if (err < 0)
16190 return err;
16191 err = alc861_auto_create_input_ctls(codec, &spec->autocfg);
16192 if (err < 0)
16193 return err;
16194
16195 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
16196
16197 alc_auto_parse_digital(codec);
16198
16199 if (spec->kctls.list)
16200 add_mixer(spec, spec->kctls.list);
16201
16202 add_verb(spec, alc861_auto_init_verbs);
16203
16204 spec->num_mux_defs = 1;
16205 spec->input_mux = &spec->private_imux[0];
16206
16207 spec->adc_nids = alc861_adc_nids;
16208 spec->num_adc_nids = ARRAY_SIZE(alc861_adc_nids);
16209 set_capture_mixer(codec);
16210
16211 alc_ssid_check(codec, 0x0e, 0x0f, 0x0b, 0);
16212
16213 return 1;
16214 }
16215
16216 /* additional initialization for auto-configuration model */
16217 static void alc861_auto_init(struct hda_codec *codec)
16218 {
16219 struct alc_spec *spec = codec->spec;
16220 alc861_auto_init_multi_out(codec);
16221 alc861_auto_init_hp_out(codec);
16222 alc861_auto_init_analog_input(codec);
16223 alc_auto_init_digital(codec);
16224 if (spec->unsol_event)
16225 alc_inithook(codec);
16226 }
16227
16228 #ifdef CONFIG_SND_HDA_POWER_SAVE
16229 static const struct hda_amp_list alc861_loopbacks[] = {
16230 { 0x15, HDA_INPUT, 0 },
16231 { 0x15, HDA_INPUT, 1 },
16232 { 0x15, HDA_INPUT, 2 },
16233 { 0x15, HDA_INPUT, 3 },
16234 { } /* end */
16235 };
16236 #endif
16237
16238
16239 /*
16240 * configuration and preset
16241 */
16242 static const char * const alc861_models[ALC861_MODEL_LAST] = {
16243 [ALC861_3ST] = "3stack",
16244 [ALC660_3ST] = "3stack-660",
16245 [ALC861_3ST_DIG] = "3stack-dig",
16246 [ALC861_6ST_DIG] = "6stack-dig",
16247 [ALC861_UNIWILL_M31] = "uniwill-m31",
16248 [ALC861_TOSHIBA] = "toshiba",
16249 [ALC861_ASUS] = "asus",
16250 [ALC861_ASUS_LAPTOP] = "asus-laptop",
16251 [ALC861_AUTO] = "auto",
16252 };
16253
16254 static const struct snd_pci_quirk alc861_cfg_tbl[] = {
16255 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
16256 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16257 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
16258 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
16259 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
16260 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
16261 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
16262 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
16263 * Any other models that need this preset?
16264 */
16265 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
16266 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
16267 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
16268 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
16269 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
16270 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
16271 /* FIXME: the below seems conflict */
16272 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
16273 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
16274 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
16275 {}
16276 };
16277
16278 static const struct alc_config_preset alc861_presets[] = {
16279 [ALC861_3ST] = {
16280 .mixers = { alc861_3ST_mixer },
16281 .init_verbs = { alc861_threestack_init_verbs },
16282 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16283 .dac_nids = alc861_dac_nids,
16284 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16285 .channel_mode = alc861_threestack_modes,
16286 .need_dac_fix = 1,
16287 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16288 .adc_nids = alc861_adc_nids,
16289 .input_mux = &alc861_capture_source,
16290 },
16291 [ALC861_3ST_DIG] = {
16292 .mixers = { alc861_base_mixer },
16293 .init_verbs = { alc861_threestack_init_verbs },
16294 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16295 .dac_nids = alc861_dac_nids,
16296 .dig_out_nid = ALC861_DIGOUT_NID,
16297 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16298 .channel_mode = alc861_threestack_modes,
16299 .need_dac_fix = 1,
16300 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16301 .adc_nids = alc861_adc_nids,
16302 .input_mux = &alc861_capture_source,
16303 },
16304 [ALC861_6ST_DIG] = {
16305 .mixers = { alc861_base_mixer },
16306 .init_verbs = { alc861_base_init_verbs },
16307 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16308 .dac_nids = alc861_dac_nids,
16309 .dig_out_nid = ALC861_DIGOUT_NID,
16310 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
16311 .channel_mode = alc861_8ch_modes,
16312 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16313 .adc_nids = alc861_adc_nids,
16314 .input_mux = &alc861_capture_source,
16315 },
16316 [ALC660_3ST] = {
16317 .mixers = { alc861_3ST_mixer },
16318 .init_verbs = { alc861_threestack_init_verbs },
16319 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
16320 .dac_nids = alc660_dac_nids,
16321 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
16322 .channel_mode = alc861_threestack_modes,
16323 .need_dac_fix = 1,
16324 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16325 .adc_nids = alc861_adc_nids,
16326 .input_mux = &alc861_capture_source,
16327 },
16328 [ALC861_UNIWILL_M31] = {
16329 .mixers = { alc861_uniwill_m31_mixer },
16330 .init_verbs = { alc861_uniwill_m31_init_verbs },
16331 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16332 .dac_nids = alc861_dac_nids,
16333 .dig_out_nid = ALC861_DIGOUT_NID,
16334 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
16335 .channel_mode = alc861_uniwill_m31_modes,
16336 .need_dac_fix = 1,
16337 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16338 .adc_nids = alc861_adc_nids,
16339 .input_mux = &alc861_capture_source,
16340 },
16341 [ALC861_TOSHIBA] = {
16342 .mixers = { alc861_toshiba_mixer },
16343 .init_verbs = { alc861_base_init_verbs,
16344 alc861_toshiba_init_verbs },
16345 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16346 .dac_nids = alc861_dac_nids,
16347 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16348 .channel_mode = alc883_3ST_2ch_modes,
16349 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16350 .adc_nids = alc861_adc_nids,
16351 .input_mux = &alc861_capture_source,
16352 .unsol_event = alc861_toshiba_unsol_event,
16353 .init_hook = alc861_toshiba_automute,
16354 },
16355 [ALC861_ASUS] = {
16356 .mixers = { alc861_asus_mixer },
16357 .init_verbs = { alc861_asus_init_verbs },
16358 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16359 .dac_nids = alc861_dac_nids,
16360 .dig_out_nid = ALC861_DIGOUT_NID,
16361 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
16362 .channel_mode = alc861_asus_modes,
16363 .need_dac_fix = 1,
16364 .hp_nid = 0x06,
16365 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16366 .adc_nids = alc861_adc_nids,
16367 .input_mux = &alc861_capture_source,
16368 },
16369 [ALC861_ASUS_LAPTOP] = {
16370 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
16371 .init_verbs = { alc861_asus_init_verbs,
16372 alc861_asus_laptop_init_verbs },
16373 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
16374 .dac_nids = alc861_dac_nids,
16375 .dig_out_nid = ALC861_DIGOUT_NID,
16376 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
16377 .channel_mode = alc883_3ST_2ch_modes,
16378 .need_dac_fix = 1,
16379 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
16380 .adc_nids = alc861_adc_nids,
16381 .input_mux = &alc861_capture_source,
16382 },
16383 };
16384
16385 /* Pin config fixes */
16386 enum {
16387 PINFIX_FSC_AMILO_PI1505,
16388 };
16389
16390 static const struct alc_fixup alc861_fixups[] = {
16391 [PINFIX_FSC_AMILO_PI1505] = {
16392 .type = ALC_FIXUP_PINS,
16393 .v.pins = (const struct alc_pincfg[]) {
16394 { 0x0b, 0x0221101f }, /* HP */
16395 { 0x0f, 0x90170310 }, /* speaker */
16396 { }
16397 }
16398 },
16399 };
16400
16401 static const struct snd_pci_quirk alc861_fixup_tbl[] = {
16402 SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505),
16403 {}
16404 };
16405
16406 static int patch_alc861(struct hda_codec *codec)
16407 {
16408 struct alc_spec *spec;
16409 int board_config;
16410 int err;
16411
16412 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
16413 if (spec == NULL)
16414 return -ENOMEM;
16415
16416 codec->spec = spec;
16417
16418 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST,
16419 alc861_models,
16420 alc861_cfg_tbl);
16421
16422 if (board_config < 0) {
16423 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16424 codec->chip_name);
16425 board_config = ALC861_AUTO;
16426 }
16427
16428 if (board_config == ALC861_AUTO) {
16429 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
16430 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16431 }
16432
16433 if (board_config == ALC861_AUTO) {
16434 /* automatic parse from the BIOS config */
16435 err = alc861_parse_auto_config(codec);
16436 if (err < 0) {
16437 alc_free(codec);
16438 return err;
16439 } else if (!err) {
16440 printk(KERN_INFO
16441 "hda_codec: Cannot set up configuration "
16442 "from BIOS. Using base mode...\n");
16443 board_config = ALC861_3ST_DIG;
16444 }
16445 }
16446
16447 err = snd_hda_attach_beep_device(codec, 0x23);
16448 if (err < 0) {
16449 alc_free(codec);
16450 return err;
16451 }
16452
16453 if (board_config != ALC861_AUTO)
16454 setup_preset(codec, &alc861_presets[board_config]);
16455
16456 spec->stream_analog_playback = &alc861_pcm_analog_playback;
16457 spec->stream_analog_capture = &alc861_pcm_analog_capture;
16458
16459 spec->stream_digital_playback = &alc861_pcm_digital_playback;
16460 spec->stream_digital_capture = &alc861_pcm_digital_capture;
16461
16462 if (!spec->cap_mixer)
16463 set_capture_mixer(codec);
16464 set_beep_amp(spec, 0x23, 0, HDA_OUTPUT);
16465
16466 spec->vmaster_nid = 0x03;
16467
16468 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
16469
16470 codec->patch_ops = alc_patch_ops;
16471 if (board_config == ALC861_AUTO) {
16472 spec->init_hook = alc861_auto_init;
16473 #ifdef CONFIG_SND_HDA_POWER_SAVE
16474 spec->power_hook = alc_power_eapd;
16475 #endif
16476 }
16477 #ifdef CONFIG_SND_HDA_POWER_SAVE
16478 if (!spec->loopback.amplist)
16479 spec->loopback.amplist = alc861_loopbacks;
16480 #endif
16481
16482 return 0;
16483 }
16484
16485 /*
16486 * ALC861-VD support
16487 *
16488 * Based on ALC882
16489 *
16490 * In addition, an independent DAC
16491 */
16492 #define ALC861VD_DIGOUT_NID 0x06
16493
16494 static const hda_nid_t alc861vd_dac_nids[4] = {
16495 /* front, surr, clfe, side surr */
16496 0x02, 0x03, 0x04, 0x05
16497 };
16498
16499 /* dac_nids for ALC660vd are in a different order - according to
16500 * Realtek's driver.
16501 * This should probably result in a different mixer for 6stack models
16502 * of ALC660vd codecs, but for now there is only 3stack mixer
16503 * - and it is the same as in 861vd.
16504 * adc_nids in ALC660vd are (is) the same as in 861vd
16505 */
16506 static const hda_nid_t alc660vd_dac_nids[3] = {
16507 /* front, rear, clfe, rear_surr */
16508 0x02, 0x04, 0x03
16509 };
16510
16511 static const hda_nid_t alc861vd_adc_nids[1] = {
16512 /* ADC0 */
16513 0x09,
16514 };
16515
16516 static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
16517
16518 /* input MUX */
16519 /* FIXME: should be a matrix-type input source selection */
16520 static const struct hda_input_mux alc861vd_capture_source = {
16521 .num_items = 4,
16522 .items = {
16523 { "Mic", 0x0 },
16524 { "Front Mic", 0x1 },
16525 { "Line", 0x2 },
16526 { "CD", 0x4 },
16527 },
16528 };
16529
16530 static const struct hda_input_mux alc861vd_dallas_capture_source = {
16531 .num_items = 2,
16532 .items = {
16533 { "Mic", 0x0 },
16534 { "Internal Mic", 0x1 },
16535 },
16536 };
16537
16538 static const struct hda_input_mux alc861vd_hp_capture_source = {
16539 .num_items = 2,
16540 .items = {
16541 { "Front Mic", 0x0 },
16542 { "ATAPI Mic", 0x1 },
16543 },
16544 };
16545
16546 /*
16547 * 2ch mode
16548 */
16549 static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
16550 { 2, NULL }
16551 };
16552
16553 /*
16554 * 6ch mode
16555 */
16556 static const struct hda_verb alc861vd_6stack_ch6_init[] = {
16557 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16558 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16559 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16560 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16561 { } /* end */
16562 };
16563
16564 /*
16565 * 8ch mode
16566 */
16567 static const struct hda_verb alc861vd_6stack_ch8_init[] = {
16568 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16569 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16570 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16571 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16572 { } /* end */
16573 };
16574
16575 static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
16576 { 6, alc861vd_6stack_ch6_init },
16577 { 8, alc861vd_6stack_ch8_init },
16578 };
16579
16580 static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
16581 {
16582 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
16583 .name = "Channel Mode",
16584 .info = alc_ch_mode_info,
16585 .get = alc_ch_mode_get,
16586 .put = alc_ch_mode_put,
16587 },
16588 { } /* end */
16589 };
16590
16591 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16592 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16593 */
16594 static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
16595 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16596 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16597
16598 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16599 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
16600
16601 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
16602 HDA_OUTPUT),
16603 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
16604 HDA_OUTPUT),
16605 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
16606 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
16607
16608 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
16609 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
16610
16611 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16612
16613 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16614 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16615 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16616
16617 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16618 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16619 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16620
16621 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16622 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16623
16624 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16625 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16626
16627 { } /* end */
16628 };
16629
16630 static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16631 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16632 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16633
16634 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16635
16636 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16637 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16638 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16639
16640 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16641 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16642 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16643
16644 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16645 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16646
16647 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16648 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16649
16650 { } /* end */
16651 };
16652
16653 static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16654 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16655 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16656 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16657
16658 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16659
16660 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16661 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16662 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16663
16664 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16665 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16666 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16667
16668 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16669 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16670
16671 { } /* end */
16672 };
16673
16674 /* Pin assignment: Speaker=0x14, HP = 0x15,
16675 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
16676 */
16677 static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
16678 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16679 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
16680 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16681 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16682 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16683 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16684 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16685 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
16686 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16687 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16688 { } /* end */
16689 };
16690
16691 /* Pin assignment: Speaker=0x14, Line-out = 0x15,
16692 * Front Mic=0x18, ATAPI Mic = 0x19,
16693 */
16694 static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16695 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16696 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16697 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16698 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16699 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16700 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16701 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16702 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16703
16704 { } /* end */
16705 };
16706
16707 /*
16708 * generic initialization of ADC, input mixers and output mixers
16709 */
16710 static const struct hda_verb alc861vd_volume_init_verbs[] = {
16711 /*
16712 * Unmute ADC0 and set the default input to mic-in
16713 */
16714 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16715 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16716
16717 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16718 * the analog-loopback mixer widget
16719 */
16720 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16721 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16722 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16723 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16724 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16725 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16726
16727 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
16728 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16729 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16730 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
16731 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
16732
16733 /*
16734 * Set up output mixers (0x02 - 0x05)
16735 */
16736 /* set vol=0 to output mixers */
16737 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16738 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16739 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16740 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16741
16742 /* set up input amps for analog loopback */
16743 /* Amp Indices: DAC = 0, mixer = 1 */
16744 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16745 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16746 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16747 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16748 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16749 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16750 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16751 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16752
16753 { }
16754 };
16755
16756 /*
16757 * 3-stack pin configuration:
16758 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16759 */
16760 static const struct hda_verb alc861vd_3stack_init_verbs[] = {
16761 /*
16762 * Set pin mode and muting
16763 */
16764 /* set front pin widgets 0x14 for output */
16765 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16766 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16767 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16768
16769 /* Mic (rear) pin: input vref at 80% */
16770 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16771 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16772 /* Front Mic pin: input vref at 80% */
16773 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16774 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16775 /* Line In pin: input */
16776 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16777 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16778 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16779 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16780 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16781 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16782 /* CD pin widget for input */
16783 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16784
16785 { }
16786 };
16787
16788 /*
16789 * 6-stack pin configuration:
16790 */
16791 static const struct hda_verb alc861vd_6stack_init_verbs[] = {
16792 /*
16793 * Set pin mode and muting
16794 */
16795 /* set front pin widgets 0x14 for output */
16796 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16797 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16798 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16799
16800 /* Rear Pin: output 1 (0x0d) */
16801 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16802 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16803 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16804 /* CLFE Pin: output 2 (0x0e) */
16805 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16806 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16807 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16808 /* Side Pin: output 3 (0x0f) */
16809 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16810 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16811 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16812
16813 /* Mic (rear) pin: input vref at 80% */
16814 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16815 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16816 /* Front Mic pin: input vref at 80% */
16817 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16818 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16819 /* Line In pin: input */
16820 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16821 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16822 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16823 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16824 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16825 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16826 /* CD pin widget for input */
16827 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16828
16829 { }
16830 };
16831
16832 static const struct hda_verb alc861vd_eapd_verbs[] = {
16833 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16834 { }
16835 };
16836
16837 static const struct hda_verb alc660vd_eapd_verbs[] = {
16838 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16839 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16840 { }
16841 };
16842
16843 static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16844 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16845 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16846 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16847 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16848 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16849 {}
16850 };
16851
16852 static void alc861vd_lenovo_setup(struct hda_codec *codec)
16853 {
16854 struct alc_spec *spec = codec->spec;
16855 spec->autocfg.hp_pins[0] = 0x1b;
16856 spec->autocfg.speaker_pins[0] = 0x14;
16857 spec->automute = 1;
16858 spec->automute_mode = ALC_AUTOMUTE_AMP;
16859 }
16860
16861 static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16862 {
16863 alc_hp_automute(codec);
16864 alc88x_simple_mic_automute(codec);
16865 }
16866
16867 static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16868 unsigned int res)
16869 {
16870 switch (res >> 26) {
16871 case ALC880_MIC_EVENT:
16872 alc88x_simple_mic_automute(codec);
16873 break;
16874 default:
16875 alc_sku_unsol_event(codec, res);
16876 break;
16877 }
16878 }
16879
16880 static const struct hda_verb alc861vd_dallas_verbs[] = {
16881 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16882 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16883 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16884 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16885
16886 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16887 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16888 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16889 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16890 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16891 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16892 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16893 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16894
16895 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16896 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16897 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16898 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16899 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16900 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16901 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16902 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16903
16904 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16905 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16906 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16907 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16908 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16909 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16910 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16911 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16912
16913 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16914 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16915 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16916 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16917
16918 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16919 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16920 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16921
16922 { } /* end */
16923 };
16924
16925 /* toggle speaker-output according to the hp-jack state */
16926 static void alc861vd_dallas_setup(struct hda_codec *codec)
16927 {
16928 struct alc_spec *spec = codec->spec;
16929
16930 spec->autocfg.hp_pins[0] = 0x15;
16931 spec->autocfg.speaker_pins[0] = 0x14;
16932 spec->automute = 1;
16933 spec->automute_mode = ALC_AUTOMUTE_AMP;
16934 }
16935
16936 #ifdef CONFIG_SND_HDA_POWER_SAVE
16937 #define alc861vd_loopbacks alc880_loopbacks
16938 #endif
16939
16940 /* pcm configuration: identical with ALC880 */
16941 #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback
16942 #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture
16943 #define alc861vd_pcm_digital_playback alc880_pcm_digital_playback
16944 #define alc861vd_pcm_digital_capture alc880_pcm_digital_capture
16945
16946 /*
16947 * configuration and preset
16948 */
16949 static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
16950 [ALC660VD_3ST] = "3stack-660",
16951 [ALC660VD_3ST_DIG] = "3stack-660-digout",
16952 [ALC660VD_ASUS_V1S] = "asus-v1s",
16953 [ALC861VD_3ST] = "3stack",
16954 [ALC861VD_3ST_DIG] = "3stack-digout",
16955 [ALC861VD_6ST_DIG] = "6stack-digout",
16956 [ALC861VD_LENOVO] = "lenovo",
16957 [ALC861VD_DALLAS] = "dallas",
16958 [ALC861VD_HP] = "hp",
16959 [ALC861VD_AUTO] = "auto",
16960 };
16961
16962 static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
16963 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16964 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
16965 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
16966 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
16967 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
16968 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
16969 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
16970 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
16971 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
16972 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
16973 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
16974 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
16975 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
16976 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
16977 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
16978 {}
16979 };
16980
16981 static const struct alc_config_preset alc861vd_presets[] = {
16982 [ALC660VD_3ST] = {
16983 .mixers = { alc861vd_3st_mixer },
16984 .init_verbs = { alc861vd_volume_init_verbs,
16985 alc861vd_3stack_init_verbs },
16986 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16987 .dac_nids = alc660vd_dac_nids,
16988 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16989 .channel_mode = alc861vd_3stack_2ch_modes,
16990 .input_mux = &alc861vd_capture_source,
16991 },
16992 [ALC660VD_3ST_DIG] = {
16993 .mixers = { alc861vd_3st_mixer },
16994 .init_verbs = { alc861vd_volume_init_verbs,
16995 alc861vd_3stack_init_verbs },
16996 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16997 .dac_nids = alc660vd_dac_nids,
16998 .dig_out_nid = ALC861VD_DIGOUT_NID,
16999 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17000 .channel_mode = alc861vd_3stack_2ch_modes,
17001 .input_mux = &alc861vd_capture_source,
17002 },
17003 [ALC861VD_3ST] = {
17004 .mixers = { alc861vd_3st_mixer },
17005 .init_verbs = { alc861vd_volume_init_verbs,
17006 alc861vd_3stack_init_verbs },
17007 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17008 .dac_nids = alc861vd_dac_nids,
17009 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17010 .channel_mode = alc861vd_3stack_2ch_modes,
17011 .input_mux = &alc861vd_capture_source,
17012 },
17013 [ALC861VD_3ST_DIG] = {
17014 .mixers = { alc861vd_3st_mixer },
17015 .init_verbs = { alc861vd_volume_init_verbs,
17016 alc861vd_3stack_init_verbs },
17017 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17018 .dac_nids = alc861vd_dac_nids,
17019 .dig_out_nid = ALC861VD_DIGOUT_NID,
17020 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17021 .channel_mode = alc861vd_3stack_2ch_modes,
17022 .input_mux = &alc861vd_capture_source,
17023 },
17024 [ALC861VD_6ST_DIG] = {
17025 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
17026 .init_verbs = { alc861vd_volume_init_verbs,
17027 alc861vd_6stack_init_verbs },
17028 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17029 .dac_nids = alc861vd_dac_nids,
17030 .dig_out_nid = ALC861VD_DIGOUT_NID,
17031 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
17032 .channel_mode = alc861vd_6stack_modes,
17033 .input_mux = &alc861vd_capture_source,
17034 },
17035 [ALC861VD_LENOVO] = {
17036 .mixers = { alc861vd_lenovo_mixer },
17037 .init_verbs = { alc861vd_volume_init_verbs,
17038 alc861vd_3stack_init_verbs,
17039 alc861vd_eapd_verbs,
17040 alc861vd_lenovo_unsol_verbs },
17041 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17042 .dac_nids = alc660vd_dac_nids,
17043 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17044 .channel_mode = alc861vd_3stack_2ch_modes,
17045 .input_mux = &alc861vd_capture_source,
17046 .unsol_event = alc861vd_lenovo_unsol_event,
17047 .setup = alc861vd_lenovo_setup,
17048 .init_hook = alc861vd_lenovo_init_hook,
17049 },
17050 [ALC861VD_DALLAS] = {
17051 .mixers = { alc861vd_dallas_mixer },
17052 .init_verbs = { alc861vd_dallas_verbs },
17053 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17054 .dac_nids = alc861vd_dac_nids,
17055 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17056 .channel_mode = alc861vd_3stack_2ch_modes,
17057 .input_mux = &alc861vd_dallas_capture_source,
17058 .unsol_event = alc_sku_unsol_event,
17059 .setup = alc861vd_dallas_setup,
17060 .init_hook = alc_hp_automute,
17061 },
17062 [ALC861VD_HP] = {
17063 .mixers = { alc861vd_hp_mixer },
17064 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
17065 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
17066 .dac_nids = alc861vd_dac_nids,
17067 .dig_out_nid = ALC861VD_DIGOUT_NID,
17068 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17069 .channel_mode = alc861vd_3stack_2ch_modes,
17070 .input_mux = &alc861vd_hp_capture_source,
17071 .unsol_event = alc_sku_unsol_event,
17072 .setup = alc861vd_dallas_setup,
17073 .init_hook = alc_hp_automute,
17074 },
17075 [ALC660VD_ASUS_V1S] = {
17076 .mixers = { alc861vd_lenovo_mixer },
17077 .init_verbs = { alc861vd_volume_init_verbs,
17078 alc861vd_3stack_init_verbs,
17079 alc861vd_eapd_verbs,
17080 alc861vd_lenovo_unsol_verbs },
17081 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
17082 .dac_nids = alc660vd_dac_nids,
17083 .dig_out_nid = ALC861VD_DIGOUT_NID,
17084 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
17085 .channel_mode = alc861vd_3stack_2ch_modes,
17086 .input_mux = &alc861vd_capture_source,
17087 .unsol_event = alc861vd_lenovo_unsol_event,
17088 .setup = alc861vd_lenovo_setup,
17089 .init_hook = alc861vd_lenovo_init_hook,
17090 },
17091 };
17092
17093 /*
17094 * BIOS auto configuration
17095 */
17096 static int alc861vd_auto_create_input_ctls(struct hda_codec *codec,
17097 const struct auto_pin_cfg *cfg)
17098 {
17099 return alc_auto_create_input_ctls(codec, cfg, 0x0b, 0x22, 0);
17100 }
17101
17102
17103 static void alc861vd_auto_set_output_and_unmute(struct hda_codec *codec,
17104 hda_nid_t nid, int pin_type, int dac_idx)
17105 {
17106 alc_set_pin_output(codec, nid, pin_type);
17107 }
17108
17109 static void alc861vd_auto_init_multi_out(struct hda_codec *codec)
17110 {
17111 struct alc_spec *spec = codec->spec;
17112 int i;
17113
17114 for (i = 0; i <= HDA_SIDE; i++) {
17115 hda_nid_t nid = spec->autocfg.line_out_pins[i];
17116 int pin_type = get_pin_type(spec->autocfg.line_out_type);
17117 if (nid)
17118 alc861vd_auto_set_output_and_unmute(codec, nid,
17119 pin_type, i);
17120 }
17121 }
17122
17123
17124 static void alc861vd_auto_init_hp_out(struct hda_codec *codec)
17125 {
17126 struct alc_spec *spec = codec->spec;
17127 hda_nid_t pin;
17128
17129 pin = spec->autocfg.hp_pins[0];
17130 if (pin) /* connect to front and use dac 0 */
17131 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_HP, 0);
17132 pin = spec->autocfg.speaker_pins[0];
17133 if (pin)
17134 alc861vd_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0);
17135 }
17136
17137 #define ALC861VD_PIN_CD_NID ALC880_PIN_CD_NID
17138
17139 static void alc861vd_auto_init_analog_input(struct hda_codec *codec)
17140 {
17141 struct alc_spec *spec = codec->spec;
17142 struct auto_pin_cfg *cfg = &spec->autocfg;
17143 int i;
17144
17145 for (i = 0; i < cfg->num_inputs; i++) {
17146 hda_nid_t nid = cfg->inputs[i].pin;
17147 if (alc_is_input_pin(codec, nid)) {
17148 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
17149 if (nid != ALC861VD_PIN_CD_NID &&
17150 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
17151 snd_hda_codec_write(codec, nid, 0,
17152 AC_VERB_SET_AMP_GAIN_MUTE,
17153 AMP_OUT_MUTE);
17154 }
17155 }
17156 }
17157
17158 #define alc861vd_auto_init_input_src alc882_auto_init_input_src
17159
17160 #define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
17161 #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
17162
17163 /* add playback controls from the parsed DAC table */
17164 /* Based on ALC880 version. But ALC861VD has separate,
17165 * different NIDs for mute/unmute switch and volume control */
17166 static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
17167 const struct auto_pin_cfg *cfg)
17168 {
17169 static const char * const chname[4] = {
17170 "Front", "Surround", "CLFE", "Side"
17171 };
17172 const char *pfx = alc_get_line_out_pfx(spec, true);
17173 hda_nid_t nid_v, nid_s;
17174 int i, err, noutputs;
17175
17176 noutputs = cfg->line_outs;
17177 if (spec->multi_ios > 0)
17178 noutputs += spec->multi_ios;
17179
17180 for (i = 0; i < noutputs; i++) {
17181 if (!spec->multiout.dac_nids[i])
17182 continue;
17183 nid_v = alc861vd_idx_to_mixer_vol(
17184 alc880_dac_to_idx(
17185 spec->multiout.dac_nids[i]));
17186 nid_s = alc861vd_idx_to_mixer_switch(
17187 alc880_dac_to_idx(
17188 spec->multiout.dac_nids[i]));
17189
17190 if (!pfx && i == 2) {
17191 /* Center/LFE */
17192 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17193 "Center",
17194 HDA_COMPOSE_AMP_VAL(nid_v, 1, 0,
17195 HDA_OUTPUT));
17196 if (err < 0)
17197 return err;
17198 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17199 "LFE",
17200 HDA_COMPOSE_AMP_VAL(nid_v, 2, 0,
17201 HDA_OUTPUT));
17202 if (err < 0)
17203 return err;
17204 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17205 "Center",
17206 HDA_COMPOSE_AMP_VAL(nid_s, 1, 2,
17207 HDA_INPUT));
17208 if (err < 0)
17209 return err;
17210 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17211 "LFE",
17212 HDA_COMPOSE_AMP_VAL(nid_s, 2, 2,
17213 HDA_INPUT));
17214 if (err < 0)
17215 return err;
17216 } else {
17217 const char *name = pfx;
17218 int index = i;
17219 if (!name) {
17220 name = chname[i];
17221 index = 0;
17222 }
17223 err = __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL,
17224 name, index,
17225 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0,
17226 HDA_OUTPUT));
17227 if (err < 0)
17228 return err;
17229 err = __add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE,
17230 name, index,
17231 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2,
17232 HDA_INPUT));
17233 if (err < 0)
17234 return err;
17235 }
17236 }
17237 return 0;
17238 }
17239
17240 /* add playback controls for speaker and HP outputs */
17241 /* Based on ALC880 version. But ALC861VD has separate,
17242 * different NIDs for mute/unmute switch and volume control */
17243 static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
17244 hda_nid_t pin, const char *pfx)
17245 {
17246 hda_nid_t nid_v, nid_s;
17247 int err;
17248
17249 if (!pin)
17250 return 0;
17251
17252 if (alc880_is_fixed_pin(pin)) {
17253 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin));
17254 /* specify the DAC as the extra output */
17255 if (!spec->multiout.hp_nid)
17256 spec->multiout.hp_nid = nid_v;
17257 else
17258 spec->multiout.extra_out_nid[0] = nid_v;
17259 /* control HP volume/switch on the output mixer amp */
17260 nid_v = alc861vd_idx_to_mixer_vol(
17261 alc880_fixed_pin_idx(pin));
17262 nid_s = alc861vd_idx_to_mixer_switch(
17263 alc880_fixed_pin_idx(pin));
17264
17265 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
17266 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
17267 if (err < 0)
17268 return err;
17269 err = add_pb_sw_ctrl(spec, ALC_CTL_BIND_MUTE, pfx,
17270 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
17271 if (err < 0)
17272 return err;
17273 } else if (alc880_is_multi_pin(pin)) {
17274 /* set manual connection */
17275 /* we have only a switch on HP-out PIN */
17276 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
17277 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
17278 if (err < 0)
17279 return err;
17280 }
17281 return 0;
17282 }
17283
17284 /* parse the BIOS configuration and set up the alc_spec
17285 * return 1 if successful, 0 if the proper config is not found,
17286 * or a negative error code
17287 * Based on ALC880 version - had to change it to override
17288 * alc880_auto_create_extra_out and alc880_auto_create_multi_out_ctls */
17289 static int alc861vd_parse_auto_config(struct hda_codec *codec)
17290 {
17291 struct alc_spec *spec = codec->spec;
17292 int err;
17293 static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 };
17294
17295 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
17296 alc861vd_ignore);
17297 if (err < 0)
17298 return err;
17299 if (!spec->autocfg.line_outs)
17300 return 0; /* can't find valid BIOS pin config */
17301
17302 err = alc880_auto_fill_dac_nids(spec, &spec->autocfg);
17303 if (err < 0)
17304 return err;
17305 err = alc_auto_add_multi_channel_mode(codec);
17306 if (err < 0)
17307 return err;
17308 err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg);
17309 if (err < 0)
17310 return err;
17311 err = alc861vd_auto_create_extra_out(spec,
17312 spec->autocfg.speaker_pins[0],
17313 "Speaker");
17314 if (err < 0)
17315 return err;
17316 err = alc861vd_auto_create_extra_out(spec,
17317 spec->autocfg.hp_pins[0],
17318 "Headphone");
17319 if (err < 0)
17320 return err;
17321 err = alc861vd_auto_create_input_ctls(codec, &spec->autocfg);
17322 if (err < 0)
17323 return err;
17324
17325 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
17326
17327 alc_auto_parse_digital(codec);
17328
17329 if (spec->kctls.list)
17330 add_mixer(spec, spec->kctls.list);
17331
17332 add_verb(spec, alc861vd_volume_init_verbs);
17333
17334 spec->num_mux_defs = 1;
17335 spec->input_mux = &spec->private_imux[0];
17336
17337 err = alc_auto_add_mic_boost(codec);
17338 if (err < 0)
17339 return err;
17340
17341 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
17342
17343 return 1;
17344 }
17345
17346 /* additional initialization for auto-configuration model */
17347 static void alc861vd_auto_init(struct hda_codec *codec)
17348 {
17349 struct alc_spec *spec = codec->spec;
17350 alc861vd_auto_init_multi_out(codec);
17351 alc861vd_auto_init_hp_out(codec);
17352 alc861vd_auto_init_analog_input(codec);
17353 alc861vd_auto_init_input_src(codec);
17354 alc_auto_init_digital(codec);
17355 if (spec->unsol_event)
17356 alc_inithook(codec);
17357 }
17358
17359 enum {
17360 ALC660VD_FIX_ASUS_GPIO1
17361 };
17362
17363 /* reset GPIO1 */
17364 static const struct alc_fixup alc861vd_fixups[] = {
17365 [ALC660VD_FIX_ASUS_GPIO1] = {
17366 .type = ALC_FIXUP_VERBS,
17367 .v.verbs = (const struct hda_verb[]) {
17368 {0x01, AC_VERB_SET_GPIO_MASK, 0x03},
17369 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
17370 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
17371 { }
17372 }
17373 },
17374 };
17375
17376 static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
17377 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1),
17378 {}
17379 };
17380
17381 static int patch_alc861vd(struct hda_codec *codec)
17382 {
17383 struct alc_spec *spec;
17384 int err, board_config;
17385
17386 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
17387 if (spec == NULL)
17388 return -ENOMEM;
17389
17390 codec->spec = spec;
17391
17392 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST,
17393 alc861vd_models,
17394 alc861vd_cfg_tbl);
17395
17396 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) {
17397 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
17398 codec->chip_name);
17399 board_config = ALC861VD_AUTO;
17400 }
17401
17402 if (board_config == ALC861VD_AUTO) {
17403 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
17404 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
17405 }
17406
17407 if (board_config == ALC861VD_AUTO) {
17408 /* automatic parse from the BIOS config */
17409 err = alc861vd_parse_auto_config(codec);
17410 if (err < 0) {
17411 alc_free(codec);
17412 return err;
17413 } else if (!err) {
17414 printk(KERN_INFO
17415 "hda_codec: Cannot set up configuration "
17416 "from BIOS. Using base mode...\n");
17417 board_config = ALC861VD_3ST;
17418 }
17419 }
17420
17421 err = snd_hda_attach_beep_device(codec, 0x23);
17422 if (err < 0) {
17423 alc_free(codec);
17424 return err;
17425 }
17426
17427 if (board_config != ALC861VD_AUTO)
17428 setup_preset(codec, &alc861vd_presets[board_config]);
17429
17430 if (codec->vendor_id == 0x10ec0660) {
17431 /* always turn on EAPD */
17432 add_verb(spec, alc660vd_eapd_verbs);
17433 }
17434
17435 spec->stream_analog_playback = &alc861vd_pcm_analog_playback;
17436 spec->stream_analog_capture = &alc861vd_pcm_analog_capture;
17437
17438 spec->stream_digital_playback = &alc861vd_pcm_digital_playback;
17439 spec->stream_digital_capture = &alc861vd_pcm_digital_capture;
17440
17441 if (!spec->adc_nids) {
17442 spec->adc_nids = alc861vd_adc_nids;
17443 spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids);
17444 }
17445 if (!spec->capsrc_nids)
17446 spec->capsrc_nids = alc861vd_capsrc_nids;
17447
17448 set_capture_mixer(codec);
17449 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
17450
17451 spec->vmaster_nid = 0x02;
17452
17453 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
17454
17455 codec->patch_ops = alc_patch_ops;
17456
17457 if (board_config == ALC861VD_AUTO)
17458 spec->init_hook = alc861vd_auto_init;
17459 spec->shutup = alc_eapd_shutup;
17460 #ifdef CONFIG_SND_HDA_POWER_SAVE
17461 if (!spec->loopback.amplist)
17462 spec->loopback.amplist = alc861vd_loopbacks;
17463 #endif
17464
17465 return 0;
17466 }
17467
17468 /*
17469 * ALC662 support
17470 *
17471 * ALC662 is almost identical with ALC880 but has cleaner and more flexible
17472 * configuration. Each pin widget can choose any input DACs and a mixer.
17473 * Each ADC is connected from a mixer of all inputs. This makes possible
17474 * 6-channel independent captures.
17475 *
17476 * In addition, an independent DAC for the multi-playback (not used in this
17477 * driver yet).
17478 */
17479 #define ALC662_DIGOUT_NID 0x06
17480 #define ALC662_DIGIN_NID 0x0a
17481
17482 static const hda_nid_t alc662_dac_nids[3] = {
17483 /* front, rear, clfe */
17484 0x02, 0x03, 0x04
17485 };
17486
17487 static const hda_nid_t alc272_dac_nids[2] = {
17488 0x02, 0x03
17489 };
17490
17491 static const hda_nid_t alc662_adc_nids[2] = {
17492 /* ADC1-2 */
17493 0x09, 0x08
17494 };
17495
17496 static const hda_nid_t alc272_adc_nids[1] = {
17497 /* ADC1-2 */
17498 0x08,
17499 };
17500
17501 static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
17502 static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
17503
17504
17505 /* input MUX */
17506 /* FIXME: should be a matrix-type input source selection */
17507 static const struct hda_input_mux alc662_capture_source = {
17508 .num_items = 4,
17509 .items = {
17510 { "Mic", 0x0 },
17511 { "Front Mic", 0x1 },
17512 { "Line", 0x2 },
17513 { "CD", 0x4 },
17514 },
17515 };
17516
17517 static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
17518 .num_items = 2,
17519 .items = {
17520 { "Mic", 0x1 },
17521 { "Line", 0x2 },
17522 },
17523 };
17524
17525 static const struct hda_input_mux alc663_capture_source = {
17526 .num_items = 3,
17527 .items = {
17528 { "Mic", 0x0 },
17529 { "Front Mic", 0x1 },
17530 { "Line", 0x2 },
17531 },
17532 };
17533
17534 #if 0 /* set to 1 for testing other input sources below */
17535 static const struct hda_input_mux alc272_nc10_capture_source = {
17536 .num_items = 16,
17537 .items = {
17538 { "Autoselect Mic", 0x0 },
17539 { "Internal Mic", 0x1 },
17540 { "In-0x02", 0x2 },
17541 { "In-0x03", 0x3 },
17542 { "In-0x04", 0x4 },
17543 { "In-0x05", 0x5 },
17544 { "In-0x06", 0x6 },
17545 { "In-0x07", 0x7 },
17546 { "In-0x08", 0x8 },
17547 { "In-0x09", 0x9 },
17548 { "In-0x0a", 0x0a },
17549 { "In-0x0b", 0x0b },
17550 { "In-0x0c", 0x0c },
17551 { "In-0x0d", 0x0d },
17552 { "In-0x0e", 0x0e },
17553 { "In-0x0f", 0x0f },
17554 },
17555 };
17556 #endif
17557
17558 /*
17559 * 2ch mode
17560 */
17561 static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
17562 { 2, NULL }
17563 };
17564
17565 /*
17566 * 2ch mode
17567 */
17568 static const struct hda_verb alc662_3ST_ch2_init[] = {
17569 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
17570 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17571 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
17572 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
17573 { } /* end */
17574 };
17575
17576 /*
17577 * 6ch mode
17578 */
17579 static const struct hda_verb alc662_3ST_ch6_init[] = {
17580 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17581 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17582 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
17583 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17584 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
17585 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
17586 { } /* end */
17587 };
17588
17589 static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
17590 { 2, alc662_3ST_ch2_init },
17591 { 6, alc662_3ST_ch6_init },
17592 };
17593
17594 /*
17595 * 2ch mode
17596 */
17597 static const struct hda_verb alc662_sixstack_ch6_init[] = {
17598 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17599 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
17600 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17601 { } /* end */
17602 };
17603
17604 /*
17605 * 6ch mode
17606 */
17607 static const struct hda_verb alc662_sixstack_ch8_init[] = {
17608 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17609 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17610 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
17611 { } /* end */
17612 };
17613
17614 static const struct hda_channel_mode alc662_5stack_modes[2] = {
17615 { 2, alc662_sixstack_ch6_init },
17616 { 6, alc662_sixstack_ch8_init },
17617 };
17618
17619 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
17620 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
17621 */
17622
17623 static const struct snd_kcontrol_new alc662_base_mixer[] = {
17624 /* output mixer control */
17625 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
17626 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17627 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
17628 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17629 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17630 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17631 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17632 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17633 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17634
17635 /*Input mixer control */
17636 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
17637 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
17638 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
17639 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
17640 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
17641 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
17642 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
17643 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
17644 { } /* end */
17645 };
17646
17647 static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
17648 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17649 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17650 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17651 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17652 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17653 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17654 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17655 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17656 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17657 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17658 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17659 { } /* end */
17660 };
17661
17662 static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
17663 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17664 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
17665 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17666 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
17667 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17668 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17669 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
17670 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
17671 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17672 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
17673 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
17674 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17675 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17676 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17677 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17678 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17679 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17680 { } /* end */
17681 };
17682
17683 static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
17684 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17685 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
17686 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17687 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
17688 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17689 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17690 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17691 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17692 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17693 { } /* end */
17694 };
17695
17696 static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
17697 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17698 ALC262_HIPPO_MASTER_SWITCH,
17699
17700 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
17701 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17702 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17703
17704 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17705 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17706 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17707 { } /* end */
17708 };
17709
17710 static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
17711 ALC262_HIPPO_MASTER_SWITCH,
17712 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17713 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17714 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17715 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17716 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17717 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17718 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17719 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17720 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17721 { } /* end */
17722 };
17723
17724 static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
17725 .ops = &snd_hda_bind_vol,
17726 .values = {
17727 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17728 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17729 0
17730 },
17731 };
17732
17733 static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
17734 .ops = &snd_hda_bind_sw,
17735 .values = {
17736 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17737 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17738 0
17739 },
17740 };
17741
17742 static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
17743 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17744 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17745 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17746 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17747 { } /* end */
17748 };
17749
17750 static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17751 .ops = &snd_hda_bind_sw,
17752 .values = {
17753 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17754 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17755 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17756 0
17757 },
17758 };
17759
17760 static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17761 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17762 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17763 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17764 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17765 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17766 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17767
17768 { } /* end */
17769 };
17770
17771 static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
17772 .ops = &snd_hda_bind_sw,
17773 .values = {
17774 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17775 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17776 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17777 0
17778 },
17779 };
17780
17781 static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17782 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17783 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17784 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17785 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17786 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17787 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17788 { } /* end */
17789 };
17790
17791 static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
17792 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17793 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17794 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17795 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17796 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17797 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17798 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17799 { } /* end */
17800 };
17801
17802 static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17803 .ops = &snd_hda_bind_vol,
17804 .values = {
17805 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17806 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17807 0
17808 },
17809 };
17810
17811 static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
17812 .ops = &snd_hda_bind_sw,
17813 .values = {
17814 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17815 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17816 0
17817 },
17818 };
17819
17820 static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17821 HDA_BIND_VOL("Master Playback Volume",
17822 &alc663_asus_two_bind_master_vol),
17823 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17824 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17825 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17826 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17827 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17828 { } /* end */
17829 };
17830
17831 static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17832 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17833 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17834 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17835 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17836 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17837 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17838 { } /* end */
17839 };
17840
17841 static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
17842 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17843 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17844 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17845 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17846 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17847
17848 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17849 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17850 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17851 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17852 { } /* end */
17853 };
17854
17855 static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
17856 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17857 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17858 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17859
17860 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17861 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17862 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17863 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17864 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17865 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17866 { } /* end */
17867 };
17868
17869 static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17870 .ops = &snd_hda_bind_sw,
17871 .values = {
17872 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17873 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17874 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17875 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17876 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17877 0
17878 },
17879 };
17880
17881 static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17882 .ops = &snd_hda_bind_sw,
17883 .values = {
17884 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17885 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17886 0
17887 },
17888 };
17889
17890 static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
17891 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17892 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17893 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17894 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17895 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17896 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17897 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17898 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17899 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17900 { } /* end */
17901 };
17902
17903 static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
17904 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17905 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17906 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17907 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17908 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17909 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17910 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17911 { } /* end */
17912 };
17913
17914
17915 static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
17916 {
17917 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17918 .name = "Channel Mode",
17919 .info = alc_ch_mode_info,
17920 .get = alc_ch_mode_get,
17921 .put = alc_ch_mode_put,
17922 },
17923 { } /* end */
17924 };
17925
17926 static const struct hda_verb alc662_init_verbs[] = {
17927 /* ADC: mute amp left and right */
17928 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17929 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
17930
17931 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17932 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17933 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17934 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17935 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17936 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17937
17938 /* Front Pin: output 0 (0x0c) */
17939 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17940 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17941
17942 /* Rear Pin: output 1 (0x0d) */
17943 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17944 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17945
17946 /* CLFE Pin: output 2 (0x0e) */
17947 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17948 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17949
17950 /* Mic (rear) pin: input vref at 80% */
17951 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17952 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17953 /* Front Mic pin: input vref at 80% */
17954 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17955 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17956 /* Line In pin: input */
17957 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17958 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17959 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17960 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17961 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17962 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17963 /* CD pin widget for input */
17964 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17965
17966 /* FIXME: use matrix-type input source selection */
17967 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17968 /* Input mixer */
17969 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17970 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17971
17972 { }
17973 };
17974
17975 static const struct hda_verb alc662_eapd_init_verbs[] = {
17976 /* always trun on EAPD */
17977 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17978 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17979 { }
17980 };
17981
17982 static const struct hda_verb alc662_sue_init_verbs[] = {
17983 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17984 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17985 {}
17986 };
17987
17988 static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17989 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17990 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17991 {}
17992 };
17993
17994 /* Set Unsolicited Event*/
17995 static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17996 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17997 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17998 {}
17999 };
18000
18001 static const struct hda_verb alc663_m51va_init_verbs[] = {
18002 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18003 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18004 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18005 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18006 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18007 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18008 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18009 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18010 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18011 {}
18012 };
18013
18014 static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
18015 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18016 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18017 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18018 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18019 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18020 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18021 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18022 {}
18023 };
18024
18025 static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
18026 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18027 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18028 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18029 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18030 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18031 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18032 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18033 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18034 {}
18035 };
18036
18037 static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
18038 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18039 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18040 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18041 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18042 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18043 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18044 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18045 {}
18046 };
18047
18048 static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
18049 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18050 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18051 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18052 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18053 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18054 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18055 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
18056 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18057 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18058 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18059 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18060 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18061 {}
18062 };
18063
18064 static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
18065 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18066 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18067 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18068 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18069 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18070 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18071 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18072 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18073 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
18074 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18075 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18076 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18077 {}
18078 };
18079
18080 static const struct hda_verb alc663_g71v_init_verbs[] = {
18081 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18082 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
18083 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
18084
18085 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18086 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18087 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18088
18089 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
18090 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
18091 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
18092 {}
18093 };
18094
18095 static const struct hda_verb alc663_g50v_init_verbs[] = {
18096 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18097 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18098 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
18099
18100 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18101 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18102 {}
18103 };
18104
18105 static const struct hda_verb alc662_ecs_init_verbs[] = {
18106 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
18107 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18108 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18109 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18110 {}
18111 };
18112
18113 static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
18114 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18115 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18116 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18117 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18118 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18119 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18120 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18121 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18122 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18123 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18124 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18125 {}
18126 };
18127
18128 static const struct hda_verb alc272_dell_init_verbs[] = {
18129 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18130 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18131 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18132 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18133 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18134 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18135 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18136 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18137 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18138 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18139 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18140 {}
18141 };
18142
18143 static const struct hda_verb alc663_mode7_init_verbs[] = {
18144 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18145 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18146 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18147 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18148 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18149 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18150 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
18151 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18152 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18153 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18154 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18155 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18156 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18157 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18158 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18159 {}
18160 };
18161
18162 static const struct hda_verb alc663_mode8_init_verbs[] = {
18163 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18164 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18165 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18166 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
18167 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18168 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
18169 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18170 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
18171 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
18172 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
18173 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
18174 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
18175 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
18176 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18177 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
18178 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
18179 {}
18180 };
18181
18182 static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
18183 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
18184 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
18185 { } /* end */
18186 };
18187
18188 static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
18189 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
18190 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
18191 { } /* end */
18192 };
18193
18194 static void alc662_lenovo_101e_setup(struct hda_codec *codec)
18195 {
18196 struct alc_spec *spec = codec->spec;
18197
18198 spec->autocfg.hp_pins[0] = 0x1b;
18199 spec->autocfg.line_out_pins[0] = 0x14;
18200 spec->autocfg.speaker_pins[0] = 0x15;
18201 spec->automute = 1;
18202 spec->detect_line = 1;
18203 spec->automute_lines = 1;
18204 spec->automute_mode = ALC_AUTOMUTE_AMP;
18205 }
18206
18207 static void alc662_eeepc_setup(struct hda_codec *codec)
18208 {
18209 struct alc_spec *spec = codec->spec;
18210
18211 alc262_hippo1_setup(codec);
18212 spec->ext_mic.pin = 0x18;
18213 spec->ext_mic.mux_idx = 0;
18214 spec->int_mic.pin = 0x19;
18215 spec->int_mic.mux_idx = 1;
18216 spec->auto_mic = 1;
18217 }
18218
18219 static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
18220 {
18221 struct alc_spec *spec = codec->spec;
18222
18223 spec->autocfg.hp_pins[0] = 0x14;
18224 spec->autocfg.speaker_pins[0] = 0x1b;
18225 spec->automute = 1;
18226 spec->automute_mode = ALC_AUTOMUTE_AMP;
18227 }
18228
18229 static void alc663_m51va_setup(struct hda_codec *codec)
18230 {
18231 struct alc_spec *spec = codec->spec;
18232 spec->autocfg.hp_pins[0] = 0x21;
18233 spec->autocfg.speaker_pins[0] = 0x14;
18234 spec->automute_mixer_nid[0] = 0x0c;
18235 spec->automute = 1;
18236 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18237 spec->ext_mic.pin = 0x18;
18238 spec->ext_mic.mux_idx = 0;
18239 spec->int_mic.pin = 0x12;
18240 spec->int_mic.mux_idx = 9;
18241 spec->auto_mic = 1;
18242 }
18243
18244 /* ***************** Mode1 ******************************/
18245 static void alc663_mode1_setup(struct hda_codec *codec)
18246 {
18247 struct alc_spec *spec = codec->spec;
18248 spec->autocfg.hp_pins[0] = 0x21;
18249 spec->autocfg.speaker_pins[0] = 0x14;
18250 spec->automute_mixer_nid[0] = 0x0c;
18251 spec->automute = 1;
18252 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18253 spec->ext_mic.pin = 0x18;
18254 spec->ext_mic.mux_idx = 0;
18255 spec->int_mic.pin = 0x19;
18256 spec->int_mic.mux_idx = 1;
18257 spec->auto_mic = 1;
18258 }
18259
18260 /* ***************** Mode2 ******************************/
18261 static void alc662_mode2_setup(struct hda_codec *codec)
18262 {
18263 struct alc_spec *spec = codec->spec;
18264 spec->autocfg.hp_pins[0] = 0x1b;
18265 spec->autocfg.speaker_pins[0] = 0x14;
18266 spec->automute = 1;
18267 spec->automute_mode = ALC_AUTOMUTE_PIN;
18268 spec->ext_mic.pin = 0x18;
18269 spec->ext_mic.mux_idx = 0;
18270 spec->int_mic.pin = 0x19;
18271 spec->int_mic.mux_idx = 1;
18272 spec->auto_mic = 1;
18273 }
18274
18275 /* ***************** Mode3 ******************************/
18276 static void alc663_mode3_setup(struct hda_codec *codec)
18277 {
18278 struct alc_spec *spec = codec->spec;
18279 spec->autocfg.hp_pins[0] = 0x21;
18280 spec->autocfg.hp_pins[0] = 0x15;
18281 spec->autocfg.speaker_pins[0] = 0x14;
18282 spec->automute = 1;
18283 spec->automute_mode = ALC_AUTOMUTE_PIN;
18284 spec->ext_mic.pin = 0x18;
18285 spec->ext_mic.mux_idx = 0;
18286 spec->int_mic.pin = 0x19;
18287 spec->int_mic.mux_idx = 1;
18288 spec->auto_mic = 1;
18289 }
18290
18291 /* ***************** Mode4 ******************************/
18292 static void alc663_mode4_setup(struct hda_codec *codec)
18293 {
18294 struct alc_spec *spec = codec->spec;
18295 spec->autocfg.hp_pins[0] = 0x21;
18296 spec->autocfg.speaker_pins[0] = 0x14;
18297 spec->autocfg.speaker_pins[1] = 0x16;
18298 spec->automute_mixer_nid[0] = 0x0c;
18299 spec->automute_mixer_nid[1] = 0x0e;
18300 spec->automute = 1;
18301 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18302 spec->ext_mic.pin = 0x18;
18303 spec->ext_mic.mux_idx = 0;
18304 spec->int_mic.pin = 0x19;
18305 spec->int_mic.mux_idx = 1;
18306 spec->auto_mic = 1;
18307 }
18308
18309 /* ***************** Mode5 ******************************/
18310 static void alc663_mode5_setup(struct hda_codec *codec)
18311 {
18312 struct alc_spec *spec = codec->spec;
18313 spec->autocfg.hp_pins[0] = 0x15;
18314 spec->autocfg.speaker_pins[0] = 0x14;
18315 spec->autocfg.speaker_pins[1] = 0x16;
18316 spec->automute_mixer_nid[0] = 0x0c;
18317 spec->automute_mixer_nid[1] = 0x0e;
18318 spec->automute = 1;
18319 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18320 spec->ext_mic.pin = 0x18;
18321 spec->ext_mic.mux_idx = 0;
18322 spec->int_mic.pin = 0x19;
18323 spec->int_mic.mux_idx = 1;
18324 spec->auto_mic = 1;
18325 }
18326
18327 /* ***************** Mode6 ******************************/
18328 static void alc663_mode6_setup(struct hda_codec *codec)
18329 {
18330 struct alc_spec *spec = codec->spec;
18331 spec->autocfg.hp_pins[0] = 0x1b;
18332 spec->autocfg.hp_pins[0] = 0x15;
18333 spec->autocfg.speaker_pins[0] = 0x14;
18334 spec->automute_mixer_nid[0] = 0x0c;
18335 spec->automute = 1;
18336 spec->automute_mode = ALC_AUTOMUTE_MIXER;
18337 spec->ext_mic.pin = 0x18;
18338 spec->ext_mic.mux_idx = 0;
18339 spec->int_mic.pin = 0x19;
18340 spec->int_mic.mux_idx = 1;
18341 spec->auto_mic = 1;
18342 }
18343
18344 /* ***************** Mode7 ******************************/
18345 static void alc663_mode7_setup(struct hda_codec *codec)
18346 {
18347 struct alc_spec *spec = codec->spec;
18348 spec->autocfg.hp_pins[0] = 0x1b;
18349 spec->autocfg.hp_pins[0] = 0x21;
18350 spec->autocfg.speaker_pins[0] = 0x14;
18351 spec->autocfg.speaker_pins[0] = 0x17;
18352 spec->automute = 1;
18353 spec->automute_mode = ALC_AUTOMUTE_PIN;
18354 spec->ext_mic.pin = 0x18;
18355 spec->ext_mic.mux_idx = 0;
18356 spec->int_mic.pin = 0x19;
18357 spec->int_mic.mux_idx = 1;
18358 spec->auto_mic = 1;
18359 }
18360
18361 /* ***************** Mode8 ******************************/
18362 static void alc663_mode8_setup(struct hda_codec *codec)
18363 {
18364 struct alc_spec *spec = codec->spec;
18365 spec->autocfg.hp_pins[0] = 0x21;
18366 spec->autocfg.hp_pins[1] = 0x15;
18367 spec->autocfg.speaker_pins[0] = 0x14;
18368 spec->autocfg.speaker_pins[0] = 0x17;
18369 spec->automute = 1;
18370 spec->automute_mode = ALC_AUTOMUTE_PIN;
18371 spec->ext_mic.pin = 0x18;
18372 spec->ext_mic.mux_idx = 0;
18373 spec->int_mic.pin = 0x12;
18374 spec->int_mic.mux_idx = 9;
18375 spec->auto_mic = 1;
18376 }
18377
18378 static void alc663_g71v_setup(struct hda_codec *codec)
18379 {
18380 struct alc_spec *spec = codec->spec;
18381 spec->autocfg.hp_pins[0] = 0x21;
18382 spec->autocfg.line_out_pins[0] = 0x15;
18383 spec->autocfg.speaker_pins[0] = 0x14;
18384 spec->automute = 1;
18385 spec->automute_mode = ALC_AUTOMUTE_AMP;
18386 spec->detect_line = 1;
18387 spec->automute_lines = 1;
18388 spec->ext_mic.pin = 0x18;
18389 spec->ext_mic.mux_idx = 0;
18390 spec->int_mic.pin = 0x12;
18391 spec->int_mic.mux_idx = 9;
18392 spec->auto_mic = 1;
18393 }
18394
18395 #define alc663_g50v_setup alc663_m51va_setup
18396
18397 static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
18398 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18399 ALC262_HIPPO_MASTER_SWITCH,
18400
18401 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
18402 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
18403 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
18404
18405 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18406 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18407 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18408 { } /* end */
18409 };
18410
18411 static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
18412 /* Master Playback automatically created from Speaker and Headphone */
18413 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
18414 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
18415 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
18416 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
18417
18418 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
18419 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
18420 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
18421
18422 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
18423 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
18424 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
18425 { } /* end */
18426 };
18427
18428 #ifdef CONFIG_SND_HDA_POWER_SAVE
18429 #define alc662_loopbacks alc880_loopbacks
18430 #endif
18431
18432
18433 /* pcm configuration: identical with ALC880 */
18434 #define alc662_pcm_analog_playback alc880_pcm_analog_playback
18435 #define alc662_pcm_analog_capture alc880_pcm_analog_capture
18436 #define alc662_pcm_digital_playback alc880_pcm_digital_playback
18437 #define alc662_pcm_digital_capture alc880_pcm_digital_capture
18438
18439 /*
18440 * configuration and preset
18441 */
18442 static const char * const alc662_models[ALC662_MODEL_LAST] = {
18443 [ALC662_3ST_2ch_DIG] = "3stack-dig",
18444 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
18445 [ALC662_3ST_6ch] = "3stack-6ch",
18446 [ALC662_5ST_DIG] = "5stack-dig",
18447 [ALC662_LENOVO_101E] = "lenovo-101e",
18448 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
18449 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
18450 [ALC662_ECS] = "ecs",
18451 [ALC663_ASUS_M51VA] = "m51va",
18452 [ALC663_ASUS_G71V] = "g71v",
18453 [ALC663_ASUS_H13] = "h13",
18454 [ALC663_ASUS_G50V] = "g50v",
18455 [ALC663_ASUS_MODE1] = "asus-mode1",
18456 [ALC662_ASUS_MODE2] = "asus-mode2",
18457 [ALC663_ASUS_MODE3] = "asus-mode3",
18458 [ALC663_ASUS_MODE4] = "asus-mode4",
18459 [ALC663_ASUS_MODE5] = "asus-mode5",
18460 [ALC663_ASUS_MODE6] = "asus-mode6",
18461 [ALC663_ASUS_MODE7] = "asus-mode7",
18462 [ALC663_ASUS_MODE8] = "asus-mode8",
18463 [ALC272_DELL] = "dell",
18464 [ALC272_DELL_ZM1] = "dell-zm1",
18465 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
18466 [ALC662_AUTO] = "auto",
18467 };
18468
18469 static const struct snd_pci_quirk alc662_cfg_tbl[] = {
18470 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
18471 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
18472 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
18473 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
18474 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
18475 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
18476 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
18477 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
18478 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
18479 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
18480 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
18481 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
18482 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
18483 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
18484 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
18485 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
18486 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
18487 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
18488 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
18489 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
18490 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
18491 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
18492 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
18493 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
18494 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
18495 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
18496 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
18497 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
18498 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
18499 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
18500 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
18501 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
18502 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
18503 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
18504 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
18505 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
18506 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
18507 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
18508 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
18509 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
18510 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
18511 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
18512 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
18513 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
18514 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
18515 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
18516 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
18517 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
18518 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
18519 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
18520 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
18521 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
18522 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
18523 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
18524 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
18525 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
18526 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
18527 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
18528 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
18529 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
18530 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
18531 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
18532 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
18533 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
18534 ALC662_3ST_6ch_DIG),
18535 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
18536 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
18537 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
18538 ALC662_3ST_6ch_DIG),
18539 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
18540 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
18541 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
18542 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
18543 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
18544 ALC662_3ST_6ch_DIG),
18545 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
18546 ALC663_ASUS_H13),
18547 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
18548 {}
18549 };
18550
18551 static const struct alc_config_preset alc662_presets[] = {
18552 [ALC662_3ST_2ch_DIG] = {
18553 .mixers = { alc662_3ST_2ch_mixer },
18554 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18555 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18556 .dac_nids = alc662_dac_nids,
18557 .dig_out_nid = ALC662_DIGOUT_NID,
18558 .dig_in_nid = ALC662_DIGIN_NID,
18559 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18560 .channel_mode = alc662_3ST_2ch_modes,
18561 .input_mux = &alc662_capture_source,
18562 },
18563 [ALC662_3ST_6ch_DIG] = {
18564 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18565 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18566 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18567 .dac_nids = alc662_dac_nids,
18568 .dig_out_nid = ALC662_DIGOUT_NID,
18569 .dig_in_nid = ALC662_DIGIN_NID,
18570 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18571 .channel_mode = alc662_3ST_6ch_modes,
18572 .need_dac_fix = 1,
18573 .input_mux = &alc662_capture_source,
18574 },
18575 [ALC662_3ST_6ch] = {
18576 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
18577 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18578 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18579 .dac_nids = alc662_dac_nids,
18580 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18581 .channel_mode = alc662_3ST_6ch_modes,
18582 .need_dac_fix = 1,
18583 .input_mux = &alc662_capture_source,
18584 },
18585 [ALC662_5ST_DIG] = {
18586 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
18587 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
18588 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18589 .dac_nids = alc662_dac_nids,
18590 .dig_out_nid = ALC662_DIGOUT_NID,
18591 .dig_in_nid = ALC662_DIGIN_NID,
18592 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
18593 .channel_mode = alc662_5stack_modes,
18594 .input_mux = &alc662_capture_source,
18595 },
18596 [ALC662_LENOVO_101E] = {
18597 .mixers = { alc662_lenovo_101e_mixer },
18598 .init_verbs = { alc662_init_verbs,
18599 alc662_eapd_init_verbs,
18600 alc662_sue_init_verbs },
18601 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18602 .dac_nids = alc662_dac_nids,
18603 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18604 .channel_mode = alc662_3ST_2ch_modes,
18605 .input_mux = &alc662_lenovo_101e_capture_source,
18606 .unsol_event = alc_sku_unsol_event,
18607 .setup = alc662_lenovo_101e_setup,
18608 .init_hook = alc_inithook,
18609 },
18610 [ALC662_ASUS_EEEPC_P701] = {
18611 .mixers = { alc662_eeepc_p701_mixer },
18612 .init_verbs = { alc662_init_verbs,
18613 alc662_eapd_init_verbs,
18614 alc662_eeepc_sue_init_verbs },
18615 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18616 .dac_nids = alc662_dac_nids,
18617 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18618 .channel_mode = alc662_3ST_2ch_modes,
18619 .unsol_event = alc_sku_unsol_event,
18620 .setup = alc662_eeepc_setup,
18621 .init_hook = alc_inithook,
18622 },
18623 [ALC662_ASUS_EEEPC_EP20] = {
18624 .mixers = { alc662_eeepc_ep20_mixer,
18625 alc662_chmode_mixer },
18626 .init_verbs = { alc662_init_verbs,
18627 alc662_eapd_init_verbs,
18628 alc662_eeepc_ep20_sue_init_verbs },
18629 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18630 .dac_nids = alc662_dac_nids,
18631 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18632 .channel_mode = alc662_3ST_6ch_modes,
18633 .input_mux = &alc662_lenovo_101e_capture_source,
18634 .unsol_event = alc_sku_unsol_event,
18635 .setup = alc662_eeepc_ep20_setup,
18636 .init_hook = alc_inithook,
18637 },
18638 [ALC662_ECS] = {
18639 .mixers = { alc662_ecs_mixer },
18640 .init_verbs = { alc662_init_verbs,
18641 alc662_eapd_init_verbs,
18642 alc662_ecs_init_verbs },
18643 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18644 .dac_nids = alc662_dac_nids,
18645 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18646 .channel_mode = alc662_3ST_2ch_modes,
18647 .unsol_event = alc_sku_unsol_event,
18648 .setup = alc662_eeepc_setup,
18649 .init_hook = alc_inithook,
18650 },
18651 [ALC663_ASUS_M51VA] = {
18652 .mixers = { alc663_m51va_mixer },
18653 .init_verbs = { alc662_init_verbs,
18654 alc662_eapd_init_verbs,
18655 alc663_m51va_init_verbs },
18656 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18657 .dac_nids = alc662_dac_nids,
18658 .dig_out_nid = ALC662_DIGOUT_NID,
18659 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18660 .channel_mode = alc662_3ST_2ch_modes,
18661 .unsol_event = alc_sku_unsol_event,
18662 .setup = alc663_m51va_setup,
18663 .init_hook = alc_inithook,
18664 },
18665 [ALC663_ASUS_G71V] = {
18666 .mixers = { alc663_g71v_mixer },
18667 .init_verbs = { alc662_init_verbs,
18668 alc662_eapd_init_verbs,
18669 alc663_g71v_init_verbs },
18670 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18671 .dac_nids = alc662_dac_nids,
18672 .dig_out_nid = ALC662_DIGOUT_NID,
18673 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18674 .channel_mode = alc662_3ST_2ch_modes,
18675 .unsol_event = alc_sku_unsol_event,
18676 .setup = alc663_g71v_setup,
18677 .init_hook = alc_inithook,
18678 },
18679 [ALC663_ASUS_H13] = {
18680 .mixers = { alc663_m51va_mixer },
18681 .init_verbs = { alc662_init_verbs,
18682 alc662_eapd_init_verbs,
18683 alc663_m51va_init_verbs },
18684 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18685 .dac_nids = alc662_dac_nids,
18686 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18687 .channel_mode = alc662_3ST_2ch_modes,
18688 .setup = alc663_m51va_setup,
18689 .unsol_event = alc_sku_unsol_event,
18690 .init_hook = alc_inithook,
18691 },
18692 [ALC663_ASUS_G50V] = {
18693 .mixers = { alc663_g50v_mixer },
18694 .init_verbs = { alc662_init_verbs,
18695 alc662_eapd_init_verbs,
18696 alc663_g50v_init_verbs },
18697 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18698 .dac_nids = alc662_dac_nids,
18699 .dig_out_nid = ALC662_DIGOUT_NID,
18700 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
18701 .channel_mode = alc662_3ST_6ch_modes,
18702 .input_mux = &alc663_capture_source,
18703 .unsol_event = alc_sku_unsol_event,
18704 .setup = alc663_g50v_setup,
18705 .init_hook = alc_inithook,
18706 },
18707 [ALC663_ASUS_MODE1] = {
18708 .mixers = { alc663_m51va_mixer },
18709 .cap_mixer = alc662_auto_capture_mixer,
18710 .init_verbs = { alc662_init_verbs,
18711 alc662_eapd_init_verbs,
18712 alc663_21jd_amic_init_verbs },
18713 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18714 .hp_nid = 0x03,
18715 .dac_nids = alc662_dac_nids,
18716 .dig_out_nid = ALC662_DIGOUT_NID,
18717 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18718 .channel_mode = alc662_3ST_2ch_modes,
18719 .unsol_event = alc_sku_unsol_event,
18720 .setup = alc663_mode1_setup,
18721 .init_hook = alc_inithook,
18722 },
18723 [ALC662_ASUS_MODE2] = {
18724 .mixers = { alc662_1bjd_mixer },
18725 .cap_mixer = alc662_auto_capture_mixer,
18726 .init_verbs = { alc662_init_verbs,
18727 alc662_eapd_init_verbs,
18728 alc662_1bjd_amic_init_verbs },
18729 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18730 .dac_nids = alc662_dac_nids,
18731 .dig_out_nid = ALC662_DIGOUT_NID,
18732 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18733 .channel_mode = alc662_3ST_2ch_modes,
18734 .unsol_event = alc_sku_unsol_event,
18735 .setup = alc662_mode2_setup,
18736 .init_hook = alc_inithook,
18737 },
18738 [ALC663_ASUS_MODE3] = {
18739 .mixers = { alc663_two_hp_m1_mixer },
18740 .cap_mixer = alc662_auto_capture_mixer,
18741 .init_verbs = { alc662_init_verbs,
18742 alc662_eapd_init_verbs,
18743 alc663_two_hp_amic_m1_init_verbs },
18744 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18745 .hp_nid = 0x03,
18746 .dac_nids = alc662_dac_nids,
18747 .dig_out_nid = ALC662_DIGOUT_NID,
18748 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18749 .channel_mode = alc662_3ST_2ch_modes,
18750 .unsol_event = alc_sku_unsol_event,
18751 .setup = alc663_mode3_setup,
18752 .init_hook = alc_inithook,
18753 },
18754 [ALC663_ASUS_MODE4] = {
18755 .mixers = { alc663_asus_21jd_clfe_mixer },
18756 .cap_mixer = alc662_auto_capture_mixer,
18757 .init_verbs = { alc662_init_verbs,
18758 alc662_eapd_init_verbs,
18759 alc663_21jd_amic_init_verbs},
18760 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18761 .hp_nid = 0x03,
18762 .dac_nids = alc662_dac_nids,
18763 .dig_out_nid = ALC662_DIGOUT_NID,
18764 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18765 .channel_mode = alc662_3ST_2ch_modes,
18766 .unsol_event = alc_sku_unsol_event,
18767 .setup = alc663_mode4_setup,
18768 .init_hook = alc_inithook,
18769 },
18770 [ALC663_ASUS_MODE5] = {
18771 .mixers = { alc663_asus_15jd_clfe_mixer },
18772 .cap_mixer = alc662_auto_capture_mixer,
18773 .init_verbs = { alc662_init_verbs,
18774 alc662_eapd_init_verbs,
18775 alc663_15jd_amic_init_verbs },
18776 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18777 .hp_nid = 0x03,
18778 .dac_nids = alc662_dac_nids,
18779 .dig_out_nid = ALC662_DIGOUT_NID,
18780 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18781 .channel_mode = alc662_3ST_2ch_modes,
18782 .unsol_event = alc_sku_unsol_event,
18783 .setup = alc663_mode5_setup,
18784 .init_hook = alc_inithook,
18785 },
18786 [ALC663_ASUS_MODE6] = {
18787 .mixers = { alc663_two_hp_m2_mixer },
18788 .cap_mixer = alc662_auto_capture_mixer,
18789 .init_verbs = { alc662_init_verbs,
18790 alc662_eapd_init_verbs,
18791 alc663_two_hp_amic_m2_init_verbs },
18792 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18793 .hp_nid = 0x03,
18794 .dac_nids = alc662_dac_nids,
18795 .dig_out_nid = ALC662_DIGOUT_NID,
18796 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18797 .channel_mode = alc662_3ST_2ch_modes,
18798 .unsol_event = alc_sku_unsol_event,
18799 .setup = alc663_mode6_setup,
18800 .init_hook = alc_inithook,
18801 },
18802 [ALC663_ASUS_MODE7] = {
18803 .mixers = { alc663_mode7_mixer },
18804 .cap_mixer = alc662_auto_capture_mixer,
18805 .init_verbs = { alc662_init_verbs,
18806 alc662_eapd_init_verbs,
18807 alc663_mode7_init_verbs },
18808 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18809 .hp_nid = 0x03,
18810 .dac_nids = alc662_dac_nids,
18811 .dig_out_nid = ALC662_DIGOUT_NID,
18812 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18813 .channel_mode = alc662_3ST_2ch_modes,
18814 .unsol_event = alc_sku_unsol_event,
18815 .setup = alc663_mode7_setup,
18816 .init_hook = alc_inithook,
18817 },
18818 [ALC663_ASUS_MODE8] = {
18819 .mixers = { alc663_mode8_mixer },
18820 .cap_mixer = alc662_auto_capture_mixer,
18821 .init_verbs = { alc662_init_verbs,
18822 alc662_eapd_init_verbs,
18823 alc663_mode8_init_verbs },
18824 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18825 .hp_nid = 0x03,
18826 .dac_nids = alc662_dac_nids,
18827 .dig_out_nid = ALC662_DIGOUT_NID,
18828 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18829 .channel_mode = alc662_3ST_2ch_modes,
18830 .unsol_event = alc_sku_unsol_event,
18831 .setup = alc663_mode8_setup,
18832 .init_hook = alc_inithook,
18833 },
18834 [ALC272_DELL] = {
18835 .mixers = { alc663_m51va_mixer },
18836 .cap_mixer = alc272_auto_capture_mixer,
18837 .init_verbs = { alc662_init_verbs,
18838 alc662_eapd_init_verbs,
18839 alc272_dell_init_verbs },
18840 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18841 .dac_nids = alc272_dac_nids,
18842 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18843 .adc_nids = alc272_adc_nids,
18844 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18845 .capsrc_nids = alc272_capsrc_nids,
18846 .channel_mode = alc662_3ST_2ch_modes,
18847 .unsol_event = alc_sku_unsol_event,
18848 .setup = alc663_m51va_setup,
18849 .init_hook = alc_inithook,
18850 },
18851 [ALC272_DELL_ZM1] = {
18852 .mixers = { alc663_m51va_mixer },
18853 .cap_mixer = alc662_auto_capture_mixer,
18854 .init_verbs = { alc662_init_verbs,
18855 alc662_eapd_init_verbs,
18856 alc272_dell_zm1_init_verbs },
18857 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18858 .dac_nids = alc272_dac_nids,
18859 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18860 .adc_nids = alc662_adc_nids,
18861 .num_adc_nids = 1,
18862 .capsrc_nids = alc662_capsrc_nids,
18863 .channel_mode = alc662_3ST_2ch_modes,
18864 .unsol_event = alc_sku_unsol_event,
18865 .setup = alc663_m51va_setup,
18866 .init_hook = alc_inithook,
18867 },
18868 [ALC272_SAMSUNG_NC10] = {
18869 .mixers = { alc272_nc10_mixer },
18870 .init_verbs = { alc662_init_verbs,
18871 alc662_eapd_init_verbs,
18872 alc663_21jd_amic_init_verbs },
18873 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18874 .dac_nids = alc272_dac_nids,
18875 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18876 .channel_mode = alc662_3ST_2ch_modes,
18877 /*.input_mux = &alc272_nc10_capture_source,*/
18878 .unsol_event = alc_sku_unsol_event,
18879 .setup = alc663_mode4_setup,
18880 .init_hook = alc_inithook,
18881 },
18882 };
18883
18884
18885 /*
18886 * BIOS auto configuration
18887 */
18888
18889 /* convert from MIX nid to DAC */
18890 static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
18891 {
18892 hda_nid_t list[5];
18893 int i, num;
18894
18895 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
18896 for (i = 0; i < num; i++) {
18897 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
18898 return list[i];
18899 }
18900 return 0;
18901 }
18902
18903 /* go down to the selector widget before the mixer */
18904 static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18905 {
18906 hda_nid_t srcs[5];
18907 int num = snd_hda_get_connections(codec, pin, srcs,
18908 ARRAY_SIZE(srcs));
18909 if (num != 1 ||
18910 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18911 return pin;
18912 return srcs[0];
18913 }
18914
18915 /* get MIX nid connected to the given pin targeted to DAC */
18916 static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18917 hda_nid_t dac)
18918 {
18919 hda_nid_t mix[5];
18920 int i, num;
18921
18922 pin = alc_go_down_to_selector(codec, pin);
18923 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18924 for (i = 0; i < num; i++) {
18925 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
18926 return mix[i];
18927 }
18928 return 0;
18929 }
18930
18931 /* select the connection from pin to DAC if needed */
18932 static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18933 hda_nid_t dac)
18934 {
18935 hda_nid_t mix[5];
18936 int i, num;
18937
18938 pin = alc_go_down_to_selector(codec, pin);
18939 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18940 if (num < 2)
18941 return 0;
18942 for (i = 0; i < num; i++) {
18943 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18944 snd_hda_codec_update_cache(codec, pin, 0,
18945 AC_VERB_SET_CONNECT_SEL, i);
18946 return 0;
18947 }
18948 }
18949 return 0;
18950 }
18951
18952 /* look for an empty DAC slot */
18953 static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18954 {
18955 struct alc_spec *spec = codec->spec;
18956 hda_nid_t srcs[5];
18957 int i, j, num;
18958
18959 pin = alc_go_down_to_selector(codec, pin);
18960 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18961 for (i = 0; i < num; i++) {
18962 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
18963 if (!nid)
18964 continue;
18965 for (j = 0; j < spec->multiout.num_dacs; j++)
18966 if (spec->multiout.dac_nids[j] == nid)
18967 break;
18968 if (j >= spec->multiout.num_dacs)
18969 return nid;
18970 }
18971 return 0;
18972 }
18973
18974 /* fill in the dac_nids table from the parsed pin configuration */
18975 static int alc662_auto_fill_dac_nids(struct hda_codec *codec,
18976 const struct auto_pin_cfg *cfg)
18977 {
18978 struct alc_spec *spec = codec->spec;
18979 int i;
18980 hda_nid_t dac;
18981
18982 spec->multiout.dac_nids = spec->private_dac_nids;
18983 for (i = 0; i < cfg->line_outs; i++) {
18984 dac = alc_auto_look_for_dac(codec, cfg->line_out_pins[i]);
18985 if (!dac)
18986 continue;
18987 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
18988 }
18989 return 0;
18990 }
18991
18992 static inline int __alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx,
18993 hda_nid_t nid, int idx, unsigned int chs)
18994 {
18995 return __add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, idx,
18996 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18997 }
18998
18999 static inline int __alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx,
19000 hda_nid_t nid, int idx, unsigned int chs)
19001 {
19002 return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, idx,
19003 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT));
19004 }
19005
19006 #define alc662_add_vol_ctl(spec, pfx, nid, chs) \
19007 __alc662_add_vol_ctl(spec, pfx, nid, 0, chs)
19008 #define alc662_add_sw_ctl(spec, pfx, nid, chs) \
19009 __alc662_add_sw_ctl(spec, pfx, nid, 0, chs)
19010 #define alc662_add_stereo_vol(spec, pfx, nid) \
19011 alc662_add_vol_ctl(spec, pfx, nid, 3)
19012 #define alc662_add_stereo_sw(spec, pfx, nid) \
19013 alc662_add_sw_ctl(spec, pfx, nid, 3)
19014
19015 /* add playback controls from the parsed DAC table */
19016 static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec,
19017 const struct auto_pin_cfg *cfg)
19018 {
19019 struct alc_spec *spec = codec->spec;
19020 static const char * const chname[4] = {
19021 "Front", "Surround", NULL /*CLFE*/, "Side"
19022 };
19023 const char *pfx = alc_get_line_out_pfx(spec, true);
19024 hda_nid_t nid, mix, pin;
19025 int i, err, noutputs;
19026
19027 noutputs = cfg->line_outs;
19028 if (spec->multi_ios > 0)
19029 noutputs += spec->multi_ios;
19030
19031 for (i = 0; i < noutputs; i++) {
19032 nid = spec->multiout.dac_nids[i];
19033 if (!nid)
19034 continue;
19035 if (i >= cfg->line_outs)
19036 pin = spec->multi_io[i - 1].pin;
19037 else
19038 pin = cfg->line_out_pins[i];
19039 mix = alc_auto_dac_to_mix(codec, pin, nid);
19040 if (!mix)
19041 continue;
19042 if (!pfx && i == 2) {
19043 /* Center/LFE */
19044 err = alc662_add_vol_ctl(spec, "Center", nid, 1);
19045 if (err < 0)
19046 return err;
19047 err = alc662_add_vol_ctl(spec, "LFE", nid, 2);
19048 if (err < 0)
19049 return err;
19050 err = alc662_add_sw_ctl(spec, "Center", mix, 1);
19051 if (err < 0)
19052 return err;
19053 err = alc662_add_sw_ctl(spec, "LFE", mix, 2);
19054 if (err < 0)
19055 return err;
19056 } else {
19057 const char *name = pfx;
19058 int index = i;
19059 if (!name) {
19060 name = chname[i];
19061 index = 0;
19062 }
19063 err = __alc662_add_vol_ctl(spec, name, nid, index, 3);
19064 if (err < 0)
19065 return err;
19066 err = __alc662_add_sw_ctl(spec, name, mix, index, 3);
19067 if (err < 0)
19068 return err;
19069 }
19070 }
19071 return 0;
19072 }
19073
19074 /* add playback controls for speaker and HP outputs */
19075 /* return DAC nid if any new DAC is assigned */
19076 static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
19077 const char *pfx)
19078 {
19079 struct alc_spec *spec = codec->spec;
19080 hda_nid_t nid, mix;
19081 int err;
19082
19083 if (!pin)
19084 return 0;
19085 nid = alc_auto_look_for_dac(codec, pin);
19086 if (!nid) {
19087 /* the corresponding DAC is already occupied */
19088 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
19089 return 0; /* no way */
19090 /* create a switch only */
19091 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
19092 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
19093 }
19094
19095 mix = alc_auto_dac_to_mix(codec, pin, nid);
19096 if (!mix)
19097 return 0;
19098 err = alc662_add_vol_ctl(spec, pfx, nid, 3);
19099 if (err < 0)
19100 return err;
19101 err = alc662_add_sw_ctl(spec, pfx, mix, 3);
19102 if (err < 0)
19103 return err;
19104 return nid;
19105 }
19106
19107 /* create playback/capture controls for input pins */
19108 #define alc662_auto_create_input_ctls \
19109 alc882_auto_create_input_ctls
19110
19111 static void alc662_auto_set_output_and_unmute(struct hda_codec *codec,
19112 hda_nid_t nid, int pin_type,
19113 hda_nid_t dac)
19114 {
19115 int i, num;
19116 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
19117
19118 alc_set_pin_output(codec, nid, pin_type);
19119 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
19120 for (i = 0; i < num; i++) {
19121 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
19122 continue;
19123 /* need the manual connection? */
19124 if (num > 1)
19125 snd_hda_codec_write(codec, nid, 0,
19126 AC_VERB_SET_CONNECT_SEL, i);
19127 /* unmute mixer widget inputs */
19128 snd_hda_codec_write(codec, srcs[i], 0,
19129 AC_VERB_SET_AMP_GAIN_MUTE,
19130 AMP_IN_UNMUTE(0));
19131 snd_hda_codec_write(codec, srcs[i], 0,
19132 AC_VERB_SET_AMP_GAIN_MUTE,
19133 AMP_IN_UNMUTE(1));
19134 return;
19135 }
19136 }
19137
19138 static void alc662_auto_init_multi_out(struct hda_codec *codec)
19139 {
19140 struct alc_spec *spec = codec->spec;
19141 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19142 int i;
19143
19144 for (i = 0; i <= HDA_SIDE; i++) {
19145 hda_nid_t nid = spec->autocfg.line_out_pins[i];
19146 if (nid)
19147 alc662_auto_set_output_and_unmute(codec, nid, pin_type,
19148 spec->multiout.dac_nids[i]);
19149 }
19150 }
19151
19152 static void alc662_auto_init_hp_out(struct hda_codec *codec)
19153 {
19154 struct alc_spec *spec = codec->spec;
19155 hda_nid_t pin;
19156
19157 pin = spec->autocfg.hp_pins[0];
19158 if (pin)
19159 alc662_auto_set_output_and_unmute(codec, pin, PIN_HP,
19160 spec->multiout.hp_nid);
19161 pin = spec->autocfg.speaker_pins[0];
19162 if (pin)
19163 alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT,
19164 spec->multiout.extra_out_nid[0]);
19165 }
19166
19167 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID
19168
19169 static void alc662_auto_init_analog_input(struct hda_codec *codec)
19170 {
19171 struct alc_spec *spec = codec->spec;
19172 struct auto_pin_cfg *cfg = &spec->autocfg;
19173 int i;
19174
19175 for (i = 0; i < cfg->num_inputs; i++) {
19176 hda_nid_t nid = cfg->inputs[i].pin;
19177 if (alc_is_input_pin(codec, nid)) {
19178 alc_set_input_pin(codec, nid, cfg->inputs[i].type);
19179 if (nid != ALC662_PIN_CD_NID &&
19180 (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
19181 snd_hda_codec_write(codec, nid, 0,
19182 AC_VERB_SET_AMP_GAIN_MUTE,
19183 AMP_OUT_MUTE);
19184 }
19185 }
19186 }
19187
19188 #define alc662_auto_init_input_src alc882_auto_init_input_src
19189
19190 /*
19191 * multi-io helper
19192 */
19193 static int alc_auto_fill_multi_ios(struct hda_codec *codec,
19194 unsigned int location)
19195 {
19196 struct alc_spec *spec = codec->spec;
19197 struct auto_pin_cfg *cfg = &spec->autocfg;
19198 int type, i, num_pins = 0;
19199
19200 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
19201 for (i = 0; i < cfg->num_inputs; i++) {
19202 hda_nid_t nid = cfg->inputs[i].pin;
19203 hda_nid_t dac;
19204 unsigned int defcfg, caps;
19205 if (cfg->inputs[i].type != type)
19206 continue;
19207 defcfg = snd_hda_codec_get_pincfg(codec, nid);
19208 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
19209 continue;
19210 if (location && get_defcfg_location(defcfg) != location)
19211 continue;
19212 caps = snd_hda_query_pin_caps(codec, nid);
19213 if (!(caps & AC_PINCAP_OUT))
19214 continue;
19215 dac = alc_auto_look_for_dac(codec, nid);
19216 if (!dac)
19217 continue;
19218 spec->multi_io[num_pins].pin = nid;
19219 spec->multi_io[num_pins].dac = dac;
19220 num_pins++;
19221 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19222 }
19223 }
19224 spec->multiout.num_dacs = 1;
19225 if (num_pins < 2)
19226 return 0;
19227 return num_pins;
19228 }
19229
19230 static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
19231 struct snd_ctl_elem_info *uinfo)
19232 {
19233 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19234 struct alc_spec *spec = codec->spec;
19235
19236 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
19237 uinfo->count = 1;
19238 uinfo->value.enumerated.items = spec->multi_ios + 1;
19239 if (uinfo->value.enumerated.item > spec->multi_ios)
19240 uinfo->value.enumerated.item = spec->multi_ios;
19241 sprintf(uinfo->value.enumerated.name, "%dch",
19242 (uinfo->value.enumerated.item + 1) * 2);
19243 return 0;
19244 }
19245
19246 static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
19247 struct snd_ctl_elem_value *ucontrol)
19248 {
19249 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19250 struct alc_spec *spec = codec->spec;
19251 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
19252 return 0;
19253 }
19254
19255 static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
19256 {
19257 struct alc_spec *spec = codec->spec;
19258 hda_nid_t nid = spec->multi_io[idx].pin;
19259
19260 if (!spec->multi_io[idx].ctl_in)
19261 spec->multi_io[idx].ctl_in =
19262 snd_hda_codec_read(codec, nid, 0,
19263 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
19264 if (output) {
19265 snd_hda_codec_update_cache(codec, nid, 0,
19266 AC_VERB_SET_PIN_WIDGET_CONTROL,
19267 PIN_OUT);
19268 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19269 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19270 HDA_AMP_MUTE, 0);
19271 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
19272 } else {
19273 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
19274 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
19275 HDA_AMP_MUTE, HDA_AMP_MUTE);
19276 snd_hda_codec_update_cache(codec, nid, 0,
19277 AC_VERB_SET_PIN_WIDGET_CONTROL,
19278 spec->multi_io[idx].ctl_in);
19279 }
19280 return 0;
19281 }
19282
19283 static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
19284 struct snd_ctl_elem_value *ucontrol)
19285 {
19286 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
19287 struct alc_spec *spec = codec->spec;
19288 int i, ch;
19289
19290 ch = ucontrol->value.enumerated.item[0];
19291 if (ch < 0 || ch > spec->multi_ios)
19292 return -EINVAL;
19293 if (ch == (spec->ext_channel_count - 1) / 2)
19294 return 0;
19295 spec->ext_channel_count = (ch + 1) * 2;
19296 for (i = 0; i < spec->multi_ios; i++)
19297 alc_set_multi_io(codec, i, i < ch);
19298 spec->multiout.max_channels = spec->ext_channel_count;
19299 return 1;
19300 }
19301
19302 static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
19303 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
19304 .name = "Channel Mode",
19305 .info = alc_auto_ch_mode_info,
19306 .get = alc_auto_ch_mode_get,
19307 .put = alc_auto_ch_mode_put,
19308 };
19309
19310 static int alc_auto_add_multi_channel_mode(struct hda_codec *codec)
19311 {
19312 struct alc_spec *spec = codec->spec;
19313 struct auto_pin_cfg *cfg = &spec->autocfg;
19314 unsigned int location, defcfg;
19315 int num_pins;
19316
19317 if (cfg->line_outs != 1 ||
19318 cfg->line_out_type != AUTO_PIN_LINE_OUT)
19319 return 0;
19320
19321 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
19322 location = get_defcfg_location(defcfg);
19323
19324 num_pins = alc_auto_fill_multi_ios(codec, location);
19325 if (num_pins > 0) {
19326 struct snd_kcontrol_new *knew;
19327
19328 knew = alc_kcontrol_new(spec);
19329 if (!knew)
19330 return -ENOMEM;
19331 *knew = alc_auto_channel_mode_enum;
19332 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
19333 if (!knew->name)
19334 return -ENOMEM;
19335
19336 spec->multi_ios = num_pins;
19337 spec->ext_channel_count = 2;
19338 spec->multiout.num_dacs = num_pins + 1;
19339 }
19340 return 0;
19341 }
19342
19343 static int alc662_parse_auto_config(struct hda_codec *codec)
19344 {
19345 struct alc_spec *spec = codec->spec;
19346 int err;
19347 static const hda_nid_t alc662_ignore[] = { 0x1d, 0 };
19348
19349 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19350 alc662_ignore);
19351 if (err < 0)
19352 return err;
19353 if (!spec->autocfg.line_outs)
19354 return 0; /* can't find valid BIOS pin config */
19355
19356 err = alc662_auto_fill_dac_nids(codec, &spec->autocfg);
19357 if (err < 0)
19358 return err;
19359 err = alc_auto_add_multi_channel_mode(codec);
19360 if (err < 0)
19361 return err;
19362 err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg);
19363 if (err < 0)
19364 return err;
19365 err = alc662_auto_create_extra_out(codec,
19366 spec->autocfg.speaker_pins[0],
19367 "Speaker");
19368 if (err < 0)
19369 return err;
19370 if (err)
19371 spec->multiout.extra_out_nid[0] = err;
19372 err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
19373 "Headphone");
19374 if (err < 0)
19375 return err;
19376 if (err)
19377 spec->multiout.hp_nid = err;
19378 err = alc662_auto_create_input_ctls(codec, &spec->autocfg);
19379 if (err < 0)
19380 return err;
19381
19382 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
19383
19384 alc_auto_parse_digital(codec);
19385
19386 if (spec->kctls.list)
19387 add_mixer(spec, spec->kctls.list);
19388
19389 spec->num_mux_defs = 1;
19390 spec->input_mux = &spec->private_imux[0];
19391
19392 err = alc_auto_add_mic_boost(codec);
19393 if (err < 0)
19394 return err;
19395
19396 if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 ||
19397 codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670)
19398 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0x21);
19399 else
19400 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
19401
19402 return 1;
19403 }
19404
19405 /* additional initialization for auto-configuration model */
19406 static void alc662_auto_init(struct hda_codec *codec)
19407 {
19408 struct alc_spec *spec = codec->spec;
19409 alc662_auto_init_multi_out(codec);
19410 alc662_auto_init_hp_out(codec);
19411 alc662_auto_init_analog_input(codec);
19412 alc662_auto_init_input_src(codec);
19413 alc_auto_init_digital(codec);
19414 if (spec->unsol_event)
19415 alc_inithook(codec);
19416 }
19417
19418 static void alc272_fixup_mario(struct hda_codec *codec,
19419 const struct alc_fixup *fix, int action)
19420 {
19421 if (action != ALC_FIXUP_ACT_PROBE)
19422 return;
19423 if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT,
19424 (0x3b << AC_AMPCAP_OFFSET_SHIFT) |
19425 (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) |
19426 (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) |
19427 (0 << AC_AMPCAP_MUTE_SHIFT)))
19428 printk(KERN_WARNING
19429 "hda_codec: failed to override amp caps for NID 0x2\n");
19430 }
19431
19432 enum {
19433 ALC662_FIXUP_ASPIRE,
19434 ALC662_FIXUP_IDEAPAD,
19435 ALC272_FIXUP_MARIO,
19436 ALC662_FIXUP_CZC_P10T,
19437 ALC662_FIXUP_SKU_IGNORE,
19438 };
19439
19440 static const struct alc_fixup alc662_fixups[] = {
19441 [ALC662_FIXUP_ASPIRE] = {
19442 .type = ALC_FIXUP_PINS,
19443 .v.pins = (const struct alc_pincfg[]) {
19444 { 0x15, 0x99130112 }, /* subwoofer */
19445 { }
19446 }
19447 },
19448 [ALC662_FIXUP_IDEAPAD] = {
19449 .type = ALC_FIXUP_PINS,
19450 .v.pins = (const struct alc_pincfg[]) {
19451 { 0x17, 0x99130112 }, /* subwoofer */
19452 { }
19453 }
19454 },
19455 [ALC272_FIXUP_MARIO] = {
19456 .type = ALC_FIXUP_FUNC,
19457 .v.func = alc272_fixup_mario,
19458 },
19459 [ALC662_FIXUP_CZC_P10T] = {
19460 .type = ALC_FIXUP_VERBS,
19461 .v.verbs = (const struct hda_verb[]) {
19462 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0},
19463 {}
19464 }
19465 },
19466 [ALC662_FIXUP_SKU_IGNORE] = {
19467 .type = ALC_FIXUP_SKU,
19468 .v.sku = ALC_FIXUP_SKU_IGNORE,
19469 },
19470 };
19471
19472 static const struct snd_pci_quirk alc662_fixup_tbl[] = {
19473 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
19474 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
19475 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
19476 SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
19477 SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
19478 SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
19479 SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
19480 {}
19481 };
19482
19483 static const struct alc_model_fixup alc662_fixup_models[] = {
19484 {.id = ALC272_FIXUP_MARIO, .name = "mario"},
19485 {}
19486 };
19487
19488
19489 static int patch_alc662(struct hda_codec *codec)
19490 {
19491 struct alc_spec *spec;
19492 int err, board_config;
19493 int coef;
19494
19495 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
19496 if (!spec)
19497 return -ENOMEM;
19498
19499 codec->spec = spec;
19500
19501 alc_auto_parse_customize_define(codec);
19502
19503 alc_fix_pll_init(codec, 0x20, 0x04, 15);
19504
19505 coef = alc_read_coef_idx(codec, 0);
19506 if (coef == 0x8020 || coef == 0x8011)
19507 alc_codec_rename(codec, "ALC661");
19508 else if (coef & (1 << 14) &&
19509 codec->bus->pci->subsystem_vendor == 0x1025 &&
19510 spec->cdefine.platform_type == 1)
19511 alc_codec_rename(codec, "ALC272X");
19512 else if (coef == 0x4011)
19513 alc_codec_rename(codec, "ALC656");
19514
19515 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST,
19516 alc662_models,
19517 alc662_cfg_tbl);
19518 if (board_config < 0) {
19519 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19520 codec->chip_name);
19521 board_config = ALC662_AUTO;
19522 }
19523
19524 if (board_config == ALC662_AUTO) {
19525 alc_pick_fixup(codec, alc662_fixup_models,
19526 alc662_fixup_tbl, alc662_fixups);
19527 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
19528 /* automatic parse from the BIOS config */
19529 err = alc662_parse_auto_config(codec);
19530 if (err < 0) {
19531 alc_free(codec);
19532 return err;
19533 } else if (!err) {
19534 printk(KERN_INFO
19535 "hda_codec: Cannot set up configuration "
19536 "from BIOS. Using base mode...\n");
19537 board_config = ALC662_3ST_2ch_DIG;
19538 }
19539 }
19540
19541 if (has_cdefine_beep(codec)) {
19542 err = snd_hda_attach_beep_device(codec, 0x1);
19543 if (err < 0) {
19544 alc_free(codec);
19545 return err;
19546 }
19547 }
19548
19549 if (board_config != ALC662_AUTO)
19550 setup_preset(codec, &alc662_presets[board_config]);
19551
19552 spec->stream_analog_playback = &alc662_pcm_analog_playback;
19553 spec->stream_analog_capture = &alc662_pcm_analog_capture;
19554
19555 spec->stream_digital_playback = &alc662_pcm_digital_playback;
19556 spec->stream_digital_capture = &alc662_pcm_digital_capture;
19557
19558 if (!spec->adc_nids) {
19559 spec->adc_nids = alc662_adc_nids;
19560 spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids);
19561 }
19562 if (!spec->capsrc_nids)
19563 spec->capsrc_nids = alc662_capsrc_nids;
19564
19565 if (!spec->cap_mixer)
19566 set_capture_mixer(codec);
19567
19568 if (has_cdefine_beep(codec)) {
19569 switch (codec->vendor_id) {
19570 case 0x10ec0662:
19571 set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT);
19572 break;
19573 case 0x10ec0272:
19574 case 0x10ec0663:
19575 case 0x10ec0665:
19576 set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT);
19577 break;
19578 case 0x10ec0273:
19579 set_beep_amp(spec, 0x0b, 0x03, HDA_INPUT);
19580 break;
19581 }
19582 }
19583 spec->vmaster_nid = 0x02;
19584
19585 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
19586
19587 codec->patch_ops = alc_patch_ops;
19588 if (board_config == ALC662_AUTO)
19589 spec->init_hook = alc662_auto_init;
19590 spec->shutup = alc_eapd_shutup;
19591
19592 alc_init_jacks(codec);
19593
19594 #ifdef CONFIG_SND_HDA_POWER_SAVE
19595 if (!spec->loopback.amplist)
19596 spec->loopback.amplist = alc662_loopbacks;
19597 #endif
19598
19599 return 0;
19600 }
19601
19602 static int patch_alc888(struct hda_codec *codec)
19603 {
19604 if ((alc_read_coef_idx(codec, 0) & 0x00f0)==0x0030){
19605 kfree(codec->chip_name);
19606 if (codec->vendor_id == 0x10ec0887)
19607 codec->chip_name = kstrdup("ALC887-VD", GFP_KERNEL);
19608 else
19609 codec->chip_name = kstrdup("ALC888-VD", GFP_KERNEL);
19610 if (!codec->chip_name) {
19611 alc_free(codec);
19612 return -ENOMEM;
19613 }
19614 return patch_alc662(codec);
19615 }
19616 return patch_alc882(codec);
19617 }
19618
19619 static int patch_alc899(struct hda_codec *codec)
19620 {
19621 if ((alc_read_coef_idx(codec, 0) & 0x2000) != 0x2000) {
19622 kfree(codec->chip_name);
19623 codec->chip_name = kstrdup("ALC898", GFP_KERNEL);
19624 }
19625 return patch_alc882(codec);
19626 }
19627
19628 /*
19629 * ALC680 support
19630 */
19631 #define ALC680_DIGIN_NID ALC880_DIGIN_NID
19632 #define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
19633 #define alc680_modes alc260_modes
19634
19635 static const hda_nid_t alc680_dac_nids[3] = {
19636 /* Lout1, Lout2, hp */
19637 0x02, 0x03, 0x04
19638 };
19639
19640 static const hda_nid_t alc680_adc_nids[3] = {
19641 /* ADC0-2 */
19642 /* DMIC, MIC, Line-in*/
19643 0x07, 0x08, 0x09
19644 };
19645
19646 /*
19647 * Analog capture ADC cgange
19648 */
19649 static void alc680_rec_autoswitch(struct hda_codec *codec)
19650 {
19651 struct alc_spec *spec = codec->spec;
19652 struct auto_pin_cfg *cfg = &spec->autocfg;
19653 int pin_found = 0;
19654 int type_found = AUTO_PIN_LAST;
19655 hda_nid_t nid;
19656 int i;
19657
19658 for (i = 0; i < cfg->num_inputs; i++) {
19659 nid = cfg->inputs[i].pin;
19660 if (!is_jack_detectable(codec, nid))
19661 continue;
19662 if (snd_hda_jack_detect(codec, nid)) {
19663 if (cfg->inputs[i].type < type_found) {
19664 type_found = cfg->inputs[i].type;
19665 pin_found = nid;
19666 }
19667 }
19668 }
19669
19670 nid = 0x07;
19671 if (pin_found)
19672 snd_hda_get_connections(codec, pin_found, &nid, 1);
19673
19674 if (nid != spec->cur_adc)
19675 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
19676 spec->cur_adc = nid;
19677 snd_hda_codec_setup_stream(codec, nid, spec->cur_adc_stream_tag, 0,
19678 spec->cur_adc_format);
19679 }
19680
19681 static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19682 struct hda_codec *codec,
19683 unsigned int stream_tag,
19684 unsigned int format,
19685 struct snd_pcm_substream *substream)
19686 {
19687 struct alc_spec *spec = codec->spec;
19688
19689 spec->cur_adc = 0x07;
19690 spec->cur_adc_stream_tag = stream_tag;
19691 spec->cur_adc_format = format;
19692
19693 alc680_rec_autoswitch(codec);
19694 return 0;
19695 }
19696
19697 static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19698 struct hda_codec *codec,
19699 struct snd_pcm_substream *substream)
19700 {
19701 snd_hda_codec_cleanup_stream(codec, 0x07);
19702 snd_hda_codec_cleanup_stream(codec, 0x08);
19703 snd_hda_codec_cleanup_stream(codec, 0x09);
19704 return 0;
19705 }
19706
19707 static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19708 .substreams = 1, /* can be overridden */
19709 .channels_min = 2,
19710 .channels_max = 2,
19711 /* NID is set in alc_build_pcms */
19712 .ops = {
19713 .prepare = alc680_capture_pcm_prepare,
19714 .cleanup = alc680_capture_pcm_cleanup
19715 },
19716 };
19717
19718 static const struct snd_kcontrol_new alc680_base_mixer[] = {
19719 /* output mixer control */
19720 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19721 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19722 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19723 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
19724 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19725 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19726 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
19727 { }
19728 };
19729
19730 static const struct hda_bind_ctls alc680_bind_cap_vol = {
19731 .ops = &snd_hda_bind_vol,
19732 .values = {
19733 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19734 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19735 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19736 0
19737 },
19738 };
19739
19740 static const struct hda_bind_ctls alc680_bind_cap_switch = {
19741 .ops = &snd_hda_bind_sw,
19742 .values = {
19743 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19744 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19745 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19746 0
19747 },
19748 };
19749
19750 static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19751 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19752 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
19753 { } /* end */
19754 };
19755
19756 /*
19757 * generic initialization of ADC, input mixers and output mixers
19758 */
19759 static const struct hda_verb alc680_init_verbs[] = {
19760 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19761 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19762 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19763
19764 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19765 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19766 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19767 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19768 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19769 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19770
19771 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19772 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19773 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19774 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19775 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19776
19777 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19778 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19779 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19780
19781 { }
19782 };
19783
19784 /* toggle speaker-output according to the hp-jack state */
19785 static void alc680_base_setup(struct hda_codec *codec)
19786 {
19787 struct alc_spec *spec = codec->spec;
19788
19789 spec->autocfg.hp_pins[0] = 0x16;
19790 spec->autocfg.speaker_pins[0] = 0x14;
19791 spec->autocfg.speaker_pins[1] = 0x15;
19792 spec->autocfg.num_inputs = 2;
19793 spec->autocfg.inputs[0].pin = 0x18;
19794 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19795 spec->autocfg.inputs[1].pin = 0x19;
19796 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
19797 spec->automute = 1;
19798 spec->automute_mode = ALC_AUTOMUTE_AMP;
19799 }
19800
19801 static void alc680_unsol_event(struct hda_codec *codec,
19802 unsigned int res)
19803 {
19804 if ((res >> 26) == ALC880_HP_EVENT)
19805 alc_hp_automute(codec);
19806 if ((res >> 26) == ALC880_MIC_EVENT)
19807 alc680_rec_autoswitch(codec);
19808 }
19809
19810 static void alc680_inithook(struct hda_codec *codec)
19811 {
19812 alc_hp_automute(codec);
19813 alc680_rec_autoswitch(codec);
19814 }
19815
19816 /* create input playback/capture controls for the given pin */
19817 static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19818 const char *ctlname, int idx)
19819 {
19820 hda_nid_t dac;
19821 int err;
19822
19823 switch (nid) {
19824 case 0x14:
19825 dac = 0x02;
19826 break;
19827 case 0x15:
19828 dac = 0x03;
19829 break;
19830 case 0x16:
19831 dac = 0x04;
19832 break;
19833 default:
19834 return 0;
19835 }
19836 if (spec->multiout.dac_nids[0] != dac &&
19837 spec->multiout.dac_nids[1] != dac) {
19838 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, ctlname,
19839 HDA_COMPOSE_AMP_VAL(dac, 3, idx,
19840 HDA_OUTPUT));
19841 if (err < 0)
19842 return err;
19843
19844 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, ctlname,
19845 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_OUTPUT));
19846
19847 if (err < 0)
19848 return err;
19849 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
19850 }
19851
19852 return 0;
19853 }
19854
19855 /* add playback controls from the parsed DAC table */
19856 static int alc680_auto_create_multi_out_ctls(struct alc_spec *spec,
19857 const struct auto_pin_cfg *cfg)
19858 {
19859 hda_nid_t nid;
19860 int err;
19861
19862 spec->multiout.dac_nids = spec->private_dac_nids;
19863
19864 nid = cfg->line_out_pins[0];
19865 if (nid) {
19866 const char *name;
19867 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
19868 name = "Speaker";
19869 else
19870 name = "Front";
19871 err = alc680_new_analog_output(spec, nid, name, 0);
19872 if (err < 0)
19873 return err;
19874 }
19875
19876 nid = cfg->speaker_pins[0];
19877 if (nid) {
19878 err = alc680_new_analog_output(spec, nid, "Speaker", 0);
19879 if (err < 0)
19880 return err;
19881 }
19882 nid = cfg->hp_pins[0];
19883 if (nid) {
19884 err = alc680_new_analog_output(spec, nid, "Headphone", 0);
19885 if (err < 0)
19886 return err;
19887 }
19888
19889 return 0;
19890 }
19891
19892 static void alc680_auto_set_output_and_unmute(struct hda_codec *codec,
19893 hda_nid_t nid, int pin_type)
19894 {
19895 alc_set_pin_output(codec, nid, pin_type);
19896 }
19897
19898 static void alc680_auto_init_multi_out(struct hda_codec *codec)
19899 {
19900 struct alc_spec *spec = codec->spec;
19901 hda_nid_t nid = spec->autocfg.line_out_pins[0];
19902 if (nid) {
19903 int pin_type = get_pin_type(spec->autocfg.line_out_type);
19904 alc680_auto_set_output_and_unmute(codec, nid, pin_type);
19905 }
19906 }
19907
19908 static void alc680_auto_init_hp_out(struct hda_codec *codec)
19909 {
19910 struct alc_spec *spec = codec->spec;
19911 hda_nid_t pin;
19912
19913 pin = spec->autocfg.hp_pins[0];
19914 if (pin)
19915 alc680_auto_set_output_and_unmute(codec, pin, PIN_HP);
19916 pin = spec->autocfg.speaker_pins[0];
19917 if (pin)
19918 alc680_auto_set_output_and_unmute(codec, pin, PIN_OUT);
19919 }
19920
19921 /* pcm configuration: identical with ALC880 */
19922 #define alc680_pcm_analog_playback alc880_pcm_analog_playback
19923 #define alc680_pcm_analog_capture alc880_pcm_analog_capture
19924 #define alc680_pcm_analog_alt_capture alc880_pcm_analog_alt_capture
19925 #define alc680_pcm_digital_playback alc880_pcm_digital_playback
19926 #define alc680_pcm_digital_capture alc880_pcm_digital_capture
19927
19928 /*
19929 * BIOS auto configuration
19930 */
19931 static int alc680_parse_auto_config(struct hda_codec *codec)
19932 {
19933 struct alc_spec *spec = codec->spec;
19934 int err;
19935 static const hda_nid_t alc680_ignore[] = { 0 };
19936
19937 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
19938 alc680_ignore);
19939 if (err < 0)
19940 return err;
19941
19942 if (!spec->autocfg.line_outs) {
19943 if (spec->autocfg.dig_outs || spec->autocfg.dig_in_pin) {
19944 spec->multiout.max_channels = 2;
19945 spec->no_analog = 1;
19946 goto dig_only;
19947 }
19948 return 0; /* can't find valid BIOS pin config */
19949 }
19950 err = alc680_auto_create_multi_out_ctls(spec, &spec->autocfg);
19951 if (err < 0)
19952 return err;
19953
19954 spec->multiout.max_channels = 2;
19955
19956 dig_only:
19957 /* digital only support output */
19958 alc_auto_parse_digital(codec);
19959 if (spec->kctls.list)
19960 add_mixer(spec, spec->kctls.list);
19961
19962 add_verb(spec, alc680_init_verbs);
19963
19964 err = alc_auto_add_mic_boost(codec);
19965 if (err < 0)
19966 return err;
19967
19968 return 1;
19969 }
19970
19971 #define alc680_auto_init_analog_input alc882_auto_init_analog_input
19972
19973 /* init callback for auto-configuration model -- overriding the default init */
19974 static void alc680_auto_init(struct hda_codec *codec)
19975 {
19976 struct alc_spec *spec = codec->spec;
19977 alc680_auto_init_multi_out(codec);
19978 alc680_auto_init_hp_out(codec);
19979 alc680_auto_init_analog_input(codec);
19980 alc_auto_init_digital(codec);
19981 if (spec->unsol_event)
19982 alc_inithook(codec);
19983 }
19984
19985 /*
19986 * configuration and preset
19987 */
19988 static const char * const alc680_models[ALC680_MODEL_LAST] = {
19989 [ALC680_BASE] = "base",
19990 [ALC680_AUTO] = "auto",
19991 };
19992
19993 static const struct snd_pci_quirk alc680_cfg_tbl[] = {
19994 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19995 {}
19996 };
19997
19998 static const struct alc_config_preset alc680_presets[] = {
19999 [ALC680_BASE] = {
20000 .mixers = { alc680_base_mixer },
20001 .cap_mixer = alc680_master_capture_mixer,
20002 .init_verbs = { alc680_init_verbs },
20003 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
20004 .dac_nids = alc680_dac_nids,
20005 .dig_out_nid = ALC680_DIGOUT_NID,
20006 .num_channel_mode = ARRAY_SIZE(alc680_modes),
20007 .channel_mode = alc680_modes,
20008 .unsol_event = alc680_unsol_event,
20009 .setup = alc680_base_setup,
20010 .init_hook = alc680_inithook,
20011
20012 },
20013 };
20014
20015 static int patch_alc680(struct hda_codec *codec)
20016 {
20017 struct alc_spec *spec;
20018 int board_config;
20019 int err;
20020
20021 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
20022 if (spec == NULL)
20023 return -ENOMEM;
20024
20025 codec->spec = spec;
20026
20027 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST,
20028 alc680_models,
20029 alc680_cfg_tbl);
20030
20031 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) {
20032 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
20033 codec->chip_name);
20034 board_config = ALC680_AUTO;
20035 }
20036
20037 if (board_config == ALC680_AUTO) {
20038 /* automatic parse from the BIOS config */
20039 err = alc680_parse_auto_config(codec);
20040 if (err < 0) {
20041 alc_free(codec);
20042 return err;
20043 } else if (!err) {
20044 printk(KERN_INFO
20045 "hda_codec: Cannot set up configuration "
20046 "from BIOS. Using base mode...\n");
20047 board_config = ALC680_BASE;
20048 }
20049 }
20050
20051 if (board_config != ALC680_AUTO)
20052 setup_preset(codec, &alc680_presets[board_config]);
20053
20054 spec->stream_analog_playback = &alc680_pcm_analog_playback;
20055 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
20056 spec->stream_digital_playback = &alc680_pcm_digital_playback;
20057 spec->stream_digital_capture = &alc680_pcm_digital_capture;
20058
20059 if (!spec->adc_nids) {
20060 spec->adc_nids = alc680_adc_nids;
20061 spec->num_adc_nids = ARRAY_SIZE(alc680_adc_nids);
20062 }
20063
20064 if (!spec->cap_mixer)
20065 set_capture_mixer(codec);
20066
20067 spec->vmaster_nid = 0x02;
20068
20069 codec->patch_ops = alc_patch_ops;
20070 if (board_config == ALC680_AUTO)
20071 spec->init_hook = alc680_auto_init;
20072
20073 return 0;
20074 }
20075
20076 /*
20077 * patch entries
20078 */
20079 static const struct hda_codec_preset snd_hda_preset_realtek[] = {
20080 { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 },
20081 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 },
20082 { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 },
20083 { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 },
20084 { .id = 0x10ec0268, .name = "ALC268", .patch = patch_alc268 },
20085 { .id = 0x10ec0269, .name = "ALC269", .patch = patch_alc269 },
20086 { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 },
20087 { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 },
20088 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
20089 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
20090 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
20091 .patch = patch_alc861 },
20092 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
20093 { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 },
20094 { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd },
20095 { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2",
20096 .patch = patch_alc882 },
20097 { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1",
20098 .patch = patch_alc662 },
20099 { .id = 0x10ec0663, .name = "ALC663", .patch = patch_alc662 },
20100 { .id = 0x10ec0665, .name = "ALC665", .patch = patch_alc662 },
20101 { .id = 0x10ec0670, .name = "ALC670", .patch = patch_alc662 },
20102 { .id = 0x10ec0680, .name = "ALC680", .patch = patch_alc680 },
20103 { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 },
20104 { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 },
20105 { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc882 },
20106 { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A",
20107 .patch = patch_alc882 },
20108 { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A",
20109 .patch = patch_alc882 },
20110 { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 },
20111 { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc888 },
20112 { .id = 0x10ec0888, .rev = 0x100101, .name = "ALC1200",
20113 .patch = patch_alc882 },
20114 { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 },
20115 { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 },
20116 { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 },
20117 { .id = 0x10ec0899, .name = "ALC899", .patch = patch_alc899 },
20118 {} /* terminator */
20119 };
20120
20121 MODULE_ALIAS("snd-hda-codec-id:10ec*");
20122
20123 MODULE_LICENSE("GPL");
20124 MODULE_DESCRIPTION("Realtek HD-audio codec");
20125
20126 static struct hda_codec_preset_list realtek_list = {
20127 .preset = snd_hda_preset_realtek,
20128 .owner = THIS_MODULE,
20129 };
20130
20131 static int __init patch_realtek_init(void)
20132 {
20133 return snd_hda_add_codec_preset(&realtek_list);
20134 }
20135
20136 static void __exit patch_realtek_exit(void)
20137 {
20138 snd_hda_delete_codec_preset(&realtek_list);
20139 }
20140
20141 module_init(patch_realtek_init)
20142 module_exit(patch_realtek_exit)
This page took 0.637925 seconds and 6 git commands to generate.