aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_realtek.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-07-07 12:23:21 -0400
committerTakashi Iwai <tiwai@suse.de>2011-07-07 12:27:29 -0400
commit1d045db96ad9b8f4d876d5945ab097425252e4ab (patch)
treeb7479a54398cec0a3fc72b357790a986e38990cb /sound/pci/hda/patch_realtek.c
parent0e4a73ae5893d61ae10a9f219e2f3371e44589a8 (diff)
ALSA: hda - Split quirk codes from patch_realtek.c
Put the all static quirk codes out of patch_realtek.c, split into the file for each codec model. For controlling the build of quirk codes, a new Kconfig, CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS is introduced. By setting this off, all quirk codes won't be built, thus you can save lots of memory. The codes in patch_realtek.c are also shuffled and more comments are given, but the contents aren't changed. This is just a refactoring. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r--sound/pci/hda/patch_realtek.c15010
1 files changed, 1089 insertions, 13921 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 8366e02df3c..c1adb3bce7e 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Universal Interface for Intel High Definition Audio Codec 2 * Universal Interface for Intel High Definition Audio Codec
3 * 3 *
4 * HD audio interface patch for ALC 260/880/882 codecs 4 * HD audio interface patch for Realtek ALC codecs
5 * 5 *
6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw> 6 * Copyright (c) 2004 Kailang Yang <kailang@realtek.com.tw>
7 * PeiSen Hou <pshou@realtek.com.tw> 7 * PeiSen Hou <pshou@realtek.com.tw>
@@ -33,236 +33,11 @@
33#include "hda_local.h" 33#include "hda_local.h"
34#include "hda_beep.h" 34#include "hda_beep.h"
35 35
36#define ALC880_FRONT_EVENT 0x01 36/* unsol event tags */
37#define ALC880_DCVOL_EVENT 0x02 37#define ALC_FRONT_EVENT 0x01
38#define ALC880_HP_EVENT 0x04 38#define ALC_DCVOL_EVENT 0x02
39#define ALC880_MIC_EVENT 0x08 39#define ALC_HP_EVENT 0x04
40 40#define ALC_MIC_EVENT 0x08
41/* ALC880 board config type */
42enum {
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 */
73enum {
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 */
91enum {
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 */
115enum {
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 */
132enum {
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 */
147enum {
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 */
161enum {
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 */
176enum {
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 */
205enum {
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 */
261enum {
262 ALC680_BASE,
263 ALC680_AUTO,
264 ALC680_MODEL_LAST,
265};
266 41
267/* for GPIO Poll */ 42/* for GPIO Poll */
268#define GPIO_MASK 0x03 43#define GPIO_MASK 0x03
@@ -429,39 +204,7 @@ struct alc_spec {
429 struct alc_multi_io multi_io[4]; 204 struct alc_multi_io multi_io[4];
430}; 205};
431 206
432/* 207#define ALC_MODEL_AUTO 0 /* common for all chips */
433 * configuration template - to be copied to the spec instance
434 */
435struct alc_config_preset {
436 const struct snd_kcontrol_new *mixers[5]; /* should be identical size
437 * with spec
438 */
439 const struct snd_kcontrol_new *cap_mixer; /* capture mixer */
440 const struct hda_verb *init_verbs[5];
441 unsigned int num_dacs;
442 const hda_nid_t *dac_nids;
443 hda_nid_t dig_out_nid; /* optional */
444 hda_nid_t hp_nid; /* optional */
445 const hda_nid_t *slave_dig_outs;
446 unsigned int num_adc_nids;
447 const hda_nid_t *adc_nids;
448 const hda_nid_t *capsrc_nids;
449 hda_nid_t dig_in_nid;
450 unsigned int num_channel_mode;
451 const struct hda_channel_mode *channel_mode;
452 int need_dac_fix;
453 int const_channel_count;
454 unsigned int num_mux_defs;
455 const struct hda_input_mux *input_mux;
456 void (*unsol_event)(struct hda_codec *, unsigned int);
457 void (*setup)(struct hda_codec *);
458 void (*init_hook)(struct hda_codec *);
459#ifdef CONFIG_SND_HDA_POWER_SAVE
460 const struct hda_amp_list *loopbacks;
461 void (*power_hook)(struct hda_codec *codec);
462#endif
463};
464
465 208
466/* 209/*
467 * input MUX handling 210 * input MUX handling
@@ -568,345 +311,6 @@ static int alc_mux_enum_put(struct snd_kcontrol *kcontrol,
568} 311}
569 312
570/* 313/*
571 * channel mode setting
572 */
573static int alc_ch_mode_info(struct snd_kcontrol *kcontrol,
574 struct snd_ctl_elem_info *uinfo)
575{
576 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
577 struct alc_spec *spec = codec->spec;
578 return snd_hda_ch_mode_info(codec, uinfo, spec->channel_mode,
579 spec->num_channel_mode);
580}
581
582static int alc_ch_mode_get(struct snd_kcontrol *kcontrol,
583 struct snd_ctl_elem_value *ucontrol)
584{
585 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
586 struct alc_spec *spec = codec->spec;
587 return snd_hda_ch_mode_get(codec, ucontrol, spec->channel_mode,
588 spec->num_channel_mode,
589 spec->ext_channel_count);
590}
591
592static int alc_ch_mode_put(struct snd_kcontrol *kcontrol,
593 struct snd_ctl_elem_value *ucontrol)
594{
595 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
596 struct alc_spec *spec = codec->spec;
597 int err = snd_hda_ch_mode_put(codec, ucontrol, spec->channel_mode,
598 spec->num_channel_mode,
599 &spec->ext_channel_count);
600 if (err >= 0 && !spec->const_channel_count) {
601 spec->multiout.max_channels = spec->ext_channel_count;
602 if (spec->need_dac_fix)
603 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
604 }
605 return err;
606}
607
608/*
609 * Control the mode of pin widget settings via the mixer. "pc" is used
610 * instead of "%" to avoid consequences of accidentally treating the % as
611 * being part of a format specifier. Maximum allowed length of a value is
612 * 63 characters plus NULL terminator.
613 *
614 * Note: some retasking pin complexes seem to ignore requests for input
615 * states other than HiZ (eg: PIN_VREFxx) and revert to HiZ if any of these
616 * are requested. Therefore order this list so that this behaviour will not
617 * cause problems when mixer clients move through the enum sequentially.
618 * NIDs 0x0f and 0x10 have been observed to have this behaviour as of
619 * March 2006.
620 */
621static const char * const alc_pin_mode_names[] = {
622 "Mic 50pc bias", "Mic 80pc bias",
623 "Line in", "Line out", "Headphone out",
624};
625static const unsigned char alc_pin_mode_values[] = {
626 PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP,
627};
628/* The control can present all 5 options, or it can limit the options based
629 * in the pin being assumed to be exclusively an input or an output pin. In
630 * addition, "input" pins may or may not process the mic bias option
631 * depending on actual widget capability (NIDs 0x0f and 0x10 don't seem to
632 * accept requests for bias as of chip versions up to March 2006) and/or
633 * wiring in the computer.
634 */
635#define ALC_PIN_DIR_IN 0x00
636#define ALC_PIN_DIR_OUT 0x01
637#define ALC_PIN_DIR_INOUT 0x02
638#define ALC_PIN_DIR_IN_NOMICBIAS 0x03
639#define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04
640
641/* Info about the pin modes supported by the different pin direction modes.
642 * For each direction the minimum and maximum values are given.
643 */
644static const signed char alc_pin_mode_dir_info[5][2] = {
645 { 0, 2 }, /* ALC_PIN_DIR_IN */
646 { 3, 4 }, /* ALC_PIN_DIR_OUT */
647 { 0, 4 }, /* ALC_PIN_DIR_INOUT */
648 { 2, 2 }, /* ALC_PIN_DIR_IN_NOMICBIAS */
649 { 2, 4 }, /* ALC_PIN_DIR_INOUT_NOMICBIAS */
650};
651#define alc_pin_mode_min(_dir) (alc_pin_mode_dir_info[_dir][0])
652#define alc_pin_mode_max(_dir) (alc_pin_mode_dir_info[_dir][1])
653#define alc_pin_mode_n_items(_dir) \
654 (alc_pin_mode_max(_dir)-alc_pin_mode_min(_dir)+1)
655
656static int alc_pin_mode_info(struct snd_kcontrol *kcontrol,
657 struct snd_ctl_elem_info *uinfo)
658{
659 unsigned int item_num = uinfo->value.enumerated.item;
660 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
661
662 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
663 uinfo->count = 1;
664 uinfo->value.enumerated.items = alc_pin_mode_n_items(dir);
665
666 if (item_num<alc_pin_mode_min(dir) || item_num>alc_pin_mode_max(dir))
667 item_num = alc_pin_mode_min(dir);
668 strcpy(uinfo->value.enumerated.name, alc_pin_mode_names[item_num]);
669 return 0;
670}
671
672static int alc_pin_mode_get(struct snd_kcontrol *kcontrol,
673 struct snd_ctl_elem_value *ucontrol)
674{
675 unsigned int i;
676 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
677 hda_nid_t nid = kcontrol->private_value & 0xffff;
678 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
679 long *valp = ucontrol->value.integer.value;
680 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
681 AC_VERB_GET_PIN_WIDGET_CONTROL,
682 0x00);
683
684 /* Find enumerated value for current pinctl setting */
685 i = alc_pin_mode_min(dir);
686 while (i <= alc_pin_mode_max(dir) && alc_pin_mode_values[i] != pinctl)
687 i++;
688 *valp = i <= alc_pin_mode_max(dir) ? i: alc_pin_mode_min(dir);
689 return 0;
690}
691
692static int alc_pin_mode_put(struct snd_kcontrol *kcontrol,
693 struct snd_ctl_elem_value *ucontrol)
694{
695 signed int change;
696 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
697 hda_nid_t nid = kcontrol->private_value & 0xffff;
698 unsigned char dir = (kcontrol->private_value >> 16) & 0xff;
699 long val = *ucontrol->value.integer.value;
700 unsigned int pinctl = snd_hda_codec_read(codec, nid, 0,
701 AC_VERB_GET_PIN_WIDGET_CONTROL,
702 0x00);
703
704 if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir))
705 val = alc_pin_mode_min(dir);
706
707 change = pinctl != alc_pin_mode_values[val];
708 if (change) {
709 /* Set pin mode to that requested */
710 snd_hda_codec_write_cache(codec, nid, 0,
711 AC_VERB_SET_PIN_WIDGET_CONTROL,
712 alc_pin_mode_values[val]);
713
714 /* Also enable the retasking pin's input/output as required
715 * for the requested pin mode. Enum values of 2 or less are
716 * input modes.
717 *
718 * Dynamically switching the input/output buffers probably
719 * reduces noise slightly (particularly on input) so we'll
720 * do it. However, having both input and output buffers
721 * enabled simultaneously doesn't seem to be problematic if
722 * this turns out to be necessary in the future.
723 */
724 if (val <= 2) {
725 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
726 HDA_AMP_MUTE, HDA_AMP_MUTE);
727 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
728 HDA_AMP_MUTE, 0);
729 } else {
730 snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0,
731 HDA_AMP_MUTE, HDA_AMP_MUTE);
732 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
733 HDA_AMP_MUTE, 0);
734 }
735 }
736 return change;
737}
738
739#define ALC_PIN_MODE(xname, nid, dir) \
740 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
741 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
742 .info = alc_pin_mode_info, \
743 .get = alc_pin_mode_get, \
744 .put = alc_pin_mode_put, \
745 .private_value = nid | (dir<<16) }
746
747/* A switch control for ALC260 GPIO pins. Multiple GPIOs can be ganged
748 * together using a mask with more than one bit set. This control is
749 * currently used only by the ALC260 test model. At this stage they are not
750 * needed for any "production" models.
751 */
752#ifdef CONFIG_SND_DEBUG
753#define alc_gpio_data_info snd_ctl_boolean_mono_info
754
755static int alc_gpio_data_get(struct snd_kcontrol *kcontrol,
756 struct snd_ctl_elem_value *ucontrol)
757{
758 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
759 hda_nid_t nid = kcontrol->private_value & 0xffff;
760 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
761 long *valp = ucontrol->value.integer.value;
762 unsigned int val = snd_hda_codec_read(codec, nid, 0,
763 AC_VERB_GET_GPIO_DATA, 0x00);
764
765 *valp = (val & mask) != 0;
766 return 0;
767}
768static int alc_gpio_data_put(struct snd_kcontrol *kcontrol,
769 struct snd_ctl_elem_value *ucontrol)
770{
771 signed int change;
772 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
773 hda_nid_t nid = kcontrol->private_value & 0xffff;
774 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
775 long val = *ucontrol->value.integer.value;
776 unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0,
777 AC_VERB_GET_GPIO_DATA,
778 0x00);
779
780 /* Set/unset the masked GPIO bit(s) as needed */
781 change = (val == 0 ? 0 : mask) != (gpio_data & mask);
782 if (val == 0)
783 gpio_data &= ~mask;
784 else
785 gpio_data |= mask;
786 snd_hda_codec_write_cache(codec, nid, 0,
787 AC_VERB_SET_GPIO_DATA, gpio_data);
788
789 return change;
790}
791#define ALC_GPIO_DATA_SWITCH(xname, nid, mask) \
792 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
793 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
794 .info = alc_gpio_data_info, \
795 .get = alc_gpio_data_get, \
796 .put = alc_gpio_data_put, \
797 .private_value = nid | (mask<<16) }
798#endif /* CONFIG_SND_DEBUG */
799
800/* A switch control to allow the enabling of the digital IO pins on the
801 * ALC260. This is incredibly simplistic; the intention of this control is
802 * to provide something in the test model allowing digital outputs to be
803 * identified if present. If models are found which can utilise these
804 * outputs a more complete mixer control can be devised for those models if
805 * necessary.
806 */
807#ifdef CONFIG_SND_DEBUG
808#define alc_spdif_ctrl_info snd_ctl_boolean_mono_info
809
810static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol,
811 struct snd_ctl_elem_value *ucontrol)
812{
813 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
814 hda_nid_t nid = kcontrol->private_value & 0xffff;
815 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
816 long *valp = ucontrol->value.integer.value;
817 unsigned int val = snd_hda_codec_read(codec, nid, 0,
818 AC_VERB_GET_DIGI_CONVERT_1, 0x00);
819
820 *valp = (val & mask) != 0;
821 return 0;
822}
823static int alc_spdif_ctrl_put(struct snd_kcontrol *kcontrol,
824 struct snd_ctl_elem_value *ucontrol)
825{
826 signed int change;
827 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
828 hda_nid_t nid = kcontrol->private_value & 0xffff;
829 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
830 long val = *ucontrol->value.integer.value;
831 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
832 AC_VERB_GET_DIGI_CONVERT_1,
833 0x00);
834
835 /* Set/unset the masked control bit(s) as needed */
836 change = (val == 0 ? 0 : mask) != (ctrl_data & mask);
837 if (val==0)
838 ctrl_data &= ~mask;
839 else
840 ctrl_data |= mask;
841 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1,
842 ctrl_data);
843
844 return change;
845}
846#define ALC_SPDIF_CTRL_SWITCH(xname, nid, mask) \
847 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
848 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
849 .info = alc_spdif_ctrl_info, \
850 .get = alc_spdif_ctrl_get, \
851 .put = alc_spdif_ctrl_put, \
852 .private_value = nid | (mask<<16) }
853#endif /* CONFIG_SND_DEBUG */
854
855/* A switch control to allow the enabling EAPD digital outputs on the ALC26x.
856 * Again, this is only used in the ALC26x test models to help identify when
857 * the EAPD line must be asserted for features to work.
858 */
859#ifdef CONFIG_SND_DEBUG
860#define alc_eapd_ctrl_info snd_ctl_boolean_mono_info
861
862static int alc_eapd_ctrl_get(struct snd_kcontrol *kcontrol,
863 struct snd_ctl_elem_value *ucontrol)
864{
865 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
866 hda_nid_t nid = kcontrol->private_value & 0xffff;
867 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
868 long *valp = ucontrol->value.integer.value;
869 unsigned int val = snd_hda_codec_read(codec, nid, 0,
870 AC_VERB_GET_EAPD_BTLENABLE, 0x00);
871
872 *valp = (val & mask) != 0;
873 return 0;
874}
875
876static int alc_eapd_ctrl_put(struct snd_kcontrol *kcontrol,
877 struct snd_ctl_elem_value *ucontrol)
878{
879 int change;
880 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
881 hda_nid_t nid = kcontrol->private_value & 0xffff;
882 unsigned char mask = (kcontrol->private_value >> 16) & 0xff;
883 long val = *ucontrol->value.integer.value;
884 unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0,
885 AC_VERB_GET_EAPD_BTLENABLE,
886 0x00);
887
888 /* Set/unset the masked control bit(s) as needed */
889 change = (!val ? 0 : mask) != (ctrl_data & mask);
890 if (!val)
891 ctrl_data &= ~mask;
892 else
893 ctrl_data |= mask;
894 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_EAPD_BTLENABLE,
895 ctrl_data);
896
897 return change;
898}
899
900#define ALC_EAPD_CTRL_SWITCH(xname, nid, mask) \
901 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
902 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
903 .info = alc_eapd_ctrl_info, \
904 .get = alc_eapd_ctrl_get, \
905 .put = alc_eapd_ctrl_put, \
906 .private_value = nid | (mask<<16) }
907#endif /* CONFIG_SND_DEBUG */
908
909/*
910 * set up the input pin config (depending on the given auto-pin type) 314 * set up the input pin config (depending on the given auto-pin type)
911 */ 315 */
912static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid, 316static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
@@ -934,29 +338,10 @@ static void alc_set_input_pin(struct hda_codec *codec, hda_nid_t nid,
934 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val); 338 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, val);
935} 339}
936 340
937static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec)
938{
939 struct alc_spec *spec = codec->spec;
940 struct auto_pin_cfg *cfg = &spec->autocfg;
941
942 if (!cfg->line_outs) {
943 while (cfg->line_outs < AUTO_CFG_MAX_OUTS &&
944 cfg->line_out_pins[cfg->line_outs])
945 cfg->line_outs++;
946 }
947 if (!cfg->speaker_outs) {
948 while (cfg->speaker_outs < AUTO_CFG_MAX_OUTS &&
949 cfg->speaker_pins[cfg->speaker_outs])
950 cfg->speaker_outs++;
951 }
952 if (!cfg->hp_outs) {
953 while (cfg->hp_outs < AUTO_CFG_MAX_OUTS &&
954 cfg->hp_pins[cfg->hp_outs])
955 cfg->hp_outs++;
956 }
957}
958
959/* 341/*
342 * Append the given mixer and verb elements for the later use
343 * The mixer array is referred in build_controls(), and init_verbs are
344 * called in init().
960 */ 345 */
961static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix) 346static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix)
962{ 347{
@@ -973,61 +358,8 @@ static void add_verb(struct alc_spec *spec, const struct hda_verb *verb)
973} 358}
974 359
975/* 360/*
976 * set up from the preset table 361 * GPIO setup tables, used in initialization
977 */ 362 */
978static void setup_preset(struct hda_codec *codec,
979 const struct alc_config_preset *preset)
980{
981 struct alc_spec *spec = codec->spec;
982 int i;
983
984 for (i = 0; i < ARRAY_SIZE(preset->mixers) && preset->mixers[i]; i++)
985 add_mixer(spec, preset->mixers[i]);
986 spec->cap_mixer = preset->cap_mixer;
987 for (i = 0; i < ARRAY_SIZE(preset->init_verbs) && preset->init_verbs[i];
988 i++)
989 add_verb(spec, preset->init_verbs[i]);
990
991 spec->channel_mode = preset->channel_mode;
992 spec->num_channel_mode = preset->num_channel_mode;
993 spec->need_dac_fix = preset->need_dac_fix;
994 spec->const_channel_count = preset->const_channel_count;
995
996 if (preset->const_channel_count)
997 spec->multiout.max_channels = preset->const_channel_count;
998 else
999 spec->multiout.max_channels = spec->channel_mode[0].channels;
1000 spec->ext_channel_count = spec->channel_mode[0].channels;
1001
1002 spec->multiout.num_dacs = preset->num_dacs;
1003 spec->multiout.dac_nids = preset->dac_nids;
1004 spec->multiout.dig_out_nid = preset->dig_out_nid;
1005 spec->multiout.slave_dig_outs = preset->slave_dig_outs;
1006 spec->multiout.hp_nid = preset->hp_nid;
1007
1008 spec->num_mux_defs = preset->num_mux_defs;
1009 if (!spec->num_mux_defs)
1010 spec->num_mux_defs = 1;
1011 spec->input_mux = preset->input_mux;
1012
1013 spec->num_adc_nids = preset->num_adc_nids;
1014 spec->adc_nids = preset->adc_nids;
1015 spec->capsrc_nids = preset->capsrc_nids;
1016 spec->dig_in_nid = preset->dig_in_nid;
1017
1018 spec->unsol_event = preset->unsol_event;
1019 spec->init_hook = preset->init_hook;
1020#ifdef CONFIG_SND_HDA_POWER_SAVE
1021 spec->power_hook = preset->power_hook;
1022 spec->loopback.amplist = preset->loopbacks;
1023#endif
1024
1025 if (preset->setup)
1026 preset->setup(codec);
1027
1028 alc_fixup_autocfg_pin_nums(codec);
1029}
1030
1031/* Enable GPIO mask and set output */ 363/* Enable GPIO mask and set output */
1032static const struct hda_verb alc_gpio1_init_verbs[] = { 364static const struct hda_verb alc_gpio1_init_verbs[] = {
1033 {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, 365 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
@@ -1082,6 +414,11 @@ static void alc_fix_pll_init(struct hda_codec *codec, hda_nid_t nid,
1082 alc_fix_pll(codec); 414 alc_fix_pll(codec);
1083} 415}
1084 416
417/*
418 * Jack-reporting via input-jack layer
419 */
420
421/* initialization of jacks; currently checks only a few known pins */
1085static int alc_init_jacks(struct hda_codec *codec) 422static int alc_init_jacks(struct hda_codec *codec)
1086{ 423{
1087#ifdef CONFIG_SND_HDA_INPUT_JACK 424#ifdef CONFIG_SND_HDA_INPUT_JACK
@@ -1117,7 +454,12 @@ static int alc_init_jacks(struct hda_codec *codec)
1117 return 0; 454 return 0;
1118} 455}
1119 456
1120static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) 457/*
458 * Jack detections for HP auto-mute and mic-switch
459 */
460
461/* check each pin in the given array; returns true if any of them is plugged */
462static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
1121{ 463{
1122 int i, present = 0; 464 int i, present = 0;
1123 465
@@ -1131,6 +473,7 @@ static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
1131 return present; 473 return present;
1132} 474}
1133 475
476/* standard HP/line-out auto-mute helper */
1134static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, 477static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
1135 bool mute, bool hp_out) 478 bool mute, bool hp_out)
1136{ 479{
@@ -1201,6 +544,7 @@ static void update_speakers(struct hda_codec *codec)
1201 spec->autocfg.line_out_pins, on, false); 544 spec->autocfg.line_out_pins, on, false);
1202} 545}
1203 546
547/* standard HP-automute helper */
1204static void alc_hp_automute(struct hda_codec *codec) 548static void alc_hp_automute(struct hda_codec *codec)
1205{ 549{
1206 struct alc_spec *spec = codec->spec; 550 struct alc_spec *spec = codec->spec;
@@ -1213,6 +557,7 @@ static void alc_hp_automute(struct hda_codec *codec)
1213 update_speakers(codec); 557 update_speakers(codec);
1214} 558}
1215 559
560/* standard line-out-automute helper */
1216static void alc_line_automute(struct hda_codec *codec) 561static void alc_line_automute(struct hda_codec *codec)
1217{ 562{
1218 struct alc_spec *spec = codec->spec; 563 struct alc_spec *spec = codec->spec;
@@ -1228,6 +573,7 @@ static void alc_line_automute(struct hda_codec *codec)
1228#define get_connection_index(codec, mux, nid) \ 573#define get_connection_index(codec, mux, nid) \
1229 snd_hda_get_conn_index(codec, mux, nid, 0) 574 snd_hda_get_conn_index(codec, mux, nid, 0)
1230 575
576/* standard mic auto-switch helper */
1231static void alc_mic_automute(struct hda_codec *codec) 577static void alc_mic_automute(struct hda_codec *codec)
1232{ 578{
1233 struct alc_spec *spec = codec->spec; 579 struct alc_spec *spec = codec->spec;
@@ -1261,18 +607,19 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res)
1261 else 607 else
1262 res >>= 26; 608 res >>= 26;
1263 switch (res) { 609 switch (res) {
1264 case ALC880_HP_EVENT: 610 case ALC_HP_EVENT:
1265 alc_hp_automute(codec); 611 alc_hp_automute(codec);
1266 break; 612 break;
1267 case ALC880_FRONT_EVENT: 613 case ALC_FRONT_EVENT:
1268 alc_line_automute(codec); 614 alc_line_automute(codec);
1269 break; 615 break;
1270 case ALC880_MIC_EVENT: 616 case ALC_MIC_EVENT:
1271 alc_mic_automute(codec); 617 alc_mic_automute(codec);
1272 break; 618 break;
1273 } 619 }
1274} 620}
1275 621
622/* call init functions of standard auto-mute helpers */
1276static void alc_inithook(struct hda_codec *codec) 623static void alc_inithook(struct hda_codec *codec)
1277{ 624{
1278 alc_hp_automute(codec); 625 alc_hp_automute(codec);
@@ -1298,6 +645,7 @@ static void alc888_coef_init(struct hda_codec *codec)
1298 AC_VERB_SET_PROC_COEF, 0x3030); 645 AC_VERB_SET_PROC_COEF, 0x3030);
1299} 646}
1300 647
648/* additional initialization for ALC889 variants */
1301static void alc889_coef_init(struct hda_codec *codec) 649static void alc889_coef_init(struct hda_codec *codec)
1302{ 650{
1303 unsigned int tmp; 651 unsigned int tmp;
@@ -1339,6 +687,7 @@ static void alc_eapd_shutup(struct hda_codec *codec)
1339 msleep(200); 687 msleep(200);
1340} 688}
1341 689
690/* generic EAPD initialization */
1342static void alc_auto_init_amp(struct hda_codec *codec, int type) 691static void alc_auto_init_amp(struct hda_codec *codec, int type)
1343{ 692{
1344 unsigned int tmp; 693 unsigned int tmp;
@@ -1398,6 +747,9 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type)
1398 } 747 }
1399} 748}
1400 749
750/*
751 * Auto-Mute mode mixer enum support
752 */
1401static int alc_automute_mode_info(struct snd_kcontrol *kcontrol, 753static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
1402 struct snd_ctl_elem_info *uinfo) 754 struct snd_ctl_elem_info *uinfo)
1403{ 755{
@@ -1484,7 +836,11 @@ static const struct snd_kcontrol_new alc_automute_mode_enum = {
1484 .put = alc_automute_mode_put, 836 .put = alc_automute_mode_put,
1485}; 837};
1486 838
1487static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec); 839static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
840{
841 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
842 return snd_array_new(&spec->kctls);
843}
1488 844
1489static int alc_add_automute_mode_enum(struct hda_codec *codec) 845static int alc_add_automute_mode_enum(struct hda_codec *codec)
1490{ 846{
@@ -1501,6 +857,10 @@ static int alc_add_automute_mode_enum(struct hda_codec *codec)
1501 return 0; 857 return 0;
1502} 858}
1503 859
860/*
861 * Check the availability of HP/line-out auto-mute;
862 * Set up appropriately if really supported
863 */
1504static void alc_init_auto_hp(struct hda_codec *codec) 864static void alc_init_auto_hp(struct hda_codec *codec)
1505{ 865{
1506 struct alc_spec *spec = codec->spec; 866 struct alc_spec *spec = codec->spec;
@@ -1539,7 +899,7 @@ static void alc_init_auto_hp(struct hda_codec *codec)
1539 nid); 899 nid);
1540 snd_hda_codec_write_cache(codec, nid, 0, 900 snd_hda_codec_write_cache(codec, nid, 0,
1541 AC_VERB_SET_UNSOLICITED_ENABLE, 901 AC_VERB_SET_UNSOLICITED_ENABLE,
1542 AC_USRSP_EN | ALC880_HP_EVENT); 902 AC_USRSP_EN | ALC_HP_EVENT);
1543 spec->automute = 1; 903 spec->automute = 1;
1544 spec->automute_mode = ALC_AUTOMUTE_PIN; 904 spec->automute_mode = ALC_AUTOMUTE_PIN;
1545 } 905 }
@@ -1554,7 +914,7 @@ static void alc_init_auto_hp(struct hda_codec *codec)
1554 "on NID 0x%x\n", nid); 914 "on NID 0x%x\n", nid);
1555 snd_hda_codec_write_cache(codec, nid, 0, 915 snd_hda_codec_write_cache(codec, nid, 0,
1556 AC_VERB_SET_UNSOLICITED_ENABLE, 916 AC_VERB_SET_UNSOLICITED_ENABLE,
1557 AC_USRSP_EN | ALC880_FRONT_EVENT); 917 AC_USRSP_EN | ALC_FRONT_EVENT);
1558 spec->detect_line = 1; 918 spec->detect_line = 1;
1559 } 919 }
1560 spec->automute_lines = spec->detect_line; 920 spec->automute_lines = spec->detect_line;
@@ -1567,6 +927,7 @@ static void alc_init_auto_hp(struct hda_codec *codec)
1567 } 927 }
1568} 928}
1569 929
930/* return the position of NID in the list, or -1 if not found */
1570static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) 931static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
1571{ 932{
1572 int i; 933 int i;
@@ -1576,7 +937,47 @@ static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
1576 return -1; 937 return -1;
1577} 938}
1578 939
1579static bool alc_check_dyn_adc_switch(struct hda_codec *codec); 940/* check whether dynamic ADC-switching is available */
941static bool alc_check_dyn_adc_switch(struct hda_codec *codec)
942{
943 struct alc_spec *spec = codec->spec;
944 struct hda_input_mux *imux = &spec->private_imux[0];
945 int i, n, idx;
946 hda_nid_t cap, pin;
947
948 if (imux != spec->input_mux) /* no dynamic imux? */
949 return false;
950
951 for (n = 0; n < spec->num_adc_nids; n++) {
952 cap = spec->private_capsrc_nids[n];
953 for (i = 0; i < imux->num_items; i++) {
954 pin = spec->imux_pins[i];
955 if (!pin)
956 return false;
957 if (get_connection_index(codec, cap, pin) < 0)
958 break;
959 }
960 if (i >= imux->num_items)
961 return false; /* no ADC-switch is needed */
962 }
963
964 for (i = 0; i < imux->num_items; i++) {
965 pin = spec->imux_pins[i];
966 for (n = 0; n < spec->num_adc_nids; n++) {
967 cap = spec->private_capsrc_nids[n];
968 idx = get_connection_index(codec, cap, pin);
969 if (idx >= 0) {
970 imux->items[i].index = idx;
971 spec->dyn_adc_idx[i] = n;
972 break;
973 }
974 }
975 }
976
977 snd_printdd("realtek: enabling ADC switching\n");
978 spec->dyn_adc_switch = 1;
979 return true;
980}
1580 981
1581/* rebuild imux for matching with the given auto-mic pins (if not yet) */ 982/* rebuild imux for matching with the given auto-mic pins (if not yet) */
1582static bool alc_rebuild_imux_for_auto_mic(struct hda_codec *codec) 983static bool alc_rebuild_imux_for_auto_mic(struct hda_codec *codec)
@@ -1637,17 +1038,21 @@ static bool alc_auto_mic_check_imux(struct hda_codec *codec)
1637 1038
1638 snd_hda_codec_write_cache(codec, spec->ext_mic_pin, 0, 1039 snd_hda_codec_write_cache(codec, spec->ext_mic_pin, 0,
1639 AC_VERB_SET_UNSOLICITED_ENABLE, 1040 AC_VERB_SET_UNSOLICITED_ENABLE,
1640 AC_USRSP_EN | ALC880_MIC_EVENT); 1041 AC_USRSP_EN | ALC_MIC_EVENT);
1641 if (spec->dock_mic_pin) 1042 if (spec->dock_mic_pin)
1642 snd_hda_codec_write_cache(codec, spec->dock_mic_pin, 0, 1043 snd_hda_codec_write_cache(codec, spec->dock_mic_pin, 0,
1643 AC_VERB_SET_UNSOLICITED_ENABLE, 1044 AC_VERB_SET_UNSOLICITED_ENABLE,
1644 AC_USRSP_EN | ALC880_MIC_EVENT); 1045 AC_USRSP_EN | ALC_MIC_EVENT);
1645 1046
1646 spec->auto_mic_valid_imux = 1; 1047 spec->auto_mic_valid_imux = 1;
1647 spec->auto_mic = 1; 1048 spec->auto_mic = 1;
1648 return true; 1049 return true;
1649} 1050}
1650 1051
1052/*
1053 * Check the availability of auto-mic switch;
1054 * Set up if really supported
1055 */
1651static void alc_init_auto_mic(struct hda_codec *codec) 1056static void alc_init_auto_mic(struct hda_codec *codec)
1652{ 1057{
1653 struct alc_spec *spec = codec->spec; 1058 struct alc_spec *spec = codec->spec;
@@ -1713,6 +1118,17 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1713 spec->unsol_event = alc_sku_unsol_event; 1118 spec->unsol_event = alc_sku_unsol_event;
1714} 1119}
1715 1120
1121/* check the availabilities of auto-mute and auto-mic switches */
1122static void alc_auto_check_switches(struct hda_codec *codec)
1123{
1124 alc_init_auto_hp(codec);
1125 alc_init_auto_mic(codec);
1126}
1127
1128/*
1129 * Realtek SSID verification
1130 */
1131
1716/* Could be any non-zero and even value. When used as fixup, tells 1132/* Could be any non-zero and even value. When used as fixup, tells
1717 * the driver to ignore any present sku defines. 1133 * the driver to ignore any present sku defines.
1718 */ 1134 */
@@ -1783,6 +1199,7 @@ do_sku:
1783 return 0; 1199 return 0;
1784} 1200}
1785 1201
1202/* return true if the given NID is found in the list */
1786static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums) 1203static bool found_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
1787{ 1204{
1788 return find_idx_in_nid_list(nid, list, nums) >= 0; 1205 return find_idx_in_nid_list(nid, list, nums) >= 0;
@@ -1917,13 +1334,6 @@ static void alc_ssid_check(struct hda_codec *codec,
1917 } 1334 }
1918} 1335}
1919 1336
1920/* check the availabilities of auto-mute and auto-mic switches */
1921static void alc_auto_check_switches(struct hda_codec *codec)
1922{
1923 alc_init_auto_hp(codec);
1924 alc_init_auto_mic(codec);
1925}
1926
1927/* 1337/*
1928 * Fix-up pin default configurations and add default verbs 1338 * Fix-up pin default configurations and add default verbs
1929 */ 1339 */
@@ -2069,6 +1479,9 @@ static void alc_pick_fixup(struct hda_codec *codec,
2069 } 1479 }
2070} 1480}
2071 1481
1482/*
1483 * COEF access helper functions
1484 */
2072static int alc_read_coef_idx(struct hda_codec *codec, 1485static int alc_read_coef_idx(struct hda_codec *codec,
2073 unsigned int coef_idx) 1486 unsigned int coef_idx)
2074{ 1487{
@@ -2089,6 +1502,10 @@ static void alc_write_coef_idx(struct hda_codec *codec, unsigned int coef_idx,
2089 coef_val); 1502 coef_val);
2090} 1503}
2091 1504
1505/*
1506 * Digital I/O handling
1507 */
1508
2092/* set right pin controls for digital I/O */ 1509/* set right pin controls for digital I/O */
2093static void alc_auto_init_digital(struct hda_codec *codec) 1510static void alc_auto_init_digital(struct hda_codec *codec)
2094{ 1511{
@@ -2167,562 +1584,8 @@ static void alc_auto_parse_digital(struct hda_codec *codec)
2167} 1584}
2168 1585
2169/* 1586/*
2170 * ALC888 1587 * capture mixer elements
2171 */
2172
2173/*
2174 * 2ch mode
2175 */
2176static const struct hda_verb alc888_4ST_ch2_intel_init[] = {
2177/* Mic-in jack as mic in */
2178 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2179 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2180/* Line-in jack as Line in */
2181 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2182 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2183/* Line-Out as Front */
2184 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2185 { } /* end */
2186};
2187
2188/*
2189 * 4ch mode
2190 */
2191static const struct hda_verb alc888_4ST_ch4_intel_init[] = {
2192/* Mic-in jack as mic in */
2193 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2194 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2195/* Line-in jack as Surround */
2196 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2197 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2198/* Line-Out as Front */
2199 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00},
2200 { } /* end */
2201};
2202
2203/*
2204 * 6ch mode
2205 */
2206static const struct hda_verb alc888_4ST_ch6_intel_init[] = {
2207/* Mic-in jack as CLFE */
2208 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2209 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2210/* Line-in jack as Surround */
2211 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2212 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2213/* Line-Out as CLFE (workaround because Mic-in is not loud enough) */
2214 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2215 { } /* end */
2216};
2217
2218/*
2219 * 8ch mode
2220 */
2221static const struct hda_verb alc888_4ST_ch8_intel_init[] = {
2222/* Mic-in jack as CLFE */
2223 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2224 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2225/* Line-in jack as Surround */
2226 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2227 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2228/* Line-Out as Side */
2229 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2230 { } /* end */
2231};
2232
2233static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = {
2234 { 2, alc888_4ST_ch2_intel_init },
2235 { 4, alc888_4ST_ch4_intel_init },
2236 { 6, alc888_4ST_ch6_intel_init },
2237 { 8, alc888_4ST_ch8_intel_init },
2238};
2239
2240/*
2241 * ALC888 Fujitsu Siemens Amillo xa3530
2242 */
2243
2244static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = {
2245/* Front Mic: set to PIN_IN (empty by default) */
2246 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2247/* Connect Internal HP to Front */
2248 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2249 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2250 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2251/* Connect Bass HP to Front */
2252 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2253 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2254 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2255/* Connect Line-Out side jack (SPDIF) to Side */
2256 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2257 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2258 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
2259/* Connect Mic jack to CLFE */
2260 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2261 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2262 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
2263/* Connect Line-in jack to Surround */
2264 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2265 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2266 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
2267/* Connect HP out jack to Front */
2268 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2269 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2270 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
2271/* Enable unsolicited event for HP jack and Line-out jack */
2272 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2273 {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2274 {}
2275};
2276
2277static void alc889_automute_setup(struct hda_codec *codec)
2278{
2279 struct alc_spec *spec = codec->spec;
2280
2281 spec->autocfg.hp_pins[0] = 0x15;
2282 spec->autocfg.speaker_pins[0] = 0x14;
2283 spec->autocfg.speaker_pins[1] = 0x16;
2284 spec->autocfg.speaker_pins[2] = 0x17;
2285 spec->autocfg.speaker_pins[3] = 0x19;
2286 spec->autocfg.speaker_pins[4] = 0x1a;
2287 spec->automute = 1;
2288 spec->automute_mode = ALC_AUTOMUTE_AMP;
2289}
2290
2291static void alc889_intel_init_hook(struct hda_codec *codec)
2292{
2293 alc889_coef_init(codec);
2294 alc_hp_automute(codec);
2295}
2296
2297static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec)
2298{
2299 struct alc_spec *spec = codec->spec;
2300
2301 spec->autocfg.hp_pins[0] = 0x17; /* line-out */
2302 spec->autocfg.hp_pins[1] = 0x1b; /* hp */
2303 spec->autocfg.speaker_pins[0] = 0x14; /* speaker */
2304 spec->autocfg.speaker_pins[1] = 0x15; /* bass */
2305 spec->automute = 1;
2306 spec->automute_mode = ALC_AUTOMUTE_AMP;
2307}
2308
2309/*
2310 * ALC888 Acer Aspire 4930G model
2311 */
2312
2313static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = {
2314/* Front Mic: set to PIN_IN (empty by default) */
2315 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2316/* Unselect Front Mic by default in input mixer 3 */
2317 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2318/* Enable unsolicited event for HP jack */
2319 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2320/* Connect Internal HP to front */
2321 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2322 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2323 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2324/* Connect HP out to front */
2325 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2326 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2327 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2328 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2329 { }
2330};
2331
2332/*
2333 * ALC888 Acer Aspire 6530G model
2334 */
2335
2336static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = {
2337/* Route to built-in subwoofer as well as speakers */
2338 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2339 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2340 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2341 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
2342/* Bias voltage on for external mic port */
2343 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2344/* Front Mic: set to PIN_IN (empty by default) */
2345 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2346/* Unselect Front Mic by default in input mixer 3 */
2347 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2348/* Enable unsolicited event for HP jack */
2349 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2350/* Enable speaker output */
2351 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2352 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2353 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2354/* Enable headphone output */
2355 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2356 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2357 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2358 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2359 { }
2360};
2361
2362/*
2363 *ALC888 Acer Aspire 7730G model
2364 */
2365
2366static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = {
2367/* Bias voltage on for external mic port */
2368 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80},
2369/* Front Mic: set to PIN_IN (empty by default) */
2370 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2371/* Unselect Front Mic by default in input mixer 3 */
2372 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2373/* Enable unsolicited event for HP jack */
2374 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2375/* Enable speaker output */
2376 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2377 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2378 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
2379/* Enable headphone output */
2380 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2381 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2382 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2383 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
2384/*Enable internal subwoofer */
2385 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2386 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2387 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
2388 {0x17, AC_VERB_SET_EAPD_BTLENABLE, 2},
2389 { }
2390};
2391
2392/*
2393 * ALC889 Acer Aspire 8930G model
2394 */
2395
2396static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = {
2397/* Front Mic: set to PIN_IN (empty by default) */
2398 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2399/* Unselect Front Mic by default in input mixer 3 */
2400 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0xb)},
2401/* Enable unsolicited event for HP jack */
2402 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
2403/* Connect Internal Front to Front */
2404 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2405 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2406 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
2407/* Connect Internal Rear to Rear */
2408 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2409 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2410 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
2411/* Connect Internal CLFE to CLFE */
2412 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2413 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2414 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
2415/* Connect HP out to Front */
2416 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP},
2417 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2418 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
2419/* Enable all DACs */
2420/* DAC DISABLE/MUTE 1? */
2421/* setting bits 1-5 disables DAC nids 0x02-0x06 apparently. Init=0x38 */
2422 {0x20, AC_VERB_SET_COEF_INDEX, 0x03},
2423 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2424/* DAC DISABLE/MUTE 2? */
2425/* some bit here disables the other DACs. Init=0x4900 */
2426 {0x20, AC_VERB_SET_COEF_INDEX, 0x08},
2427 {0x20, AC_VERB_SET_PROC_COEF, 0x0000},
2428/* DMIC fix
2429 * This laptop has a stereo digital microphone. The mics are only 1cm apart
2430 * which makes the stereo useless. However, either the mic or the ALC889
2431 * makes the signal become a difference/sum signal instead of standard
2432 * stereo, which is annoying. So instead we flip this bit which makes the
2433 * codec replicate the sum signal to both channels, turning it into a
2434 * normal mono mic.
2435 */
2436/* DMIC_CONTROL? Init value = 0x0001 */
2437 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
2438 {0x20, AC_VERB_SET_PROC_COEF, 0x0003},
2439 { }
2440};
2441
2442static const struct hda_input_mux alc888_2_capture_sources[2] = {
2443 /* Front mic only available on one ADC */
2444 {
2445 .num_items = 4,
2446 .items = {
2447 { "Mic", 0x0 },
2448 { "Line", 0x2 },
2449 { "CD", 0x4 },
2450 { "Front Mic", 0xb },
2451 },
2452 },
2453 {
2454 .num_items = 3,
2455 .items = {
2456 { "Mic", 0x0 },
2457 { "Line", 0x2 },
2458 { "CD", 0x4 },
2459 },
2460 }
2461};
2462
2463static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = {
2464 /* Interal mic only available on one ADC */
2465 {
2466 .num_items = 5,
2467 .items = {
2468 { "Mic", 0x0 },
2469 { "Line In", 0x2 },
2470 { "CD", 0x4 },
2471 { "Input Mix", 0xa },
2472 { "Internal Mic", 0xb },
2473 },
2474 },
2475 {
2476 .num_items = 4,
2477 .items = {
2478 { "Mic", 0x0 },
2479 { "Line In", 0x2 },
2480 { "CD", 0x4 },
2481 { "Input Mix", 0xa },
2482 },
2483 }
2484};
2485
2486static const struct hda_input_mux alc889_capture_sources[3] = {
2487 /* Digital mic only available on first "ADC" */
2488 {
2489 .num_items = 5,
2490 .items = {
2491 { "Mic", 0x0 },
2492 { "Line", 0x2 },
2493 { "CD", 0x4 },
2494 { "Front Mic", 0xb },
2495 { "Input Mix", 0xa },
2496 },
2497 },
2498 {
2499 .num_items = 4,
2500 .items = {
2501 { "Mic", 0x0 },
2502 { "Line", 0x2 },
2503 { "CD", 0x4 },
2504 { "Input Mix", 0xa },
2505 },
2506 },
2507 {
2508 .num_items = 4,
2509 .items = {
2510 { "Mic", 0x0 },
2511 { "Line", 0x2 },
2512 { "CD", 0x4 },
2513 { "Input Mix", 0xa },
2514 },
2515 }
2516};
2517
2518static const struct snd_kcontrol_new alc888_base_mixer[] = {
2519 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2520 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2521 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2522 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2523 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2524 HDA_OUTPUT),
2525 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2526 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2527 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2528 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2529 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2530 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2531 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2532 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2533 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2534 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2535 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2536 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2537 { } /* end */
2538};
2539
2540static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = {
2541 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2542 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2543 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2544 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2545 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2546 HDA_OUTPUT),
2547 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2548 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2549 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2550 HDA_CODEC_VOLUME_MONO("Internal LFE Playback Volume", 0x0f, 1, 0x0, HDA_OUTPUT),
2551 HDA_BIND_MUTE_MONO("Internal LFE Playback Switch", 0x0f, 1, 2, HDA_INPUT),
2552 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2553 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2554 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2555 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2556 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2557 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2558 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2559 { } /* end */
2560};
2561
2562static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = {
2563 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2564 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2565 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2566 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2567 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
2568 HDA_OUTPUT),
2569 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2570 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2571 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2572 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2573 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2574 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2575 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
2576 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2577 { } /* end */
2578};
2579
2580
2581static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec)
2582{
2583 struct alc_spec *spec = codec->spec;
2584
2585 spec->autocfg.hp_pins[0] = 0x15;
2586 spec->autocfg.speaker_pins[0] = 0x14;
2587 spec->autocfg.speaker_pins[1] = 0x16;
2588 spec->autocfg.speaker_pins[2] = 0x17;
2589 spec->automute = 1;
2590 spec->automute_mode = ALC_AUTOMUTE_AMP;
2591}
2592
2593static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec)
2594{
2595 struct alc_spec *spec = codec->spec;
2596
2597 spec->autocfg.hp_pins[0] = 0x15;
2598 spec->autocfg.speaker_pins[0] = 0x14;
2599 spec->autocfg.speaker_pins[1] = 0x16;
2600 spec->autocfg.speaker_pins[2] = 0x17;
2601 spec->automute = 1;
2602 spec->automute_mode = ALC_AUTOMUTE_AMP;
2603}
2604
2605static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec)
2606{
2607 struct alc_spec *spec = codec->spec;
2608
2609 spec->autocfg.hp_pins[0] = 0x15;
2610 spec->autocfg.speaker_pins[0] = 0x14;
2611 spec->autocfg.speaker_pins[1] = 0x16;
2612 spec->autocfg.speaker_pins[2] = 0x17;
2613 spec->automute = 1;
2614 spec->automute_mode = ALC_AUTOMUTE_AMP;
2615}
2616
2617static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec)
2618{
2619 struct alc_spec *spec = codec->spec;
2620
2621 spec->autocfg.hp_pins[0] = 0x15;
2622 spec->autocfg.speaker_pins[0] = 0x14;
2623 spec->autocfg.speaker_pins[1] = 0x16;
2624 spec->autocfg.speaker_pins[2] = 0x1b;
2625 spec->automute = 1;
2626 spec->automute_mode = ALC_AUTOMUTE_AMP;
2627}
2628
2629/*
2630 * ALC880 3-stack model
2631 *
2632 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0e)
2633 * Pin assignment: Front = 0x14, Line-In/Surr = 0x1a, Mic/CLFE = 0x18,
2634 * F-Mic = 0x1b, HP = 0x19
2635 */ 1588 */
2636
2637static const hda_nid_t alc880_dac_nids[4] = {
2638 /* front, rear, clfe, rear_surr */
2639 0x02, 0x05, 0x04, 0x03
2640};
2641
2642static const hda_nid_t alc880_adc_nids[3] = {
2643 /* ADC0-2 */
2644 0x07, 0x08, 0x09,
2645};
2646
2647/* The datasheet says the node 0x07 is connected from inputs,
2648 * but it shows zero connection in the real implementation on some devices.
2649 * Note: this is a 915GAV bug, fixed on 915GLV
2650 */
2651static const hda_nid_t alc880_adc_nids_alt[2] = {
2652 /* ADC1-2 */
2653 0x08, 0x09,
2654};
2655
2656#define ALC880_DIGOUT_NID 0x06
2657#define ALC880_DIGIN_NID 0x0a
2658
2659static const struct hda_input_mux alc880_capture_source = {
2660 .num_items = 4,
2661 .items = {
2662 { "Mic", 0x0 },
2663 { "Front Mic", 0x3 },
2664 { "Line", 0x2 },
2665 { "CD", 0x4 },
2666 },
2667};
2668
2669/* channel source setting (2/6 channel selection for 3-stack) */
2670/* 2ch mode */
2671static const struct hda_verb alc880_threestack_ch2_init[] = {
2672 /* set line-in to input, mute it */
2673 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2674 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2675 /* set mic-in to input vref 80%, mute it */
2676 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2677 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2678 { } /* end */
2679};
2680
2681/* 6ch mode */
2682static const struct hda_verb alc880_threestack_ch6_init[] = {
2683 /* set line-in to output, unmute it */
2684 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2685 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2686 /* set mic-in to output, unmute it */
2687 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2688 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2689 { } /* end */
2690};
2691
2692static const struct hda_channel_mode alc880_threestack_modes[2] = {
2693 { 2, alc880_threestack_ch2_init },
2694 { 6, alc880_threestack_ch6_init },
2695};
2696
2697static const struct snd_kcontrol_new alc880_three_stack_mixer[] = {
2698 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2699 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2700 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2701 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
2702 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2703 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2704 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2705 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2706 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2707 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2708 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2709 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2710 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2711 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2712 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
2713 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
2714 HDA_CODEC_MUTE("Headphone Playback Switch", 0x19, 0x0, HDA_OUTPUT),
2715 {
2716 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2717 .name = "Channel Mode",
2718 .info = alc_ch_mode_info,
2719 .get = alc_ch_mode_get,
2720 .put = alc_ch_mode_put,
2721 },
2722 { } /* end */
2723};
2724
2725/* capture mixer elements */
2726static int alc_cap_vol_info(struct snd_kcontrol *kcontrol, 1589static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
2727 struct snd_ctl_elem_info *uinfo) 1590 struct snd_ctl_elem_info *uinfo)
2728{ 1591{
@@ -2886,335 +1749,6 @@ DEFINE_CAPMIX_NOSRC(2);
2886DEFINE_CAPMIX_NOSRC(3); 1749DEFINE_CAPMIX_NOSRC(3);
2887 1750
2888/* 1751/*
2889 * ALC880 5-stack model
2890 *
2891 * DAC: Front = 0x02 (0x0c), Surr = 0x05 (0x0f), CLFE = 0x04 (0x0d),
2892 * Side = 0x02 (0xd)
2893 * Pin assignment: Front = 0x14, Surr = 0x17, CLFE = 0x16
2894 * Line-In/Side = 0x1a, Mic = 0x18, F-Mic = 0x1b, HP = 0x19
2895 */
2896
2897/* additional mixers to alc880_three_stack_mixer */
2898static const struct snd_kcontrol_new alc880_five_stack_mixer[] = {
2899 HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2900 HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT),
2901 { } /* end */
2902};
2903
2904/* channel source setting (6/8 channel selection for 5-stack) */
2905/* 6ch mode */
2906static const struct hda_verb alc880_fivestack_ch6_init[] = {
2907 /* set line-in to input, mute it */
2908 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2909 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2910 { } /* end */
2911};
2912
2913/* 8ch mode */
2914static const struct hda_verb alc880_fivestack_ch8_init[] = {
2915 /* set line-in to output, unmute it */
2916 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2917 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2918 { } /* end */
2919};
2920
2921static const struct hda_channel_mode alc880_fivestack_modes[2] = {
2922 { 6, alc880_fivestack_ch6_init },
2923 { 8, alc880_fivestack_ch8_init },
2924};
2925
2926
2927/*
2928 * ALC880 6-stack model
2929 *
2930 * DAC: Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e),
2931 * Side = 0x05 (0x0f)
2932 * Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, Side = 0x17,
2933 * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b
2934 */
2935
2936static const hda_nid_t alc880_6st_dac_nids[4] = {
2937 /* front, rear, clfe, rear_surr */
2938 0x02, 0x03, 0x04, 0x05
2939};
2940
2941static const struct hda_input_mux alc880_6stack_capture_source = {
2942 .num_items = 4,
2943 .items = {
2944 { "Mic", 0x0 },
2945 { "Front Mic", 0x1 },
2946 { "Line", 0x2 },
2947 { "CD", 0x4 },
2948 },
2949};
2950
2951/* fixed 8-channels */
2952static const struct hda_channel_mode alc880_sixstack_modes[1] = {
2953 { 8, NULL },
2954};
2955
2956static const struct snd_kcontrol_new alc880_six_stack_mixer[] = {
2957 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
2958 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
2959 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
2960 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
2961 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
2962 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
2963 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
2964 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
2965 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
2966 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
2967 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
2968 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
2969 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
2970 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
2971 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
2972 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
2973 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
2974 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
2975 {
2976 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2977 .name = "Channel Mode",
2978 .info = alc_ch_mode_info,
2979 .get = alc_ch_mode_get,
2980 .put = alc_ch_mode_put,
2981 },
2982 { } /* end */
2983};
2984
2985
2986/*
2987 * ALC880 W810 model
2988 *
2989 * W810 has rear IO for:
2990 * Front (DAC 02)
2991 * Surround (DAC 03)
2992 * Center/LFE (DAC 04)
2993 * Digital out (06)
2994 *
2995 * The system also has a pair of internal speakers, and a headphone jack.
2996 * These are both connected to Line2 on the codec, hence to DAC 02.
2997 *
2998 * There is a variable resistor to control the speaker or headphone
2999 * volume. This is a hardware-only device without a software API.
3000 *
3001 * Plugging headphones in will disable the internal speakers. This is
3002 * implemented in hardware, not via the driver using jack sense. In
3003 * a similar fashion, plugging into the rear socket marked "front" will
3004 * disable both the speakers and headphones.
3005 *
3006 * For input, there's a microphone jack, and an "audio in" jack.
3007 * These may not do anything useful with this driver yet, because I
3008 * haven't setup any initialization verbs for these yet...
3009 */
3010
3011static const hda_nid_t alc880_w810_dac_nids[3] = {
3012 /* front, rear/surround, clfe */
3013 0x02, 0x03, 0x04
3014};
3015
3016/* fixed 6 channels */
3017static const struct hda_channel_mode alc880_w810_modes[1] = {
3018 { 6, NULL }
3019};
3020
3021/* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */
3022static const struct snd_kcontrol_new alc880_w810_base_mixer[] = {
3023 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3024 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3025 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3026 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3027 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3028 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3029 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3030 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3031 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3032 { } /* end */
3033};
3034
3035
3036/*
3037 * Z710V model
3038 *
3039 * DAC: Front = 0x02 (0x0c), HP = 0x03 (0x0d)
3040 * Pin assignment: Front = 0x14, HP = 0x15, Mic = 0x18, Mic2 = 0x19(?),
3041 * Line = 0x1a
3042 */
3043
3044static const hda_nid_t alc880_z71v_dac_nids[1] = {
3045 0x02
3046};
3047#define ALC880_Z71V_HP_DAC 0x03
3048
3049/* fixed 2 channels */
3050static const struct hda_channel_mode alc880_2_jack_modes[1] = {
3051 { 2, NULL }
3052};
3053
3054static const struct snd_kcontrol_new alc880_z71v_mixer[] = {
3055 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3056 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3057 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3058 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
3059 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3060 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3061 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3062 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3063 { } /* end */
3064};
3065
3066
3067/*
3068 * ALC880 F1734 model
3069 *
3070 * DAC: HP = 0x02 (0x0c), Front = 0x03 (0x0d)
3071 * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18
3072 */
3073
3074static const hda_nid_t alc880_f1734_dac_nids[1] = {
3075 0x03
3076};
3077#define ALC880_F1734_HP_DAC 0x02
3078
3079static const struct snd_kcontrol_new alc880_f1734_mixer[] = {
3080 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3081 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3082 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3083 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3084 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3085 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3086 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3087 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3088 { } /* end */
3089};
3090
3091static const struct hda_input_mux alc880_f1734_capture_source = {
3092 .num_items = 2,
3093 .items = {
3094 { "Mic", 0x1 },
3095 { "CD", 0x4 },
3096 },
3097};
3098
3099
3100/*
3101 * ALC880 ASUS model
3102 *
3103 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3104 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3105 * Mic = 0x18, Line = 0x1a
3106 */
3107
3108#define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */
3109#define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */
3110
3111static const struct snd_kcontrol_new alc880_asus_mixer[] = {
3112 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3113 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
3114 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3115 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
3116 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3117 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3118 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3119 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3120 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3121 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3122 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3123 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3124 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3125 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3126 {
3127 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3128 .name = "Channel Mode",
3129 .info = alc_ch_mode_info,
3130 .get = alc_ch_mode_get,
3131 .put = alc_ch_mode_put,
3132 },
3133 { } /* end */
3134};
3135
3136/*
3137 * ALC880 ASUS W1V model
3138 *
3139 * DAC: HP/Front = 0x02 (0x0c), Surr = 0x03 (0x0d), CLFE = 0x04 (0x0e)
3140 * Pin assignment: HP/Front = 0x14, Surr = 0x15, CLFE = 0x16,
3141 * Mic = 0x18, Line = 0x1a, Line2 = 0x1b
3142 */
3143
3144/* additional mixers to alc880_asus_mixer */
3145static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = {
3146 HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT),
3147 HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT),
3148 { } /* end */
3149};
3150
3151/* TCL S700 */
3152static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = {
3153 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3154 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
3155 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
3156 HDA_CODEC_VOLUME("CD Playback Volume", 0x0B, 0x04, HDA_INPUT),
3157 HDA_CODEC_MUTE("CD Playback Switch", 0x0B, 0x04, HDA_INPUT),
3158 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0B, 0x0, HDA_INPUT),
3159 HDA_CODEC_MUTE("Mic Playback Switch", 0x0B, 0x0, HDA_INPUT),
3160 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
3161 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
3162 { } /* end */
3163};
3164
3165/* Uniwill */
3166static const struct snd_kcontrol_new alc880_uniwill_mixer[] = {
3167 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3168 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3169 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3170 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3171 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
3172 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
3173 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
3174 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
3175 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3176 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3177 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
3178 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
3179 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3180 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3181 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3182 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3183 {
3184 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3185 .name = "Channel Mode",
3186 .info = alc_ch_mode_info,
3187 .get = alc_ch_mode_get,
3188 .put = alc_ch_mode_put,
3189 },
3190 { } /* end */
3191};
3192
3193static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = {
3194 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3195 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3196 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3197 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3198 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
3199 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
3200 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3201 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3202 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3203 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3204 { } /* end */
3205};
3206
3207static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = {
3208 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3209 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
3210 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
3211 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
3212 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
3213 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
3214 { } /* end */
3215};
3216
3217/*
3218 * virtual master controls 1752 * virtual master controls
3219 */ 1753 */
3220 1754
@@ -3425,789 +1959,6 @@ static int alc_build_controls(struct hda_codec *codec)
3425 1959
3426 1960
3427/* 1961/*
3428 * initialize the codec volumes, etc
3429 */
3430
3431/*
3432 * generic initialization of ADC, input mixers and output mixers
3433 */
3434static const struct hda_verb alc880_volume_init_verbs[] = {
3435 /*
3436 * Unmute ADC0-2 and set the default input to mic-in
3437 */
3438 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
3439 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3440 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
3441 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3442 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
3443 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3444
3445 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
3446 * mixer widget
3447 * Note: PASD motherboards uses the Line In 2 as the input for front
3448 * panel mic (mic 2)
3449 */
3450 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
3451 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3452 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3453 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3454 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3455 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3456 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3457 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3458
3459 /*
3460 * Set up output mixers (0x0c - 0x0f)
3461 */
3462 /* set vol=0 to output mixers */
3463 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3464 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3465 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3466 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3467 /* set up input amps for analog loopback */
3468 /* Amp Indices: DAC = 0, mixer = 1 */
3469 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3470 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3471 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3472 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3473 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3474 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3475 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3476 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3477
3478 { }
3479};
3480
3481/*
3482 * 3-stack pin configuration:
3483 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
3484 */
3485static const struct hda_verb alc880_pin_3stack_init_verbs[] = {
3486 /*
3487 * preset connection lists of input pins
3488 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3489 */
3490 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
3491 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3492 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
3493
3494 /*
3495 * Set pin mode and muting
3496 */
3497 /* set front pin widgets 0x14 for output */
3498 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3499 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3500 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3501 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3502 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3503 /* Mic2 (as headphone out) for HP output */
3504 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3505 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3506 /* Line In pin widget for input */
3507 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3508 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3509 /* Line2 (as front mic) pin widget for input and vref at 80% */
3510 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3511 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3512 /* CD pin widget for input */
3513 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3514
3515 { }
3516};
3517
3518/*
3519 * 5-stack pin configuration:
3520 * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19,
3521 * line-in/side = 0x1a, f-mic = 0x1b
3522 */
3523static const struct hda_verb alc880_pin_5stack_init_verbs[] = {
3524 /*
3525 * preset connection lists of input pins
3526 * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround
3527 */
3528 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3529 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/side */
3530
3531 /*
3532 * Set pin mode and muting
3533 */
3534 /* set pin widgets 0x14-0x17 for output */
3535 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3536 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3537 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3538 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3539 /* unmute pins for output (no gain on this amp) */
3540 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3541 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3542 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3543 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3544
3545 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3546 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3547 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3548 /* Mic2 (as headphone out) for HP output */
3549 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3550 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3551 /* Line In pin widget for input */
3552 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3553 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3554 /* Line2 (as front mic) pin widget for input and vref at 80% */
3555 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3556 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3557 /* CD pin widget for input */
3558 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3559
3560 { }
3561};
3562
3563/*
3564 * W810 pin configuration:
3565 * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b
3566 */
3567static const struct hda_verb alc880_pin_w810_init_verbs[] = {
3568 /* hphone/speaker input selector: front DAC */
3569 {0x13, AC_VERB_SET_CONNECT_SEL, 0x0},
3570
3571 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3572 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3573 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3574 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3575 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3576 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3577
3578 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3579 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3580
3581 { }
3582};
3583
3584/*
3585 * Z71V pin configuration:
3586 * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?)
3587 */
3588static const struct hda_verb alc880_pin_z71v_init_verbs[] = {
3589 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3590 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3591 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3592 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3593
3594 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3595 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3596 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3597 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3598
3599 { }
3600};
3601
3602/*
3603 * 6-stack pin configuration:
3604 * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18,
3605 * f-mic = 0x19, line = 0x1a, HP = 0x1b
3606 */
3607static const struct hda_verb alc880_pin_6stack_init_verbs[] = {
3608 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3609
3610 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3611 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3612 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3613 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3614 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3615 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3616 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3617 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3618
3619 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3620 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3621 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3622 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3623 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3624 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3625 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3626 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3627 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3628
3629 { }
3630};
3631
3632/*
3633 * Uniwill pin configuration:
3634 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19,
3635 * line = 0x1a
3636 */
3637static const struct hda_verb alc880_uniwill_init_verbs[] = {
3638 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3639
3640 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3641 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3642 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3643 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3644 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3645 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3646 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3647 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3648 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3649 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3650 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3651 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3652 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3653 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3654
3655 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3656 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3657 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3658 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3659 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3660 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3661 /* {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, */
3662 /* {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
3663 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3664
3665 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3666 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
3667
3668 { }
3669};
3670
3671/*
3672* Uniwill P53
3673* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19,
3674 */
3675static const struct hda_verb alc880_uniwill_p53_init_verbs[] = {
3676 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
3677
3678 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3679 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3680 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3681 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3682 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3683 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3684 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3685 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3686 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3687 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3688 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
3689 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
3690
3691 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3692 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3693 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3694 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3695 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3696 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3697
3698 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
3699 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_DCVOL_EVENT},
3700
3701 { }
3702};
3703
3704static const struct hda_verb alc880_beep_init_verbs[] = {
3705 { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) },
3706 { }
3707};
3708
3709/* auto-toggle front mic */
3710static void alc88x_simple_mic_automute(struct hda_codec *codec)
3711{
3712 unsigned int present;
3713 unsigned char bits;
3714
3715 present = snd_hda_jack_detect(codec, 0x18);
3716 bits = present ? HDA_AMP_MUTE : 0;
3717 snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits);
3718}
3719
3720static void alc880_uniwill_setup(struct hda_codec *codec)
3721{
3722 struct alc_spec *spec = codec->spec;
3723
3724 spec->autocfg.hp_pins[0] = 0x14;
3725 spec->autocfg.speaker_pins[0] = 0x15;
3726 spec->autocfg.speaker_pins[0] = 0x16;
3727 spec->automute = 1;
3728 spec->automute_mode = ALC_AUTOMUTE_AMP;
3729}
3730
3731static void alc880_uniwill_init_hook(struct hda_codec *codec)
3732{
3733 alc_hp_automute(codec);
3734 alc88x_simple_mic_automute(codec);
3735}
3736
3737static void alc880_uniwill_unsol_event(struct hda_codec *codec,
3738 unsigned int res)
3739{
3740 /* Looks like the unsol event is incompatible with the standard
3741 * definition. 4bit tag is placed at 28 bit!
3742 */
3743 switch (res >> 28) {
3744 case ALC880_MIC_EVENT:
3745 alc88x_simple_mic_automute(codec);
3746 break;
3747 default:
3748 alc_sku_unsol_event(codec, res);
3749 break;
3750 }
3751}
3752
3753static void alc880_uniwill_p53_setup(struct hda_codec *codec)
3754{
3755 struct alc_spec *spec = codec->spec;
3756
3757 spec->autocfg.hp_pins[0] = 0x14;
3758 spec->autocfg.speaker_pins[0] = 0x15;
3759 spec->automute = 1;
3760 spec->automute_mode = ALC_AUTOMUTE_AMP;
3761}
3762
3763static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec)
3764{
3765 unsigned int present;
3766
3767 present = snd_hda_codec_read(codec, 0x21, 0,
3768 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
3769 present &= HDA_AMP_VOLMASK;
3770 snd_hda_codec_amp_stereo(codec, 0x0c, HDA_OUTPUT, 0,
3771 HDA_AMP_VOLMASK, present);
3772 snd_hda_codec_amp_stereo(codec, 0x0d, HDA_OUTPUT, 0,
3773 HDA_AMP_VOLMASK, present);
3774}
3775
3776static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec,
3777 unsigned int res)
3778{
3779 /* Looks like the unsol event is incompatible with the standard
3780 * definition. 4bit tag is placed at 28 bit!
3781 */
3782 if ((res >> 28) == ALC880_DCVOL_EVENT)
3783 alc880_uniwill_p53_dcvol_automute(codec);
3784 else
3785 alc_sku_unsol_event(codec, res);
3786}
3787
3788/*
3789 * F1734 pin configuration:
3790 * HP = 0x14, speaker-out = 0x15, mic = 0x18
3791 */
3792static const struct hda_verb alc880_pin_f1734_init_verbs[] = {
3793 {0x07, AC_VERB_SET_CONNECT_SEL, 0x01},
3794 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3795 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3796 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3797 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3798
3799 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3800 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3801 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3802 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3803
3804 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3805 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3806 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
3807 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3808 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3809 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3810 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3811 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3812 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3813
3814 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
3815 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_DCVOL_EVENT},
3816
3817 { }
3818};
3819
3820/*
3821 * ASUS pin configuration:
3822 * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a
3823 */
3824static const struct hda_verb alc880_pin_asus_init_verbs[] = {
3825 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02},
3826 {0x11, AC_VERB_SET_CONNECT_SEL, 0x00},
3827 {0x12, AC_VERB_SET_CONNECT_SEL, 0x01},
3828 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00},
3829
3830 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3831 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3832 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3833 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3834 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3835 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3836 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3837 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3838
3839 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3840 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3841 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3842 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3843 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3844 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3845 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3846 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3847 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3848
3849 { }
3850};
3851
3852/* Enable GPIO mask and set output */
3853#define alc880_gpio1_init_verbs alc_gpio1_init_verbs
3854#define alc880_gpio2_init_verbs alc_gpio2_init_verbs
3855#define alc880_gpio3_init_verbs alc_gpio3_init_verbs
3856
3857/* Clevo m520g init */
3858static const struct hda_verb alc880_pin_clevo_init_verbs[] = {
3859 /* headphone output */
3860 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
3861 /* line-out */
3862 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3863 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3864 /* Line-in */
3865 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3866 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3867 /* CD */
3868 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3869 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3870 /* Mic1 (rear panel) */
3871 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3872 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3873 /* Mic2 (front panel) */
3874 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3875 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3876 /* headphone */
3877 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3878 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3879 /* change to EAPD mode */
3880 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3881 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3882
3883 { }
3884};
3885
3886static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = {
3887 /* change to EAPD mode */
3888 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3889 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
3890
3891 /* Headphone output */
3892 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3893 /* Front output*/
3894 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3895 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
3896
3897 /* Line In pin widget for input */
3898 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3899 /* CD pin widget for input */
3900 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
3901 /* Mic1 (rear panel) pin widget for input and vref at 80% */
3902 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3903
3904 /* change to EAPD mode */
3905 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
3906 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
3907
3908 { }
3909};
3910
3911/*
3912 * LG m1 express dual
3913 *
3914 * Pin assignment:
3915 * Rear Line-In/Out (blue): 0x14
3916 * Build-in Mic-In: 0x15
3917 * Speaker-out: 0x17
3918 * HP-Out (green): 0x1b
3919 * Mic-In/Out (red): 0x19
3920 * SPDIF-Out: 0x1e
3921 */
3922
3923/* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */
3924static const hda_nid_t alc880_lg_dac_nids[3] = {
3925 0x05, 0x02, 0x03
3926};
3927
3928/* seems analog CD is not working */
3929static const struct hda_input_mux alc880_lg_capture_source = {
3930 .num_items = 3,
3931 .items = {
3932 { "Mic", 0x1 },
3933 { "Line", 0x5 },
3934 { "Internal Mic", 0x6 },
3935 },
3936};
3937
3938/* 2,4,6 channel modes */
3939static const struct hda_verb alc880_lg_ch2_init[] = {
3940 /* set line-in and mic-in to input */
3941 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
3942 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3943 { }
3944};
3945
3946static const struct hda_verb alc880_lg_ch4_init[] = {
3947 /* set line-in to out and mic-in to input */
3948 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3949 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
3950 { }
3951};
3952
3953static const struct hda_verb alc880_lg_ch6_init[] = {
3954 /* set line-in and mic-in to output */
3955 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3956 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
3957 { }
3958};
3959
3960static const struct hda_channel_mode alc880_lg_ch_modes[3] = {
3961 { 2, alc880_lg_ch2_init },
3962 { 4, alc880_lg_ch4_init },
3963 { 6, alc880_lg_ch6_init },
3964};
3965
3966static const struct snd_kcontrol_new alc880_lg_mixer[] = {
3967 HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
3968 HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT),
3969 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
3970 HDA_BIND_MUTE("Surround Playback Switch", 0x0c, 2, HDA_INPUT),
3971 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0d, 1, 0x0, HDA_OUTPUT),
3972 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
3973 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
3974 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
3975 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
3976 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
3977 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x06, HDA_INPUT),
3978 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x06, HDA_INPUT),
3979 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x07, HDA_INPUT),
3980 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x07, HDA_INPUT),
3981 {
3982 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3983 .name = "Channel Mode",
3984 .info = alc_ch_mode_info,
3985 .get = alc_ch_mode_get,
3986 .put = alc_ch_mode_put,
3987 },
3988 { } /* end */
3989};
3990
3991static const struct hda_verb alc880_lg_init_verbs[] = {
3992 /* set capture source to mic-in */
3993 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3994 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3995 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3996 /* mute all amp mixer inputs */
3997 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)},
3998 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3999 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
4000 /* line-in to input */
4001 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4002 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4003 /* built-in mic */
4004 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4005 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4006 /* speaker-out */
4007 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4008 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4009 /* mic-in to input */
4010 {0x11, AC_VERB_SET_CONNECT_SEL, 0x01},
4011 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4012 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4013 /* HP-out */
4014 {0x13, AC_VERB_SET_CONNECT_SEL, 0x03},
4015 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4016 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4017 /* jack sense */
4018 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4019 { }
4020};
4021
4022/* toggle speaker-output according to the hp-jack state */
4023static void alc880_lg_setup(struct hda_codec *codec)
4024{
4025 struct alc_spec *spec = codec->spec;
4026
4027 spec->autocfg.hp_pins[0] = 0x1b;
4028 spec->autocfg.speaker_pins[0] = 0x17;
4029 spec->automute = 1;
4030 spec->automute_mode = ALC_AUTOMUTE_AMP;
4031}
4032
4033/*
4034 * LG LW20
4035 *
4036 * Pin assignment:
4037 * Speaker-out: 0x14
4038 * Mic-In: 0x18
4039 * Built-in Mic-In: 0x19
4040 * Line-In: 0x1b
4041 * HP-Out: 0x1a
4042 * SPDIF-Out: 0x1e
4043 */
4044
4045static const struct hda_input_mux alc880_lg_lw_capture_source = {
4046 .num_items = 3,
4047 .items = {
4048 { "Mic", 0x0 },
4049 { "Internal Mic", 0x1 },
4050 { "Line In", 0x2 },
4051 },
4052};
4053
4054#define alc880_lg_lw_modes alc880_threestack_modes
4055
4056static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = {
4057 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4058 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4059 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4060 HDA_BIND_MUTE("Surround Playback Switch", 0x0f, 2, HDA_INPUT),
4061 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
4062 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
4063 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
4064 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
4065 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
4066 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
4067 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4068 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4069 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
4070 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
4071 {
4072 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4073 .name = "Channel Mode",
4074 .info = alc_ch_mode_info,
4075 .get = alc_ch_mode_get,
4076 .put = alc_ch_mode_put,
4077 },
4078 { } /* end */
4079};
4080
4081static const struct hda_verb alc880_lg_lw_init_verbs[] = {
4082 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4083 {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
4084 {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */
4085
4086 /* set capture source to mic-in */
4087 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4088 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4089 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4090 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
4091 /* speaker-out */
4092 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4093 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4094 /* HP-out */
4095 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4096 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4097 /* mic-in to input */
4098 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4099 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4100 /* built-in mic */
4101 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4102 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4103 /* jack sense */
4104 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4105 { }
4106};
4107
4108/* toggle speaker-output according to the hp-jack state */
4109static void alc880_lg_lw_setup(struct hda_codec *codec)
4110{
4111 struct alc_spec *spec = codec->spec;
4112
4113 spec->autocfg.hp_pins[0] = 0x1b;
4114 spec->autocfg.speaker_pins[0] = 0x14;
4115 spec->automute = 1;
4116 spec->automute_mode = ALC_AUTOMUTE_AMP;
4117}
4118
4119static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = {
4120 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4121 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
4122 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
4123 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
4124 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
4125 HDA_CODEC_MUTE("Internal Playback Switch", 0x0b, 0x1, HDA_INPUT),
4126 { } /* end */
4127};
4128
4129static const struct hda_input_mux alc880_medion_rim_capture_source = {
4130 .num_items = 2,
4131 .items = {
4132 { "Mic", 0x0 },
4133 { "Internal Mic", 0x1 },
4134 },
4135};
4136
4137static const struct hda_verb alc880_medion_rim_init_verbs[] = {
4138 {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
4139
4140 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4141 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4142
4143 /* Mic1 (rear panel) pin widget for input and vref at 80% */
4144 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4145 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4146 /* Mic2 (as headphone out) for HP output */
4147 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4148 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4149 /* Internal Speaker */
4150 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4151 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4152
4153 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
4154 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
4155
4156 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
4157 { }
4158};
4159
4160/* toggle speaker-output according to the hp-jack state */
4161static void alc880_medion_rim_automute(struct hda_codec *codec)
4162{
4163 struct alc_spec *spec = codec->spec;
4164 alc_hp_automute(codec);
4165 /* toggle EAPD */
4166 if (spec->jack_present)
4167 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0);
4168 else
4169 snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 2);
4170}
4171
4172static void alc880_medion_rim_unsol_event(struct hda_codec *codec,
4173 unsigned int res)
4174{
4175 /* Looks like the unsol event is incompatible with the standard
4176 * definition. 4bit tag is placed at 28 bit!
4177 */
4178 if ((res >> 28) == ALC880_HP_EVENT)
4179 alc880_medion_rim_automute(codec);
4180}
4181
4182static void alc880_medion_rim_setup(struct hda_codec *codec)
4183{
4184 struct alc_spec *spec = codec->spec;
4185
4186 spec->autocfg.hp_pins[0] = 0x14;
4187 spec->autocfg.speaker_pins[0] = 0x1b;
4188 spec->automute = 1;
4189 spec->automute_mode = ALC_AUTOMUTE_AMP;
4190}
4191
4192#ifdef CONFIG_SND_HDA_POWER_SAVE
4193static const struct hda_amp_list alc880_loopbacks[] = {
4194 { 0x0b, HDA_INPUT, 0 },
4195 { 0x0b, HDA_INPUT, 1 },
4196 { 0x0b, HDA_INPUT, 2 },
4197 { 0x0b, HDA_INPUT, 3 },
4198 { 0x0b, HDA_INPUT, 4 },
4199 { } /* end */
4200};
4201
4202static const struct hda_amp_list alc880_lg_loopbacks[] = {
4203 { 0x0b, HDA_INPUT, 1 },
4204 { 0x0b, HDA_INPUT, 6 },
4205 { 0x0b, HDA_INPUT, 7 },
4206 { } /* end */
4207};
4208#endif
4209
4210/*
4211 * Common callbacks 1962 * Common callbacks
4212 */ 1963 */
4213 1964
@@ -4662,679 +2413,6 @@ static int alc_codec_rename(struct hda_codec *codec, const char *name)
4662} 2413}
4663 2414
4664/* 2415/*
4665 * Test configuration for debugging
4666 *
4667 * Almost all inputs/outputs are enabled. I/O pins can be configured via
4668 * enum controls.
4669 */
4670#ifdef CONFIG_SND_DEBUG
4671static const hda_nid_t alc880_test_dac_nids[4] = {
4672 0x02, 0x03, 0x04, 0x05
4673};
4674
4675static const struct hda_input_mux alc880_test_capture_source = {
4676 .num_items = 7,
4677 .items = {
4678 { "In-1", 0x0 },
4679 { "In-2", 0x1 },
4680 { "In-3", 0x2 },
4681 { "In-4", 0x3 },
4682 { "CD", 0x4 },
4683 { "Front", 0x5 },
4684 { "Surround", 0x6 },
4685 },
4686};
4687
4688static const struct hda_channel_mode alc880_test_modes[4] = {
4689 { 2, NULL },
4690 { 4, NULL },
4691 { 6, NULL },
4692 { 8, NULL },
4693};
4694
4695static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol,
4696 struct snd_ctl_elem_info *uinfo)
4697{
4698 static const char * const texts[] = {
4699 "N/A", "Line Out", "HP Out",
4700 "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%"
4701 };
4702 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4703 uinfo->count = 1;
4704 uinfo->value.enumerated.items = 8;
4705 if (uinfo->value.enumerated.item >= 8)
4706 uinfo->value.enumerated.item = 7;
4707 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4708 return 0;
4709}
4710
4711static int alc_test_pin_ctl_get(struct snd_kcontrol *kcontrol,
4712 struct snd_ctl_elem_value *ucontrol)
4713{
4714 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4715 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4716 unsigned int pin_ctl, item = 0;
4717
4718 pin_ctl = snd_hda_codec_read(codec, nid, 0,
4719 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4720 if (pin_ctl & AC_PINCTL_OUT_EN) {
4721 if (pin_ctl & AC_PINCTL_HP_EN)
4722 item = 2;
4723 else
4724 item = 1;
4725 } else if (pin_ctl & AC_PINCTL_IN_EN) {
4726 switch (pin_ctl & AC_PINCTL_VREFEN) {
4727 case AC_PINCTL_VREF_HIZ: item = 3; break;
4728 case AC_PINCTL_VREF_50: item = 4; break;
4729 case AC_PINCTL_VREF_GRD: item = 5; break;
4730 case AC_PINCTL_VREF_80: item = 6; break;
4731 case AC_PINCTL_VREF_100: item = 7; break;
4732 }
4733 }
4734 ucontrol->value.enumerated.item[0] = item;
4735 return 0;
4736}
4737
4738static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol,
4739 struct snd_ctl_elem_value *ucontrol)
4740{
4741 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4742 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4743 static const unsigned int ctls[] = {
4744 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN,
4745 AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ,
4746 AC_PINCTL_IN_EN | AC_PINCTL_VREF_50,
4747 AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD,
4748 AC_PINCTL_IN_EN | AC_PINCTL_VREF_80,
4749 AC_PINCTL_IN_EN | AC_PINCTL_VREF_100,
4750 };
4751 unsigned int old_ctl, new_ctl;
4752
4753 old_ctl = snd_hda_codec_read(codec, nid, 0,
4754 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
4755 new_ctl = ctls[ucontrol->value.enumerated.item[0]];
4756 if (old_ctl != new_ctl) {
4757 int val;
4758 snd_hda_codec_write_cache(codec, nid, 0,
4759 AC_VERB_SET_PIN_WIDGET_CONTROL,
4760 new_ctl);
4761 val = ucontrol->value.enumerated.item[0] >= 3 ?
4762 HDA_AMP_MUTE : 0;
4763 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
4764 HDA_AMP_MUTE, val);
4765 return 1;
4766 }
4767 return 0;
4768}
4769
4770static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol,
4771 struct snd_ctl_elem_info *uinfo)
4772{
4773 static const char * const texts[] = {
4774 "Front", "Surround", "CLFE", "Side"
4775 };
4776 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
4777 uinfo->count = 1;
4778 uinfo->value.enumerated.items = 4;
4779 if (uinfo->value.enumerated.item >= 4)
4780 uinfo->value.enumerated.item = 3;
4781 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
4782 return 0;
4783}
4784
4785static int alc_test_pin_src_get(struct snd_kcontrol *kcontrol,
4786 struct snd_ctl_elem_value *ucontrol)
4787{
4788 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4789 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4790 unsigned int sel;
4791
4792 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0);
4793 ucontrol->value.enumerated.item[0] = sel & 3;
4794 return 0;
4795}
4796
4797static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol,
4798 struct snd_ctl_elem_value *ucontrol)
4799{
4800 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4801 hda_nid_t nid = (hda_nid_t)kcontrol->private_value;
4802 unsigned int sel;
4803
4804 sel = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_SEL, 0) & 3;
4805 if (ucontrol->value.enumerated.item[0] != sel) {
4806 sel = ucontrol->value.enumerated.item[0] & 3;
4807 snd_hda_codec_write_cache(codec, nid, 0,
4808 AC_VERB_SET_CONNECT_SEL, sel);
4809 return 1;
4810 }
4811 return 0;
4812}
4813
4814#define PIN_CTL_TEST(xname,nid) { \
4815 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4816 .name = xname, \
4817 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4818 .info = alc_test_pin_ctl_info, \
4819 .get = alc_test_pin_ctl_get, \
4820 .put = alc_test_pin_ctl_put, \
4821 .private_value = nid \
4822 }
4823
4824#define PIN_SRC_TEST(xname,nid) { \
4825 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
4826 .name = xname, \
4827 .subdevice = HDA_SUBDEV_NID_FLAG | nid, \
4828 .info = alc_test_pin_src_info, \
4829 .get = alc_test_pin_src_get, \
4830 .put = alc_test_pin_src_put, \
4831 .private_value = nid \
4832 }
4833
4834static const struct snd_kcontrol_new alc880_test_mixer[] = {
4835 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
4836 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
4837 HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
4838 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
4839 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
4840 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
4841 HDA_BIND_MUTE("CLFE Playback Switch", 0x0e, 2, HDA_INPUT),
4842 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
4843 PIN_CTL_TEST("Front Pin Mode", 0x14),
4844 PIN_CTL_TEST("Surround Pin Mode", 0x15),
4845 PIN_CTL_TEST("CLFE Pin Mode", 0x16),
4846 PIN_CTL_TEST("Side Pin Mode", 0x17),
4847 PIN_CTL_TEST("In-1 Pin Mode", 0x18),
4848 PIN_CTL_TEST("In-2 Pin Mode", 0x19),
4849 PIN_CTL_TEST("In-3 Pin Mode", 0x1a),
4850 PIN_CTL_TEST("In-4 Pin Mode", 0x1b),
4851 PIN_SRC_TEST("In-1 Pin Source", 0x18),
4852 PIN_SRC_TEST("In-2 Pin Source", 0x19),
4853 PIN_SRC_TEST("In-3 Pin Source", 0x1a),
4854 PIN_SRC_TEST("In-4 Pin Source", 0x1b),
4855 HDA_CODEC_VOLUME("In-1 Playback Volume", 0x0b, 0x0, HDA_INPUT),
4856 HDA_CODEC_MUTE("In-1 Playback Switch", 0x0b, 0x0, HDA_INPUT),
4857 HDA_CODEC_VOLUME("In-2 Playback Volume", 0x0b, 0x1, HDA_INPUT),
4858 HDA_CODEC_MUTE("In-2 Playback Switch", 0x0b, 0x1, HDA_INPUT),
4859 HDA_CODEC_VOLUME("In-3 Playback Volume", 0x0b, 0x2, HDA_INPUT),
4860 HDA_CODEC_MUTE("In-3 Playback Switch", 0x0b, 0x2, HDA_INPUT),
4861 HDA_CODEC_VOLUME("In-4 Playback Volume", 0x0b, 0x3, HDA_INPUT),
4862 HDA_CODEC_MUTE("In-4 Playback Switch", 0x0b, 0x3, HDA_INPUT),
4863 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x4, HDA_INPUT),
4864 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x4, HDA_INPUT),
4865 {
4866 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4867 .name = "Channel Mode",
4868 .info = alc_ch_mode_info,
4869 .get = alc_ch_mode_get,
4870 .put = alc_ch_mode_put,
4871 },
4872 { } /* end */
4873};
4874
4875static const struct hda_verb alc880_test_init_verbs[] = {
4876 /* Unmute inputs of 0x0c - 0x0f */
4877 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4878 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4879 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4880 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4881 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4882 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4883 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4884 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4885 /* Vol output for 0x0c-0x0f */
4886 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4887 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4888 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4889 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
4890 /* Set output pins 0x14-0x17 */
4891 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4892 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4893 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4894 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4895 /* Unmute output pins 0x14-0x17 */
4896 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4897 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4898 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4899 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4900 /* Set input pins 0x18-0x1c */
4901 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4902 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4903 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4904 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4905 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4906 /* Mute input pins 0x18-0x1b */
4907 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4908 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4909 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4910 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4911 /* ADC set up */
4912 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4913 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
4914 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4915 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
4916 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4917 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
4918 /* Analog input/passthru */
4919 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4920 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4921 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4922 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4923 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4924 { }
4925};
4926#endif
4927
4928/*
4929 */
4930
4931static const char * const alc880_models[ALC880_MODEL_LAST] = {
4932 [ALC880_3ST] = "3stack",
4933 [ALC880_TCL_S700] = "tcl",
4934 [ALC880_3ST_DIG] = "3stack-digout",
4935 [ALC880_CLEVO] = "clevo",
4936 [ALC880_5ST] = "5stack",
4937 [ALC880_5ST_DIG] = "5stack-digout",
4938 [ALC880_W810] = "w810",
4939 [ALC880_Z71V] = "z71v",
4940 [ALC880_6ST] = "6stack",
4941 [ALC880_6ST_DIG] = "6stack-digout",
4942 [ALC880_ASUS] = "asus",
4943 [ALC880_ASUS_W1V] = "asus-w1v",
4944 [ALC880_ASUS_DIG] = "asus-dig",
4945 [ALC880_ASUS_DIG2] = "asus-dig2",
4946 [ALC880_UNIWILL_DIG] = "uniwill",
4947 [ALC880_UNIWILL_P53] = "uniwill-p53",
4948 [ALC880_FUJITSU] = "fujitsu",
4949 [ALC880_F1734] = "F1734",
4950 [ALC880_LG] = "lg",
4951 [ALC880_LG_LW] = "lg-lw",
4952 [ALC880_MEDION_RIM] = "medion",
4953#ifdef CONFIG_SND_DEBUG
4954 [ALC880_TEST] = "test",
4955#endif
4956 [ALC880_AUTO] = "auto",
4957};
4958
4959static const struct snd_pci_quirk alc880_cfg_tbl[] = {
4960 SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810),
4961 SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG),
4962 SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST),
4963 SND_PCI_QUIRK(0x1025, 0x0070, "ULI", ALC880_3ST_DIG),
4964 SND_PCI_QUIRK(0x1025, 0x0077, "ULI", ALC880_6ST_DIG),
4965 SND_PCI_QUIRK(0x1025, 0x0078, "ULI", ALC880_6ST_DIG),
4966 SND_PCI_QUIRK(0x1025, 0x0087, "ULI", ALC880_6ST_DIG),
4967 SND_PCI_QUIRK(0x1025, 0xe309, "ULI", ALC880_3ST_DIG),
4968 SND_PCI_QUIRK(0x1025, 0xe310, "ULI", ALC880_3ST),
4969 SND_PCI_QUIRK(0x1039, 0x1234, NULL, ALC880_6ST_DIG),
4970 SND_PCI_QUIRK(0x1043, 0x10b3, "ASUS W1V", ALC880_ASUS_W1V),
4971 SND_PCI_QUIRK(0x1043, 0x10c2, "ASUS W6A", ALC880_ASUS_DIG),
4972 SND_PCI_QUIRK(0x1043, 0x10c3, "ASUS Wxx", ALC880_ASUS_DIG),
4973 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS", ALC880_ASUS_DIG),
4974 SND_PCI_QUIRK(0x1043, 0x1123, "ASUS", ALC880_ASUS_DIG),
4975 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS", ALC880_ASUS_DIG),
4976 SND_PCI_QUIRK(0x1043, 0x1964, "ASUS Z71V", ALC880_Z71V),
4977 /* SND_PCI_QUIRK(0x1043, 0x1964, "ASUS", ALC880_ASUS_DIG), */
4978 SND_PCI_QUIRK(0x1043, 0x1973, "ASUS", ALC880_ASUS_DIG),
4979 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS", ALC880_ASUS_DIG),
4980 SND_PCI_QUIRK(0x1043, 0x814e, "ASUS P5GD1 w/SPDIF", ALC880_6ST_DIG),
4981 SND_PCI_QUIRK(0x1043, 0x8181, "ASUS P4GPL", ALC880_ASUS_DIG),
4982 SND_PCI_QUIRK(0x1043, 0x8196, "ASUS P5GD1", ALC880_6ST),
4983 SND_PCI_QUIRK(0x1043, 0x81b4, "ASUS", ALC880_6ST),
4984 SND_PCI_QUIRK_VENDOR(0x1043, "ASUS", ALC880_ASUS), /* default ASUS */
4985 SND_PCI_QUIRK(0x104d, 0x81a0, "Sony", ALC880_3ST),
4986 SND_PCI_QUIRK(0x104d, 0x81d6, "Sony", ALC880_3ST),
4987 SND_PCI_QUIRK(0x107b, 0x3032, "Gateway", ALC880_5ST),
4988 SND_PCI_QUIRK(0x107b, 0x3033, "Gateway", ALC880_5ST),
4989 SND_PCI_QUIRK(0x107b, 0x4039, "Gateway", ALC880_5ST),
4990 SND_PCI_QUIRK(0x1297, 0xc790, "Shuttle ST20G5", ALC880_6ST_DIG),
4991 SND_PCI_QUIRK(0x1458, 0xa102, "Gigabyte K8", ALC880_6ST_DIG),
4992 SND_PCI_QUIRK(0x1462, 0x1150, "MSI", ALC880_6ST_DIG),
4993 SND_PCI_QUIRK(0x1509, 0x925d, "FIC P4M", ALC880_6ST_DIG),
4994 SND_PCI_QUIRK(0x1558, 0x0520, "Clevo m520G", ALC880_CLEVO),
4995 SND_PCI_QUIRK(0x1558, 0x0660, "Clevo m655n", ALC880_CLEVO),
4996 SND_PCI_QUIRK(0x1558, 0x5401, "ASUS", ALC880_ASUS_DIG2),
4997 SND_PCI_QUIRK(0x1565, 0x8202, "Biostar", ALC880_5ST_DIG),
4998 SND_PCI_QUIRK(0x1584, 0x9050, "Uniwill", ALC880_UNIWILL_DIG),
4999 SND_PCI_QUIRK(0x1584, 0x9054, "Uniwill", ALC880_F1734),
5000 SND_PCI_QUIRK(0x1584, 0x9070, "Uniwill", ALC880_UNIWILL),
5001 SND_PCI_QUIRK(0x1584, 0x9077, "Uniwill P53", ALC880_UNIWILL_P53),
5002 SND_PCI_QUIRK(0x161f, 0x203d, "W810", ALC880_W810),
5003 SND_PCI_QUIRK(0x161f, 0x205d, "Medion Rim 2150", ALC880_MEDION_RIM),
5004 SND_PCI_QUIRK(0x1695, 0x400d, "EPoX", ALC880_5ST_DIG),
5005 SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG),
5006 SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734),
5007 SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU),
5008 SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734),
5009 SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU),
5010 SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW),
5011 SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG),
5012 SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG),
5013 SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG),
5014 SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW),
5015 SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700),
5016 SND_PCI_QUIRK(0x2668, 0x8086, NULL, ALC880_6ST_DIG), /* broken BIOS */
5017 SND_PCI_QUIRK(0x8086, 0x2668, NULL, ALC880_6ST_DIG),
5018 SND_PCI_QUIRK(0x8086, 0xa100, "Intel mobo", ALC880_5ST_DIG),
5019 SND_PCI_QUIRK(0x8086, 0xd400, "Intel mobo", ALC880_5ST_DIG),
5020 SND_PCI_QUIRK(0x8086, 0xd401, "Intel mobo", ALC880_5ST_DIG),
5021 SND_PCI_QUIRK(0x8086, 0xd402, "Intel mobo", ALC880_3ST_DIG),
5022 SND_PCI_QUIRK(0x8086, 0xe224, "Intel mobo", ALC880_5ST_DIG),
5023 SND_PCI_QUIRK(0x8086, 0xe305, "Intel mobo", ALC880_3ST_DIG),
5024 SND_PCI_QUIRK(0x8086, 0xe308, "Intel mobo", ALC880_3ST_DIG),
5025 SND_PCI_QUIRK(0x8086, 0xe400, "Intel mobo", ALC880_5ST_DIG),
5026 SND_PCI_QUIRK(0x8086, 0xe401, "Intel mobo", ALC880_5ST_DIG),
5027 SND_PCI_QUIRK(0x8086, 0xe402, "Intel mobo", ALC880_5ST_DIG),
5028 /* default Intel */
5029 SND_PCI_QUIRK_VENDOR(0x8086, "Intel mobo", ALC880_3ST),
5030 SND_PCI_QUIRK(0xa0a0, 0x0560, "AOpen i915GMm-HFS", ALC880_5ST_DIG),
5031 SND_PCI_QUIRK(0xe803, 0x1019, NULL, ALC880_6ST_DIG),
5032 {}
5033};
5034
5035/*
5036 * ALC880 codec presets
5037 */
5038static const struct alc_config_preset alc880_presets[] = {
5039 [ALC880_3ST] = {
5040 .mixers = { alc880_three_stack_mixer },
5041 .init_verbs = { alc880_volume_init_verbs,
5042 alc880_pin_3stack_init_verbs },
5043 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5044 .dac_nids = alc880_dac_nids,
5045 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5046 .channel_mode = alc880_threestack_modes,
5047 .need_dac_fix = 1,
5048 .input_mux = &alc880_capture_source,
5049 },
5050 [ALC880_3ST_DIG] = {
5051 .mixers = { alc880_three_stack_mixer },
5052 .init_verbs = { alc880_volume_init_verbs,
5053 alc880_pin_3stack_init_verbs },
5054 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5055 .dac_nids = alc880_dac_nids,
5056 .dig_out_nid = ALC880_DIGOUT_NID,
5057 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5058 .channel_mode = alc880_threestack_modes,
5059 .need_dac_fix = 1,
5060 .input_mux = &alc880_capture_source,
5061 },
5062 [ALC880_TCL_S700] = {
5063 .mixers = { alc880_tcl_s700_mixer },
5064 .init_verbs = { alc880_volume_init_verbs,
5065 alc880_pin_tcl_S700_init_verbs,
5066 alc880_gpio2_init_verbs },
5067 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5068 .dac_nids = alc880_dac_nids,
5069 .adc_nids = alc880_adc_nids_alt, /* FIXME: correct? */
5070 .num_adc_nids = 1, /* single ADC */
5071 .hp_nid = 0x03,
5072 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5073 .channel_mode = alc880_2_jack_modes,
5074 .input_mux = &alc880_capture_source,
5075 },
5076 [ALC880_5ST] = {
5077 .mixers = { alc880_three_stack_mixer,
5078 alc880_five_stack_mixer},
5079 .init_verbs = { alc880_volume_init_verbs,
5080 alc880_pin_5stack_init_verbs },
5081 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5082 .dac_nids = alc880_dac_nids,
5083 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5084 .channel_mode = alc880_fivestack_modes,
5085 .input_mux = &alc880_capture_source,
5086 },
5087 [ALC880_5ST_DIG] = {
5088 .mixers = { alc880_three_stack_mixer,
5089 alc880_five_stack_mixer },
5090 .init_verbs = { alc880_volume_init_verbs,
5091 alc880_pin_5stack_init_verbs },
5092 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5093 .dac_nids = alc880_dac_nids,
5094 .dig_out_nid = ALC880_DIGOUT_NID,
5095 .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes),
5096 .channel_mode = alc880_fivestack_modes,
5097 .input_mux = &alc880_capture_source,
5098 },
5099 [ALC880_6ST] = {
5100 .mixers = { alc880_six_stack_mixer },
5101 .init_verbs = { alc880_volume_init_verbs,
5102 alc880_pin_6stack_init_verbs },
5103 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5104 .dac_nids = alc880_6st_dac_nids,
5105 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5106 .channel_mode = alc880_sixstack_modes,
5107 .input_mux = &alc880_6stack_capture_source,
5108 },
5109 [ALC880_6ST_DIG] = {
5110 .mixers = { alc880_six_stack_mixer },
5111 .init_verbs = { alc880_volume_init_verbs,
5112 alc880_pin_6stack_init_verbs },
5113 .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids),
5114 .dac_nids = alc880_6st_dac_nids,
5115 .dig_out_nid = ALC880_DIGOUT_NID,
5116 .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes),
5117 .channel_mode = alc880_sixstack_modes,
5118 .input_mux = &alc880_6stack_capture_source,
5119 },
5120 [ALC880_W810] = {
5121 .mixers = { alc880_w810_base_mixer },
5122 .init_verbs = { alc880_volume_init_verbs,
5123 alc880_pin_w810_init_verbs,
5124 alc880_gpio2_init_verbs },
5125 .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids),
5126 .dac_nids = alc880_w810_dac_nids,
5127 .dig_out_nid = ALC880_DIGOUT_NID,
5128 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5129 .channel_mode = alc880_w810_modes,
5130 .input_mux = &alc880_capture_source,
5131 },
5132 [ALC880_Z71V] = {
5133 .mixers = { alc880_z71v_mixer },
5134 .init_verbs = { alc880_volume_init_verbs,
5135 alc880_pin_z71v_init_verbs },
5136 .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids),
5137 .dac_nids = alc880_z71v_dac_nids,
5138 .dig_out_nid = ALC880_DIGOUT_NID,
5139 .hp_nid = 0x03,
5140 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5141 .channel_mode = alc880_2_jack_modes,
5142 .input_mux = &alc880_capture_source,
5143 },
5144 [ALC880_F1734] = {
5145 .mixers = { alc880_f1734_mixer },
5146 .init_verbs = { alc880_volume_init_verbs,
5147 alc880_pin_f1734_init_verbs },
5148 .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids),
5149 .dac_nids = alc880_f1734_dac_nids,
5150 .hp_nid = 0x02,
5151 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5152 .channel_mode = alc880_2_jack_modes,
5153 .input_mux = &alc880_f1734_capture_source,
5154 .unsol_event = alc880_uniwill_p53_unsol_event,
5155 .setup = alc880_uniwill_p53_setup,
5156 .init_hook = alc_hp_automute,
5157 },
5158 [ALC880_ASUS] = {
5159 .mixers = { alc880_asus_mixer },
5160 .init_verbs = { alc880_volume_init_verbs,
5161 alc880_pin_asus_init_verbs,
5162 alc880_gpio1_init_verbs },
5163 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5164 .dac_nids = alc880_asus_dac_nids,
5165 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5166 .channel_mode = alc880_asus_modes,
5167 .need_dac_fix = 1,
5168 .input_mux = &alc880_capture_source,
5169 },
5170 [ALC880_ASUS_DIG] = {
5171 .mixers = { alc880_asus_mixer },
5172 .init_verbs = { alc880_volume_init_verbs,
5173 alc880_pin_asus_init_verbs,
5174 alc880_gpio1_init_verbs },
5175 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5176 .dac_nids = alc880_asus_dac_nids,
5177 .dig_out_nid = ALC880_DIGOUT_NID,
5178 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5179 .channel_mode = alc880_asus_modes,
5180 .need_dac_fix = 1,
5181 .input_mux = &alc880_capture_source,
5182 },
5183 [ALC880_ASUS_DIG2] = {
5184 .mixers = { alc880_asus_mixer },
5185 .init_verbs = { alc880_volume_init_verbs,
5186 alc880_pin_asus_init_verbs,
5187 alc880_gpio2_init_verbs }, /* use GPIO2 */
5188 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5189 .dac_nids = alc880_asus_dac_nids,
5190 .dig_out_nid = ALC880_DIGOUT_NID,
5191 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5192 .channel_mode = alc880_asus_modes,
5193 .need_dac_fix = 1,
5194 .input_mux = &alc880_capture_source,
5195 },
5196 [ALC880_ASUS_W1V] = {
5197 .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer },
5198 .init_verbs = { alc880_volume_init_verbs,
5199 alc880_pin_asus_init_verbs,
5200 alc880_gpio1_init_verbs },
5201 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5202 .dac_nids = alc880_asus_dac_nids,
5203 .dig_out_nid = ALC880_DIGOUT_NID,
5204 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5205 .channel_mode = alc880_asus_modes,
5206 .need_dac_fix = 1,
5207 .input_mux = &alc880_capture_source,
5208 },
5209 [ALC880_UNIWILL_DIG] = {
5210 .mixers = { alc880_asus_mixer },
5211 .init_verbs = { alc880_volume_init_verbs,
5212 alc880_pin_asus_init_verbs },
5213 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5214 .dac_nids = alc880_asus_dac_nids,
5215 .dig_out_nid = ALC880_DIGOUT_NID,
5216 .num_channel_mode = ARRAY_SIZE(alc880_asus_modes),
5217 .channel_mode = alc880_asus_modes,
5218 .need_dac_fix = 1,
5219 .input_mux = &alc880_capture_source,
5220 },
5221 [ALC880_UNIWILL] = {
5222 .mixers = { alc880_uniwill_mixer },
5223 .init_verbs = { alc880_volume_init_verbs,
5224 alc880_uniwill_init_verbs },
5225 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5226 .dac_nids = alc880_asus_dac_nids,
5227 .dig_out_nid = ALC880_DIGOUT_NID,
5228 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5229 .channel_mode = alc880_threestack_modes,
5230 .need_dac_fix = 1,
5231 .input_mux = &alc880_capture_source,
5232 .unsol_event = alc880_uniwill_unsol_event,
5233 .setup = alc880_uniwill_setup,
5234 .init_hook = alc880_uniwill_init_hook,
5235 },
5236 [ALC880_UNIWILL_P53] = {
5237 .mixers = { alc880_uniwill_p53_mixer },
5238 .init_verbs = { alc880_volume_init_verbs,
5239 alc880_uniwill_p53_init_verbs },
5240 .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids),
5241 .dac_nids = alc880_asus_dac_nids,
5242 .num_channel_mode = ARRAY_SIZE(alc880_w810_modes),
5243 .channel_mode = alc880_threestack_modes,
5244 .input_mux = &alc880_capture_source,
5245 .unsol_event = alc880_uniwill_p53_unsol_event,
5246 .setup = alc880_uniwill_p53_setup,
5247 .init_hook = alc_hp_automute,
5248 },
5249 [ALC880_FUJITSU] = {
5250 .mixers = { alc880_fujitsu_mixer },
5251 .init_verbs = { alc880_volume_init_verbs,
5252 alc880_uniwill_p53_init_verbs,
5253 alc880_beep_init_verbs },
5254 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5255 .dac_nids = alc880_dac_nids,
5256 .dig_out_nid = ALC880_DIGOUT_NID,
5257 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5258 .channel_mode = alc880_2_jack_modes,
5259 .input_mux = &alc880_capture_source,
5260 .unsol_event = alc880_uniwill_p53_unsol_event,
5261 .setup = alc880_uniwill_p53_setup,
5262 .init_hook = alc_hp_automute,
5263 },
5264 [ALC880_CLEVO] = {
5265 .mixers = { alc880_three_stack_mixer },
5266 .init_verbs = { alc880_volume_init_verbs,
5267 alc880_pin_clevo_init_verbs },
5268 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5269 .dac_nids = alc880_dac_nids,
5270 .hp_nid = 0x03,
5271 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
5272 .channel_mode = alc880_threestack_modes,
5273 .need_dac_fix = 1,
5274 .input_mux = &alc880_capture_source,
5275 },
5276 [ALC880_LG] = {
5277 .mixers = { alc880_lg_mixer },
5278 .init_verbs = { alc880_volume_init_verbs,
5279 alc880_lg_init_verbs },
5280 .num_dacs = ARRAY_SIZE(alc880_lg_dac_nids),
5281 .dac_nids = alc880_lg_dac_nids,
5282 .dig_out_nid = ALC880_DIGOUT_NID,
5283 .num_channel_mode = ARRAY_SIZE(alc880_lg_ch_modes),
5284 .channel_mode = alc880_lg_ch_modes,
5285 .need_dac_fix = 1,
5286 .input_mux = &alc880_lg_capture_source,
5287 .unsol_event = alc_sku_unsol_event,
5288 .setup = alc880_lg_setup,
5289 .init_hook = alc_hp_automute,
5290#ifdef CONFIG_SND_HDA_POWER_SAVE
5291 .loopbacks = alc880_lg_loopbacks,
5292#endif
5293 },
5294 [ALC880_LG_LW] = {
5295 .mixers = { alc880_lg_lw_mixer },
5296 .init_verbs = { alc880_volume_init_verbs,
5297 alc880_lg_lw_init_verbs },
5298 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5299 .dac_nids = alc880_dac_nids,
5300 .dig_out_nid = ALC880_DIGOUT_NID,
5301 .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes),
5302 .channel_mode = alc880_lg_lw_modes,
5303 .input_mux = &alc880_lg_lw_capture_source,
5304 .unsol_event = alc_sku_unsol_event,
5305 .setup = alc880_lg_lw_setup,
5306 .init_hook = alc_hp_automute,
5307 },
5308 [ALC880_MEDION_RIM] = {
5309 .mixers = { alc880_medion_rim_mixer },
5310 .init_verbs = { alc880_volume_init_verbs,
5311 alc880_medion_rim_init_verbs,
5312 alc_gpio2_init_verbs },
5313 .num_dacs = ARRAY_SIZE(alc880_dac_nids),
5314 .dac_nids = alc880_dac_nids,
5315 .dig_out_nid = ALC880_DIGOUT_NID,
5316 .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes),
5317 .channel_mode = alc880_2_jack_modes,
5318 .input_mux = &alc880_medion_rim_capture_source,
5319 .unsol_event = alc880_medion_rim_unsol_event,
5320 .setup = alc880_medion_rim_setup,
5321 .init_hook = alc880_medion_rim_automute,
5322 },
5323#ifdef CONFIG_SND_DEBUG
5324 [ALC880_TEST] = {
5325 .mixers = { alc880_test_mixer },
5326 .init_verbs = { alc880_test_init_verbs },
5327 .num_dacs = ARRAY_SIZE(alc880_test_dac_nids),
5328 .dac_nids = alc880_test_dac_nids,
5329 .dig_out_nid = ALC880_DIGOUT_NID,
5330 .num_channel_mode = ARRAY_SIZE(alc880_test_modes),
5331 .channel_mode = alc880_test_modes,
5332 .input_mux = &alc880_test_capture_source,
5333 },
5334#endif
5335};
5336
5337/*
5338 * Automatic parse of I/O pins from the BIOS configuration 2416 * Automatic parse of I/O pins from the BIOS configuration
5339 */ 2417 */
5340 2418
@@ -5343,18 +2421,12 @@ enum {
5343 ALC_CTL_WIDGET_MUTE, 2421 ALC_CTL_WIDGET_MUTE,
5344 ALC_CTL_BIND_MUTE, 2422 ALC_CTL_BIND_MUTE,
5345}; 2423};
5346static const struct snd_kcontrol_new alc880_control_templates[] = { 2424static const struct snd_kcontrol_new alc_control_templates[] = {
5347 HDA_CODEC_VOLUME(NULL, 0, 0, 0), 2425 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
5348 HDA_CODEC_MUTE(NULL, 0, 0, 0), 2426 HDA_CODEC_MUTE(NULL, 0, 0, 0),
5349 HDA_BIND_MUTE(NULL, 0, 0, 0), 2427 HDA_BIND_MUTE(NULL, 0, 0, 0),
5350}; 2428};
5351 2429
5352static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec)
5353{
5354 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
5355 return snd_array_new(&spec->kctls);
5356}
5357
5358/* add dynamic controls */ 2430/* add dynamic controls */
5359static int add_control(struct alc_spec *spec, int type, const char *name, 2431static int add_control(struct alc_spec *spec, int type, const char *name,
5360 int cidx, unsigned long val) 2432 int cidx, unsigned long val)
@@ -5364,7 +2436,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name,
5364 knew = alc_kcontrol_new(spec); 2436 knew = alc_kcontrol_new(spec);
5365 if (!knew) 2437 if (!knew)
5366 return -ENOMEM; 2438 return -ENOMEM;
5367 *knew = alc880_control_templates[type]; 2439 *knew = alc_control_templates[type];
5368 knew->name = kstrdup(name, GFP_KERNEL); 2440 knew->name = kstrdup(name, GFP_KERNEL);
5369 if (!knew->name) 2441 if (!knew->name)
5370 return -ENOMEM; 2442 return -ENOMEM;
@@ -5393,16 +2465,6 @@ static int add_control_with_pfx(struct alc_spec *spec, int type,
5393#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \ 2465#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
5394 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val) 2466 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
5395 2467
5396#define alc880_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5397#define alc880_fixed_pin_idx(nid) ((nid) - 0x14)
5398#define alc880_is_multi_pin(nid) ((nid) >= 0x18)
5399#define alc880_multi_pin_idx(nid) ((nid) - 0x18)
5400#define alc880_idx_to_dac(nid) ((nid) + 0x02)
5401#define alc880_dac_to_idx(nid) ((nid) - 0x02)
5402#define alc880_idx_to_mixer(nid) ((nid) + 0x0c)
5403#define alc880_idx_to_selector(nid) ((nid) + 0x10)
5404#define ALC880_PIN_CD_NID 0x1c
5405
5406static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch, 2468static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch,
5407 bool can_be_master, int *index) 2469 bool can_be_master, int *index)
5408{ 2470{
@@ -5459,6 +2521,7 @@ static int alc_is_input_pin(struct hda_codec *codec, hda_nid_t nid)
5459 return (pincap & AC_PINCAP_IN) != 0; 2521 return (pincap & AC_PINCAP_IN) != 0;
5460} 2522}
5461 2523
2524/* Parse the codec tree and retrieve ADCs and corresponding capsrc MUXs */
5462static int alc_auto_fill_adc_caps(struct hda_codec *codec) 2525static int alc_auto_fill_adc_caps(struct hda_codec *codec)
5463{ 2526{
5464 struct alc_spec *spec = codec->spec; 2527 struct alc_spec *spec = codec->spec;
@@ -5568,14 +2631,6 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec)
5568 return 0; 2631 return 0;
5569} 2632}
5570 2633
5571static int alc_auto_fill_dac_nids(struct hda_codec *codec);
5572static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
5573 const struct auto_pin_cfg *cfg);
5574static int alc_auto_create_hp_out(struct hda_codec *codec);
5575static int alc_auto_create_speaker_out(struct hda_codec *codec);
5576static void alc_auto_init_multi_out(struct hda_codec *codec);
5577static void alc_auto_init_extra_out(struct hda_codec *codec);
5578
5579static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid, 2634static void alc_set_pin_output(struct hda_codec *codec, hda_nid_t nid,
5580 unsigned int pin_type) 2635 unsigned int pin_type)
5581{ 2636{
@@ -5621,73 +2676,664 @@ static void alc_auto_init_analog_input(struct hda_codec *codec)
5621 } 2676 }
5622} 2677}
5623 2678
5624static int alc_auto_add_multi_channel_mode(struct hda_codec *codec, 2679/* convert from MIX nid to DAC */
5625 int (*fill_dac)(struct hda_codec *)); 2680static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
5626static void alc_remove_invalid_adc_nids(struct hda_codec *codec); 2681{
5627static void alc_auto_init_input_src(struct hda_codec *codec); 2682 hda_nid_t list[5];
2683 int i, num;
5628 2684
5629/* parse the BIOS configuration and set up the alc_spec */ 2685 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
5630/* return 1 if successful, 0 if the proper config is not found, 2686 for (i = 0; i < num; i++) {
5631 * or a negative error code 2687 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
2688 return list[i];
2689 }
2690 return 0;
2691}
2692
2693/* go down to the selector widget before the mixer */
2694static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
2695{
2696 hda_nid_t srcs[5];
2697 int num = snd_hda_get_connections(codec, pin, srcs,
2698 ARRAY_SIZE(srcs));
2699 if (num != 1 ||
2700 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
2701 return pin;
2702 return srcs[0];
2703}
2704
2705/* get MIX nid connected to the given pin targeted to DAC */
2706static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
2707 hda_nid_t dac)
2708{
2709 hda_nid_t mix[5];
2710 int i, num;
2711
2712 pin = alc_go_down_to_selector(codec, pin);
2713 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
2714 for (i = 0; i < num; i++) {
2715 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
2716 return mix[i];
2717 }
2718 return 0;
2719}
2720
2721/* select the connection from pin to DAC if needed */
2722static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
2723 hda_nid_t dac)
2724{
2725 hda_nid_t mix[5];
2726 int i, num;
2727
2728 pin = alc_go_down_to_selector(codec, pin);
2729 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
2730 if (num < 2)
2731 return 0;
2732 for (i = 0; i < num; i++) {
2733 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
2734 snd_hda_codec_update_cache(codec, pin, 0,
2735 AC_VERB_SET_CONNECT_SEL, i);
2736 return 0;
2737 }
2738 }
2739 return 0;
2740}
2741
2742/* look for an empty DAC slot */
2743static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
2744{
2745 struct alc_spec *spec = codec->spec;
2746 hda_nid_t srcs[5];
2747 int i, num;
2748
2749 pin = alc_go_down_to_selector(codec, pin);
2750 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
2751 for (i = 0; i < num; i++) {
2752 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
2753 if (!nid)
2754 continue;
2755 if (found_in_nid_list(nid, spec->multiout.dac_nids,
2756 spec->multiout.num_dacs))
2757 continue;
2758 if (spec->multiout.hp_nid == nid)
2759 continue;
2760 if (found_in_nid_list(nid, spec->multiout.extra_out_nid,
2761 ARRAY_SIZE(spec->multiout.extra_out_nid)))
2762 continue;
2763 return nid;
2764 }
2765 return 0;
2766}
2767
2768static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
2769{
2770 hda_nid_t sel = alc_go_down_to_selector(codec, pin);
2771 if (snd_hda_get_conn_list(codec, sel, NULL) == 1)
2772 return alc_auto_look_for_dac(codec, pin);
2773 return 0;
2774}
2775
2776/* fill in the dac_nids table from the parsed pin configuration */
2777static int alc_auto_fill_dac_nids(struct hda_codec *codec)
2778{
2779 struct alc_spec *spec = codec->spec;
2780 const struct auto_pin_cfg *cfg = &spec->autocfg;
2781 bool redone = false;
2782 int i;
2783
2784 again:
2785 spec->multiout.num_dacs = 0;
2786 spec->multiout.hp_nid = 0;
2787 spec->multiout.extra_out_nid[0] = 0;
2788 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
2789 spec->multiout.dac_nids = spec->private_dac_nids;
2790
2791 /* fill hard-wired DACs first */
2792 if (!redone) {
2793 for (i = 0; i < cfg->line_outs; i++)
2794 spec->private_dac_nids[i] =
2795 get_dac_if_single(codec, cfg->line_out_pins[i]);
2796 if (cfg->hp_outs)
2797 spec->multiout.hp_nid =
2798 get_dac_if_single(codec, cfg->hp_pins[0]);
2799 if (cfg->speaker_outs)
2800 spec->multiout.extra_out_nid[0] =
2801 get_dac_if_single(codec, cfg->speaker_pins[0]);
2802 }
2803
2804 for (i = 0; i < cfg->line_outs; i++) {
2805 hda_nid_t pin = cfg->line_out_pins[i];
2806 if (spec->private_dac_nids[i])
2807 continue;
2808 spec->private_dac_nids[i] = alc_auto_look_for_dac(codec, pin);
2809 if (!spec->private_dac_nids[i] && !redone) {
2810 /* if we can't find primary DACs, re-probe without
2811 * checking the hard-wired DACs
2812 */
2813 redone = true;
2814 goto again;
2815 }
2816 }
2817
2818 for (i = 0; i < cfg->line_outs; i++) {
2819 if (spec->private_dac_nids[i])
2820 spec->multiout.num_dacs++;
2821 else
2822 memmove(spec->private_dac_nids + i,
2823 spec->private_dac_nids + i + 1,
2824 sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
2825 }
2826
2827 if (cfg->hp_outs && !spec->multiout.hp_nid)
2828 spec->multiout.hp_nid =
2829 alc_auto_look_for_dac(codec, cfg->hp_pins[0]);
2830 if (cfg->speaker_outs && !spec->multiout.extra_out_nid[0])
2831 spec->multiout.extra_out_nid[0] =
2832 alc_auto_look_for_dac(codec, cfg->speaker_pins[0]);
2833
2834 return 0;
2835}
2836
2837static int alc_auto_add_vol_ctl(struct hda_codec *codec,
2838 const char *pfx, int cidx,
2839 hda_nid_t nid, unsigned int chs)
2840{
2841 return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx,
2842 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
2843}
2844
2845#define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \
2846 alc_auto_add_vol_ctl(codec, pfx, cidx, nid, 3)
2847
2848/* create a mute-switch for the given mixer widget;
2849 * if it has multiple sources (e.g. DAC and loopback), create a bind-mute
5632 */ 2850 */
5633static int alc880_parse_auto_config(struct hda_codec *codec) 2851static int alc_auto_add_sw_ctl(struct hda_codec *codec,
2852 const char *pfx, int cidx,
2853 hda_nid_t nid, unsigned int chs)
2854{
2855 int type;
2856 unsigned long val;
2857 if (snd_hda_get_conn_list(codec, nid, NULL) == 1) {
2858 type = ALC_CTL_WIDGET_MUTE;
2859 val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT);
2860 } else {
2861 type = ALC_CTL_BIND_MUTE;
2862 val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT);
2863 }
2864 return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val);
2865}
2866
2867#define alc_auto_add_stereo_sw(codec, pfx, cidx, nid) \
2868 alc_auto_add_sw_ctl(codec, pfx, cidx, nid, 3)
2869
2870/* add playback controls from the parsed DAC table */
2871static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
2872 const struct auto_pin_cfg *cfg)
5634{ 2873{
5635 struct alc_spec *spec = codec->spec; 2874 struct alc_spec *spec = codec->spec;
2875 hda_nid_t nid, mix, pin;
2876 int i, err, noutputs;
2877
2878 noutputs = cfg->line_outs;
2879 if (spec->multi_ios > 0)
2880 noutputs += spec->multi_ios;
2881
2882 for (i = 0; i < noutputs; i++) {
2883 const char *name;
2884 int index;
2885 nid = spec->multiout.dac_nids[i];
2886 if (!nid)
2887 continue;
2888 if (i >= cfg->line_outs)
2889 pin = spec->multi_io[i - 1].pin;
2890 else
2891 pin = cfg->line_out_pins[i];
2892 mix = alc_auto_dac_to_mix(codec, pin, nid);
2893 if (!mix)
2894 continue;
2895 name = alc_get_line_out_pfx(spec, i, true, &index);
2896 if (!name) {
2897 /* Center/LFE */
2898 err = alc_auto_add_vol_ctl(codec, "Center", 0, nid, 1);
2899 if (err < 0)
2900 return err;
2901 err = alc_auto_add_vol_ctl(codec, "LFE", 0, nid, 2);
2902 if (err < 0)
2903 return err;
2904 err = alc_auto_add_sw_ctl(codec, "Center", 0, mix, 1);
2905 if (err < 0)
2906 return err;
2907 err = alc_auto_add_sw_ctl(codec, "LFE", 0, mix, 2);
2908 if (err < 0)
2909 return err;
2910 } else {
2911 err = alc_auto_add_stereo_vol(codec, name, index, nid);
2912 if (err < 0)
2913 return err;
2914 err = alc_auto_add_stereo_sw(codec, name, index, mix);
2915 if (err < 0)
2916 return err;
2917 }
2918 }
2919 return 0;
2920}
2921
2922/* add playback controls for speaker and HP outputs */
2923static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
2924 hda_nid_t dac, const char *pfx)
2925{
2926 struct alc_spec *spec = codec->spec;
2927 hda_nid_t mix;
5636 int err; 2928 int err;
5637 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
5638 2929
5639 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, 2930 if (!pin)
5640 alc880_ignore); 2931 return 0;
5641 if (err < 0) 2932 if (!dac) {
5642 return err; 2933 /* the corresponding DAC is already occupied */
5643 if (!spec->autocfg.line_outs) 2934 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
5644 return 0; /* can't find valid BIOS pin config */ 2935 return 0; /* no way */
2936 /* create a switch only */
2937 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
2938 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
2939 }
5645 2940
5646 err = alc_auto_fill_dac_nids(codec); 2941 mix = alc_auto_dac_to_mix(codec, pin, dac);
5647 if (err < 0) 2942 if (!mix)
5648 return err; 2943 return 0;
5649 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids); 2944 err = alc_auto_add_stereo_vol(codec, pfx, 0, dac);
5650 if (err < 0)
5651 return err;
5652 err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg);
5653 if (err < 0)
5654 return err;
5655 err = alc_auto_create_hp_out(codec);
5656 if (err < 0)
5657 return err;
5658 err = alc_auto_create_speaker_out(codec);
5659 if (err < 0) 2945 if (err < 0)
5660 return err; 2946 return err;
5661 err = alc_auto_create_input_ctls(codec); 2947 err = alc_auto_add_stereo_sw(codec, pfx, 0, mix);
5662 if (err < 0) 2948 if (err < 0)
5663 return err; 2949 return err;
2950 return 0;
2951}
5664 2952
5665 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 2953static int alc_auto_create_hp_out(struct hda_codec *codec)
2954{
2955 struct alc_spec *spec = codec->spec;
2956 return alc_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
2957 spec->multiout.hp_nid,
2958 "Headphone");
2959}
5666 2960
5667 alc_auto_parse_digital(codec); 2961static int alc_auto_create_speaker_out(struct hda_codec *codec)
2962{
2963 struct alc_spec *spec = codec->spec;
2964 return alc_auto_create_extra_out(codec, spec->autocfg.speaker_pins[0],
2965 spec->multiout.extra_out_nid[0],
2966 "Speaker");
2967}
5668 2968
5669 if (spec->kctls.list) 2969static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
5670 add_mixer(spec, spec->kctls.list); 2970 hda_nid_t nid, int pin_type,
2971 hda_nid_t dac)
2972{
2973 int i, num;
2974 hda_nid_t mix = 0;
2975 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
5671 2976
5672 alc_remove_invalid_adc_nids(codec); 2977 alc_set_pin_output(codec, nid, pin_type);
2978 nid = alc_go_down_to_selector(codec, nid);
2979 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
2980 for (i = 0; i < num; i++) {
2981 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
2982 continue;
2983 mix = srcs[i];
2984 break;
2985 }
2986 if (!mix)
2987 return;
5673 2988
5674 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); 2989 /* need the manual connection? */
5675 alc_auto_check_switches(codec); 2990 if (num > 1)
2991 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
2992 /* unmute mixer widget inputs */
2993 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2994 AMP_IN_UNMUTE(0));
2995 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
2996 AMP_IN_UNMUTE(1));
2997 /* initialize volume */
2998 if (query_amp_caps(codec, dac, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
2999 nid = dac;
3000 else if (query_amp_caps(codec, mix, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
3001 nid = mix;
3002 else
3003 return;
3004 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
3005 AMP_OUT_ZERO);
3006}
3007
3008static void alc_auto_init_multi_out(struct hda_codec *codec)
3009{
3010 struct alc_spec *spec = codec->spec;
3011 int pin_type = get_pin_type(spec->autocfg.line_out_type);
3012 int i;
3013
3014 for (i = 0; i <= HDA_SIDE; i++) {
3015 hda_nid_t nid = spec->autocfg.line_out_pins[i];
3016 if (nid)
3017 alc_auto_set_output_and_unmute(codec, nid, pin_type,
3018 spec->multiout.dac_nids[i]);
3019 }
3020}
3021
3022static void alc_auto_init_extra_out(struct hda_codec *codec)
3023{
3024 struct alc_spec *spec = codec->spec;
3025 hda_nid_t pin;
3026
3027 pin = spec->autocfg.hp_pins[0];
3028 if (pin)
3029 alc_auto_set_output_and_unmute(codec, pin, PIN_HP,
3030 spec->multiout.hp_nid);
3031 pin = spec->autocfg.speaker_pins[0];
3032 if (pin)
3033 alc_auto_set_output_and_unmute(codec, pin, PIN_OUT,
3034 spec->multiout.extra_out_nid[0]);
3035}
5676 3036
3037/*
3038 * multi-io helper
3039 */
3040static int alc_auto_fill_multi_ios(struct hda_codec *codec,
3041 unsigned int location)
3042{
3043 struct alc_spec *spec = codec->spec;
3044 struct auto_pin_cfg *cfg = &spec->autocfg;
3045 int type, i, num_pins = 0;
3046
3047 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
3048 for (i = 0; i < cfg->num_inputs; i++) {
3049 hda_nid_t nid = cfg->inputs[i].pin;
3050 hda_nid_t dac;
3051 unsigned int defcfg, caps;
3052 if (cfg->inputs[i].type != type)
3053 continue;
3054 defcfg = snd_hda_codec_get_pincfg(codec, nid);
3055 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
3056 continue;
3057 if (location && get_defcfg_location(defcfg) != location)
3058 continue;
3059 caps = snd_hda_query_pin_caps(codec, nid);
3060 if (!(caps & AC_PINCAP_OUT))
3061 continue;
3062 dac = alc_auto_look_for_dac(codec, nid);
3063 if (!dac)
3064 continue;
3065 spec->multi_io[num_pins].pin = nid;
3066 spec->multi_io[num_pins].dac = dac;
3067 num_pins++;
3068 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
3069 }
3070 }
3071 spec->multiout.num_dacs = 1;
3072 if (num_pins < 2)
3073 return 0;
3074 return num_pins;
3075}
3076
3077static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
3078 struct snd_ctl_elem_info *uinfo)
3079{
3080 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3081 struct alc_spec *spec = codec->spec;
3082
3083 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3084 uinfo->count = 1;
3085 uinfo->value.enumerated.items = spec->multi_ios + 1;
3086 if (uinfo->value.enumerated.item > spec->multi_ios)
3087 uinfo->value.enumerated.item = spec->multi_ios;
3088 sprintf(uinfo->value.enumerated.name, "%dch",
3089 (uinfo->value.enumerated.item + 1) * 2);
3090 return 0;
3091}
3092
3093static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
3094 struct snd_ctl_elem_value *ucontrol)
3095{
3096 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3097 struct alc_spec *spec = codec->spec;
3098 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
3099 return 0;
3100}
3101
3102static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
3103{
3104 struct alc_spec *spec = codec->spec;
3105 hda_nid_t nid = spec->multi_io[idx].pin;
3106
3107 if (!spec->multi_io[idx].ctl_in)
3108 spec->multi_io[idx].ctl_in =
3109 snd_hda_codec_read(codec, nid, 0,
3110 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3111 if (output) {
3112 snd_hda_codec_update_cache(codec, nid, 0,
3113 AC_VERB_SET_PIN_WIDGET_CONTROL,
3114 PIN_OUT);
3115 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
3116 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3117 HDA_AMP_MUTE, 0);
3118 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
3119 } else {
3120 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
3121 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
3122 HDA_AMP_MUTE, HDA_AMP_MUTE);
3123 snd_hda_codec_update_cache(codec, nid, 0,
3124 AC_VERB_SET_PIN_WIDGET_CONTROL,
3125 spec->multi_io[idx].ctl_in);
3126 }
3127 return 0;
3128}
3129
3130static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
3131 struct snd_ctl_elem_value *ucontrol)
3132{
3133 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3134 struct alc_spec *spec = codec->spec;
3135 int i, ch;
3136
3137 ch = ucontrol->value.enumerated.item[0];
3138 if (ch < 0 || ch > spec->multi_ios)
3139 return -EINVAL;
3140 if (ch == (spec->ext_channel_count - 1) / 2)
3141 return 0;
3142 spec->ext_channel_count = (ch + 1) * 2;
3143 for (i = 0; i < spec->multi_ios; i++)
3144 alc_set_multi_io(codec, i, i < ch);
3145 spec->multiout.max_channels = spec->ext_channel_count;
5677 return 1; 3146 return 1;
5678} 3147}
5679 3148
5680/* additional initialization for auto-configuration model */ 3149static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
5681static void alc880_auto_init(struct hda_codec *codec) 3150 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3151 .name = "Channel Mode",
3152 .info = alc_auto_ch_mode_info,
3153 .get = alc_auto_ch_mode_get,
3154 .put = alc_auto_ch_mode_put,
3155};
3156
3157static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
3158 int (*fill_dac)(struct hda_codec *))
5682{ 3159{
5683 struct alc_spec *spec = codec->spec; 3160 struct alc_spec *spec = codec->spec;
5684 alc_auto_init_multi_out(codec); 3161 struct auto_pin_cfg *cfg = &spec->autocfg;
5685 alc_auto_init_extra_out(codec); 3162 unsigned int location, defcfg;
5686 alc_auto_init_analog_input(codec); 3163 int num_pins;
5687 alc_auto_init_input_src(codec); 3164
5688 alc_auto_init_digital(codec); 3165 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && cfg->hp_outs == 1) {
5689 if (spec->unsol_event) 3166 /* use HP as primary out */
5690 alc_inithook(codec); 3167 cfg->speaker_outs = cfg->line_outs;
3168 memcpy(cfg->speaker_pins, cfg->line_out_pins,
3169 sizeof(cfg->speaker_pins));
3170 cfg->line_outs = cfg->hp_outs;
3171 memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
3172 cfg->hp_outs = 0;
3173 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
3174 cfg->line_out_type = AUTO_PIN_HP_OUT;
3175 if (fill_dac)
3176 fill_dac(codec);
3177 }
3178 if (cfg->line_outs != 1 ||
3179 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
3180 return 0;
3181
3182 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
3183 location = get_defcfg_location(defcfg);
3184
3185 num_pins = alc_auto_fill_multi_ios(codec, location);
3186 if (num_pins > 0) {
3187 struct snd_kcontrol_new *knew;
3188
3189 knew = alc_kcontrol_new(spec);
3190 if (!knew)
3191 return -ENOMEM;
3192 *knew = alc_auto_channel_mode_enum;
3193 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
3194 if (!knew->name)
3195 return -ENOMEM;
3196
3197 spec->multi_ios = num_pins;
3198 spec->ext_channel_count = 2;
3199 spec->multiout.num_dacs = num_pins + 1;
3200 }
3201 return 0;
3202}
3203
3204/* filter out invalid adc_nids (and capsrc_nids) that don't give all
3205 * active input pins
3206 */
3207static void alc_remove_invalid_adc_nids(struct hda_codec *codec)
3208{
3209 struct alc_spec *spec = codec->spec;
3210 const struct hda_input_mux *imux;
3211 hda_nid_t adc_nids[ARRAY_SIZE(spec->private_adc_nids)];
3212 hda_nid_t capsrc_nids[ARRAY_SIZE(spec->private_adc_nids)];
3213 int i, n, nums;
3214
3215 imux = spec->input_mux;
3216 if (!imux)
3217 return;
3218 if (spec->dyn_adc_switch)
3219 return;
3220
3221 nums = 0;
3222 for (n = 0; n < spec->num_adc_nids; n++) {
3223 hda_nid_t cap = spec->private_capsrc_nids[n];
3224 int num_conns = snd_hda_get_conn_list(codec, cap, NULL);
3225 for (i = 0; i < imux->num_items; i++) {
3226 hda_nid_t pin = spec->imux_pins[i];
3227 if (pin) {
3228 if (get_connection_index(codec, cap, pin) < 0)
3229 break;
3230 } else if (num_conns <= imux->items[i].index)
3231 break;
3232 }
3233 if (i >= imux->num_items) {
3234 adc_nids[nums] = spec->private_adc_nids[n];
3235 capsrc_nids[nums++] = cap;
3236 }
3237 }
3238 if (!nums) {
3239 /* check whether ADC-switch is possible */
3240 if (!alc_check_dyn_adc_switch(codec)) {
3241 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
3242 " using fallback 0x%x\n",
3243 codec->chip_name, spec->private_adc_nids[0]);
3244 spec->num_adc_nids = 1;
3245 spec->auto_mic = 0;
3246 return;
3247 }
3248 } else if (nums != spec->num_adc_nids) {
3249 memcpy(spec->private_adc_nids, adc_nids,
3250 nums * sizeof(hda_nid_t));
3251 memcpy(spec->private_capsrc_nids, capsrc_nids,
3252 nums * sizeof(hda_nid_t));
3253 spec->num_adc_nids = nums;
3254 }
3255
3256 if (spec->auto_mic)
3257 alc_auto_mic_check_imux(codec); /* check auto-mic setups */
3258 else if (spec->input_mux->num_items == 1)
3259 spec->num_adc_nids = 1; /* reduce to a single ADC */
3260}
3261
3262/*
3263 * initialize ADC paths
3264 */
3265static void alc_auto_init_adc(struct hda_codec *codec, int adc_idx)
3266{
3267 struct alc_spec *spec = codec->spec;
3268 hda_nid_t nid;
3269
3270 nid = spec->adc_nids[adc_idx];
3271 /* mute ADC */
3272 if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE) {
3273 snd_hda_codec_write(codec, nid, 0,
3274 AC_VERB_SET_AMP_GAIN_MUTE,
3275 AMP_IN_MUTE(0));
3276 return;
3277 }
3278 if (!spec->capsrc_nids)
3279 return;
3280 nid = spec->capsrc_nids[adc_idx];
3281 if (query_amp_caps(codec, nid, HDA_OUTPUT) & AC_AMPCAP_MUTE)
3282 snd_hda_codec_write(codec, nid, 0,
3283 AC_VERB_SET_AMP_GAIN_MUTE,
3284 AMP_OUT_MUTE);
3285}
3286
3287static void alc_auto_init_input_src(struct hda_codec *codec)
3288{
3289 struct alc_spec *spec = codec->spec;
3290 int c, nums;
3291
3292 for (c = 0; c < spec->num_adc_nids; c++)
3293 alc_auto_init_adc(codec, c);
3294 if (spec->dyn_adc_switch)
3295 nums = 1;
3296 else
3297 nums = spec->num_adc_nids;
3298 for (c = 0; c < nums; c++)
3299 alc_mux_select(codec, 0, spec->cur_mux[c], true);
3300}
3301
3302/* add mic boosts if needed */
3303static int alc_auto_add_mic_boost(struct hda_codec *codec)
3304{
3305 struct alc_spec *spec = codec->spec;
3306 struct auto_pin_cfg *cfg = &spec->autocfg;
3307 int i, err;
3308 int type_idx = 0;
3309 hda_nid_t nid;
3310 const char *prev_label = NULL;
3311
3312 for (i = 0; i < cfg->num_inputs; i++) {
3313 if (cfg->inputs[i].type > AUTO_PIN_MIC)
3314 break;
3315 nid = cfg->inputs[i].pin;
3316 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
3317 const char *label;
3318 char boost_label[32];
3319
3320 label = hda_get_autocfg_input_label(codec, cfg, i);
3321 if (prev_label && !strcmp(label, prev_label))
3322 type_idx++;
3323 else
3324 type_idx = 0;
3325 prev_label = label;
3326
3327 snprintf(boost_label, sizeof(boost_label),
3328 "%s Boost Volume", label);
3329 err = add_control(spec, ALC_CTL_WIDGET_VOL,
3330 boost_label, type_idx,
3331 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
3332 if (err < 0)
3333 return err;
3334 }
3335 }
3336 return 0;
5691} 3337}
5692 3338
5693/* select or unmute the given capsrc route */ 3339/* select or unmute the given capsrc route */
@@ -5735,6 +3381,7 @@ static void alc_init_special_input_src(struct hda_codec *codec)
5735 init_capsrc_for_pin(codec, spec->autocfg.inputs[i].pin); 3381 init_capsrc_for_pin(codec, spec->autocfg.inputs[i].pin);
5736} 3382}
5737 3383
3384/* assign appropriate capture mixers */
5738static void set_capture_mixer(struct hda_codec *codec) 3385static void set_capture_mixer(struct hda_codec *codec)
5739{ 3386{
5740 struct alc_spec *spec = codec->spec; 3387 struct alc_spec *spec = codec->spec;
@@ -5780,106 +3427,9 @@ static void set_capture_mixer(struct hda_codec *codec)
5780 } 3427 }
5781} 3428}
5782 3429
5783/* check whether dynamic ADC-switching is available */ 3430/*
5784static bool alc_check_dyn_adc_switch(struct hda_codec *codec) 3431 * Digital-beep handlers
5785{
5786 struct alc_spec *spec = codec->spec;
5787 struct hda_input_mux *imux = &spec->private_imux[0];
5788 int i, n, idx;
5789 hda_nid_t cap, pin;
5790
5791 if (imux != spec->input_mux) /* no dynamic imux? */
5792 return false;
5793
5794 for (n = 0; n < spec->num_adc_nids; n++) {
5795 cap = spec->private_capsrc_nids[n];
5796 for (i = 0; i < imux->num_items; i++) {
5797 pin = spec->imux_pins[i];
5798 if (!pin)
5799 return false;
5800 if (get_connection_index(codec, cap, pin) < 0)
5801 break;
5802 }
5803 if (i >= imux->num_items)
5804 return false; /* no ADC-switch is needed */
5805 }
5806
5807 for (i = 0; i < imux->num_items; i++) {
5808 pin = spec->imux_pins[i];
5809 for (n = 0; n < spec->num_adc_nids; n++) {
5810 cap = spec->private_capsrc_nids[n];
5811 idx = get_connection_index(codec, cap, pin);
5812 if (idx >= 0) {
5813 imux->items[i].index = idx;
5814 spec->dyn_adc_idx[i] = n;
5815 break;
5816 }
5817 }
5818 }
5819
5820 snd_printdd("realtek: enabling ADC switching\n");
5821 spec->dyn_adc_switch = 1;
5822 return true;
5823}
5824
5825/* filter out invalid adc_nids (and capsrc_nids) that don't give all
5826 * active input pins
5827 */ 3432 */
5828static void alc_remove_invalid_adc_nids(struct hda_codec *codec)
5829{
5830 struct alc_spec *spec = codec->spec;
5831 const struct hda_input_mux *imux;
5832 hda_nid_t adc_nids[ARRAY_SIZE(spec->private_adc_nids)];
5833 hda_nid_t capsrc_nids[ARRAY_SIZE(spec->private_adc_nids)];
5834 int i, n, nums;
5835
5836 imux = spec->input_mux;
5837 if (!imux)
5838 return;
5839 if (spec->dyn_adc_switch)
5840 return;
5841
5842 nums = 0;
5843 for (n = 0; n < spec->num_adc_nids; n++) {
5844 hda_nid_t cap = spec->private_capsrc_nids[n];
5845 int num_conns = snd_hda_get_conn_list(codec, cap, NULL);
5846 for (i = 0; i < imux->num_items; i++) {
5847 hda_nid_t pin = spec->imux_pins[i];
5848 if (pin) {
5849 if (get_connection_index(codec, cap, pin) < 0)
5850 break;
5851 } else if (num_conns <= imux->items[i].index)
5852 break;
5853 }
5854 if (i >= imux->num_items) {
5855 adc_nids[nums] = spec->private_adc_nids[n];
5856 capsrc_nids[nums++] = cap;
5857 }
5858 }
5859 if (!nums) {
5860 /* check whether ADC-switch is possible */
5861 if (!alc_check_dyn_adc_switch(codec)) {
5862 printk(KERN_WARNING "hda_codec: %s: no valid ADC found;"
5863 " using fallback 0x%x\n",
5864 codec->chip_name, spec->private_adc_nids[0]);
5865 spec->num_adc_nids = 1;
5866 spec->auto_mic = 0;
5867 return;
5868 }
5869 } else if (nums != spec->num_adc_nids) {
5870 memcpy(spec->private_adc_nids, adc_nids,
5871 nums * sizeof(hda_nid_t));
5872 memcpy(spec->private_capsrc_nids, capsrc_nids,
5873 nums * sizeof(hda_nid_t));
5874 spec->num_adc_nids = nums;
5875 }
5876
5877 if (spec->auto_mic)
5878 alc_auto_mic_check_imux(codec); /* check auto-mic setups */
5879 else if (spec->input_mux->num_items == 1)
5880 spec->num_adc_nids = 1; /* reduce to a single ADC */
5881}
5882
5883#ifdef CONFIG_SND_HDA_INPUT_BEEP 3433#ifdef CONFIG_SND_HDA_INPUT_BEEP
5884#define set_beep_amp(spec, nid, idx, dir) \ 3434#define set_beep_amp(spec, nid, idx, dir) \
5885 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) 3435 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir))
@@ -5907,9 +3457,102 @@ static inline int has_cdefine_beep(struct hda_codec *codec)
5907#define has_cdefine_beep(codec) 0 3457#define has_cdefine_beep(codec) 0
5908#endif 3458#endif
5909 3459
3460/* parse the BIOS configuration and set up the alc_spec */
3461/* return 1 if successful, 0 if the proper config is not found,
3462 * or a negative error code
3463 */
3464static int alc880_parse_auto_config(struct hda_codec *codec)
3465{
3466 struct alc_spec *spec = codec->spec;
3467 int err;
3468 static const hda_nid_t alc880_ignore[] = { 0x1d, 0 };
3469
3470 err = snd_hda_parse_pin_def_config(codec, &spec->autocfg,
3471 alc880_ignore);
3472 if (err < 0)
3473 return err;
3474 if (!spec->autocfg.line_outs)
3475 return 0; /* can't find valid BIOS pin config */
3476
3477 err = alc_auto_fill_dac_nids(codec);
3478 if (err < 0)
3479 return err;
3480 err = alc_auto_add_multi_channel_mode(codec, alc_auto_fill_dac_nids);
3481 if (err < 0)
3482 return err;
3483 err = alc_auto_create_multi_out_ctls(codec, &spec->autocfg);
3484 if (err < 0)
3485 return err;
3486 err = alc_auto_create_hp_out(codec);
3487 if (err < 0)
3488 return err;
3489 err = alc_auto_create_speaker_out(codec);
3490 if (err < 0)
3491 return err;
3492 err = alc_auto_create_input_ctls(codec);
3493 if (err < 0)
3494 return err;
3495
3496 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
3497
3498 alc_auto_parse_digital(codec);
3499
3500 if (spec->kctls.list)
3501 add_mixer(spec, spec->kctls.list);
3502
3503 alc_remove_invalid_adc_nids(codec);
3504
3505 alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0);
3506 alc_auto_check_switches(codec);
3507
3508 return 1;
3509}
3510
3511/* additional initialization for auto-configuration model */
3512static void alc880_auto_init(struct hda_codec *codec)
3513{
3514 struct alc_spec *spec = codec->spec;
3515 alc_auto_init_multi_out(codec);
3516 alc_auto_init_extra_out(codec);
3517 alc_auto_init_analog_input(codec);
3518 alc_auto_init_input_src(codec);
3519 alc_auto_init_digital(codec);
3520 if (spec->unsol_event)
3521 alc_inithook(codec);
3522}
3523
3524#ifdef CONFIG_SND_HDA_POWER_SAVE
3525static const struct hda_amp_list alc880_loopbacks[] = {
3526 { 0x0b, HDA_INPUT, 0 },
3527 { 0x0b, HDA_INPUT, 1 },
3528 { 0x0b, HDA_INPUT, 2 },
3529 { 0x0b, HDA_INPUT, 3 },
3530 { 0x0b, HDA_INPUT, 4 },
3531 { } /* end */
3532};
3533#endif
3534
3535/*
3536 * board setups
3537 */
3538#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
3539#define alc_board_config \
3540 snd_hda_check_board_config
3541#define alc_board_codec_sid_config \
3542 snd_hda_check_board_codec_sid_config
3543#include "alc_quirks.c"
3544#else
3545#define alc_board_config(codec, nums, models, tbl) -1
3546#define alc_board_codec_sid_config(codec, nums, models, tbl) -1
3547#define setup_preset(codec, x) /* NOP */
3548#endif
3549
5910/* 3550/*
5911 * OK, here we have finally the patch for ALC880 3551 * OK, here we have finally the patch for ALC880
5912 */ 3552 */
3553#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
3554#include "alc880_quirks.c"
3555#endif
5913 3556
5914static int patch_alc880(struct hda_codec *codec) 3557static int patch_alc880(struct hda_codec *codec)
5915{ 3558{
@@ -5925,27 +3568,29 @@ static int patch_alc880(struct hda_codec *codec)
5925 3568
5926 spec->mixer_nid = 0x0b; 3569 spec->mixer_nid = 0x0b;
5927 3570
5928 board_config = snd_hda_check_board_config(codec, ALC880_MODEL_LAST, 3571 board_config = alc_board_config(codec, ALC880_MODEL_LAST,
5929 alc880_models, 3572 alc880_models, alc880_cfg_tbl);
5930 alc880_cfg_tbl);
5931 if (board_config < 0) { 3573 if (board_config < 0) {
5932 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 3574 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5933 codec->chip_name); 3575 codec->chip_name);
5934 board_config = ALC880_AUTO; 3576 board_config = ALC_MODEL_AUTO;
5935 } 3577 }
5936 3578
5937 if (board_config == ALC880_AUTO) { 3579 if (board_config == ALC_MODEL_AUTO) {
5938 /* automatic parse from the BIOS config */ 3580 /* automatic parse from the BIOS config */
5939 err = alc880_parse_auto_config(codec); 3581 err = alc880_parse_auto_config(codec);
5940 if (err < 0) { 3582 if (err < 0) {
5941 alc_free(codec); 3583 alc_free(codec);
5942 return err; 3584 return err;
5943 } else if (!err) { 3585 }
3586#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
3587 else if (!err) {
5944 printk(KERN_INFO 3588 printk(KERN_INFO
5945 "hda_codec: Cannot set up configuration " 3589 "hda_codec: Cannot set up configuration "
5946 "from BIOS. Using 3-stack mode...\n"); 3590 "from BIOS. Using 3-stack mode...\n");
5947 board_config = ALC880_3ST; 3591 board_config = ALC880_3ST;
5948 } 3592 }
3593#endif
5949 } 3594 }
5950 3595
5951 err = snd_hda_attach_beep_device(codec, 0x1); 3596 err = snd_hda_attach_beep_device(codec, 0x1);
@@ -5954,7 +3599,7 @@ static int patch_alc880(struct hda_codec *codec)
5954 return err; 3599 return err;
5955 } 3600 }
5956 3601
5957 if (board_config != ALC880_AUTO) 3602 if (board_config != ALC_MODEL_AUTO)
5958 setup_preset(codec, &alc880_presets[board_config]); 3603 setup_preset(codec, &alc880_presets[board_config]);
5959 3604
5960 if (!spec->adc_nids && spec->input_mux) { 3605 if (!spec->adc_nids && spec->input_mux) {
@@ -5968,7 +3613,7 @@ static int patch_alc880(struct hda_codec *codec)
5968 spec->vmaster_nid = 0x0c; 3613 spec->vmaster_nid = 0x0c;
5969 3614
5970 codec->patch_ops = alc_patch_ops; 3615 codec->patch_ops = alc_patch_ops;
5971 if (board_config == ALC880_AUTO) 3616 if (board_config == ALC_MODEL_AUTO)
5972 spec->init_hook = alc880_auto_init; 3617 spec->init_hook = alc880_auto_init;
5973#ifdef CONFIG_SND_HDA_POWER_SAVE 3618#ifdef CONFIG_SND_HDA_POWER_SAVE
5974 if (!spec->loopback.amplist) 3619 if (!spec->loopback.amplist)
@@ -5983,1077 +3628,6 @@ static int patch_alc880(struct hda_codec *codec)
5983 * ALC260 support 3628 * ALC260 support
5984 */ 3629 */
5985 3630
5986static const hda_nid_t alc260_dac_nids[1] = {
5987 /* front */
5988 0x02,
5989};
5990
5991static const hda_nid_t alc260_adc_nids[1] = {
5992 /* ADC0 */
5993 0x04,
5994};
5995
5996static const hda_nid_t alc260_adc_nids_alt[1] = {
5997 /* ADC1 */
5998 0x05,
5999};
6000
6001/* NIDs used when simultaneous access to both ADCs makes sense. Note that
6002 * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC.
6003 */
6004static const hda_nid_t alc260_dual_adc_nids[2] = {
6005 /* ADC0, ADC1 */
6006 0x04, 0x05
6007};
6008
6009#define ALC260_DIGOUT_NID 0x03
6010#define ALC260_DIGIN_NID 0x06
6011
6012static const struct hda_input_mux alc260_capture_source = {
6013 .num_items = 4,
6014 .items = {
6015 { "Mic", 0x0 },
6016 { "Front Mic", 0x1 },
6017 { "Line", 0x2 },
6018 { "CD", 0x4 },
6019 },
6020};
6021
6022/* On Fujitsu S702x laptops capture only makes sense from Mic/LineIn jack,
6023 * headphone jack and the internal CD lines since these are the only pins at
6024 * which audio can appear. For flexibility, also allow the option of
6025 * recording the mixer output on the second ADC (ADC0 doesn't have a
6026 * connection to the mixer output).
6027 */
6028static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = {
6029 {
6030 .num_items = 3,
6031 .items = {
6032 { "Mic/Line", 0x0 },
6033 { "CD", 0x4 },
6034 { "Headphone", 0x2 },
6035 },
6036 },
6037 {
6038 .num_items = 4,
6039 .items = {
6040 { "Mic/Line", 0x0 },
6041 { "CD", 0x4 },
6042 { "Headphone", 0x2 },
6043 { "Mixer", 0x5 },
6044 },
6045 },
6046
6047};
6048
6049/* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to
6050 * the Fujitsu S702x, but jacks are marked differently.
6051 */
6052static const struct hda_input_mux alc260_acer_capture_sources[2] = {
6053 {
6054 .num_items = 4,
6055 .items = {
6056 { "Mic", 0x0 },
6057 { "Line", 0x2 },
6058 { "CD", 0x4 },
6059 { "Headphone", 0x5 },
6060 },
6061 },
6062 {
6063 .num_items = 5,
6064 .items = {
6065 { "Mic", 0x0 },
6066 { "Line", 0x2 },
6067 { "CD", 0x4 },
6068 { "Headphone", 0x6 },
6069 { "Mixer", 0x5 },
6070 },
6071 },
6072};
6073
6074/* Maxdata Favorit 100XS */
6075static const struct hda_input_mux alc260_favorit100_capture_sources[2] = {
6076 {
6077 .num_items = 2,
6078 .items = {
6079 { "Line/Mic", 0x0 },
6080 { "CD", 0x4 },
6081 },
6082 },
6083 {
6084 .num_items = 3,
6085 .items = {
6086 { "Line/Mic", 0x0 },
6087 { "CD", 0x4 },
6088 { "Mixer", 0x5 },
6089 },
6090 },
6091};
6092
6093/*
6094 * This is just place-holder, so there's something for alc_build_pcms to look
6095 * at when it calculates the maximum number of channels. ALC260 has no mixer
6096 * element which allows changing the channel mode, so the verb list is
6097 * never used.
6098 */
6099static const struct hda_channel_mode alc260_modes[1] = {
6100 { 2, NULL },
6101};
6102
6103
6104/* Mixer combinations
6105 *
6106 * basic: base_output + input + pc_beep + capture
6107 * HP: base_output + input + capture_alt
6108 * HP_3013: hp_3013 + input + capture
6109 * fujitsu: fujitsu + capture
6110 * acer: acer + capture
6111 */
6112
6113static const struct snd_kcontrol_new alc260_base_output_mixer[] = {
6114 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6115 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6116 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6117 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6118 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6119 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6120 { } /* end */
6121};
6122
6123static const struct snd_kcontrol_new alc260_input_mixer[] = {
6124 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6125 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6126 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6127 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6128 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6129 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6130 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x07, 0x01, HDA_INPUT),
6131 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x07, 0x01, HDA_INPUT),
6132 { } /* end */
6133};
6134
6135/* update HP, line and mono out pins according to the master switch */
6136static void alc260_hp_master_update(struct hda_codec *codec)
6137{
6138 update_speakers(codec);
6139}
6140
6141static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol,
6142 struct snd_ctl_elem_value *ucontrol)
6143{
6144 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6145 struct alc_spec *spec = codec->spec;
6146 *ucontrol->value.integer.value = !spec->master_mute;
6147 return 0;
6148}
6149
6150static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol,
6151 struct snd_ctl_elem_value *ucontrol)
6152{
6153 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
6154 struct alc_spec *spec = codec->spec;
6155 int val = !*ucontrol->value.integer.value;
6156
6157 if (val == spec->master_mute)
6158 return 0;
6159 spec->master_mute = val;
6160 alc260_hp_master_update(codec);
6161 return 1;
6162}
6163
6164static const struct snd_kcontrol_new alc260_hp_output_mixer[] = {
6165 {
6166 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6167 .name = "Master Playback Switch",
6168 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6169 .info = snd_ctl_boolean_mono_info,
6170 .get = alc260_hp_master_sw_get,
6171 .put = alc260_hp_master_sw_put,
6172 },
6173 HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6174 HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT),
6175 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6176 HDA_BIND_MUTE("Headphone Playback Switch", 0x09, 2, HDA_INPUT),
6177 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6178 HDA_OUTPUT),
6179 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6180 { } /* end */
6181};
6182
6183static const struct hda_verb alc260_hp_unsol_verbs[] = {
6184 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6185 {},
6186};
6187
6188static void alc260_hp_setup(struct hda_codec *codec)
6189{
6190 struct alc_spec *spec = codec->spec;
6191
6192 spec->autocfg.hp_pins[0] = 0x0f;
6193 spec->autocfg.speaker_pins[0] = 0x10;
6194 spec->autocfg.speaker_pins[1] = 0x11;
6195 spec->automute = 1;
6196 spec->automute_mode = ALC_AUTOMUTE_PIN;
6197}
6198
6199static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = {
6200 {
6201 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
6202 .name = "Master Playback Switch",
6203 .subdevice = HDA_SUBDEV_NID_FLAG | 0x11,
6204 .info = snd_ctl_boolean_mono_info,
6205 .get = alc260_hp_master_sw_get,
6206 .put = alc260_hp_master_sw_put,
6207 },
6208 HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6209 HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6210 HDA_CODEC_VOLUME("Aux-In Playback Volume", 0x07, 0x06, HDA_INPUT),
6211 HDA_CODEC_MUTE("Aux-In Playback Switch", 0x07, 0x06, HDA_INPUT),
6212 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6213 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
6214 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6215 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x11, 1, 0x0, HDA_OUTPUT),
6216 { } /* end */
6217};
6218
6219static void alc260_hp_3013_setup(struct hda_codec *codec)
6220{
6221 struct alc_spec *spec = codec->spec;
6222
6223 spec->autocfg.hp_pins[0] = 0x15;
6224 spec->autocfg.speaker_pins[0] = 0x10;
6225 spec->autocfg.speaker_pins[1] = 0x11;
6226 spec->automute = 1;
6227 spec->automute_mode = ALC_AUTOMUTE_PIN;
6228}
6229
6230static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = {
6231 .ops = &snd_hda_bind_vol,
6232 .values = {
6233 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT),
6234 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT),
6235 HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT),
6236 0
6237 },
6238};
6239
6240static const struct hda_bind_ctls alc260_dc7600_bind_switch = {
6241 .ops = &snd_hda_bind_sw,
6242 .values = {
6243 HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT),
6244 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
6245 0
6246 },
6247};
6248
6249static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = {
6250 HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol),
6251 HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch),
6252 HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT),
6253 HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT),
6254 { } /* end */
6255};
6256
6257static const struct hda_verb alc260_hp_3013_unsol_verbs[] = {
6258 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6259 {},
6260};
6261
6262static void alc260_hp_3012_setup(struct hda_codec *codec)
6263{
6264 struct alc_spec *spec = codec->spec;
6265
6266 spec->autocfg.hp_pins[0] = 0x10;
6267 spec->autocfg.speaker_pins[0] = 0x0f;
6268 spec->autocfg.speaker_pins[1] = 0x11;
6269 spec->autocfg.speaker_pins[2] = 0x15;
6270 spec->automute = 1;
6271 spec->automute_mode = ALC_AUTOMUTE_PIN;
6272}
6273
6274/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12,
6275 * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10.
6276 */
6277static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = {
6278 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6279 HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT),
6280 ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6281 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6282 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6283 HDA_CODEC_VOLUME("Mic/Line Playback Volume", 0x07, 0x0, HDA_INPUT),
6284 HDA_CODEC_MUTE("Mic/Line Playback Switch", 0x07, 0x0, HDA_INPUT),
6285 ALC_PIN_MODE("Mic/Line Jack Mode", 0x12, ALC_PIN_DIR_IN),
6286 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6287 HDA_BIND_MUTE("Speaker Playback Switch", 0x09, 2, HDA_INPUT),
6288 { } /* end */
6289};
6290
6291/* Mixer for Acer TravelMate(/Extensa/Aspire) notebooks. Note that current
6292 * versions of the ALC260 don't act on requests to enable mic bias from NID
6293 * 0x0f (used to drive the headphone jack in these laptops). The ALC260
6294 * datasheet doesn't mention this restriction. At this stage it's not clear
6295 * whether this behaviour is intentional or is a hardware bug in chip
6296 * revisions available in early 2006. Therefore for now allow the
6297 * "Headphone Jack Mode" control to span all choices, but if it turns out
6298 * that the lack of mic bias for this NID is intentional we could change the
6299 * mode from ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6300 *
6301 * In addition, Acer TravelMate(/Extensa/Aspire) notebooks in early 2006
6302 * don't appear to make the mic bias available from the "line" jack, even
6303 * though the NID used for this jack (0x14) can supply it. The theory is
6304 * that perhaps Acer have included blocking capacitors between the ALC260
6305 * and the output jack. If this turns out to be the case for all such
6306 * models the "Line Jack Mode" mode could be changed from ALC_PIN_DIR_INOUT
6307 * to ALC_PIN_DIR_INOUT_NOMICBIAS.
6308 *
6309 * The C20x Tablet series have a mono internal speaker which is controlled
6310 * via the chip's Mono sum widget and pin complex, so include the necessary
6311 * controls for such models. On models without a "mono speaker" the control
6312 * won't do anything.
6313 */
6314static const struct snd_kcontrol_new alc260_acer_mixer[] = {
6315 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6316 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6317 ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6318 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0a, 1, 0x0,
6319 HDA_OUTPUT),
6320 HDA_BIND_MUTE_MONO("Speaker Playback Switch", 0x0a, 1, 2,
6321 HDA_INPUT),
6322 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6323 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6324 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6325 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6326 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6327 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6328 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6329 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6330 { } /* end */
6331};
6332
6333/* Maxdata Favorit 100XS: one output and one input (0x12) jack
6334 */
6335static const struct snd_kcontrol_new alc260_favorit100_mixer[] = {
6336 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6337 HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT),
6338 ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT),
6339 HDA_CODEC_VOLUME("Line/Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6340 HDA_CODEC_MUTE("Line/Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6341 ALC_PIN_MODE("Line/Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6342 { } /* end */
6343};
6344
6345/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12,
6346 * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17.
6347 */
6348static const struct snd_kcontrol_new alc260_will_mixer[] = {
6349 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6350 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6351 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6352 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6353 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6354 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6355 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6356 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6357 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6358 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6359 { } /* end */
6360};
6361
6362/* Replacer 672V ALC260 pin usage: Mic jack = 0x12,
6363 * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f.
6364 */
6365static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = {
6366 HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6367 HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT),
6368 HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT),
6369 HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT),
6370 ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN),
6371 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT),
6372 HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT),
6373 HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT),
6374 HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT),
6375 ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT),
6376 { } /* end */
6377};
6378
6379/*
6380 * initialization verbs
6381 */
6382static const struct hda_verb alc260_init_verbs[] = {
6383 /* Line In pin widget for input */
6384 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6385 /* CD pin widget for input */
6386 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6387 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6388 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6389 /* Mic2 (front panel) pin widget for input and vref at 80% */
6390 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6391 /* LINE-2 is used for line-out in rear */
6392 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6393 /* select line-out */
6394 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
6395 /* LINE-OUT pin */
6396 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6397 /* enable HP */
6398 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6399 /* enable Mono */
6400 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6401 /* mute capture amp left and right */
6402 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6403 /* set connection select to line in (default select for this ADC) */
6404 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6405 /* mute capture amp left and right */
6406 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6407 /* set connection select to line in (default select for this ADC) */
6408 {0x05, AC_VERB_SET_CONNECT_SEL, 0x02},
6409 /* set vol=0 Line-Out mixer amp left and right */
6410 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6411 /* unmute pin widget amp left and right (no gain on this amp) */
6412 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6413 /* set vol=0 HP mixer amp left and right */
6414 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6415 /* unmute pin widget amp left and right (no gain on this amp) */
6416 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6417 /* set vol=0 Mono mixer amp left and right */
6418 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6419 /* unmute pin widget amp left and right (no gain on this amp) */
6420 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6421 /* unmute LINE-2 out pin */
6422 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6423 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6424 * Line In 2 = 0x03
6425 */
6426 /* mute analog inputs */
6427 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6428 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6429 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6430 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6431 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6432 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6433 /* mute Front out path */
6434 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6435 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6436 /* mute Headphone out path */
6437 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6438 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6439 /* mute Mono out path */
6440 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6441 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6442 { }
6443};
6444
6445#if 0 /* should be identical with alc260_init_verbs? */
6446static const struct hda_verb alc260_hp_init_verbs[] = {
6447 /* Headphone and output */
6448 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6449 /* mono output */
6450 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6451 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6452 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6453 /* Mic2 (front panel) pin widget for input and vref at 80% */
6454 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6455 /* Line In pin widget for input */
6456 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6457 /* Line-2 pin widget for output */
6458 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6459 /* CD pin widget for input */
6460 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6461 /* unmute amp left and right */
6462 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6463 /* set connection select to line in (default select for this ADC) */
6464 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6465 /* unmute Line-Out mixer amp left and right (volume = 0) */
6466 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6467 /* mute pin widget amp left and right (no gain on this amp) */
6468 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6469 /* unmute HP mixer amp left and right (volume = 0) */
6470 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6471 /* mute pin widget amp left and right (no gain on this amp) */
6472 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6473 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6474 * Line In 2 = 0x03
6475 */
6476 /* mute analog inputs */
6477 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6478 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6479 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6480 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6481 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6482 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6483 /* Unmute Front out path */
6484 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6485 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6486 /* Unmute Headphone out path */
6487 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6488 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6489 /* Unmute Mono out path */
6490 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6491 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6492 { }
6493};
6494#endif
6495
6496static const struct hda_verb alc260_hp_3013_init_verbs[] = {
6497 /* Line out and output */
6498 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6499 /* mono output */
6500 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
6501 /* Mic1 (rear panel) pin widget for input and vref at 80% */
6502 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6503 /* Mic2 (front panel) pin widget for input and vref at 80% */
6504 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
6505 /* Line In pin widget for input */
6506 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6507 /* Headphone pin widget for output */
6508 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
6509 /* CD pin widget for input */
6510 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
6511 /* unmute amp left and right */
6512 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000},
6513 /* set connection select to line in (default select for this ADC) */
6514 {0x04, AC_VERB_SET_CONNECT_SEL, 0x02},
6515 /* unmute Line-Out mixer amp left and right (volume = 0) */
6516 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6517 /* mute pin widget amp left and right (no gain on this amp) */
6518 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6519 /* unmute HP mixer amp left and right (volume = 0) */
6520 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
6521 /* mute pin widget amp left and right (no gain on this amp) */
6522 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
6523 /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 &
6524 * Line In 2 = 0x03
6525 */
6526 /* mute analog inputs */
6527 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6528 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6529 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
6530 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
6531 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
6532 /* Amp Indexes: DAC = 0x01 & mixer = 0x00 */
6533 /* Unmute Front out path */
6534 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6535 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6536 /* Unmute Headphone out path */
6537 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6538 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6539 /* Unmute Mono out path */
6540 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
6541 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
6542 { }
6543};
6544
6545/* Initialisation sequence for ALC260 as configured in Fujitsu S702x
6546 * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD
6547 * audio = 0x16, internal speaker = 0x10.
6548 */
6549static const struct hda_verb alc260_fujitsu_init_verbs[] = {
6550 /* Disable all GPIOs */
6551 {0x01, AC_VERB_SET_GPIO_MASK, 0},
6552 /* Internal speaker is connected to headphone pin */
6553 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6554 /* Headphone/Line-out jack connects to Line1 pin; make it an output */
6555 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6556 /* Mic/Line-in jack is connected to mic1 pin, so make it an input */
6557 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6558 /* Ensure all other unused pins are disabled and muted. */
6559 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6560 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6561 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6562 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6563 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6564 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6565 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6566 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6567
6568 /* Disable digital (SPDIF) pins */
6569 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6570 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6571
6572 /* Ensure Line1 pin widget takes its input from the OUT1 sum bus
6573 * when acting as an output.
6574 */
6575 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6576
6577 /* Start with output sum widgets muted and their output gains at min */
6578 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6579 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6580 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6581 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6582 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6583 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6584 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6585 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6586 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6587
6588 /* Unmute HP pin widget amp left and right (no equiv mixer ctrl) */
6589 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6590 /* Unmute Line1 pin widget output buffer since it starts as an output.
6591 * If the pin mode is changed by the user the pin mode control will
6592 * take care of enabling the pin's input/output buffers as needed.
6593 * Therefore there's no need to enable the input buffer at this
6594 * stage.
6595 */
6596 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6597 /* Unmute input buffer of pin widget used for Line-in (no equiv
6598 * mixer ctrl)
6599 */
6600 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6601
6602 /* Mute capture amp left and right */
6603 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6604 /* Set ADC connection select to match default mixer setting - line
6605 * in (on mic1 pin)
6606 */
6607 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6608
6609 /* Do the same for the second ADC: mute capture input amp and
6610 * set ADC connection to line in (on mic1 pin)
6611 */
6612 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6613 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6614
6615 /* Mute all inputs to mixer widget (even unconnected ones) */
6616 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6617 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6618 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6619 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6620 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6621 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6622 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6623 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6624
6625 { }
6626};
6627
6628/* Initialisation sequence for ALC260 as configured in Acer TravelMate and
6629 * similar laptops (adapted from Fujitsu init verbs).
6630 */
6631static const struct hda_verb alc260_acer_init_verbs[] = {
6632 /* On TravelMate laptops, GPIO 0 enables the internal speaker and
6633 * the headphone jack. Turn this on and rely on the standard mute
6634 * methods whenever the user wants to turn these outputs off.
6635 */
6636 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6637 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6638 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6639 /* Internal speaker/Headphone jack is connected to Line-out pin */
6640 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6641 /* Internal microphone/Mic jack is connected to Mic1 pin */
6642 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6643 /* Line In jack is connected to Line1 pin */
6644 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
6645 /* Some Acers (eg: C20x Tablets) use Mono pin for internal speaker */
6646 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6647 /* Ensure all other unused pins are disabled and muted. */
6648 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6649 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6650 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6651 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6652 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6653 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6654 /* Disable digital (SPDIF) pins */
6655 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6656 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6657
6658 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6659 * bus when acting as outputs.
6660 */
6661 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6662 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6663
6664 /* Start with output sum widgets muted and their output gains at min */
6665 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6666 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6667 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6668 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6669 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6670 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6671 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6672 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6673 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6674
6675 /* Unmute Line-out pin widget amp left and right
6676 * (no equiv mixer ctrl)
6677 */
6678 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6679 /* Unmute mono pin widget amp output (no equiv mixer ctrl) */
6680 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6681 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6682 * inputs. If the pin mode is changed by the user the pin mode control
6683 * will take care of enabling the pin's input/output buffers as needed.
6684 * Therefore there's no need to enable the input buffer at this
6685 * stage.
6686 */
6687 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6688 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6689
6690 /* Mute capture amp left and right */
6691 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6692 /* Set ADC connection select to match default mixer setting - mic
6693 * (on mic1 pin)
6694 */
6695 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6696
6697 /* Do similar with the second ADC: mute capture input amp and
6698 * set ADC connection to mic to match ALSA's default state.
6699 */
6700 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6701 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6702
6703 /* Mute all inputs to mixer widget (even unconnected ones) */
6704 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6705 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6706 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6707 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6708 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6709 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6710 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6711 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6712
6713 { }
6714};
6715
6716/* Initialisation sequence for Maxdata Favorit 100XS
6717 * (adapted from Acer init verbs).
6718 */
6719static const struct hda_verb alc260_favorit100_init_verbs[] = {
6720 /* GPIO 0 enables the output jack.
6721 * Turn this on and rely on the standard mute
6722 * methods whenever the user wants to turn these outputs off.
6723 */
6724 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6725 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6726 {0x01, AC_VERB_SET_GPIO_DATA, 0x01},
6727 /* Line/Mic input jack is connected to Mic1 pin */
6728 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
6729 /* Ensure all other unused pins are disabled and muted. */
6730 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6731 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6732 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6733 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6734 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6735 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6736 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6737 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6738 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0},
6739 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6740 /* Disable digital (SPDIF) pins */
6741 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6742 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6743
6744 /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum
6745 * bus when acting as outputs.
6746 */
6747 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6748 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6749
6750 /* Start with output sum widgets muted and their output gains at min */
6751 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6752 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6753 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6754 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6755 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6756 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6757 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6758 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
6759 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
6760
6761 /* Unmute Line-out pin widget amp left and right
6762 * (no equiv mixer ctrl)
6763 */
6764 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
6765 /* Unmute Mic1 and Line1 pin widget input buffers since they start as
6766 * inputs. If the pin mode is changed by the user the pin mode control
6767 * will take care of enabling the pin's input/output buffers as needed.
6768 * Therefore there's no need to enable the input buffer at this
6769 * stage.
6770 */
6771 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
6772
6773 /* Mute capture amp left and right */
6774 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6775 /* Set ADC connection select to match default mixer setting - mic
6776 * (on mic1 pin)
6777 */
6778 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
6779
6780 /* Do similar with the second ADC: mute capture input amp and
6781 * set ADC connection to mic to match ALSA's default state.
6782 */
6783 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
6784 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
6785
6786 /* Mute all inputs to mixer widget (even unconnected ones) */
6787 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
6788 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
6789 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
6790 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
6791 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
6792 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
6793 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
6794 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
6795
6796 { }
6797};
6798
6799static const struct hda_verb alc260_will_verbs[] = {
6800 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6801 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00},
6802 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
6803 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6804 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6805 {0x1a, AC_VERB_SET_PROC_COEF, 0x3040},
6806 {}
6807};
6808
6809static const struct hda_verb alc260_replacer_672v_verbs[] = {
6810 {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
6811 {0x1a, AC_VERB_SET_COEF_INDEX, 0x07},
6812 {0x1a, AC_VERB_SET_PROC_COEF, 0x3050},
6813
6814 {0x01, AC_VERB_SET_GPIO_MASK, 0x01},
6815 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01},
6816 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6817
6818 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6819 {}
6820};
6821
6822/* toggle speaker-output according to the hp-jack state */
6823static void alc260_replacer_672v_automute(struct hda_codec *codec)
6824{
6825 unsigned int present;
6826
6827 /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */
6828 present = snd_hda_jack_detect(codec, 0x0f);
6829 if (present) {
6830 snd_hda_codec_write_cache(codec, 0x01, 0,
6831 AC_VERB_SET_GPIO_DATA, 1);
6832 snd_hda_codec_write_cache(codec, 0x0f, 0,
6833 AC_VERB_SET_PIN_WIDGET_CONTROL,
6834 PIN_HP);
6835 } else {
6836 snd_hda_codec_write_cache(codec, 0x01, 0,
6837 AC_VERB_SET_GPIO_DATA, 0);
6838 snd_hda_codec_write_cache(codec, 0x0f, 0,
6839 AC_VERB_SET_PIN_WIDGET_CONTROL,
6840 PIN_OUT);
6841 }
6842}
6843
6844static void alc260_replacer_672v_unsol_event(struct hda_codec *codec,
6845 unsigned int res)
6846{
6847 if ((res >> 26) == ALC880_HP_EVENT)
6848 alc260_replacer_672v_automute(codec);
6849}
6850
6851static const struct hda_verb alc260_hp_dc7600_verbs[] = {
6852 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
6853 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
6854 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6855 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
6856 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6857 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6858 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
6859 {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6860 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6861 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
6862 {}
6863};
6864
6865/* Test configuration for debugging, modelled after the ALC880 test
6866 * configuration.
6867 */
6868#ifdef CONFIG_SND_DEBUG
6869static const hda_nid_t alc260_test_dac_nids[1] = {
6870 0x02,
6871};
6872static const hda_nid_t alc260_test_adc_nids[2] = {
6873 0x04, 0x05,
6874};
6875/* For testing the ALC260, each input MUX needs its own definition since
6876 * the signal assignments are different. This assumes that the first ADC
6877 * is NID 0x04.
6878 */
6879static const struct hda_input_mux alc260_test_capture_sources[2] = {
6880 {
6881 .num_items = 7,
6882 .items = {
6883 { "MIC1 pin", 0x0 },
6884 { "MIC2 pin", 0x1 },
6885 { "LINE1 pin", 0x2 },
6886 { "LINE2 pin", 0x3 },
6887 { "CD pin", 0x4 },
6888 { "LINE-OUT pin", 0x5 },
6889 { "HP-OUT pin", 0x6 },
6890 },
6891 },
6892 {
6893 .num_items = 8,
6894 .items = {
6895 { "MIC1 pin", 0x0 },
6896 { "MIC2 pin", 0x1 },
6897 { "LINE1 pin", 0x2 },
6898 { "LINE2 pin", 0x3 },
6899 { "CD pin", 0x4 },
6900 { "Mixer", 0x5 },
6901 { "LINE-OUT pin", 0x6 },
6902 { "HP-OUT pin", 0x7 },
6903 },
6904 },
6905};
6906static const struct snd_kcontrol_new alc260_test_mixer[] = {
6907 /* Output driver widgets */
6908 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
6909 HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT),
6910 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x09, 0x0, HDA_OUTPUT),
6911 HDA_BIND_MUTE("LOUT2 Playback Switch", 0x09, 2, HDA_INPUT),
6912 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x08, 0x0, HDA_OUTPUT),
6913 HDA_BIND_MUTE("LOUT1 Playback Switch", 0x08, 2, HDA_INPUT),
6914
6915 /* Modes for retasking pin widgets
6916 * Note: the ALC260 doesn't seem to act on requests to enable mic
6917 * bias from NIDs 0x0f and 0x10. The ALC260 datasheet doesn't
6918 * mention this restriction. At this stage it's not clear whether
6919 * this behaviour is intentional or is a hardware bug in chip
6920 * revisions available at least up until early 2006. Therefore for
6921 * now allow the "HP-OUT" and "LINE-OUT" Mode controls to span all
6922 * choices, but if it turns out that the lack of mic bias for these
6923 * NIDs is intentional we could change their modes from
6924 * ALC_PIN_DIR_INOUT to ALC_PIN_DIR_INOUT_NOMICBIAS.
6925 */
6926 ALC_PIN_MODE("HP-OUT pin mode", 0x10, ALC_PIN_DIR_INOUT),
6927 ALC_PIN_MODE("LINE-OUT pin mode", 0x0f, ALC_PIN_DIR_INOUT),
6928 ALC_PIN_MODE("LINE2 pin mode", 0x15, ALC_PIN_DIR_INOUT),
6929 ALC_PIN_MODE("LINE1 pin mode", 0x14, ALC_PIN_DIR_INOUT),
6930 ALC_PIN_MODE("MIC2 pin mode", 0x13, ALC_PIN_DIR_INOUT),
6931 ALC_PIN_MODE("MIC1 pin mode", 0x12, ALC_PIN_DIR_INOUT),
6932
6933 /* Loopback mixer controls */
6934 HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x07, 0x00, HDA_INPUT),
6935 HDA_CODEC_MUTE("MIC1 Playback Switch", 0x07, 0x00, HDA_INPUT),
6936 HDA_CODEC_VOLUME("MIC2 Playback Volume", 0x07, 0x01, HDA_INPUT),
6937 HDA_CODEC_MUTE("MIC2 Playback Switch", 0x07, 0x01, HDA_INPUT),
6938 HDA_CODEC_VOLUME("LINE1 Playback Volume", 0x07, 0x02, HDA_INPUT),
6939 HDA_CODEC_MUTE("LINE1 Playback Switch", 0x07, 0x02, HDA_INPUT),
6940 HDA_CODEC_VOLUME("LINE2 Playback Volume", 0x07, 0x03, HDA_INPUT),
6941 HDA_CODEC_MUTE("LINE2 Playback Switch", 0x07, 0x03, HDA_INPUT),
6942 HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT),
6943 HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT),
6944 HDA_CODEC_VOLUME("LINE-OUT loopback Playback Volume", 0x07, 0x06, HDA_INPUT),
6945 HDA_CODEC_MUTE("LINE-OUT loopback Playback Switch", 0x07, 0x06, HDA_INPUT),
6946 HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x07, 0x7, HDA_INPUT),
6947 HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x07, 0x7, HDA_INPUT),
6948
6949 /* Controls for GPIO pins, assuming they are configured as outputs */
6950 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
6951 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
6952 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
6953 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
6954
6955 /* Switches to allow the digital IO pins to be enabled. The datasheet
6956 * is ambigious as to which NID is which; testing on laptops which
6957 * make this output available should provide clarification.
6958 */
6959 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01),
6960 ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01),
6961
6962 /* A switch allowing EAPD to be enabled. Some laptops seem to use
6963 * this output to turn on an external amplifier.
6964 */
6965 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
6966 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
6967
6968 { } /* end */
6969};
6970static const struct hda_verb alc260_test_init_verbs[] = {
6971 /* Enable all GPIOs as outputs with an initial value of 0 */
6972 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f},
6973 {0x01, AC_VERB_SET_GPIO_DATA, 0x00},
6974 {0x01, AC_VERB_SET_GPIO_MASK, 0x0f},
6975
6976 /* Enable retasking pins as output, initially without power amp */
6977 {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6978 {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6979 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6980 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6981 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6982 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
6983
6984 /* Disable digital (SPDIF) pins initially, but users can enable
6985 * them via a mixer switch. In the case of SPDIF-out, this initverb
6986 * payload also sets the generation to 0, output to be in "consumer"
6987 * PCM format, copyright asserted, no pre-emphasis and no validity
6988 * control.
6989 */
6990 {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0},
6991 {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0},
6992
6993 /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the
6994 * OUT1 sum bus when acting as an output.
6995 */
6996 {0x0b, AC_VERB_SET_CONNECT_SEL, 0},
6997 {0x0c, AC_VERB_SET_CONNECT_SEL, 0},
6998 {0x0d, AC_VERB_SET_CONNECT_SEL, 0},
6999 {0x0e, AC_VERB_SET_CONNECT_SEL, 0},
7000
7001 /* Start with output sum widgets muted and their output gains at min */
7002 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7003 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7004 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7005 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7006 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7007 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7008 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7009 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7010 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
7011
7012 /* Unmute retasking pin widget output buffers since the default
7013 * state appears to be output. As the pin mode is changed by the
7014 * user the pin mode control will take care of enabling the pin's
7015 * input/output buffers as needed.
7016 */
7017 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7018 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7019 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7020 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7021 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7022 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7023 /* Also unmute the mono-out pin widget */
7024 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7025
7026 /* Mute capture amp left and right */
7027 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7028 /* Set ADC connection select to match default mixer setting (mic1
7029 * pin)
7030 */
7031 {0x04, AC_VERB_SET_CONNECT_SEL, 0x00},
7032
7033 /* Do the same for the second ADC: mute capture input amp and
7034 * set ADC connection to mic1 pin
7035 */
7036 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7037 {0x05, AC_VERB_SET_CONNECT_SEL, 0x00},
7038
7039 /* Mute all inputs to mixer widget (even unconnected ones) */
7040 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* mic1 pin */
7041 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* mic2 pin */
7042 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, /* line1 pin */
7043 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, /* line2 pin */
7044 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* CD pin */
7045 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, /* Beep-gen pin */
7046 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, /* Line-out pin */
7047 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, /* HP-pin pin */
7048
7049 { }
7050};
7051#endif
7052
7053/*
7054 * for BIOS auto-configuration
7055 */
7056
7057/* convert from pin to volume-mixer widget */ 3631/* convert from pin to volume-mixer widget */
7058static hda_nid_t alc260_pin_to_vol_mix(hda_nid_t nid) 3632static hda_nid_t alc260_pin_to_vol_mix(hda_nid_t nid)
7059{ 3633{
@@ -7259,186 +3833,10 @@ static const struct snd_pci_quirk alc260_fixup_tbl[] = {
7259}; 3833};
7260 3834
7261/* 3835/*
7262 * ALC260 configurations
7263 */ 3836 */
7264static const char * const alc260_models[ALC260_MODEL_LAST] = { 3837#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
7265 [ALC260_BASIC] = "basic", 3838#include "alc260_quirks.c"
7266 [ALC260_HP] = "hp",
7267 [ALC260_HP_3013] = "hp-3013",
7268 [ALC260_HP_DC7600] = "hp-dc7600",
7269 [ALC260_FUJITSU_S702X] = "fujitsu",
7270 [ALC260_ACER] = "acer",
7271 [ALC260_WILL] = "will",
7272 [ALC260_REPLACER_672V] = "replacer",
7273 [ALC260_FAVORIT100] = "favorit100",
7274#ifdef CONFIG_SND_DEBUG
7275 [ALC260_TEST] = "test",
7276#endif 3839#endif
7277 [ALC260_AUTO] = "auto",
7278};
7279
7280static const struct snd_pci_quirk alc260_cfg_tbl[] = {
7281 SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER),
7282 SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL),
7283 SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER),
7284 SND_PCI_QUIRK(0x1509, 0x4540, "Favorit 100XS", ALC260_FAVORIT100),
7285 SND_PCI_QUIRK(0x103c, 0x2808, "HP d5700", ALC260_HP_3013),
7286 SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_AUTO), /* no quirk */
7287 SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013),
7288 SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013),
7289 SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600),
7290 SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013),
7291 SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP),
7292 SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP),
7293 SND_PCI_QUIRK(0x103c, 0x3016, "HP", ALC260_HP),
7294 SND_PCI_QUIRK(0x104d, 0x81bb, "Sony VAIO", ALC260_BASIC),
7295 SND_PCI_QUIRK(0x104d, 0x81cc, "Sony VAIO", ALC260_BASIC),
7296 SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC),
7297 SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X),
7298 SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC),
7299 SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V),
7300 SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL),
7301 {}
7302};
7303
7304static const struct alc_config_preset alc260_presets[] = {
7305 [ALC260_BASIC] = {
7306 .mixers = { alc260_base_output_mixer,
7307 alc260_input_mixer },
7308 .init_verbs = { alc260_init_verbs },
7309 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7310 .dac_nids = alc260_dac_nids,
7311 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7312 .adc_nids = alc260_dual_adc_nids,
7313 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7314 .channel_mode = alc260_modes,
7315 .input_mux = &alc260_capture_source,
7316 },
7317 [ALC260_HP] = {
7318 .mixers = { alc260_hp_output_mixer,
7319 alc260_input_mixer },
7320 .init_verbs = { alc260_init_verbs,
7321 alc260_hp_unsol_verbs },
7322 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7323 .dac_nids = alc260_dac_nids,
7324 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7325 .adc_nids = alc260_adc_nids_alt,
7326 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7327 .channel_mode = alc260_modes,
7328 .input_mux = &alc260_capture_source,
7329 .unsol_event = alc_sku_unsol_event,
7330 .setup = alc260_hp_setup,
7331 .init_hook = alc_inithook,
7332 },
7333 [ALC260_HP_DC7600] = {
7334 .mixers = { alc260_hp_dc7600_mixer,
7335 alc260_input_mixer },
7336 .init_verbs = { alc260_init_verbs,
7337 alc260_hp_dc7600_verbs },
7338 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7339 .dac_nids = alc260_dac_nids,
7340 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7341 .adc_nids = alc260_adc_nids_alt,
7342 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7343 .channel_mode = alc260_modes,
7344 .input_mux = &alc260_capture_source,
7345 .unsol_event = alc_sku_unsol_event,
7346 .setup = alc260_hp_3012_setup,
7347 .init_hook = alc_inithook,
7348 },
7349 [ALC260_HP_3013] = {
7350 .mixers = { alc260_hp_3013_mixer,
7351 alc260_input_mixer },
7352 .init_verbs = { alc260_hp_3013_init_verbs,
7353 alc260_hp_3013_unsol_verbs },
7354 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7355 .dac_nids = alc260_dac_nids,
7356 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids_alt),
7357 .adc_nids = alc260_adc_nids_alt,
7358 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7359 .channel_mode = alc260_modes,
7360 .input_mux = &alc260_capture_source,
7361 .unsol_event = alc_sku_unsol_event,
7362 .setup = alc260_hp_3013_setup,
7363 .init_hook = alc_inithook,
7364 },
7365 [ALC260_FUJITSU_S702X] = {
7366 .mixers = { alc260_fujitsu_mixer },
7367 .init_verbs = { alc260_fujitsu_init_verbs },
7368 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7369 .dac_nids = alc260_dac_nids,
7370 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7371 .adc_nids = alc260_dual_adc_nids,
7372 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7373 .channel_mode = alc260_modes,
7374 .num_mux_defs = ARRAY_SIZE(alc260_fujitsu_capture_sources),
7375 .input_mux = alc260_fujitsu_capture_sources,
7376 },
7377 [ALC260_ACER] = {
7378 .mixers = { alc260_acer_mixer },
7379 .init_verbs = { alc260_acer_init_verbs },
7380 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7381 .dac_nids = alc260_dac_nids,
7382 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7383 .adc_nids = alc260_dual_adc_nids,
7384 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7385 .channel_mode = alc260_modes,
7386 .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources),
7387 .input_mux = alc260_acer_capture_sources,
7388 },
7389 [ALC260_FAVORIT100] = {
7390 .mixers = { alc260_favorit100_mixer },
7391 .init_verbs = { alc260_favorit100_init_verbs },
7392 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7393 .dac_nids = alc260_dac_nids,
7394 .num_adc_nids = ARRAY_SIZE(alc260_dual_adc_nids),
7395 .adc_nids = alc260_dual_adc_nids,
7396 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7397 .channel_mode = alc260_modes,
7398 .num_mux_defs = ARRAY_SIZE(alc260_favorit100_capture_sources),
7399 .input_mux = alc260_favorit100_capture_sources,
7400 },
7401 [ALC260_WILL] = {
7402 .mixers = { alc260_will_mixer },
7403 .init_verbs = { alc260_init_verbs, alc260_will_verbs },
7404 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7405 .dac_nids = alc260_dac_nids,
7406 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7407 .adc_nids = alc260_adc_nids,
7408 .dig_out_nid = ALC260_DIGOUT_NID,
7409 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7410 .channel_mode = alc260_modes,
7411 .input_mux = &alc260_capture_source,
7412 },
7413 [ALC260_REPLACER_672V] = {
7414 .mixers = { alc260_replacer_672v_mixer },
7415 .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs },
7416 .num_dacs = ARRAY_SIZE(alc260_dac_nids),
7417 .dac_nids = alc260_dac_nids,
7418 .num_adc_nids = ARRAY_SIZE(alc260_adc_nids),
7419 .adc_nids = alc260_adc_nids,
7420 .dig_out_nid = ALC260_DIGOUT_NID,
7421 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7422 .channel_mode = alc260_modes,
7423 .input_mux = &alc260_capture_source,
7424 .unsol_event = alc260_replacer_672v_unsol_event,
7425 .init_hook = alc260_replacer_672v_automute,
7426 },
7427#ifdef CONFIG_SND_DEBUG
7428 [ALC260_TEST] = {
7429 .mixers = { alc260_test_mixer },
7430 .init_verbs = { alc260_test_init_verbs },
7431 .num_dacs = ARRAY_SIZE(alc260_test_dac_nids),
7432 .dac_nids = alc260_test_dac_nids,
7433 .num_adc_nids = ARRAY_SIZE(alc260_test_adc_nids),
7434 .adc_nids = alc260_test_adc_nids,
7435 .num_channel_mode = ARRAY_SIZE(alc260_modes),
7436 .channel_mode = alc260_modes,
7437 .num_mux_defs = ARRAY_SIZE(alc260_test_capture_sources),
7438 .input_mux = alc260_test_capture_sources,
7439 },
7440#endif
7441};
7442 3840
7443static int patch_alc260(struct hda_codec *codec) 3841static int patch_alc260(struct hda_codec *codec)
7444{ 3842{
@@ -7453,32 +3851,34 @@ static int patch_alc260(struct hda_codec *codec)
7453 3851
7454 spec->mixer_nid = 0x07; 3852 spec->mixer_nid = 0x07;
7455 3853
7456 board_config = snd_hda_check_board_config(codec, ALC260_MODEL_LAST, 3854 board_config = alc_board_config(codec, ALC260_MODEL_LAST,
7457 alc260_models, 3855 alc260_models, alc260_cfg_tbl);
7458 alc260_cfg_tbl);
7459 if (board_config < 0) { 3856 if (board_config < 0) {
7460 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 3857 snd_printd(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
7461 codec->chip_name); 3858 codec->chip_name);
7462 board_config = ALC260_AUTO; 3859 board_config = ALC_MODEL_AUTO;
7463 } 3860 }
7464 3861
7465 if (board_config == ALC260_AUTO) { 3862 if (board_config == ALC_MODEL_AUTO) {
7466 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups); 3863 alc_pick_fixup(codec, NULL, alc260_fixup_tbl, alc260_fixups);
7467 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 3864 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
7468 } 3865 }
7469 3866
7470 if (board_config == ALC260_AUTO) { 3867 if (board_config == ALC_MODEL_AUTO) {
7471 /* automatic parse from the BIOS config */ 3868 /* automatic parse from the BIOS config */
7472 err = alc260_parse_auto_config(codec); 3869 err = alc260_parse_auto_config(codec);
7473 if (err < 0) { 3870 if (err < 0) {
7474 alc_free(codec); 3871 alc_free(codec);
7475 return err; 3872 return err;
7476 } else if (!err) { 3873 }
3874#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
3875 else if (!err) {
7477 printk(KERN_INFO 3876 printk(KERN_INFO
7478 "hda_codec: Cannot set up configuration " 3877 "hda_codec: Cannot set up configuration "
7479 "from BIOS. Using base mode...\n"); 3878 "from BIOS. Using base mode...\n");
7480 board_config = ALC260_BASIC; 3879 board_config = ALC260_BASIC;
7481 } 3880 }
3881#endif
7482 } 3882 }
7483 3883
7484 err = snd_hda_attach_beep_device(codec, 0x1); 3884 err = snd_hda_attach_beep_device(codec, 0x1);
@@ -7487,7 +3887,7 @@ static int patch_alc260(struct hda_codec *codec)
7487 return err; 3887 return err;
7488 } 3888 }
7489 3889
7490 if (board_config != ALC260_AUTO) 3890 if (board_config != ALC_MODEL_AUTO)
7491 setup_preset(codec, &alc260_presets[board_config]); 3891 setup_preset(codec, &alc260_presets[board_config]);
7492 3892
7493 if (!spec->adc_nids && spec->input_mux) { 3893 if (!spec->adc_nids && spec->input_mux) {
@@ -7503,7 +3903,7 @@ static int patch_alc260(struct hda_codec *codec)
7503 spec->vmaster_nid = 0x08; 3903 spec->vmaster_nid = 0x08;
7504 3904
7505 codec->patch_ops = alc_patch_ops; 3905 codec->patch_ops = alc_patch_ops;
7506 if (board_config == ALC260_AUTO) 3906 if (board_config == ALC_MODEL_AUTO)
7507 spec->init_hook = alc260_auto_init; 3907 spec->init_hook = alc260_auto_init;
7508 spec->shutup = alc_eapd_shutup; 3908 spec->shutup = alc_eapd_shutup;
7509#ifdef CONFIG_SND_HDA_POWER_SAVE 3909#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -7526,3249 +3926,10 @@ static int patch_alc260(struct hda_codec *codec)
7526 * In addition, an independent DAC for the multi-playback (not used in this 3926 * In addition, an independent DAC for the multi-playback (not used in this
7527 * driver yet). 3927 * driver yet).
7528 */ 3928 */
7529#define ALC882_DIGOUT_NID 0x06
7530#define ALC882_DIGIN_NID 0x0a
7531#define ALC883_DIGOUT_NID ALC882_DIGOUT_NID
7532#define ALC883_DIGIN_NID ALC882_DIGIN_NID
7533#define ALC1200_DIGOUT_NID 0x10
7534
7535
7536static const struct hda_channel_mode alc882_ch_modes[1] = {
7537 { 8, NULL }
7538};
7539
7540/* DACs */
7541static const hda_nid_t alc882_dac_nids[4] = {
7542 /* front, rear, clfe, rear_surr */
7543 0x02, 0x03, 0x04, 0x05
7544};
7545#define alc883_dac_nids alc882_dac_nids
7546
7547/* ADCs */
7548#define alc882_adc_nids alc880_adc_nids
7549#define alc882_adc_nids_alt alc880_adc_nids_alt
7550#define alc883_adc_nids alc882_adc_nids_alt
7551static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 };
7552static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 };
7553#define alc889_adc_nids alc880_adc_nids
7554
7555static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 };
7556static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 };
7557#define alc883_capsrc_nids alc882_capsrc_nids_alt
7558static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 };
7559#define alc889_capsrc_nids alc882_capsrc_nids
7560
7561/* input MUX */
7562/* FIXME: should be a matrix-type input source selection */
7563
7564static const struct hda_input_mux alc882_capture_source = {
7565 .num_items = 4,
7566 .items = {
7567 { "Mic", 0x0 },
7568 { "Front Mic", 0x1 },
7569 { "Line", 0x2 },
7570 { "CD", 0x4 },
7571 },
7572};
7573
7574#define alc883_capture_source alc882_capture_source
7575
7576static const struct hda_input_mux alc889_capture_source = {
7577 .num_items = 3,
7578 .items = {
7579 { "Front Mic", 0x0 },
7580 { "Mic", 0x3 },
7581 { "Line", 0x2 },
7582 },
7583};
7584
7585static const struct hda_input_mux mb5_capture_source = {
7586 .num_items = 3,
7587 .items = {
7588 { "Mic", 0x1 },
7589 { "Line", 0x7 },
7590 { "CD", 0x4 },
7591 },
7592};
7593
7594static const struct hda_input_mux macmini3_capture_source = {
7595 .num_items = 2,
7596 .items = {
7597 { "Line", 0x2 },
7598 { "CD", 0x4 },
7599 },
7600};
7601
7602static const struct hda_input_mux alc883_3stack_6ch_intel = {
7603 .num_items = 4,
7604 .items = {
7605 { "Mic", 0x1 },
7606 { "Front Mic", 0x0 },
7607 { "Line", 0x2 },
7608 { "CD", 0x4 },
7609 },
7610};
7611
7612static const struct hda_input_mux alc883_lenovo_101e_capture_source = {
7613 .num_items = 2,
7614 .items = {
7615 { "Mic", 0x1 },
7616 { "Line", 0x2 },
7617 },
7618};
7619
7620static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = {
7621 .num_items = 4,
7622 .items = {
7623 { "Mic", 0x0 },
7624 { "Internal Mic", 0x1 },
7625 { "Line", 0x2 },
7626 { "CD", 0x4 },
7627 },
7628};
7629
7630static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = {
7631 .num_items = 2,
7632 .items = {
7633 { "Mic", 0x0 },
7634 { "Internal Mic", 0x1 },
7635 },
7636};
7637
7638static const struct hda_input_mux alc883_lenovo_sky_capture_source = {
7639 .num_items = 3,
7640 .items = {
7641 { "Mic", 0x0 },
7642 { "Front Mic", 0x1 },
7643 { "Line", 0x4 },
7644 },
7645};
7646
7647static const struct hda_input_mux alc883_asus_eee1601_capture_source = {
7648 .num_items = 2,
7649 .items = {
7650 { "Mic", 0x0 },
7651 { "Line", 0x2 },
7652 },
7653};
7654
7655static const struct hda_input_mux alc889A_mb31_capture_source = {
7656 .num_items = 2,
7657 .items = {
7658 { "Mic", 0x0 },
7659 /* Front Mic (0x01) unused */
7660 { "Line", 0x2 },
7661 /* Line 2 (0x03) unused */
7662 /* CD (0x04) unused? */
7663 },
7664};
7665
7666static const struct hda_input_mux alc889A_imac91_capture_source = {
7667 .num_items = 2,
7668 .items = {
7669 { "Mic", 0x01 },
7670 { "Line", 0x2 }, /* Not sure! */
7671 },
7672};
7673
7674/*
7675 * 2ch mode
7676 */
7677static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = {
7678 { 2, NULL }
7679};
7680
7681/*
7682 * 2ch mode
7683 */
7684static const struct hda_verb alc882_3ST_ch2_init[] = {
7685 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7686 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7687 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7688 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7689 { } /* end */
7690};
7691
7692/*
7693 * 4ch mode
7694 */
7695static const struct hda_verb alc882_3ST_ch4_init[] = {
7696 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7697 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7698 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7699 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7700 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7701 { } /* end */
7702};
7703
7704/*
7705 * 6ch mode
7706 */
7707static const struct hda_verb alc882_3ST_ch6_init[] = {
7708 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7709 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7710 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7711 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7712 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7713 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7714 { } /* end */
7715};
7716
7717static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = {
7718 { 2, alc882_3ST_ch2_init },
7719 { 4, alc882_3ST_ch4_init },
7720 { 6, alc882_3ST_ch6_init },
7721};
7722
7723#define alc883_3ST_6ch_modes alc882_3ST_6ch_modes
7724
7725/*
7726 * 2ch mode
7727 */
7728static const struct hda_verb alc883_3ST_ch2_clevo_init[] = {
7729 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP },
7730 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7731 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7732 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7733 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7734 { } /* end */
7735};
7736
7737/*
7738 * 4ch mode
7739 */
7740static const struct hda_verb alc883_3ST_ch4_clevo_init[] = {
7741 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7742 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7743 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7744 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7745 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7746 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7747 { } /* end */
7748};
7749
7750/*
7751 * 6ch mode
7752 */
7753static const struct hda_verb alc883_3ST_ch6_clevo_init[] = {
7754 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7755 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7756 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7757 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7758 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7759 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7760 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7761 { } /* end */
7762};
7763
7764static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = {
7765 { 2, alc883_3ST_ch2_clevo_init },
7766 { 4, alc883_3ST_ch4_clevo_init },
7767 { 6, alc883_3ST_ch6_clevo_init },
7768};
7769
7770
7771/*
7772 * 6ch mode
7773 */
7774static const struct hda_verb alc882_sixstack_ch6_init[] = {
7775 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
7776 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7777 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7778 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7779 { } /* end */
7780};
7781
7782/*
7783 * 8ch mode
7784 */
7785static const struct hda_verb alc882_sixstack_ch8_init[] = {
7786 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7787 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7788 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7789 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7790 { } /* end */
7791};
7792
7793static const struct hda_channel_mode alc882_sixstack_modes[2] = {
7794 { 6, alc882_sixstack_ch6_init },
7795 { 8, alc882_sixstack_ch8_init },
7796};
7797
7798
7799/* Macbook Air 2,1 */
7800
7801static const struct hda_channel_mode alc885_mba21_ch_modes[1] = {
7802 { 2, NULL },
7803};
7804
7805/*
7806 * macbook pro ALC885 can switch LineIn to LineOut without losing Mic
7807 */
7808
7809/*
7810 * 2ch mode
7811 */
7812static const struct hda_verb alc885_mbp_ch2_init[] = {
7813 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7814 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
7815 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
7816 { } /* end */
7817};
7818
7819/*
7820 * 4ch mode
7821 */
7822static const struct hda_verb alc885_mbp_ch4_init[] = {
7823 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7824 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7825 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7826 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
7827 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
7828 { } /* end */
7829};
7830
7831static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = {
7832 { 2, alc885_mbp_ch2_init },
7833 { 4, alc885_mbp_ch4_init },
7834};
7835
7836/*
7837 * 2ch
7838 * Speakers/Woofer/HP = Front
7839 * LineIn = Input
7840 */
7841static const struct hda_verb alc885_mb5_ch2_init[] = {
7842 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
7843 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
7844 { } /* end */
7845};
7846
7847/*
7848 * 6ch mode
7849 * Speakers/HP = Front
7850 * Woofer = LFE
7851 * LineIn = Surround
7852 */
7853static const struct hda_verb alc885_mb5_ch6_init[] = {
7854 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
7855 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
7856 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
7857 { } /* end */
7858};
7859
7860static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = {
7861 { 2, alc885_mb5_ch2_init },
7862 { 6, alc885_mb5_ch6_init },
7863};
7864
7865#define alc885_macmini3_6ch_modes alc885_mb5_6ch_modes
7866
7867/*
7868 * 2ch mode
7869 */
7870static const struct hda_verb alc883_4ST_ch2_init[] = {
7871 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7872 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7873 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7874 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7875 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7876 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7877 { } /* end */
7878};
7879
7880/*
7881 * 4ch mode
7882 */
7883static const struct hda_verb alc883_4ST_ch4_init[] = {
7884 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7885 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7886 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7887 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7888 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7889 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7890 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7891 { } /* end */
7892};
7893
7894/*
7895 * 6ch mode
7896 */
7897static const struct hda_verb alc883_4ST_ch6_init[] = {
7898 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7899 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7900 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7901 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7902 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7903 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7904 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7905 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7906 { } /* end */
7907};
7908
7909/*
7910 * 8ch mode
7911 */
7912static const struct hda_verb alc883_4ST_ch8_init[] = {
7913 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7914 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7915 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7916 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7917 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7918 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
7919 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7920 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7921 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7922 { } /* end */
7923};
7924
7925static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = {
7926 { 2, alc883_4ST_ch2_init },
7927 { 4, alc883_4ST_ch4_init },
7928 { 6, alc883_4ST_ch6_init },
7929 { 8, alc883_4ST_ch8_init },
7930};
7931
7932
7933/*
7934 * 2ch mode
7935 */
7936static const struct hda_verb alc883_3ST_ch2_intel_init[] = {
7937 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7938 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7939 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7940 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7941 { } /* end */
7942};
7943
7944/*
7945 * 4ch mode
7946 */
7947static const struct hda_verb alc883_3ST_ch4_intel_init[] = {
7948 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
7949 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7950 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7951 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7952 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7953 { } /* end */
7954};
7955
7956/*
7957 * 6ch mode
7958 */
7959static const struct hda_verb alc883_3ST_ch6_intel_init[] = {
7960 { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7961 { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7962 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 },
7963 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
7964 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
7965 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
7966 { } /* end */
7967};
7968
7969static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = {
7970 { 2, alc883_3ST_ch2_intel_init },
7971 { 4, alc883_3ST_ch4_intel_init },
7972 { 6, alc883_3ST_ch6_intel_init },
7973};
7974
7975/*
7976 * 2ch mode
7977 */
7978static const struct hda_verb alc889_ch2_intel_init[] = {
7979 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7980 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 },
7981 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 },
7982 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x00 },
7983 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7984 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7985 { } /* end */
7986};
7987
7988/*
7989 * 6ch mode
7990 */
7991static const struct hda_verb alc889_ch6_intel_init[] = {
7992 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
7993 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
7994 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
7995 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
7996 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
7997 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
7998 { } /* end */
7999};
8000
8001/*
8002 * 8ch mode
8003 */
8004static const struct hda_verb alc889_ch8_intel_init[] = {
8005 { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 },
8006 { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 },
8007 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 },
8008 { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 },
8009 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x03 },
8010 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8011 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
8012 { } /* end */
8013};
8014
8015static const struct hda_channel_mode alc889_8ch_intel_modes[3] = {
8016 { 2, alc889_ch2_intel_init },
8017 { 6, alc889_ch6_intel_init },
8018 { 8, alc889_ch8_intel_init },
8019};
8020
8021/*
8022 * 6ch mode
8023 */
8024static const struct hda_verb alc883_sixstack_ch6_init[] = {
8025 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
8026 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8027 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8028 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8029 { } /* end */
8030};
8031
8032/*
8033 * 8ch mode
8034 */
8035static const struct hda_verb alc883_sixstack_ch8_init[] = {
8036 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8037 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8038 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8039 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
8040 { } /* end */
8041};
8042
8043static const struct hda_channel_mode alc883_sixstack_modes[2] = {
8044 { 6, alc883_sixstack_ch6_init },
8045 { 8, alc883_sixstack_ch8_init },
8046};
8047
8048
8049/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
8050 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
8051 */
8052static const struct snd_kcontrol_new alc882_base_mixer[] = {
8053 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8054 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8055 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8056 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
8057 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8058 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8059 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8060 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8061 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
8062 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
8063 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8064 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8065 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8066 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8067 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8068 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8069 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8070 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8071 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8072 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8073 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8074 { } /* end */
8075};
8076
8077/* Macbook Air 2,1 same control for HP and internal Speaker */
8078
8079static const struct snd_kcontrol_new alc885_mba21_mixer[] = {
8080 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8081 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT),
8082 { }
8083};
8084
8085
8086static const struct snd_kcontrol_new alc885_mbp3_mixer[] = {
8087 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8088 HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8089 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8090 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0e, 0x02, HDA_INPUT),
8091 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8092 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8093 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8094 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
8095 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
8096 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
8097 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
8098 { } /* end */
8099};
8100
8101static const struct snd_kcontrol_new alc885_mb5_mixer[] = {
8102 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8103 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8104 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8105 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8106 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8107 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8108 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8109 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8110 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8111 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8112 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
8113 HDA_CODEC_MUTE ("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
8114 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8115 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0x00, HDA_INPUT),
8116 { } /* end */
8117};
8118
8119static const struct snd_kcontrol_new alc885_macmini3_mixer[] = {
8120 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8121 HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
8122 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
8123 HDA_BIND_MUTE ("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
8124 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0e, 0x00, HDA_OUTPUT),
8125 HDA_BIND_MUTE ("LFE Playback Switch", 0x0e, 0x02, HDA_INPUT),
8126 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0f, 0x00, HDA_OUTPUT),
8127 HDA_BIND_MUTE ("Headphone Playback Switch", 0x0f, 0x02, HDA_INPUT),
8128 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x07, HDA_INPUT),
8129 HDA_CODEC_MUTE ("Line Playback Switch", 0x0b, 0x07, HDA_INPUT),
8130 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x00, HDA_INPUT),
8131 { } /* end */
8132};
8133
8134static const struct snd_kcontrol_new alc885_imac91_mixer[] = {
8135 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8136 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT),
8137 { } /* end */
8138};
8139
8140
8141static const struct snd_kcontrol_new alc882_w2jc_mixer[] = {
8142 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8143 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8144 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8145 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8146 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8147 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8148 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8149 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8150 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8151 { } /* end */
8152};
8153
8154static const struct snd_kcontrol_new alc882_targa_mixer[] = {
8155 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8156 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8157 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8158 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8159 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8160 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8161 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8162 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8163 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8164 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8165 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8166 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8167 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8168 { } /* end */
8169};
8170
8171/* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ???
8172 * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c
8173 */
8174static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = {
8175 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8176 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
8177 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8178 HDA_CODEC_MUTE("Mobile Front Playback Switch", 0x16, 0x0, HDA_OUTPUT),
8179 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8180 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8181 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8182 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8183 HDA_CODEC_VOLUME("Mobile Line Playback Volume", 0x0b, 0x03, HDA_INPUT),
8184 HDA_CODEC_MUTE("Mobile Line Playback Switch", 0x0b, 0x03, HDA_INPUT),
8185 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8186 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8187 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8188 { } /* end */
8189};
8190
8191static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = {
8192 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8193 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8194 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8195 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8196 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8197 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8198 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8199 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8200 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8201 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8202 { } /* end */
8203};
8204
8205static const struct snd_kcontrol_new alc882_chmode_mixer[] = {
8206 {
8207 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
8208 .name = "Channel Mode",
8209 .info = alc_ch_mode_info,
8210 .get = alc_ch_mode_get,
8211 .put = alc_ch_mode_put,
8212 },
8213 { } /* end */
8214};
8215
8216static const struct hda_verb alc882_base_init_verbs[] = {
8217 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8218 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8219 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8220 /* Rear mixer */
8221 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8222 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8223 /* CLFE mixer */
8224 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8225 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8226 /* Side mixer */
8227 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8228 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8229
8230 /* Front Pin: output 0 (0x0c) */
8231 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8232 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8233 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8234 /* Rear Pin: output 1 (0x0d) */
8235 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8236 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8237 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
8238 /* CLFE Pin: output 2 (0x0e) */
8239 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8240 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8241 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8242 /* Side Pin: output 3 (0x0f) */
8243 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8244 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8245 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8246 /* Mic (rear) pin: input vref at 80% */
8247 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8248 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8249 /* Front Mic pin: input vref at 80% */
8250 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8251 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8252 /* Line In pin: input */
8253 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8254 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8255 /* Line-2 In: Headphone output (output 0 - 0x0c) */
8256 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8257 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8258 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
8259 /* CD pin widget for input */
8260 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8261
8262 /* FIXME: use matrix-type input source selection */
8263 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8264 /* Input mixer2 */
8265 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8266 /* Input mixer3 */
8267 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8268 /* ADC2: mute amp left and right */
8269 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8270 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8271 /* ADC3: mute amp left and right */
8272 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8273 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8274
8275 { }
8276};
8277
8278static const struct hda_verb alc882_adc1_init_verbs[] = {
8279 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8280 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8281 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8282 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8283 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8284 /* ADC1: mute amp left and right */
8285 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8286 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8287 { }
8288};
8289
8290static const struct hda_verb alc882_eapd_verbs[] = {
8291 /* change to EAPD mode */
8292 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8293 {0x20, AC_VERB_SET_PROC_COEF, 0x3060},
8294 { }
8295};
8296
8297static const struct hda_verb alc889_eapd_verbs[] = {
8298 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
8299 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
8300 { }
8301};
8302
8303static const struct hda_verb alc_hp15_unsol_verbs[] = {
8304 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
8305 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8306 {}
8307};
8308
8309static const struct hda_verb alc885_init_verbs[] = {
8310 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8311 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8312 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8313 /* Rear mixer */
8314 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8315 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8316 /* CLFE mixer */
8317 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8318 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8319 /* Side mixer */
8320 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8321 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8322
8323 /* Front HP Pin: output 0 (0x0c) */
8324 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8325 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8326 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8327 /* Front Pin: output 0 (0x0c) */
8328 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8329 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8330 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8331 /* Rear Pin: output 1 (0x0d) */
8332 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8333 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8334 {0x19, AC_VERB_SET_CONNECT_SEL, 0x01},
8335 /* CLFE Pin: output 2 (0x0e) */
8336 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8337 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8338 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
8339 /* Side Pin: output 3 (0x0f) */
8340 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8341 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8342 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
8343 /* Mic (rear) pin: input vref at 80% */
8344 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8345 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8346 /* Front Mic pin: input vref at 80% */
8347 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8348 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8349 /* Line In pin: input */
8350 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8351 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8352
8353 /* Mixer elements: 0x18, , 0x1a, 0x1b */
8354 /* Input mixer1 */
8355 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8356 /* Input mixer2 */
8357 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8358 /* Input mixer3 */
8359 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8360 /* ADC2: mute amp left and right */
8361 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8362 /* ADC3: mute amp left and right */
8363 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8364
8365 { }
8366};
8367
8368static const struct hda_verb alc885_init_input_verbs[] = {
8369 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8370 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
8371 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
8372 { }
8373};
8374
8375
8376/* Unmute Selector 24h and set the default input to front mic */
8377static const struct hda_verb alc889_init_input_verbs[] = {
8378 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
8379 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8380 { }
8381};
8382
8383
8384#define alc883_init_verbs alc882_base_init_verbs
8385
8386/* Mac Pro test */
8387static const struct snd_kcontrol_new alc882_macpro_mixer[] = {
8388 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8389 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8390 HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT),
8391 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
8392 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
8393 /* FIXME: this looks suspicious...
8394 HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x02, HDA_INPUT),
8395 HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x02, HDA_INPUT),
8396 */
8397 { } /* end */
8398};
8399
8400static const struct hda_verb alc882_macpro_init_verbs[] = {
8401 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8402 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8403 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8404 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8405 /* Front Pin: output 0 (0x0c) */
8406 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8407 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8408 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
8409 /* Front Mic pin: input vref at 80% */
8410 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8411 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8412 /* Speaker: output */
8413 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8414 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8415 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x04},
8416 /* Headphone output (output 0 - 0x0c) */
8417 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8418 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8419 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8420
8421 /* FIXME: use matrix-type input source selection */
8422 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8423 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8424 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8425 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8426 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8427 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8428 /* Input mixer2 */
8429 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8430 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8431 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8432 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8433 /* Input mixer3 */
8434 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8435 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8436 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8437 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8438 /* ADC1: mute amp left and right */
8439 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8440 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8441 /* ADC2: mute amp left and right */
8442 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8443 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8444 /* ADC3: mute amp left and right */
8445 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8446 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8447
8448 { }
8449};
8450
8451/* Macbook 5,1 */
8452static const struct hda_verb alc885_mb5_init_verbs[] = {
8453 /* DACs */
8454 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8455 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8456 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8457 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8458 /* Front mixer */
8459 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8460 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8461 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8462 /* Surround mixer */
8463 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8464 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8465 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8466 /* LFE mixer */
8467 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8468 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8469 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8470 /* HP mixer */
8471 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8472 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8473 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8474 /* Front Pin (0x0c) */
8475 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8476 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8477 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8478 /* LFE Pin (0x0e) */
8479 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8480 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8481 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8482 /* HP Pin (0x0f) */
8483 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8484 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8485 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8486 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8487 /* Front Mic pin: input vref at 80% */
8488 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8489 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8490 /* Line In pin */
8491 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8492 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8493
8494 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0x1)},
8495 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x7)},
8496 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0x4)},
8497 { }
8498};
8499
8500/* Macmini 3,1 */
8501static const struct hda_verb alc885_macmini3_init_verbs[] = {
8502 /* DACs */
8503 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8504 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8505 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8506 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8507 /* Front mixer */
8508 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8509 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8510 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8511 /* Surround mixer */
8512 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8513 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8514 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8515 /* LFE mixer */
8516 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8517 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8518 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8519 /* HP mixer */
8520 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8521 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8522 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8523 /* Front Pin (0x0c) */
8524 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8525 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8526 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8527 /* LFE Pin (0x0e) */
8528 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x01},
8529 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8530 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02},
8531 /* HP Pin (0x0f) */
8532 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8533 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8534 {0x14, AC_VERB_SET_CONNECT_SEL, 0x03},
8535 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8536 /* Line In pin */
8537 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8538 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8539
8540 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8541 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8542 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8543 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8544 { }
8545};
8546
8547
8548static const struct hda_verb alc885_mba21_init_verbs[] = {
8549 /*Internal and HP Speaker Mixer*/
8550 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8551 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8552 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8553 /*Internal Speaker Pin (0x0c)*/
8554 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8555 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8556 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8557 /* HP Pin: output 0 (0x0e) */
8558 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8559 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8560 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8561 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8562 /* Line in (is hp when jack connected)*/
8563 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8564 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8565
8566 { }
8567 };
8568
8569
8570/* Macbook Pro rev3 */
8571static const struct hda_verb alc885_mbp3_init_verbs[] = {
8572 /* Front mixer: unmute input/output amp left and right (volume = 0) */
8573 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8574 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8575 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8576 /* Rear mixer */
8577 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8578 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8579 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8580 /* HP mixer */
8581 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8582 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8583 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8584 /* Front Pin: output 0 (0x0c) */
8585 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8586 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8587 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8588 /* HP Pin: output 0 (0x0e) */
8589 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4},
8590 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8591 {0x15, AC_VERB_SET_CONNECT_SEL, 0x02},
8592 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8593 /* Mic (rear) pin: input vref at 80% */
8594 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8595 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8596 /* Front Mic pin: input vref at 80% */
8597 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8598 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8599 /* Line In pin: use output 1 when in LineOut mode */
8600 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
8601 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8602 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
8603
8604 /* FIXME: use matrix-type input source selection */
8605 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
8606 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
8607 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8608 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8609 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8610 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8611 /* Input mixer2 */
8612 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8613 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8614 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8615 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8616 /* Input mixer3 */
8617 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8618 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8619 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8620 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8621 /* ADC1: mute amp left and right */
8622 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8623 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8624 /* ADC2: mute amp left and right */
8625 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8626 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8627 /* ADC3: mute amp left and right */
8628 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8629 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8630
8631 { }
8632};
8633
8634/* iMac 9,1 */
8635static const struct hda_verb alc885_imac91_init_verbs[] = {
8636 /* Internal Speaker Pin (0x0c) */
8637 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8638 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8639 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8640 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) },
8641 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8642 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8643 /* HP Pin: Rear */
8644 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8645 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8646 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8647 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, (ALC880_HP_EVENT | AC_USRSP_EN)},
8648 /* Line in Rear */
8649 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_VREF_50},
8650 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8651 /* Front Mic pin: input vref at 80% */
8652 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8653 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8654 /* Rear mixer */
8655 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8656 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8657 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8658 /* Line-Out mixer: unmute input/output amp left and right (volume = 0) */
8659 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
8660 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8661 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
8662 /* 0x24 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8663 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8664 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8665 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8666 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8667 /* 0x23 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8668 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8669 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8670 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8671 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8672 /* 0x22 [Audio Mixer] wcaps 0x20010b: Stereo Amp-In */
8673 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8674 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
8675 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
8676 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
8677 /* 0x07 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8678 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8679 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
8680 /* 0x08 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8681 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8682 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
8683 /* 0x09 [Audio Input] wcaps 0x10011b: Stereo Amp-In */
8684 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
8685 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
8686 { }
8687};
8688
8689/* iMac 24 mixer. */
8690static const struct snd_kcontrol_new alc885_imac24_mixer[] = {
8691 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
8692 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT),
8693 { } /* end */
8694};
8695
8696/* iMac 24 init verbs. */
8697static const struct hda_verb alc885_imac24_init_verbs[] = {
8698 /* Internal speakers: output 0 (0x0c) */
8699 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8700 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8701 {0x18, AC_VERB_SET_CONNECT_SEL, 0x00},
8702 /* Internal speakers: output 0 (0x0c) */
8703 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8704 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8705 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
8706 /* Headphone: output 0 (0x0c) */
8707 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8708 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
8709 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
8710 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8711 /* Front Mic: input vref at 80% */
8712 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
8713 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
8714 { }
8715};
8716
8717/* Toggle speaker-output according to the hp-jack state */
8718static void alc885_imac24_setup(struct hda_codec *codec)
8719{
8720 struct alc_spec *spec = codec->spec;
8721
8722 spec->autocfg.hp_pins[0] = 0x14;
8723 spec->autocfg.speaker_pins[0] = 0x18;
8724 spec->autocfg.speaker_pins[1] = 0x1a;
8725 spec->automute = 1;
8726 spec->automute_mode = ALC_AUTOMUTE_AMP;
8727}
8728
8729#define alc885_mb5_setup alc885_imac24_setup
8730#define alc885_macmini3_setup alc885_imac24_setup
8731
8732/* Macbook Air 2,1 */
8733static void alc885_mba21_setup(struct hda_codec *codec)
8734{
8735 struct alc_spec *spec = codec->spec;
8736
8737 spec->autocfg.hp_pins[0] = 0x14;
8738 spec->autocfg.speaker_pins[0] = 0x18;
8739 spec->automute = 1;
8740 spec->automute_mode = ALC_AUTOMUTE_AMP;
8741}
8742
8743
8744
8745static void alc885_mbp3_setup(struct hda_codec *codec)
8746{
8747 struct alc_spec *spec = codec->spec;
8748
8749 spec->autocfg.hp_pins[0] = 0x15;
8750 spec->autocfg.speaker_pins[0] = 0x14;
8751 spec->automute = 1;
8752 spec->automute_mode = ALC_AUTOMUTE_AMP;
8753}
8754
8755static void alc885_imac91_setup(struct hda_codec *codec)
8756{
8757 struct alc_spec *spec = codec->spec;
8758
8759 spec->autocfg.hp_pins[0] = 0x14;
8760 spec->autocfg.speaker_pins[0] = 0x18;
8761 spec->autocfg.speaker_pins[1] = 0x1a;
8762 spec->automute = 1;
8763 spec->automute_mode = ALC_AUTOMUTE_AMP;
8764}
8765
8766static const struct hda_verb alc882_targa_verbs[] = {
8767 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8768 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8769
8770 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8771 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8772
8773 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8774 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8775 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8776
8777 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
8778 { } /* end */
8779};
8780
8781/* toggle speaker-output according to the hp-jack state */
8782static void alc882_targa_automute(struct hda_codec *codec)
8783{
8784 struct alc_spec *spec = codec->spec;
8785 alc_hp_automute(codec);
8786 snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA,
8787 spec->jack_present ? 1 : 3);
8788}
8789
8790static void alc882_targa_setup(struct hda_codec *codec)
8791{
8792 struct alc_spec *spec = codec->spec;
8793
8794 spec->autocfg.hp_pins[0] = 0x14;
8795 spec->autocfg.speaker_pins[0] = 0x1b;
8796 spec->automute = 1;
8797 spec->automute_mode = ALC_AUTOMUTE_AMP;
8798}
8799
8800static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res)
8801{
8802 if ((res >> 26) == ALC880_HP_EVENT)
8803 alc882_targa_automute(codec);
8804}
8805
8806static const struct hda_verb alc882_asus_a7j_verbs[] = {
8807 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8808 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8809
8810 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8811 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8812 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8813
8814 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8815 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8816 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8817
8818 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8819 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8820 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8821 { } /* end */
8822};
8823
8824static const struct hda_verb alc882_asus_a7m_verbs[] = {
8825 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
8826 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
8827
8828 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
8829 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8830 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
8831
8832 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8833 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8834 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */
8835
8836 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */
8837 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */
8838 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */
8839 { } /* end */
8840};
8841
8842static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted)
8843{
8844 unsigned int gpiostate, gpiomask, gpiodir;
8845
8846 gpiostate = snd_hda_codec_read(codec, codec->afg, 0,
8847 AC_VERB_GET_GPIO_DATA, 0);
8848
8849 if (!muted)
8850 gpiostate |= (1 << pin);
8851 else
8852 gpiostate &= ~(1 << pin);
8853
8854 gpiomask = snd_hda_codec_read(codec, codec->afg, 0,
8855 AC_VERB_GET_GPIO_MASK, 0);
8856 gpiomask |= (1 << pin);
8857
8858 gpiodir = snd_hda_codec_read(codec, codec->afg, 0,
8859 AC_VERB_GET_GPIO_DIRECTION, 0);
8860 gpiodir |= (1 << pin);
8861
8862
8863 snd_hda_codec_write(codec, codec->afg, 0,
8864 AC_VERB_SET_GPIO_MASK, gpiomask);
8865 snd_hda_codec_write(codec, codec->afg, 0,
8866 AC_VERB_SET_GPIO_DIRECTION, gpiodir);
8867
8868 msleep(1);
8869
8870 snd_hda_codec_write(codec, codec->afg, 0,
8871 AC_VERB_SET_GPIO_DATA, gpiostate);
8872}
8873
8874/* set up GPIO at initialization */
8875static void alc885_macpro_init_hook(struct hda_codec *codec)
8876{
8877 alc882_gpio_mute(codec, 0, 0);
8878 alc882_gpio_mute(codec, 1, 0);
8879}
8880
8881/* set up GPIO and update auto-muting at initialization */
8882static void alc885_imac24_init_hook(struct hda_codec *codec)
8883{
8884 alc885_macpro_init_hook(codec);
8885 alc_hp_automute(codec);
8886}
8887
8888/* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */
8889static const struct hda_verb alc889A_mb31_ch2_init[] = {
8890 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8891 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8892 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8893 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8894 { } /* end */
8895};
8896
8897/* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */
8898static const struct hda_verb alc889A_mb31_ch4_init[] = {
8899 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */
8900 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8901 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8902 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8903 { } /* end */
8904};
8905
8906/* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */
8907static const struct hda_verb alc889A_mb31_ch5_init[] = {
8908 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */
8909 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */
8910 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */
8911 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Line off */
8912 { } /* end */
8913};
8914
8915/* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */
8916static const struct hda_verb alc889A_mb31_ch6_init[] = {
8917 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */
8918 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */
8919 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */
8920 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Line on */
8921 { } /* end */
8922};
8923
8924static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = {
8925 { 2, alc889A_mb31_ch2_init },
8926 { 4, alc889A_mb31_ch4_init },
8927 { 5, alc889A_mb31_ch5_init },
8928 { 6, alc889A_mb31_ch6_init },
8929};
8930
8931static const struct hda_verb alc883_medion_eapd_verbs[] = {
8932 /* eanable EAPD on medion laptop */
8933 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
8934 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
8935 { }
8936};
8937
8938#define alc883_base_mixer alc882_base_mixer
8939
8940static const struct snd_kcontrol_new alc883_mitac_mixer[] = {
8941 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8942 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8943 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
8944 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
8945 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
8946 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
8947 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
8948 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8949 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8950 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8951 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8952 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8953 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8954 { } /* end */
8955};
8956
8957static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = {
8958 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8959 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8960 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8961 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8962 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8963 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8964 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8965 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8966 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8967 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8968 { } /* end */
8969};
8970
8971static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = {
8972 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8973 HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT),
8974 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
8975 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
8976 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8977 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8978 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8979 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8980 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
8981 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8982 { } /* end */
8983};
8984
8985static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = {
8986 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
8987 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
8988 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
8989 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
8990 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
8991 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
8992 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
8993 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
8994 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
8995 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
8996 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
8997 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
8998 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
8999 { } /* end */
9000};
9001
9002static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = {
9003 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9004 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9005 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9006 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9007 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9008 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9009 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9010 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9011 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9012 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9013 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9014 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9015 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9016 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9017 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9018 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9019 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9020 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9021 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9022 { } /* end */
9023};
9024
9025static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = {
9026 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9027 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9028 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9029 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9030 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9031 HDA_OUTPUT),
9032 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9033 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9034 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9035 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9036 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9037 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9038 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9039 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9040 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9041 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9042 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9043 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9044 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9045 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9046 { } /* end */
9047};
9048
9049static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = {
9050 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9051 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9052 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9053 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9054 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0,
9055 HDA_OUTPUT),
9056 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9057 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9058 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9059 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9060 HDA_BIND_MUTE("Speaker Playback Switch", 0x0f, 2, HDA_INPUT),
9061 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9062 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9063 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9064 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x3, HDA_INPUT),
9065 HDA_CODEC_VOLUME("Mic Boost Volume", 0x1b, 0, HDA_INPUT),
9066 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x3, HDA_INPUT),
9067 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9068 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x18, 0, HDA_INPUT),
9069 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9070 { } /* end */
9071};
9072
9073static const struct snd_kcontrol_new alc883_fivestack_mixer[] = {
9074 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9075 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9076 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9077 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9078 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9079 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9080 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9081 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9082 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9083 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9084 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9085 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9086 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9087 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9088 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9089 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9090 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9091 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9092 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9093 { } /* end */
9094};
9095
9096static const struct snd_kcontrol_new alc883_targa_mixer[] = {
9097 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9098 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9099 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9100 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9101 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9102 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
9103 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
9104 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
9105 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
9106 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
9107 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9108 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9109 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9110 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9111 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9112 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9113 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9114 { } /* end */
9115};
9116
9117static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = {
9118 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9119 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9120 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9121 HDA_CODEC_MUTE("Speaker Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9122 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9123 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9124 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9125 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9126 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9127 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9128 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9129 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9130 { } /* end */
9131};
9132
9133static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = {
9134 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9135 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9136 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9137 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
9138 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9139 { } /* end */
9140};
9141
9142static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = {
9143 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9144 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9145 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
9146 HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT),
9147 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
9148 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9149 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9150 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9151 { } /* end */
9152};
9153
9154static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = {
9155 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9156 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
9157 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9158 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9159 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9160 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9161 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9162 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9163 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9164 { } /* end */
9165};
9166
9167static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = {
9168 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9169 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9170 HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9171 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
9172 HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT),
9173 HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT),
9174 { } /* end */
9175};
9176
9177static const struct hda_verb alc883_medion_wim2160_verbs[] = {
9178 /* Unmute front mixer */
9179 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9180 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9181
9182 /* Set speaker pin to front mixer */
9183 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9184
9185 /* Init headphone pin */
9186 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9187 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9188 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9189 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9190
9191 { } /* end */
9192};
9193
9194/* toggle speaker-output according to the hp-jack state */
9195static void alc883_medion_wim2160_setup(struct hda_codec *codec)
9196{
9197 struct alc_spec *spec = codec->spec;
9198
9199 spec->autocfg.hp_pins[0] = 0x1a;
9200 spec->autocfg.speaker_pins[0] = 0x15;
9201 spec->automute = 1;
9202 spec->automute_mode = ALC_AUTOMUTE_AMP;
9203}
9204
9205static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = {
9206 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9207 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9208 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9209 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9210 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9211 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9212 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9213 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9214 { } /* end */
9215};
9216
9217static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = {
9218 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9219 HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9220 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9221 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9222 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9223 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9224 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9225 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9226 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9227 { } /* end */
9228};
9229
9230static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = {
9231 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9232 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9233 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
9234 HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT),
9235 HDA_CODEC_VOLUME_MONO("Center Playback Volume",
9236 0x0d, 1, 0x0, HDA_OUTPUT),
9237 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT),
9238 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT),
9239 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT),
9240 HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT),
9241 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
9242 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
9243 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
9244 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9245 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9246 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9247 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9248 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9249 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9250 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
9251 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9252 { } /* end */
9253};
9254
9255static const struct snd_kcontrol_new alc889A_mb31_mixer[] = {
9256 /* Output mixers */
9257 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT),
9258 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT),
9259 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT),
9260 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 0x02, HDA_INPUT),
9261 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x00,
9262 HDA_OUTPUT),
9263 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x02, HDA_INPUT),
9264 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0e, 2, 0x00, HDA_OUTPUT),
9265 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x02, HDA_INPUT),
9266 /* Output switches */
9267 HDA_CODEC_MUTE("Enable Speaker", 0x14, 0x00, HDA_OUTPUT),
9268 HDA_CODEC_MUTE("Enable Headphones", 0x15, 0x00, HDA_OUTPUT),
9269 HDA_CODEC_MUTE_MONO("Enable LFE", 0x16, 2, 0x00, HDA_OUTPUT),
9270 /* Boost mixers */
9271 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x00, HDA_INPUT),
9272 HDA_CODEC_VOLUME("Line Boost Volume", 0x1a, 0x00, HDA_INPUT),
9273 /* Input mixers */
9274 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x00, HDA_INPUT),
9275 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x00, HDA_INPUT),
9276 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9277 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9278 { } /* end */
9279};
9280
9281static const struct snd_kcontrol_new alc883_vaiott_mixer[] = {
9282 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9283 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9284 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
9285 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
9286 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
9287 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
9288 { } /* end */
9289};
9290
9291static const struct hda_bind_ctls alc883_bind_cap_vol = {
9292 .ops = &snd_hda_bind_vol,
9293 .values = {
9294 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9295 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9296 0
9297 },
9298};
9299
9300static const struct hda_bind_ctls alc883_bind_cap_switch = {
9301 .ops = &snd_hda_bind_sw,
9302 .values = {
9303 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
9304 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
9305 0
9306 },
9307};
9308
9309static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = {
9310 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
9311 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
9312 HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT),
9313 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
9314 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
9315 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
9316 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
9317 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
9318 { } /* end */
9319};
9320
9321static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = {
9322 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol),
9323 HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch),
9324 {
9325 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9326 /* .name = "Capture Source", */
9327 .name = "Input Source",
9328 .count = 1,
9329 .info = alc_mux_enum_info,
9330 .get = alc_mux_enum_get,
9331 .put = alc_mux_enum_put,
9332 },
9333 { } /* end */
9334};
9335
9336static const struct snd_kcontrol_new alc883_chmode_mixer[] = {
9337 {
9338 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
9339 .name = "Channel Mode",
9340 .info = alc_ch_mode_info,
9341 .get = alc_ch_mode_get,
9342 .put = alc_ch_mode_put,
9343 },
9344 { } /* end */
9345};
9346
9347/* toggle speaker-output according to the hp-jack state */
9348static void alc883_mitac_setup(struct hda_codec *codec)
9349{
9350 struct alc_spec *spec = codec->spec;
9351
9352 spec->autocfg.hp_pins[0] = 0x15;
9353 spec->autocfg.speaker_pins[0] = 0x14;
9354 spec->autocfg.speaker_pins[1] = 0x17;
9355 spec->automute = 1;
9356 spec->automute_mode = ALC_AUTOMUTE_AMP;
9357}
9358
9359static const struct hda_verb alc883_mitac_verbs[] = {
9360 /* HP */
9361 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9362 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9363 /* Subwoofer */
9364 {0x17, AC_VERB_SET_CONNECT_SEL, 0x02},
9365 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9366
9367 /* enable unsolicited event */
9368 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9369 /* {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, */
9370
9371 { } /* end */
9372};
9373
9374static const struct hda_verb alc883_clevo_m540r_verbs[] = {
9375 /* HP */
9376 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9377 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9378 /* Int speaker */
9379 /*{0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},*/
9380
9381 /* enable unsolicited event */
9382 /*
9383 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9384 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9385 */
9386
9387 { } /* end */
9388};
9389
9390static const struct hda_verb alc883_clevo_m720_verbs[] = {
9391 /* HP */
9392 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9393 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9394 /* Int speaker */
9395 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
9396 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9397
9398 /* enable unsolicited event */
9399 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9400 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9401
9402 { } /* end */
9403};
9404
9405static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = {
9406 /* HP */
9407 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9408 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9409 /* Subwoofer */
9410 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
9411 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9412
9413 /* enable unsolicited event */
9414 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9415
9416 { } /* end */
9417};
9418
9419static const struct hda_verb alc883_targa_verbs[] = {
9420 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9421 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9422
9423 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9424 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9425
9426/* Connect Line-Out side jack (SPDIF) to Side */
9427 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9428 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9429 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
9430/* Connect Mic jack to CLFE */
9431 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9432 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9433 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02},
9434/* Connect Line-in jack to Surround */
9435 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9436 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9437 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
9438/* Connect HP out jack to Front */
9439 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9440 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9441 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9442
9443 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9444
9445 { } /* end */
9446};
9447
9448static const struct hda_verb alc883_lenovo_101e_verbs[] = {
9449 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9450 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN},
9451 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN},
9452 { } /* end */
9453};
9454
9455static const struct hda_verb alc883_lenovo_nb0763_verbs[] = {
9456 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9457 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9458 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9459 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9460 { } /* end */
9461};
9462
9463static const struct hda_verb alc888_lenovo_ms7195_verbs[] = {
9464 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9465 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9466 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9467 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT | AC_USRSP_EN},
9468 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9469 { } /* end */
9470};
9471
9472static const struct hda_verb alc883_haier_w66_verbs[] = {
9473 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9474 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9475
9476 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9477
9478 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
9479 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9480 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9481 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9482 { } /* end */
9483};
9484
9485static const struct hda_verb alc888_lenovo_sky_verbs[] = {
9486 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9487 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9488 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9489 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9490 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9491 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9492 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00},
9493 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9494 { } /* end */
9495};
9496
9497static const struct hda_verb alc888_6st_dell_verbs[] = {
9498 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9499 { }
9500};
9501
9502static const struct hda_verb alc883_vaiott_verbs[] = {
9503 /* HP */
9504 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9505 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9506
9507 /* enable unsolicited event */
9508 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9509
9510 { } /* end */
9511};
9512
9513static void alc888_3st_hp_setup(struct hda_codec *codec)
9514{
9515 struct alc_spec *spec = codec->spec;
9516
9517 spec->autocfg.hp_pins[0] = 0x1b;
9518 spec->autocfg.speaker_pins[0] = 0x14;
9519 spec->autocfg.speaker_pins[1] = 0x16;
9520 spec->autocfg.speaker_pins[2] = 0x18;
9521 spec->automute = 1;
9522 spec->automute_mode = ALC_AUTOMUTE_AMP;
9523}
9524
9525static const struct hda_verb alc888_3st_hp_verbs[] = {
9526 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */
9527 {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */
9528 {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */
9529 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9530 { } /* end */
9531};
9532
9533/*
9534 * 2ch mode
9535 */
9536static const struct hda_verb alc888_3st_hp_2ch_init[] = {
9537 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9538 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9539 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
9540 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9541 { } /* end */
9542};
9543
9544/*
9545 * 4ch mode
9546 */
9547static const struct hda_verb alc888_3st_hp_4ch_init[] = {
9548 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
9549 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
9550 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9551 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9552 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9553 { } /* end */
9554};
9555
9556/*
9557 * 6ch mode
9558 */
9559static const struct hda_verb alc888_3st_hp_6ch_init[] = {
9560 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9561 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9562 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
9563 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
9564 { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
9565 { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 },
9566 { } /* end */
9567};
9568
9569static const struct hda_channel_mode alc888_3st_hp_modes[3] = {
9570 { 2, alc888_3st_hp_2ch_init },
9571 { 4, alc888_3st_hp_4ch_init },
9572 { 6, alc888_3st_hp_6ch_init },
9573};
9574
9575static void alc888_lenovo_ms7195_setup(struct hda_codec *codec)
9576{
9577 struct alc_spec *spec = codec->spec;
9578
9579 spec->autocfg.hp_pins[0] = 0x1b;
9580 spec->autocfg.line_out_pins[0] = 0x14;
9581 spec->autocfg.speaker_pins[0] = 0x15;
9582 spec->automute = 1;
9583 spec->automute_mode = ALC_AUTOMUTE_AMP;
9584}
9585
9586/* toggle speaker-output according to the hp-jack state */
9587static void alc883_lenovo_nb0763_setup(struct hda_codec *codec)
9588{
9589 struct alc_spec *spec = codec->spec;
9590
9591 spec->autocfg.hp_pins[0] = 0x14;
9592 spec->autocfg.speaker_pins[0] = 0x15;
9593 spec->automute = 1;
9594 spec->automute_mode = ALC_AUTOMUTE_AMP;
9595}
9596
9597/* toggle speaker-output according to the hp-jack state */
9598#define alc883_targa_init_hook alc882_targa_init_hook
9599#define alc883_targa_unsol_event alc882_targa_unsol_event
9600
9601static void alc883_clevo_m720_setup(struct hda_codec *codec)
9602{
9603 struct alc_spec *spec = codec->spec;
9604
9605 spec->autocfg.hp_pins[0] = 0x15;
9606 spec->autocfg.speaker_pins[0] = 0x14;
9607 spec->automute = 1;
9608 spec->automute_mode = ALC_AUTOMUTE_AMP;
9609}
9610
9611static void alc883_clevo_m720_init_hook(struct hda_codec *codec)
9612{
9613 alc_hp_automute(codec);
9614 alc88x_simple_mic_automute(codec);
9615}
9616
9617static void alc883_clevo_m720_unsol_event(struct hda_codec *codec,
9618 unsigned int res)
9619{
9620 switch (res >> 26) {
9621 case ALC880_MIC_EVENT:
9622 alc88x_simple_mic_automute(codec);
9623 break;
9624 default:
9625 alc_sku_unsol_event(codec, res);
9626 break;
9627 }
9628}
9629
9630/* toggle speaker-output according to the hp-jack state */
9631static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec)
9632{
9633 struct alc_spec *spec = codec->spec;
9634
9635 spec->autocfg.hp_pins[0] = 0x14;
9636 spec->autocfg.speaker_pins[0] = 0x15;
9637 spec->automute = 1;
9638 spec->automute_mode = ALC_AUTOMUTE_AMP;
9639}
9640
9641static void alc883_haier_w66_setup(struct hda_codec *codec)
9642{
9643 struct alc_spec *spec = codec->spec;
9644
9645 spec->autocfg.hp_pins[0] = 0x1b;
9646 spec->autocfg.speaker_pins[0] = 0x14;
9647 spec->automute = 1;
9648 spec->automute_mode = ALC_AUTOMUTE_AMP;
9649}
9650
9651static void alc883_lenovo_101e_setup(struct hda_codec *codec)
9652{
9653 struct alc_spec *spec = codec->spec;
9654
9655 spec->autocfg.hp_pins[0] = 0x1b;
9656 spec->autocfg.line_out_pins[0] = 0x14;
9657 spec->autocfg.speaker_pins[0] = 0x15;
9658 spec->automute = 1;
9659 spec->detect_line = 1;
9660 spec->automute_lines = 1;
9661 spec->automute_mode = ALC_AUTOMUTE_AMP;
9662}
9663
9664/* toggle speaker-output according to the hp-jack state */
9665static void alc883_acer_aspire_setup(struct hda_codec *codec)
9666{
9667 struct alc_spec *spec = codec->spec;
9668
9669 spec->autocfg.hp_pins[0] = 0x14;
9670 spec->autocfg.speaker_pins[0] = 0x15;
9671 spec->autocfg.speaker_pins[1] = 0x16;
9672 spec->automute = 1;
9673 spec->automute_mode = ALC_AUTOMUTE_AMP;
9674}
9675
9676static const struct hda_verb alc883_acer_eapd_verbs[] = {
9677 /* HP Pin: output 0 (0x0c) */
9678 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9679 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
9680 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
9681 /* Front Pin: output 0 (0x0c) */
9682 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9683 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
9684 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9685 {0x16, AC_VERB_SET_CONNECT_SEL, 0x00},
9686 /* eanable EAPD on medion laptop */
9687 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
9688 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
9689 /* enable unsolicited event */
9690 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9691 { }
9692};
9693
9694static void alc888_6st_dell_setup(struct hda_codec *codec)
9695{
9696 struct alc_spec *spec = codec->spec;
9697
9698 spec->autocfg.hp_pins[0] = 0x1b;
9699 spec->autocfg.speaker_pins[0] = 0x14;
9700 spec->autocfg.speaker_pins[1] = 0x15;
9701 spec->autocfg.speaker_pins[2] = 0x16;
9702 spec->autocfg.speaker_pins[3] = 0x17;
9703 spec->automute = 1;
9704 spec->automute_mode = ALC_AUTOMUTE_AMP;
9705}
9706
9707static void alc888_lenovo_sky_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] = 0x15;
9714 spec->autocfg.speaker_pins[2] = 0x16;
9715 spec->autocfg.speaker_pins[3] = 0x17;
9716 spec->autocfg.speaker_pins[4] = 0x1a;
9717 spec->automute = 1;
9718 spec->automute_mode = ALC_AUTOMUTE_AMP;
9719}
9720
9721static void alc883_vaiott_setup(struct hda_codec *codec)
9722{
9723 struct alc_spec *spec = codec->spec;
9724
9725 spec->autocfg.hp_pins[0] = 0x15;
9726 spec->autocfg.speaker_pins[0] = 0x14;
9727 spec->autocfg.speaker_pins[1] = 0x17;
9728 spec->automute = 1;
9729 spec->automute_mode = ALC_AUTOMUTE_AMP;
9730}
9731
9732static const struct hda_verb alc888_asus_m90v_verbs[] = {
9733 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9734 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9735 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
9736 /* enable unsolicited event */
9737 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9738 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
9739 { } /* end */
9740};
9741
9742static void alc883_mode2_setup(struct hda_codec *codec)
9743{
9744 struct alc_spec *spec = codec->spec;
9745
9746 spec->autocfg.hp_pins[0] = 0x1b;
9747 spec->autocfg.speaker_pins[0] = 0x14;
9748 spec->autocfg.speaker_pins[1] = 0x15;
9749 spec->autocfg.speaker_pins[2] = 0x16;
9750 spec->ext_mic_pin = 0x18;
9751 spec->int_mic_pin = 0x19;
9752 spec->auto_mic = 1;
9753 spec->automute = 1;
9754 spec->automute_mode = ALC_AUTOMUTE_AMP;
9755}
9756
9757static const struct hda_verb alc888_asus_eee1601_verbs[] = {
9758 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
9759 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
9760 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
9761 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
9762 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
9763 {0x20, AC_VERB_SET_COEF_INDEX, 0x0b},
9764 {0x20, AC_VERB_SET_PROC_COEF, 0x0838},
9765 /* enable unsolicited event */
9766 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9767 { } /* end */
9768};
9769
9770static void alc883_eee1601_inithook(struct hda_codec *codec)
9771{
9772 struct alc_spec *spec = codec->spec;
9773
9774 spec->autocfg.hp_pins[0] = 0x14;
9775 spec->autocfg.speaker_pins[0] = 0x1b;
9776 alc_hp_automute(codec);
9777}
9778
9779static const struct hda_verb alc889A_mb31_verbs[] = {
9780 /* Init rear pin (used as headphone output) */
9781 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */
9782 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */
9783 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
9784 /* Init line pin (used as output in 4ch and 6ch mode) */
9785 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x02}, /* Connect to CLFE */
9786 /* Init line 2 pin (used as headphone out by default) */
9787 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Use as input */
9788 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Mute output */
9789 { } /* end */
9790};
9791
9792/* Mute speakers according to the headphone jack state */
9793static void alc889A_mb31_automute(struct hda_codec *codec)
9794{
9795 unsigned int present;
9796
9797 /* Mute only in 2ch or 4ch mode */
9798 if (snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_CONNECT_SEL, 0)
9799 == 0x00) {
9800 present = snd_hda_jack_detect(codec, 0x15);
9801 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
9802 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9803 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
9804 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
9805 }
9806}
9807
9808static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res)
9809{
9810 if ((res >> 26) == ALC880_HP_EVENT)
9811 alc889A_mb31_automute(codec);
9812}
9813
9814
9815#ifdef CONFIG_SND_HDA_POWER_SAVE 3929#ifdef CONFIG_SND_HDA_POWER_SAVE
9816#define alc882_loopbacks alc880_loopbacks 3930#define alc882_loopbacks alc880_loopbacks
9817#endif 3931#endif
9818 3932
9819static const hda_nid_t alc883_slave_dig_outs[] = {
9820 ALC1200_DIGOUT_NID, 0,
9821};
9822
9823static const hda_nid_t alc1200_slave_dig_outs[] = {
9824 ALC883_DIGOUT_NID, 0,
9825};
9826
9827/*
9828 * configuration and preset
9829 */
9830static const char * const alc882_models[ALC882_MODEL_LAST] = {
9831 [ALC882_3ST_DIG] = "3stack-dig",
9832 [ALC882_6ST_DIG] = "6stack-dig",
9833 [ALC882_ARIMA] = "arima",
9834 [ALC882_W2JC] = "w2jc",
9835 [ALC882_TARGA] = "targa",
9836 [ALC882_ASUS_A7J] = "asus-a7j",
9837 [ALC882_ASUS_A7M] = "asus-a7m",
9838 [ALC885_MACPRO] = "macpro",
9839 [ALC885_MB5] = "mb5",
9840 [ALC885_MACMINI3] = "macmini3",
9841 [ALC885_MBA21] = "mba21",
9842 [ALC885_MBP3] = "mbp3",
9843 [ALC885_IMAC24] = "imac24",
9844 [ALC885_IMAC91] = "imac91",
9845 [ALC883_3ST_2ch_DIG] = "3stack-2ch-dig",
9846 [ALC883_3ST_6ch_DIG] = "3stack-6ch-dig",
9847 [ALC883_3ST_6ch] = "3stack-6ch",
9848 [ALC883_6ST_DIG] = "alc883-6stack-dig",
9849 [ALC883_TARGA_DIG] = "targa-dig",
9850 [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig",
9851 [ALC883_TARGA_8ch_DIG] = "targa-8ch-dig",
9852 [ALC883_ACER] = "acer",
9853 [ALC883_ACER_ASPIRE] = "acer-aspire",
9854 [ALC888_ACER_ASPIRE_4930G] = "acer-aspire-4930g",
9855 [ALC888_ACER_ASPIRE_6530G] = "acer-aspire-6530g",
9856 [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g",
9857 [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g",
9858 [ALC883_MEDION] = "medion",
9859 [ALC883_MEDION_WIM2160] = "medion-wim2160",
9860 [ALC883_LAPTOP_EAPD] = "laptop-eapd",
9861 [ALC883_LENOVO_101E_2ch] = "lenovo-101e",
9862 [ALC883_LENOVO_NB0763] = "lenovo-nb0763",
9863 [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig",
9864 [ALC888_LENOVO_SKY] = "lenovo-sky",
9865 [ALC883_HAIER_W66] = "haier-w66",
9866 [ALC888_3ST_HP] = "3stack-hp",
9867 [ALC888_6ST_DELL] = "6stack-dell",
9868 [ALC883_MITAC] = "mitac",
9869 [ALC883_CLEVO_M540R] = "clevo-m540r",
9870 [ALC883_CLEVO_M720] = "clevo-m720",
9871 [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515",
9872 [ALC888_FUJITSU_XA3530] = "fujitsu-xa3530",
9873 [ALC883_3ST_6ch_INTEL] = "3stack-6ch-intel",
9874 [ALC889A_INTEL] = "intel-alc889a",
9875 [ALC889_INTEL] = "intel-x58",
9876 [ALC1200_ASUS_P5Q] = "asus-p5q",
9877 [ALC889A_MB31] = "mb31",
9878 [ALC883_SONY_VAIO_TT] = "sony-vaio-tt",
9879 [ALC882_AUTO] = "auto",
9880};
9881
9882static const struct snd_pci_quirk alc882_cfg_tbl[] = {
9883 SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG),
9884
9885 SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE),
9886 SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE),
9887 SND_PCI_QUIRK(0x1025, 0x010a, "Acer Ferrari 5000", ALC883_ACER_ASPIRE),
9888 SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE),
9889 SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE),
9890 SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
9891 SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
9892 ALC888_ACER_ASPIRE_4930G),
9893 SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
9894 ALC888_ACER_ASPIRE_4930G),
9895 SND_PCI_QUIRK(0x1025, 0x0145, "Acer Aspire 8930G",
9896 ALC888_ACER_ASPIRE_8930G),
9897 SND_PCI_QUIRK(0x1025, 0x0146, "Acer Aspire 6935G",
9898 ALC888_ACER_ASPIRE_8930G),
9899 SND_PCI_QUIRK(0x1025, 0x0157, "Acer X3200", ALC882_AUTO),
9900 SND_PCI_QUIRK(0x1025, 0x0158, "Acer AX1700-U3700A", ALC882_AUTO),
9901 SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
9902 ALC888_ACER_ASPIRE_6530G),
9903 SND_PCI_QUIRK(0x1025, 0x0166, "Acer Aspire 6530G",
9904 ALC888_ACER_ASPIRE_6530G),
9905 SND_PCI_QUIRK(0x1025, 0x0142, "Acer Aspire 7730G",
9906 ALC888_ACER_ASPIRE_7730G),
9907 /* default Acer -- disabled as it causes more problems.
9908 * model=auto should work fine now
9909 */
9910 /* SND_PCI_QUIRK_VENDOR(0x1025, "Acer laptop", ALC883_ACER), */
9911
9912 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
9913
9914 SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavilion", ALC883_6ST_DIG),
9915 SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP),
9916 SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP),
9917 SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG),
9918 SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP),
9919 SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP),
9920
9921 SND_PCI_QUIRK(0x1043, 0x060d, "Asus A7J", ALC882_ASUS_A7J),
9922 SND_PCI_QUIRK(0x1043, 0x1243, "Asus A7J", ALC882_ASUS_A7J),
9923 SND_PCI_QUIRK(0x1043, 0x13c2, "Asus A7M", ALC882_ASUS_A7M),
9924 SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V),
9925 SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC),
9926 SND_PCI_QUIRK(0x1043, 0x817f, "Asus P5LD2", ALC882_6ST_DIG),
9927 SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG),
9928 SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG),
9929 SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG),
9930 SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q),
9931 SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601),
9932
9933 SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC883_SONY_VAIO_TT),
9934 SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG),
9935 SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC882_6ST_DIG),
9936 SND_PCI_QUIRK(0x1071, 0x8227, "Mitac 82801H", ALC883_MITAC),
9937 SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC),
9938 SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD),
9939 SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL),
9940 SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch),
9941 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG),
9942
9943 SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG),
9944 SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG),
9945 SND_PCI_QUIRK(0x1462, 0x0579, "MSI", ALC883_TARGA_2ch_DIG),
9946 SND_PCI_QUIRK(0x1462, 0x28fb, "Targa T8", ALC882_TARGA), /* MSI-1049 T8 */
9947 SND_PCI_QUIRK(0x1462, 0x2fb3, "MSI", ALC882_AUTO),
9948 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG),
9949 SND_PCI_QUIRK(0x1462, 0x3729, "MSI S420", ALC883_TARGA_DIG),
9950 SND_PCI_QUIRK(0x1462, 0x3783, "NEC S970", ALC883_TARGA_DIG),
9951 SND_PCI_QUIRK(0x1462, 0x3b7f, "MSI", ALC883_TARGA_2ch_DIG),
9952 SND_PCI_QUIRK(0x1462, 0x3ef9, "MSI", ALC883_TARGA_DIG),
9953 SND_PCI_QUIRK(0x1462, 0x3fc1, "MSI", ALC883_TARGA_DIG),
9954 SND_PCI_QUIRK(0x1462, 0x3fc3, "MSI", ALC883_TARGA_DIG),
9955 SND_PCI_QUIRK(0x1462, 0x3fcc, "MSI", ALC883_TARGA_DIG),
9956 SND_PCI_QUIRK(0x1462, 0x3fdf, "MSI", ALC883_TARGA_DIG),
9957 SND_PCI_QUIRK(0x1462, 0x42cd, "MSI", ALC883_TARGA_DIG),
9958 SND_PCI_QUIRK(0x1462, 0x4314, "MSI", ALC883_TARGA_DIG),
9959 SND_PCI_QUIRK(0x1462, 0x4319, "MSI", ALC883_TARGA_DIG),
9960 SND_PCI_QUIRK(0x1462, 0x4324, "MSI", ALC883_TARGA_DIG),
9961 SND_PCI_QUIRK(0x1462, 0x4570, "MSI Wind Top AE2220", ALC883_TARGA_DIG),
9962 SND_PCI_QUIRK(0x1462, 0x6510, "MSI GX620", ALC883_TARGA_8ch_DIG),
9963 SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG),
9964 SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG),
9965 SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG),
9966 SND_PCI_QUIRK(0x1462, 0x7260, "MSI 7260", ALC883_TARGA_DIG),
9967 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG),
9968 SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG),
9969 SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG),
9970 SND_PCI_QUIRK(0x1462, 0x7350, "MSI", ALC883_6ST_DIG),
9971 SND_PCI_QUIRK(0x1462, 0x7437, "MSI NetOn AP1900", ALC883_TARGA_DIG),
9972 SND_PCI_QUIRK(0x1462, 0xa422, "MSI", ALC883_TARGA_2ch_DIG),
9973 SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG),
9974
9975 SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG),
9976 SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG),
9977 SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720),
9978 SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720),
9979 SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R),
9980 SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC883_LAPTOP_EAPD),
9981 SND_PCI_QUIRK(0x15d9, 0x8780, "Supermicro PDSBA", ALC883_3ST_6ch),
9982 /* SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), */
9983 SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION),
9984 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1100, "FSC AMILO Xi/Pi25xx",
9985 ALC883_FUJITSU_PI2515),
9986 SND_PCI_QUIRK_MASK(0x1734, 0xfff0, 0x1130, "Fujitsu AMILO Xa35xx",
9987 ALC888_FUJITSU_XA3530),
9988 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch),
9989 SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9990 SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9991 SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763),
9992 SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY),
9993 SND_PCI_QUIRK(0x17c0, 0x4085, "MEDION MD96630", ALC888_LENOVO_MS7195_DIG),
9994 SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG),
9995 SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
9996
9997 SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
9998 SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
9999 SND_PCI_QUIRK(0x8086, 0x2503, "82801H", ALC883_MITAC),
10000 SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC889_INTEL),
10001 SND_PCI_QUIRK(0x8086, 0x0021, "Intel IbexPeak", ALC889A_INTEL),
10002 SND_PCI_QUIRK(0x8086, 0x3b56, "Intel IbexPeak", ALC889A_INTEL),
10003 SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC882_6ST_DIG),
10004
10005 {}
10006};
10007
10008/* codec SSID table for Intel Mac */
10009static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = {
10010 SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3),
10011 SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3),
10012 SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3),
10013 SND_PCI_QUIRK(0x106b, 0x0c00, "Mac Pro", ALC885_MACPRO),
10014 SND_PCI_QUIRK(0x106b, 0x1000, "iMac 24", ALC885_IMAC24),
10015 SND_PCI_QUIRK(0x106b, 0x2800, "AppleTV", ALC885_IMAC24),
10016 SND_PCI_QUIRK(0x106b, 0x2c00, "MacbookPro rev3", ALC885_MBP3),
10017 SND_PCI_QUIRK(0x106b, 0x3000, "iMac", ALC889A_MB31),
10018 SND_PCI_QUIRK(0x106b, 0x3200, "iMac 7,1 Aluminum", ALC882_ASUS_A7M),
10019 SND_PCI_QUIRK(0x106b, 0x3400, "MacBookAir 1,1", ALC885_MBP3),
10020 SND_PCI_QUIRK(0x106b, 0x3500, "MacBookAir 2,1", ALC885_MBA21),
10021 SND_PCI_QUIRK(0x106b, 0x3600, "Macbook 3,1", ALC889A_MB31),
10022 SND_PCI_QUIRK(0x106b, 0x3800, "MacbookPro 4,1", ALC885_MBP3),
10023 SND_PCI_QUIRK(0x106b, 0x3e00, "iMac 24 Aluminum", ALC885_IMAC24),
10024 SND_PCI_QUIRK(0x106b, 0x4900, "iMac 9,1 Aluminum", ALC885_IMAC91),
10025 SND_PCI_QUIRK(0x106b, 0x3f00, "Macbook 5,1", ALC885_MB5),
10026 SND_PCI_QUIRK(0x106b, 0x4a00, "Macbook 5,2", ALC885_MB5),
10027 /* FIXME: HP jack sense seems not working for MBP 5,1 or 5,2,
10028 * so apparently no perfect solution yet
10029 */
10030 SND_PCI_QUIRK(0x106b, 0x4000, "MacbookPro 5,1", ALC885_MB5),
10031 SND_PCI_QUIRK(0x106b, 0x4600, "MacbookPro 5,2", ALC885_MB5),
10032 SND_PCI_QUIRK(0x106b, 0x4100, "Macmini 3,1", ALC885_MACMINI3),
10033 {} /* terminator */
10034};
10035
10036static const struct alc_config_preset alc882_presets[] = {
10037 [ALC882_3ST_DIG] = {
10038 .mixers = { alc882_base_mixer },
10039 .init_verbs = { alc882_base_init_verbs,
10040 alc882_adc1_init_verbs },
10041 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10042 .dac_nids = alc882_dac_nids,
10043 .dig_out_nid = ALC882_DIGOUT_NID,
10044 .dig_in_nid = ALC882_DIGIN_NID,
10045 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10046 .channel_mode = alc882_ch_modes,
10047 .need_dac_fix = 1,
10048 .input_mux = &alc882_capture_source,
10049 },
10050 [ALC882_6ST_DIG] = {
10051 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10052 .init_verbs = { alc882_base_init_verbs,
10053 alc882_adc1_init_verbs },
10054 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10055 .dac_nids = alc882_dac_nids,
10056 .dig_out_nid = ALC882_DIGOUT_NID,
10057 .dig_in_nid = ALC882_DIGIN_NID,
10058 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10059 .channel_mode = alc882_sixstack_modes,
10060 .input_mux = &alc882_capture_source,
10061 },
10062 [ALC882_ARIMA] = {
10063 .mixers = { alc882_base_mixer, alc882_chmode_mixer },
10064 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10065 alc882_eapd_verbs },
10066 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10067 .dac_nids = alc882_dac_nids,
10068 .num_channel_mode = ARRAY_SIZE(alc882_sixstack_modes),
10069 .channel_mode = alc882_sixstack_modes,
10070 .input_mux = &alc882_capture_source,
10071 },
10072 [ALC882_W2JC] = {
10073 .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer },
10074 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10075 alc882_eapd_verbs, alc880_gpio1_init_verbs },
10076 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10077 .dac_nids = alc882_dac_nids,
10078 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10079 .channel_mode = alc880_threestack_modes,
10080 .need_dac_fix = 1,
10081 .input_mux = &alc882_capture_source,
10082 .dig_out_nid = ALC882_DIGOUT_NID,
10083 },
10084 [ALC885_MBA21] = {
10085 .mixers = { alc885_mba21_mixer },
10086 .init_verbs = { alc885_mba21_init_verbs, alc880_gpio1_init_verbs },
10087 .num_dacs = 2,
10088 .dac_nids = alc882_dac_nids,
10089 .channel_mode = alc885_mba21_ch_modes,
10090 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10091 .input_mux = &alc882_capture_source,
10092 .unsol_event = alc_sku_unsol_event,
10093 .setup = alc885_mba21_setup,
10094 .init_hook = alc_hp_automute,
10095 },
10096 [ALC885_MBP3] = {
10097 .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer },
10098 .init_verbs = { alc885_mbp3_init_verbs,
10099 alc880_gpio1_init_verbs },
10100 .num_dacs = 2,
10101 .dac_nids = alc882_dac_nids,
10102 .hp_nid = 0x04,
10103 .channel_mode = alc885_mbp_4ch_modes,
10104 .num_channel_mode = ARRAY_SIZE(alc885_mbp_4ch_modes),
10105 .input_mux = &alc882_capture_source,
10106 .dig_out_nid = ALC882_DIGOUT_NID,
10107 .dig_in_nid = ALC882_DIGIN_NID,
10108 .unsol_event = alc_sku_unsol_event,
10109 .setup = alc885_mbp3_setup,
10110 .init_hook = alc_hp_automute,
10111 },
10112 [ALC885_MB5] = {
10113 .mixers = { alc885_mb5_mixer, alc882_chmode_mixer },
10114 .init_verbs = { alc885_mb5_init_verbs,
10115 alc880_gpio1_init_verbs },
10116 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10117 .dac_nids = alc882_dac_nids,
10118 .channel_mode = alc885_mb5_6ch_modes,
10119 .num_channel_mode = ARRAY_SIZE(alc885_mb5_6ch_modes),
10120 .input_mux = &mb5_capture_source,
10121 .dig_out_nid = ALC882_DIGOUT_NID,
10122 .dig_in_nid = ALC882_DIGIN_NID,
10123 .unsol_event = alc_sku_unsol_event,
10124 .setup = alc885_mb5_setup,
10125 .init_hook = alc_hp_automute,
10126 },
10127 [ALC885_MACMINI3] = {
10128 .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer },
10129 .init_verbs = { alc885_macmini3_init_verbs,
10130 alc880_gpio1_init_verbs },
10131 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10132 .dac_nids = alc882_dac_nids,
10133 .channel_mode = alc885_macmini3_6ch_modes,
10134 .num_channel_mode = ARRAY_SIZE(alc885_macmini3_6ch_modes),
10135 .input_mux = &macmini3_capture_source,
10136 .dig_out_nid = ALC882_DIGOUT_NID,
10137 .dig_in_nid = ALC882_DIGIN_NID,
10138 .unsol_event = alc_sku_unsol_event,
10139 .setup = alc885_macmini3_setup,
10140 .init_hook = alc_hp_automute,
10141 },
10142 [ALC885_MACPRO] = {
10143 .mixers = { alc882_macpro_mixer },
10144 .init_verbs = { alc882_macpro_init_verbs },
10145 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10146 .dac_nids = alc882_dac_nids,
10147 .dig_out_nid = ALC882_DIGOUT_NID,
10148 .dig_in_nid = ALC882_DIGIN_NID,
10149 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10150 .channel_mode = alc882_ch_modes,
10151 .input_mux = &alc882_capture_source,
10152 .init_hook = alc885_macpro_init_hook,
10153 },
10154 [ALC885_IMAC24] = {
10155 .mixers = { alc885_imac24_mixer },
10156 .init_verbs = { alc885_imac24_init_verbs },
10157 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10158 .dac_nids = alc882_dac_nids,
10159 .dig_out_nid = ALC882_DIGOUT_NID,
10160 .dig_in_nid = ALC882_DIGIN_NID,
10161 .num_channel_mode = ARRAY_SIZE(alc882_ch_modes),
10162 .channel_mode = alc882_ch_modes,
10163 .input_mux = &alc882_capture_source,
10164 .unsol_event = alc_sku_unsol_event,
10165 .setup = alc885_imac24_setup,
10166 .init_hook = alc885_imac24_init_hook,
10167 },
10168 [ALC885_IMAC91] = {
10169 .mixers = {alc885_imac91_mixer},
10170 .init_verbs = { alc885_imac91_init_verbs,
10171 alc880_gpio1_init_verbs },
10172 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10173 .dac_nids = alc882_dac_nids,
10174 .channel_mode = alc885_mba21_ch_modes,
10175 .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes),
10176 .input_mux = &alc889A_imac91_capture_source,
10177 .dig_out_nid = ALC882_DIGOUT_NID,
10178 .dig_in_nid = ALC882_DIGIN_NID,
10179 .unsol_event = alc_sku_unsol_event,
10180 .setup = alc885_imac91_setup,
10181 .init_hook = alc_hp_automute,
10182 },
10183 [ALC882_TARGA] = {
10184 .mixers = { alc882_targa_mixer, alc882_chmode_mixer },
10185 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10186 alc880_gpio3_init_verbs, alc882_targa_verbs},
10187 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10188 .dac_nids = alc882_dac_nids,
10189 .dig_out_nid = ALC882_DIGOUT_NID,
10190 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10191 .adc_nids = alc882_adc_nids,
10192 .capsrc_nids = alc882_capsrc_nids,
10193 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10194 .channel_mode = alc882_3ST_6ch_modes,
10195 .need_dac_fix = 1,
10196 .input_mux = &alc882_capture_source,
10197 .unsol_event = alc_sku_unsol_event,
10198 .setup = alc882_targa_setup,
10199 .init_hook = alc882_targa_automute,
10200 },
10201 [ALC882_ASUS_A7J] = {
10202 .mixers = { alc882_asus_a7j_mixer, alc882_chmode_mixer },
10203 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10204 alc882_asus_a7j_verbs},
10205 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10206 .dac_nids = alc882_dac_nids,
10207 .dig_out_nid = ALC882_DIGOUT_NID,
10208 .num_adc_nids = ARRAY_SIZE(alc882_adc_nids),
10209 .adc_nids = alc882_adc_nids,
10210 .capsrc_nids = alc882_capsrc_nids,
10211 .num_channel_mode = ARRAY_SIZE(alc882_3ST_6ch_modes),
10212 .channel_mode = alc882_3ST_6ch_modes,
10213 .need_dac_fix = 1,
10214 .input_mux = &alc882_capture_source,
10215 },
10216 [ALC882_ASUS_A7M] = {
10217 .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer },
10218 .init_verbs = { alc882_base_init_verbs, alc882_adc1_init_verbs,
10219 alc882_eapd_verbs, alc880_gpio1_init_verbs,
10220 alc882_asus_a7m_verbs },
10221 .num_dacs = ARRAY_SIZE(alc882_dac_nids),
10222 .dac_nids = alc882_dac_nids,
10223 .dig_out_nid = ALC882_DIGOUT_NID,
10224 .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes),
10225 .channel_mode = alc880_threestack_modes,
10226 .need_dac_fix = 1,
10227 .input_mux = &alc882_capture_source,
10228 },
10229 [ALC883_3ST_2ch_DIG] = {
10230 .mixers = { alc883_3ST_2ch_mixer },
10231 .init_verbs = { alc883_init_verbs },
10232 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10233 .dac_nids = alc883_dac_nids,
10234 .dig_out_nid = ALC883_DIGOUT_NID,
10235 .dig_in_nid = ALC883_DIGIN_NID,
10236 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10237 .channel_mode = alc883_3ST_2ch_modes,
10238 .input_mux = &alc883_capture_source,
10239 },
10240 [ALC883_3ST_6ch_DIG] = {
10241 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10242 .init_verbs = { alc883_init_verbs },
10243 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10244 .dac_nids = alc883_dac_nids,
10245 .dig_out_nid = ALC883_DIGOUT_NID,
10246 .dig_in_nid = ALC883_DIGIN_NID,
10247 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10248 .channel_mode = alc883_3ST_6ch_modes,
10249 .need_dac_fix = 1,
10250 .input_mux = &alc883_capture_source,
10251 },
10252 [ALC883_3ST_6ch] = {
10253 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10254 .init_verbs = { alc883_init_verbs },
10255 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10256 .dac_nids = alc883_dac_nids,
10257 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10258 .channel_mode = alc883_3ST_6ch_modes,
10259 .need_dac_fix = 1,
10260 .input_mux = &alc883_capture_source,
10261 },
10262 [ALC883_3ST_6ch_INTEL] = {
10263 .mixers = { alc883_3ST_6ch_intel_mixer, alc883_chmode_mixer },
10264 .init_verbs = { alc883_init_verbs },
10265 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10266 .dac_nids = alc883_dac_nids,
10267 .dig_out_nid = ALC883_DIGOUT_NID,
10268 .dig_in_nid = ALC883_DIGIN_NID,
10269 .slave_dig_outs = alc883_slave_dig_outs,
10270 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes),
10271 .channel_mode = alc883_3ST_6ch_intel_modes,
10272 .need_dac_fix = 1,
10273 .input_mux = &alc883_3stack_6ch_intel,
10274 },
10275 [ALC889A_INTEL] = {
10276 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10277 .init_verbs = { alc885_init_verbs, alc885_init_input_verbs,
10278 alc_hp15_unsol_verbs },
10279 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10280 .dac_nids = alc883_dac_nids,
10281 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10282 .adc_nids = alc889_adc_nids,
10283 .dig_out_nid = ALC883_DIGOUT_NID,
10284 .dig_in_nid = ALC883_DIGIN_NID,
10285 .slave_dig_outs = alc883_slave_dig_outs,
10286 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10287 .channel_mode = alc889_8ch_intel_modes,
10288 .capsrc_nids = alc889_capsrc_nids,
10289 .input_mux = &alc889_capture_source,
10290 .setup = alc889_automute_setup,
10291 .init_hook = alc_hp_automute,
10292 .unsol_event = alc_sku_unsol_event,
10293 .need_dac_fix = 1,
10294 },
10295 [ALC889_INTEL] = {
10296 .mixers = { alc885_8ch_intel_mixer, alc883_chmode_mixer },
10297 .init_verbs = { alc885_init_verbs, alc889_init_input_verbs,
10298 alc889_eapd_verbs, alc_hp15_unsol_verbs},
10299 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10300 .dac_nids = alc883_dac_nids,
10301 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10302 .adc_nids = alc889_adc_nids,
10303 .dig_out_nid = ALC883_DIGOUT_NID,
10304 .dig_in_nid = ALC883_DIGIN_NID,
10305 .slave_dig_outs = alc883_slave_dig_outs,
10306 .num_channel_mode = ARRAY_SIZE(alc889_8ch_intel_modes),
10307 .channel_mode = alc889_8ch_intel_modes,
10308 .capsrc_nids = alc889_capsrc_nids,
10309 .input_mux = &alc889_capture_source,
10310 .setup = alc889_automute_setup,
10311 .init_hook = alc889_intel_init_hook,
10312 .unsol_event = alc_sku_unsol_event,
10313 .need_dac_fix = 1,
10314 },
10315 [ALC883_6ST_DIG] = {
10316 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10317 .init_verbs = { alc883_init_verbs },
10318 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10319 .dac_nids = alc883_dac_nids,
10320 .dig_out_nid = ALC883_DIGOUT_NID,
10321 .dig_in_nid = ALC883_DIGIN_NID,
10322 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10323 .channel_mode = alc883_sixstack_modes,
10324 .input_mux = &alc883_capture_source,
10325 },
10326 [ALC883_TARGA_DIG] = {
10327 .mixers = { alc883_targa_mixer, alc883_chmode_mixer },
10328 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10329 alc883_targa_verbs},
10330 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10331 .dac_nids = alc883_dac_nids,
10332 .dig_out_nid = ALC883_DIGOUT_NID,
10333 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10334 .channel_mode = alc883_3ST_6ch_modes,
10335 .need_dac_fix = 1,
10336 .input_mux = &alc883_capture_source,
10337 .unsol_event = alc883_targa_unsol_event,
10338 .setup = alc882_targa_setup,
10339 .init_hook = alc882_targa_automute,
10340 },
10341 [ALC883_TARGA_2ch_DIG] = {
10342 .mixers = { alc883_targa_2ch_mixer},
10343 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10344 alc883_targa_verbs},
10345 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10346 .dac_nids = alc883_dac_nids,
10347 .adc_nids = alc883_adc_nids_alt,
10348 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10349 .capsrc_nids = alc883_capsrc_nids,
10350 .dig_out_nid = ALC883_DIGOUT_NID,
10351 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10352 .channel_mode = alc883_3ST_2ch_modes,
10353 .input_mux = &alc883_capture_source,
10354 .unsol_event = alc883_targa_unsol_event,
10355 .setup = alc882_targa_setup,
10356 .init_hook = alc882_targa_automute,
10357 },
10358 [ALC883_TARGA_8ch_DIG] = {
10359 .mixers = { alc883_targa_mixer, alc883_targa_8ch_mixer,
10360 alc883_chmode_mixer },
10361 .init_verbs = { alc883_init_verbs, alc880_gpio3_init_verbs,
10362 alc883_targa_verbs },
10363 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10364 .dac_nids = alc883_dac_nids,
10365 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10366 .adc_nids = alc883_adc_nids_rev,
10367 .capsrc_nids = alc883_capsrc_nids_rev,
10368 .dig_out_nid = ALC883_DIGOUT_NID,
10369 .dig_in_nid = ALC883_DIGIN_NID,
10370 .num_channel_mode = ARRAY_SIZE(alc883_4ST_8ch_modes),
10371 .channel_mode = alc883_4ST_8ch_modes,
10372 .need_dac_fix = 1,
10373 .input_mux = &alc883_capture_source,
10374 .unsol_event = alc883_targa_unsol_event,
10375 .setup = alc882_targa_setup,
10376 .init_hook = alc882_targa_automute,
10377 },
10378 [ALC883_ACER] = {
10379 .mixers = { alc883_base_mixer },
10380 /* On TravelMate laptops, GPIO 0 enables the internal speaker
10381 * and the headphone jack. Turn this on and rely on the
10382 * standard mute methods whenever the user wants to turn
10383 * these outputs off.
10384 */
10385 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs },
10386 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10387 .dac_nids = alc883_dac_nids,
10388 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10389 .channel_mode = alc883_3ST_2ch_modes,
10390 .input_mux = &alc883_capture_source,
10391 },
10392 [ALC883_ACER_ASPIRE] = {
10393 .mixers = { alc883_acer_aspire_mixer },
10394 .init_verbs = { alc883_init_verbs, alc883_acer_eapd_verbs },
10395 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10396 .dac_nids = alc883_dac_nids,
10397 .dig_out_nid = ALC883_DIGOUT_NID,
10398 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10399 .channel_mode = alc883_3ST_2ch_modes,
10400 .input_mux = &alc883_capture_source,
10401 .unsol_event = alc_sku_unsol_event,
10402 .setup = alc883_acer_aspire_setup,
10403 .init_hook = alc_hp_automute,
10404 },
10405 [ALC888_ACER_ASPIRE_4930G] = {
10406 .mixers = { alc888_acer_aspire_4930g_mixer,
10407 alc883_chmode_mixer },
10408 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10409 alc888_acer_aspire_4930g_verbs },
10410 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10411 .dac_nids = alc883_dac_nids,
10412 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10413 .adc_nids = alc883_adc_nids_rev,
10414 .capsrc_nids = alc883_capsrc_nids_rev,
10415 .dig_out_nid = ALC883_DIGOUT_NID,
10416 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10417 .channel_mode = alc883_3ST_6ch_modes,
10418 .need_dac_fix = 1,
10419 .const_channel_count = 6,
10420 .num_mux_defs =
10421 ARRAY_SIZE(alc888_2_capture_sources),
10422 .input_mux = alc888_2_capture_sources,
10423 .unsol_event = alc_sku_unsol_event,
10424 .setup = alc888_acer_aspire_4930g_setup,
10425 .init_hook = alc_hp_automute,
10426 },
10427 [ALC888_ACER_ASPIRE_6530G] = {
10428 .mixers = { alc888_acer_aspire_6530_mixer },
10429 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10430 alc888_acer_aspire_6530g_verbs },
10431 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10432 .dac_nids = alc883_dac_nids,
10433 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10434 .adc_nids = alc883_adc_nids_rev,
10435 .capsrc_nids = alc883_capsrc_nids_rev,
10436 .dig_out_nid = ALC883_DIGOUT_NID,
10437 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10438 .channel_mode = alc883_3ST_2ch_modes,
10439 .num_mux_defs =
10440 ARRAY_SIZE(alc888_2_capture_sources),
10441 .input_mux = alc888_acer_aspire_6530_sources,
10442 .unsol_event = alc_sku_unsol_event,
10443 .setup = alc888_acer_aspire_6530g_setup,
10444 .init_hook = alc_hp_automute,
10445 },
10446 [ALC888_ACER_ASPIRE_8930G] = {
10447 .mixers = { alc889_acer_aspire_8930g_mixer,
10448 alc883_chmode_mixer },
10449 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10450 alc889_acer_aspire_8930g_verbs,
10451 alc889_eapd_verbs},
10452 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10453 .dac_nids = alc883_dac_nids,
10454 .num_adc_nids = ARRAY_SIZE(alc889_adc_nids),
10455 .adc_nids = alc889_adc_nids,
10456 .capsrc_nids = alc889_capsrc_nids,
10457 .dig_out_nid = ALC883_DIGOUT_NID,
10458 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10459 .channel_mode = alc883_3ST_6ch_modes,
10460 .need_dac_fix = 1,
10461 .const_channel_count = 6,
10462 .num_mux_defs =
10463 ARRAY_SIZE(alc889_capture_sources),
10464 .input_mux = alc889_capture_sources,
10465 .unsol_event = alc_sku_unsol_event,
10466 .setup = alc889_acer_aspire_8930g_setup,
10467 .init_hook = alc_hp_automute,
10468#ifdef CONFIG_SND_HDA_POWER_SAVE
10469 .power_hook = alc_power_eapd,
10470#endif
10471 },
10472 [ALC888_ACER_ASPIRE_7730G] = {
10473 .mixers = { alc883_3ST_6ch_mixer,
10474 alc883_chmode_mixer },
10475 .init_verbs = { alc883_init_verbs, alc880_gpio1_init_verbs,
10476 alc888_acer_aspire_7730G_verbs },
10477 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10478 .dac_nids = alc883_dac_nids,
10479 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10480 .adc_nids = alc883_adc_nids_rev,
10481 .capsrc_nids = alc883_capsrc_nids_rev,
10482 .dig_out_nid = ALC883_DIGOUT_NID,
10483 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10484 .channel_mode = alc883_3ST_6ch_modes,
10485 .need_dac_fix = 1,
10486 .const_channel_count = 6,
10487 .input_mux = &alc883_capture_source,
10488 .unsol_event = alc_sku_unsol_event,
10489 .setup = alc888_acer_aspire_7730g_setup,
10490 .init_hook = alc_hp_automute,
10491 },
10492 [ALC883_MEDION] = {
10493 .mixers = { alc883_fivestack_mixer,
10494 alc883_chmode_mixer },
10495 .init_verbs = { alc883_init_verbs,
10496 alc883_medion_eapd_verbs },
10497 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10498 .dac_nids = alc883_dac_nids,
10499 .adc_nids = alc883_adc_nids_alt,
10500 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10501 .capsrc_nids = alc883_capsrc_nids,
10502 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10503 .channel_mode = alc883_sixstack_modes,
10504 .input_mux = &alc883_capture_source,
10505 },
10506 [ALC883_MEDION_WIM2160] = {
10507 .mixers = { alc883_medion_wim2160_mixer },
10508 .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs },
10509 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10510 .dac_nids = alc883_dac_nids,
10511 .dig_out_nid = ALC883_DIGOUT_NID,
10512 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10513 .adc_nids = alc883_adc_nids,
10514 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10515 .channel_mode = alc883_3ST_2ch_modes,
10516 .input_mux = &alc883_capture_source,
10517 .unsol_event = alc_sku_unsol_event,
10518 .setup = alc883_medion_wim2160_setup,
10519 .init_hook = alc_hp_automute,
10520 },
10521 [ALC883_LAPTOP_EAPD] = {
10522 .mixers = { alc883_base_mixer },
10523 .init_verbs = { alc883_init_verbs, alc882_eapd_verbs },
10524 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10525 .dac_nids = alc883_dac_nids,
10526 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10527 .channel_mode = alc883_3ST_2ch_modes,
10528 .input_mux = &alc883_capture_source,
10529 },
10530 [ALC883_CLEVO_M540R] = {
10531 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10532 .init_verbs = { alc883_init_verbs, alc883_clevo_m540r_verbs },
10533 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10534 .dac_nids = alc883_dac_nids,
10535 .dig_out_nid = ALC883_DIGOUT_NID,
10536 .dig_in_nid = ALC883_DIGIN_NID,
10537 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_clevo_modes),
10538 .channel_mode = alc883_3ST_6ch_clevo_modes,
10539 .need_dac_fix = 1,
10540 .input_mux = &alc883_capture_source,
10541 /* This machine has the hardware HP auto-muting, thus
10542 * we need no software mute via unsol event
10543 */
10544 },
10545 [ALC883_CLEVO_M720] = {
10546 .mixers = { alc883_clevo_m720_mixer },
10547 .init_verbs = { alc883_init_verbs, alc883_clevo_m720_verbs },
10548 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10549 .dac_nids = alc883_dac_nids,
10550 .dig_out_nid = ALC883_DIGOUT_NID,
10551 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10552 .channel_mode = alc883_3ST_2ch_modes,
10553 .input_mux = &alc883_capture_source,
10554 .unsol_event = alc883_clevo_m720_unsol_event,
10555 .setup = alc883_clevo_m720_setup,
10556 .init_hook = alc883_clevo_m720_init_hook,
10557 },
10558 [ALC883_LENOVO_101E_2ch] = {
10559 .mixers = { alc883_lenovo_101e_2ch_mixer},
10560 .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs},
10561 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10562 .dac_nids = alc883_dac_nids,
10563 .adc_nids = alc883_adc_nids_alt,
10564 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_alt),
10565 .capsrc_nids = alc883_capsrc_nids,
10566 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10567 .channel_mode = alc883_3ST_2ch_modes,
10568 .input_mux = &alc883_lenovo_101e_capture_source,
10569 .setup = alc883_lenovo_101e_setup,
10570 .unsol_event = alc_sku_unsol_event,
10571 .init_hook = alc_inithook,
10572 },
10573 [ALC883_LENOVO_NB0763] = {
10574 .mixers = { alc883_lenovo_nb0763_mixer },
10575 .init_verbs = { alc883_init_verbs, alc883_lenovo_nb0763_verbs},
10576 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10577 .dac_nids = alc883_dac_nids,
10578 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10579 .channel_mode = alc883_3ST_2ch_modes,
10580 .need_dac_fix = 1,
10581 .input_mux = &alc883_lenovo_nb0763_capture_source,
10582 .unsol_event = alc_sku_unsol_event,
10583 .setup = alc883_lenovo_nb0763_setup,
10584 .init_hook = alc_hp_automute,
10585 },
10586 [ALC888_LENOVO_MS7195_DIG] = {
10587 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10588 .init_verbs = { alc883_init_verbs, alc888_lenovo_ms7195_verbs},
10589 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10590 .dac_nids = alc883_dac_nids,
10591 .dig_out_nid = ALC883_DIGOUT_NID,
10592 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10593 .channel_mode = alc883_3ST_6ch_modes,
10594 .need_dac_fix = 1,
10595 .input_mux = &alc883_capture_source,
10596 .unsol_event = alc_sku_unsol_event,
10597 .setup = alc888_lenovo_ms7195_setup,
10598 .init_hook = alc_inithook,
10599 },
10600 [ALC883_HAIER_W66] = {
10601 .mixers = { alc883_targa_2ch_mixer},
10602 .init_verbs = { alc883_init_verbs, alc883_haier_w66_verbs},
10603 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10604 .dac_nids = alc883_dac_nids,
10605 .dig_out_nid = ALC883_DIGOUT_NID,
10606 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10607 .channel_mode = alc883_3ST_2ch_modes,
10608 .input_mux = &alc883_capture_source,
10609 .unsol_event = alc_sku_unsol_event,
10610 .setup = alc883_haier_w66_setup,
10611 .init_hook = alc_hp_automute,
10612 },
10613 [ALC888_3ST_HP] = {
10614 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10615 .init_verbs = { alc883_init_verbs, alc888_3st_hp_verbs },
10616 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10617 .dac_nids = alc883_dac_nids,
10618 .num_channel_mode = ARRAY_SIZE(alc888_3st_hp_modes),
10619 .channel_mode = alc888_3st_hp_modes,
10620 .need_dac_fix = 1,
10621 .input_mux = &alc883_capture_source,
10622 .unsol_event = alc_sku_unsol_event,
10623 .setup = alc888_3st_hp_setup,
10624 .init_hook = alc_hp_automute,
10625 },
10626 [ALC888_6ST_DELL] = {
10627 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10628 .init_verbs = { alc883_init_verbs, alc888_6st_dell_verbs },
10629 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10630 .dac_nids = alc883_dac_nids,
10631 .dig_out_nid = ALC883_DIGOUT_NID,
10632 .dig_in_nid = ALC883_DIGIN_NID,
10633 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10634 .channel_mode = alc883_sixstack_modes,
10635 .input_mux = &alc883_capture_source,
10636 .unsol_event = alc_sku_unsol_event,
10637 .setup = alc888_6st_dell_setup,
10638 .init_hook = alc_hp_automute,
10639 },
10640 [ALC883_MITAC] = {
10641 .mixers = { alc883_mitac_mixer },
10642 .init_verbs = { alc883_init_verbs, alc883_mitac_verbs },
10643 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10644 .dac_nids = alc883_dac_nids,
10645 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10646 .channel_mode = alc883_3ST_2ch_modes,
10647 .input_mux = &alc883_capture_source,
10648 .unsol_event = alc_sku_unsol_event,
10649 .setup = alc883_mitac_setup,
10650 .init_hook = alc_hp_automute,
10651 },
10652 [ALC883_FUJITSU_PI2515] = {
10653 .mixers = { alc883_2ch_fujitsu_pi2515_mixer },
10654 .init_verbs = { alc883_init_verbs,
10655 alc883_2ch_fujitsu_pi2515_verbs},
10656 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10657 .dac_nids = alc883_dac_nids,
10658 .dig_out_nid = ALC883_DIGOUT_NID,
10659 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10660 .channel_mode = alc883_3ST_2ch_modes,
10661 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10662 .unsol_event = alc_sku_unsol_event,
10663 .setup = alc883_2ch_fujitsu_pi2515_setup,
10664 .init_hook = alc_hp_automute,
10665 },
10666 [ALC888_FUJITSU_XA3530] = {
10667 .mixers = { alc888_base_mixer, alc883_chmode_mixer },
10668 .init_verbs = { alc883_init_verbs,
10669 alc888_fujitsu_xa3530_verbs },
10670 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10671 .dac_nids = alc883_dac_nids,
10672 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids_rev),
10673 .adc_nids = alc883_adc_nids_rev,
10674 .capsrc_nids = alc883_capsrc_nids_rev,
10675 .dig_out_nid = ALC883_DIGOUT_NID,
10676 .num_channel_mode = ARRAY_SIZE(alc888_4ST_8ch_intel_modes),
10677 .channel_mode = alc888_4ST_8ch_intel_modes,
10678 .num_mux_defs =
10679 ARRAY_SIZE(alc888_2_capture_sources),
10680 .input_mux = alc888_2_capture_sources,
10681 .unsol_event = alc_sku_unsol_event,
10682 .setup = alc888_fujitsu_xa3530_setup,
10683 .init_hook = alc_hp_automute,
10684 },
10685 [ALC888_LENOVO_SKY] = {
10686 .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer },
10687 .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs},
10688 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10689 .dac_nids = alc883_dac_nids,
10690 .dig_out_nid = ALC883_DIGOUT_NID,
10691 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10692 .channel_mode = alc883_sixstack_modes,
10693 .need_dac_fix = 1,
10694 .input_mux = &alc883_lenovo_sky_capture_source,
10695 .unsol_event = alc_sku_unsol_event,
10696 .setup = alc888_lenovo_sky_setup,
10697 .init_hook = alc_hp_automute,
10698 },
10699 [ALC888_ASUS_M90V] = {
10700 .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer },
10701 .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs },
10702 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10703 .dac_nids = alc883_dac_nids,
10704 .dig_out_nid = ALC883_DIGOUT_NID,
10705 .dig_in_nid = ALC883_DIGIN_NID,
10706 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes),
10707 .channel_mode = alc883_3ST_6ch_modes,
10708 .need_dac_fix = 1,
10709 .input_mux = &alc883_fujitsu_pi2515_capture_source,
10710 .unsol_event = alc_sku_unsol_event,
10711 .setup = alc883_mode2_setup,
10712 .init_hook = alc_inithook,
10713 },
10714 [ALC888_ASUS_EEE1601] = {
10715 .mixers = { alc883_asus_eee1601_mixer },
10716 .cap_mixer = alc883_asus_eee1601_cap_mixer,
10717 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs },
10718 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10719 .dac_nids = alc883_dac_nids,
10720 .dig_out_nid = ALC883_DIGOUT_NID,
10721 .dig_in_nid = ALC883_DIGIN_NID,
10722 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10723 .channel_mode = alc883_3ST_2ch_modes,
10724 .need_dac_fix = 1,
10725 .input_mux = &alc883_asus_eee1601_capture_source,
10726 .unsol_event = alc_sku_unsol_event,
10727 .init_hook = alc883_eee1601_inithook,
10728 },
10729 [ALC1200_ASUS_P5Q] = {
10730 .mixers = { alc883_base_mixer, alc883_chmode_mixer },
10731 .init_verbs = { alc883_init_verbs },
10732 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10733 .dac_nids = alc883_dac_nids,
10734 .dig_out_nid = ALC1200_DIGOUT_NID,
10735 .dig_in_nid = ALC883_DIGIN_NID,
10736 .slave_dig_outs = alc1200_slave_dig_outs,
10737 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes),
10738 .channel_mode = alc883_sixstack_modes,
10739 .input_mux = &alc883_capture_source,
10740 },
10741 [ALC889A_MB31] = {
10742 .mixers = { alc889A_mb31_mixer, alc883_chmode_mixer},
10743 .init_verbs = { alc883_init_verbs, alc889A_mb31_verbs,
10744 alc880_gpio1_init_verbs },
10745 .adc_nids = alc883_adc_nids,
10746 .num_adc_nids = ARRAY_SIZE(alc883_adc_nids),
10747 .capsrc_nids = alc883_capsrc_nids,
10748 .dac_nids = alc883_dac_nids,
10749 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10750 .channel_mode = alc889A_mb31_6ch_modes,
10751 .num_channel_mode = ARRAY_SIZE(alc889A_mb31_6ch_modes),
10752 .input_mux = &alc889A_mb31_capture_source,
10753 .dig_out_nid = ALC883_DIGOUT_NID,
10754 .unsol_event = alc889A_mb31_unsol_event,
10755 .init_hook = alc889A_mb31_automute,
10756 },
10757 [ALC883_SONY_VAIO_TT] = {
10758 .mixers = { alc883_vaiott_mixer },
10759 .init_verbs = { alc883_init_verbs, alc883_vaiott_verbs },
10760 .num_dacs = ARRAY_SIZE(alc883_dac_nids),
10761 .dac_nids = alc883_dac_nids,
10762 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
10763 .channel_mode = alc883_3ST_2ch_modes,
10764 .input_mux = &alc883_capture_source,
10765 .unsol_event = alc_sku_unsol_event,
10766 .setup = alc883_vaiott_setup,
10767 .init_hook = alc_hp_automute,
10768 },
10769};
10770
10771
10772/* 3933/*
10773 * Pin config fixes 3934 * Pin config fixes
10774 */ 3935 */
@@ -10821,80 +3982,6 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
10821/* 3982/*
10822 * BIOS auto configuration 3983 * BIOS auto configuration
10823 */ 3984 */
10824static void alc_auto_init_adc(struct hda_codec *codec, int adc_idx)
10825{
10826 struct alc_spec *spec = codec->spec;
10827 hda_nid_t nid;
10828
10829 nid = spec->adc_nids[adc_idx];
10830 /* mute ADC */
10831 if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE) {
10832 snd_hda_codec_write(codec, nid, 0,
10833 AC_VERB_SET_AMP_GAIN_MUTE,
10834 AMP_IN_MUTE(0));
10835 return;
10836 }
10837 if (!spec->capsrc_nids)
10838 return;
10839 nid = spec->capsrc_nids[adc_idx];
10840 if (query_amp_caps(codec, nid, HDA_OUTPUT) & AC_AMPCAP_MUTE)
10841 snd_hda_codec_write(codec, nid, 0,
10842 AC_VERB_SET_AMP_GAIN_MUTE,
10843 AMP_OUT_MUTE);
10844}
10845
10846static void alc_auto_init_input_src(struct hda_codec *codec)
10847{
10848 struct alc_spec *spec = codec->spec;
10849 int c, nums;
10850
10851 for (c = 0; c < spec->num_adc_nids; c++)
10852 alc_auto_init_adc(codec, c);
10853 if (spec->dyn_adc_switch)
10854 nums = 1;
10855 else
10856 nums = spec->num_adc_nids;
10857 for (c = 0; c < nums; c++)
10858 alc_mux_select(codec, 0, spec->cur_mux[c], true);
10859}
10860
10861/* add mic boosts if needed */
10862static int alc_auto_add_mic_boost(struct hda_codec *codec)
10863{
10864 struct alc_spec *spec = codec->spec;
10865 struct auto_pin_cfg *cfg = &spec->autocfg;
10866 int i, err;
10867 int type_idx = 0;
10868 hda_nid_t nid;
10869 const char *prev_label = NULL;
10870
10871 for (i = 0; i < cfg->num_inputs; i++) {
10872 if (cfg->inputs[i].type > AUTO_PIN_MIC)
10873 break;
10874 nid = cfg->inputs[i].pin;
10875 if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) {
10876 const char *label;
10877 char boost_label[32];
10878
10879 label = hda_get_autocfg_input_label(codec, cfg, i);
10880 if (prev_label && !strcmp(label, prev_label))
10881 type_idx++;
10882 else
10883 type_idx = 0;
10884 prev_label = label;
10885
10886 snprintf(boost_label, sizeof(boost_label),
10887 "%s Boost Volume", label);
10888 err = add_control(spec, ALC_CTL_WIDGET_VOL,
10889 boost_label, type_idx,
10890 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT));
10891 if (err < 0)
10892 return err;
10893 }
10894 }
10895 return 0;
10896}
10897
10898/* almost identical with ALC880 parser... */ 3985/* almost identical with ALC880 parser... */
10899static int alc882_parse_auto_config(struct hda_codec *codec) 3986static int alc882_parse_auto_config(struct hda_codec *codec)
10900{ 3987{
@@ -10960,6 +4047,12 @@ static void alc882_auto_init(struct hda_codec *codec)
10960 alc_inithook(codec); 4047 alc_inithook(codec);
10961} 4048}
10962 4049
4050/*
4051 */
4052#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4053#include "alc882_quirks.c"
4054#endif
4055
10963static int patch_alc882(struct hda_codec *codec) 4056static int patch_alc882(struct hda_codec *codec)
10964{ 4057{
10965 struct alc_spec *spec; 4058 struct alc_spec *spec;
@@ -10983,39 +4076,41 @@ static int patch_alc882(struct hda_codec *codec)
10983 break; 4076 break;
10984 } 4077 }
10985 4078
10986 board_config = snd_hda_check_board_config(codec, ALC882_MODEL_LAST, 4079 board_config = alc_board_config(codec, ALC882_MODEL_LAST,
10987 alc882_models, 4080 alc882_models, alc882_cfg_tbl);
10988 alc882_cfg_tbl);
10989 4081
10990 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) 4082 if (board_config < 0)
10991 board_config = snd_hda_check_board_codec_sid_config(codec, 4083 board_config = alc_board_codec_sid_config(codec,
10992 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl); 4084 ALC882_MODEL_LAST, alc882_models, alc882_ssid_cfg_tbl);
10993 4085
10994 if (board_config < 0 || board_config >= ALC882_MODEL_LAST) { 4086 if (board_config < 0) {
10995 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 4087 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
10996 codec->chip_name); 4088 codec->chip_name);
10997 board_config = ALC882_AUTO; 4089 board_config = ALC_MODEL_AUTO;
10998 } 4090 }
10999 4091
11000 if (board_config == ALC882_AUTO) { 4092 if (board_config == ALC_MODEL_AUTO) {
11001 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups); 4093 alc_pick_fixup(codec, NULL, alc882_fixup_tbl, alc882_fixups);
11002 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 4094 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
11003 } 4095 }
11004 4096
11005 alc_auto_parse_customize_define(codec); 4097 alc_auto_parse_customize_define(codec);
11006 4098
11007 if (board_config == ALC882_AUTO) { 4099 if (board_config == ALC_MODEL_AUTO) {
11008 /* automatic parse from the BIOS config */ 4100 /* automatic parse from the BIOS config */
11009 err = alc882_parse_auto_config(codec); 4101 err = alc882_parse_auto_config(codec);
11010 if (err < 0) { 4102 if (err < 0) {
11011 alc_free(codec); 4103 alc_free(codec);
11012 return err; 4104 return err;
11013 } else if (!err) { 4105 }
4106#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4107 else if (!err) {
11014 printk(KERN_INFO 4108 printk(KERN_INFO
11015 "hda_codec: Cannot set up configuration " 4109 "hda_codec: Cannot set up configuration "
11016 "from BIOS. Using base mode...\n"); 4110 "from BIOS. Using base mode...\n");
11017 board_config = ALC882_3ST_DIG; 4111 board_config = ALC882_3ST_DIG;
11018 } 4112 }
4113#endif
11019 } 4114 }
11020 4115
11021 if (has_cdefine_beep(codec)) { 4116 if (has_cdefine_beep(codec)) {
@@ -11026,7 +4121,7 @@ static int patch_alc882(struct hda_codec *codec)
11026 } 4121 }
11027 } 4122 }
11028 4123
11029 if (board_config != ALC882_AUTO) 4124 if (board_config != ALC_MODEL_AUTO)
11030 setup_preset(codec, &alc882_presets[board_config]); 4125 setup_preset(codec, &alc882_presets[board_config]);
11031 4126
11032 if (!spec->adc_nids && spec->input_mux) { 4127 if (!spec->adc_nids && spec->input_mux) {
@@ -11045,7 +4140,7 @@ static int patch_alc882(struct hda_codec *codec)
11045 spec->vmaster_nid = 0x0c; 4140 spec->vmaster_nid = 0x0c;
11046 4141
11047 codec->patch_ops = alc_patch_ops; 4142 codec->patch_ops = alc_patch_ops;
11048 if (board_config == ALC882_AUTO) 4143 if (board_config == ALC_MODEL_AUTO)
11049 spec->init_hook = alc882_auto_init; 4144 spec->init_hook = alc882_auto_init;
11050 4145
11051 alc_init_jacks(codec); 4146 alc_init_jacks(codec);
@@ -11062,798 +4157,6 @@ static int patch_alc882(struct hda_codec *codec)
11062 * ALC262 support 4157 * ALC262 support
11063 */ 4158 */
11064 4159
11065#define ALC262_DIGOUT_NID ALC880_DIGOUT_NID
11066#define ALC262_DIGIN_NID ALC880_DIGIN_NID
11067
11068#define alc262_dac_nids alc260_dac_nids
11069#define alc262_adc_nids alc882_adc_nids
11070#define alc262_adc_nids_alt alc882_adc_nids_alt
11071#define alc262_capsrc_nids alc882_capsrc_nids
11072#define alc262_capsrc_nids_alt alc882_capsrc_nids_alt
11073
11074#define alc262_modes alc260_modes
11075#define alc262_capture_source alc882_capture_source
11076
11077static const hda_nid_t alc262_dmic_adc_nids[1] = {
11078 /* ADC0 */
11079 0x09
11080};
11081
11082static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 };
11083
11084static const struct snd_kcontrol_new alc262_base_mixer[] = {
11085 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11086 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11087 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11088 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11089 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11090 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11091 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11092 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11093 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11094 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11095 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11096 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11097 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),
11098 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11099 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT),
11100 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
11101 { } /* end */
11102};
11103
11104/* update HP, line and mono-out pins according to the master switch */
11105#define alc262_hp_master_update alc260_hp_master_update
11106
11107static void alc262_hp_bpc_setup(struct hda_codec *codec)
11108{
11109 struct alc_spec *spec = codec->spec;
11110
11111 spec->autocfg.hp_pins[0] = 0x1b;
11112 spec->autocfg.speaker_pins[0] = 0x16;
11113 spec->automute = 1;
11114 spec->automute_mode = ALC_AUTOMUTE_PIN;
11115}
11116
11117static void alc262_hp_wildwest_setup(struct hda_codec *codec)
11118{
11119 struct alc_spec *spec = codec->spec;
11120
11121 spec->autocfg.hp_pins[0] = 0x15;
11122 spec->autocfg.speaker_pins[0] = 0x16;
11123 spec->automute = 1;
11124 spec->automute_mode = ALC_AUTOMUTE_PIN;
11125}
11126
11127#define alc262_hp_master_sw_get alc260_hp_master_sw_get
11128#define alc262_hp_master_sw_put alc260_hp_master_sw_put
11129
11130#define ALC262_HP_MASTER_SWITCH \
11131 { \
11132 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11133 .name = "Master Playback Switch", \
11134 .info = snd_ctl_boolean_mono_info, \
11135 .get = alc262_hp_master_sw_get, \
11136 .put = alc262_hp_master_sw_put, \
11137 }, \
11138 { \
11139 .iface = NID_MAPPING, \
11140 .name = "Master Playback Switch", \
11141 .private_value = 0x15 | (0x16 << 8) | (0x1b << 16), \
11142 }
11143
11144
11145static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = {
11146 ALC262_HP_MASTER_SWITCH,
11147 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11148 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11149 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11150 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11151 HDA_OUTPUT),
11152 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11153 HDA_OUTPUT),
11154 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11155 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11156 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11157 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11158 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11159 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11160 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11161 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11162 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11163 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11164 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT),
11165 HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT),
11166 { } /* end */
11167};
11168
11169static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = {
11170 ALC262_HP_MASTER_SWITCH,
11171 HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11172 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11173 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11174 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11175 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 2, 0x0,
11176 HDA_OUTPUT),
11177 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 2, 0x0,
11178 HDA_OUTPUT),
11179 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x02, HDA_INPUT),
11180 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x02, HDA_INPUT),
11181 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x1a, 0, HDA_INPUT),
11182 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11183 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11184 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11185 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11186 { } /* end */
11187};
11188
11189static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = {
11190 HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11191 HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11192 HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT),
11193 { } /* end */
11194};
11195
11196/* mute/unmute internal speaker according to the hp jack and mute state */
11197static void alc262_hp_t5735_setup(struct hda_codec *codec)
11198{
11199 struct alc_spec *spec = codec->spec;
11200
11201 spec->autocfg.hp_pins[0] = 0x15;
11202 spec->autocfg.speaker_pins[0] = 0x14;
11203 spec->automute = 1;
11204 spec->automute_mode = ALC_AUTOMUTE_PIN;
11205}
11206
11207static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = {
11208 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11209 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11210 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11211 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11212 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11213 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11214 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11215 { } /* end */
11216};
11217
11218static const struct hda_verb alc262_hp_t5735_verbs[] = {
11219 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11220 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11221
11222 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
11223 { }
11224};
11225
11226static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = {
11227 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11228 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
11229 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT),
11230 HDA_CODEC_MUTE("Speaker Playback Switch", 0x16, 0x0, HDA_OUTPUT),
11231 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x01, HDA_INPUT),
11232 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT),
11233 { } /* end */
11234};
11235
11236static const struct hda_verb alc262_hp_rp5700_verbs[] = {
11237 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11238 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11239 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11240 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11241 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11242 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11243 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11244 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
11245 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11246 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x00 << 8))},
11247 {}
11248};
11249
11250static const struct hda_input_mux alc262_hp_rp5700_capture_source = {
11251 .num_items = 1,
11252 .items = {
11253 { "Line", 0x1 },
11254 },
11255};
11256
11257/* bind hp and internal speaker mute (with plug check) as master switch */
11258#define alc262_hippo_master_update alc262_hp_master_update
11259#define alc262_hippo_master_sw_get alc262_hp_master_sw_get
11260#define alc262_hippo_master_sw_put alc262_hp_master_sw_put
11261
11262#define ALC262_HIPPO_MASTER_SWITCH \
11263 { \
11264 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
11265 .name = "Master Playback Switch", \
11266 .info = snd_ctl_boolean_mono_info, \
11267 .get = alc262_hippo_master_sw_get, \
11268 .put = alc262_hippo_master_sw_put, \
11269 }, \
11270 { \
11271 .iface = NID_MAPPING, \
11272 .name = "Master Playback Switch", \
11273 .subdevice = SUBDEV_HP(0) | (SUBDEV_LINE(0) << 8) | \
11274 (SUBDEV_SPEAKER(0) << 16), \
11275 }
11276
11277static const struct snd_kcontrol_new alc262_hippo_mixer[] = {
11278 ALC262_HIPPO_MASTER_SWITCH,
11279 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11280 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11281 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11282 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11283 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11284 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11285 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11286 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11287 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11288 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11289 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11290 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11291 { } /* end */
11292};
11293
11294static const struct snd_kcontrol_new alc262_hippo1_mixer[] = {
11295 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11296 ALC262_HIPPO_MASTER_SWITCH,
11297 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11298 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11299 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11300 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11301 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11302 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11303 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11304 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11305 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11306 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11307 { } /* end */
11308};
11309
11310/* mute/unmute internal speaker according to the hp jack and mute state */
11311static void alc262_hippo_setup(struct hda_codec *codec)
11312{
11313 struct alc_spec *spec = codec->spec;
11314
11315 spec->autocfg.hp_pins[0] = 0x15;
11316 spec->autocfg.speaker_pins[0] = 0x14;
11317 spec->automute = 1;
11318 spec->automute_mode = ALC_AUTOMUTE_AMP;
11319}
11320
11321static void alc262_hippo1_setup(struct hda_codec *codec)
11322{
11323 struct alc_spec *spec = codec->spec;
11324
11325 spec->autocfg.hp_pins[0] = 0x1b;
11326 spec->autocfg.speaker_pins[0] = 0x14;
11327 spec->automute = 1;
11328 spec->automute_mode = ALC_AUTOMUTE_AMP;
11329}
11330
11331
11332static const struct snd_kcontrol_new alc262_sony_mixer[] = {
11333 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11334 ALC262_HIPPO_MASTER_SWITCH,
11335 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11336 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11337 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11338 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11339 { } /* end */
11340};
11341
11342static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = {
11343 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11344 ALC262_HIPPO_MASTER_SWITCH,
11345 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11346 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11347 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11348 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11349 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11350 { } /* end */
11351};
11352
11353static const struct snd_kcontrol_new alc262_tyan_mixer[] = {
11354 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11355 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11356 HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT),
11357 HDA_CODEC_MUTE("Aux Playback Switch", 0x0b, 0x06, HDA_INPUT),
11358 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
11359 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
11360 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11361 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11362 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11363 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11364 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11365 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11366 { } /* end */
11367};
11368
11369static const struct hda_verb alc262_tyan_verbs[] = {
11370 /* Headphone automute */
11371 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11372 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11373 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11374
11375 /* P11 AUX_IN, white 4-pin connector */
11376 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11377 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_1, 0xe1},
11378 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_2, 0x93},
11379 {0x14, AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, 0x19},
11380
11381 {}
11382};
11383
11384/* unsolicited event for HP jack sensing */
11385static void alc262_tyan_setup(struct hda_codec *codec)
11386{
11387 struct alc_spec *spec = codec->spec;
11388
11389 spec->autocfg.hp_pins[0] = 0x1b;
11390 spec->autocfg.speaker_pins[0] = 0x15;
11391 spec->automute = 1;
11392 spec->automute_mode = ALC_AUTOMUTE_AMP;
11393}
11394
11395
11396#define alc262_capture_mixer alc882_capture_mixer
11397#define alc262_capture_alt_mixer alc882_capture_alt_mixer
11398
11399/*
11400 * generic initialization of ADC, input mixers and output mixers
11401 */
11402static const struct hda_verb alc262_init_verbs[] = {
11403 /*
11404 * Unmute ADC0-2 and set the default input to mic-in
11405 */
11406 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11407 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11408 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11409 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11410 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11411 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11412
11413 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11414 * mixer widget
11415 * Note: PASD motherboards uses the Line In 2 as the input for
11416 * front panel mic (mic 2)
11417 */
11418 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11419 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11420 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11421 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11422 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11423 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11424
11425 /*
11426 * Set up output mixers (0x0c - 0x0e)
11427 */
11428 /* set vol=0 to output mixers */
11429 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11430 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11431 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11432 /* set up input amps for analog loopback */
11433 /* Amp Indices: DAC = 0, mixer = 1 */
11434 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11435 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11436 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11437 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11438 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11439 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11440
11441 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11442 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11443 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
11444 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11445 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11446 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
11447
11448 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11449 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11450 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11451 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11452 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11453
11454 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11455 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
11456
11457 /* FIXME: use matrix-type input source selection */
11458 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
11459 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
11460 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11461 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11462 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11463 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11464 /* Input mixer2 */
11465 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11466 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11467 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11468 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11469 /* Input mixer3 */
11470 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
11471 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
11472 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
11473 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
11474
11475 { }
11476};
11477
11478static const struct hda_verb alc262_eapd_verbs[] = {
11479 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
11480 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
11481 { }
11482};
11483
11484static const struct hda_verb alc262_hippo1_unsol_verbs[] = {
11485 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11486 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
11487 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000},
11488
11489 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11490 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11491 {}
11492};
11493
11494static const struct hda_verb alc262_sony_unsol_verbs[] = {
11495 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
11496 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11497 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic
11498
11499 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11500 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11501 {}
11502};
11503
11504static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = {
11505 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11506 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
11507 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11508 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11509 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11510 { } /* end */
11511};
11512
11513static const struct hda_verb alc262_toshiba_s06_verbs[] = {
11514 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
11515 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11516 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11517 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11518 {0x22, AC_VERB_SET_CONNECT_SEL, 0x09},
11519 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11520 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
11521 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11522 {}
11523};
11524
11525static void alc262_toshiba_s06_setup(struct hda_codec *codec)
11526{
11527 struct alc_spec *spec = codec->spec;
11528
11529 spec->autocfg.hp_pins[0] = 0x15;
11530 spec->autocfg.speaker_pins[0] = 0x14;
11531 spec->ext_mic_pin = 0x18;
11532 spec->int_mic_pin = 0x12;
11533 spec->auto_mic = 1;
11534 spec->automute = 1;
11535 spec->automute_mode = ALC_AUTOMUTE_PIN;
11536}
11537
11538/*
11539 * nec model
11540 * 0x15 = headphone
11541 * 0x16 = internal speaker
11542 * 0x18 = external mic
11543 */
11544
11545static const struct snd_kcontrol_new alc262_nec_mixer[] = {
11546 HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT),
11547 HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT),
11548
11549 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11550 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11551 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11552
11553 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT),
11554 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
11555 { } /* end */
11556};
11557
11558static const struct hda_verb alc262_nec_verbs[] = {
11559 /* Unmute Speaker */
11560 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
11561
11562 /* Headphone */
11563 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11564 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11565
11566 /* External mic to headphone */
11567 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11568 /* External mic to speaker */
11569 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11570 {}
11571};
11572
11573/*
11574 * fujitsu model
11575 * 0x14 = headphone/spdif-out, 0x15 = internal speaker,
11576 * 0x1b = port replicator headphone out
11577 */
11578
11579#define ALC_HP_EVENT ALC880_HP_EVENT
11580
11581static const struct hda_verb alc262_fujitsu_unsol_verbs[] = {
11582 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11583 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11584 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11585 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11586 {}
11587};
11588
11589static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = {
11590 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT},
11591 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11592 {}
11593};
11594
11595static const struct hda_verb alc262_lenovo_3000_init_verbs[] = {
11596 /* Front Mic pin: input vref at 50% */
11597 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
11598 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11599 {}
11600};
11601
11602static const struct hda_input_mux alc262_fujitsu_capture_source = {
11603 .num_items = 3,
11604 .items = {
11605 { "Mic", 0x0 },
11606 { "Internal Mic", 0x1 },
11607 { "CD", 0x4 },
11608 },
11609};
11610
11611static const struct hda_input_mux alc262_HP_capture_source = {
11612 .num_items = 5,
11613 .items = {
11614 { "Mic", 0x0 },
11615 { "Front Mic", 0x1 },
11616 { "Line", 0x2 },
11617 { "CD", 0x4 },
11618 { "AUX IN", 0x6 },
11619 },
11620};
11621
11622static const struct hda_input_mux alc262_HP_D7000_capture_source = {
11623 .num_items = 4,
11624 .items = {
11625 { "Mic", 0x0 },
11626 { "Front Mic", 0x2 },
11627 { "Line", 0x1 },
11628 { "CD", 0x4 },
11629 },
11630};
11631
11632static void alc262_fujitsu_setup(struct hda_codec *codec)
11633{
11634 struct alc_spec *spec = codec->spec;
11635
11636 spec->autocfg.hp_pins[0] = 0x14;
11637 spec->autocfg.hp_pins[1] = 0x1b;
11638 spec->autocfg.speaker_pins[0] = 0x15;
11639 spec->automute = 1;
11640 spec->automute_mode = ALC_AUTOMUTE_AMP;
11641}
11642
11643/* bind volumes of both NID 0x0c and 0x0d */
11644static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = {
11645 .ops = &snd_hda_bind_vol,
11646 .values = {
11647 HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT),
11648 HDA_COMPOSE_AMP_VAL(0x0d, 3, 0, HDA_OUTPUT),
11649 0
11650 },
11651};
11652
11653static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = {
11654 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11655 {
11656 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11657 .name = "Master Playback Switch",
11658 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
11659 .info = snd_ctl_boolean_mono_info,
11660 .get = alc262_hp_master_sw_get,
11661 .put = alc262_hp_master_sw_put,
11662 },
11663 {
11664 .iface = NID_MAPPING,
11665 .name = "Master Playback Switch",
11666 .private_value = 0x1b,
11667 },
11668 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11669 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11670 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11671 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11672 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11673 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11674 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11675 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11676 { } /* end */
11677};
11678
11679static void alc262_lenovo_3000_setup(struct hda_codec *codec)
11680{
11681 struct alc_spec *spec = codec->spec;
11682
11683 spec->autocfg.hp_pins[0] = 0x1b;
11684 spec->autocfg.speaker_pins[0] = 0x14;
11685 spec->autocfg.speaker_pins[1] = 0x16;
11686 spec->automute = 1;
11687 spec->automute_mode = ALC_AUTOMUTE_AMP;
11688}
11689
11690static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = {
11691 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11692 {
11693 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11694 .name = "Master Playback Switch",
11695 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
11696 .info = snd_ctl_boolean_mono_info,
11697 .get = alc262_hp_master_sw_get,
11698 .put = alc262_hp_master_sw_put,
11699 },
11700 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
11701 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
11702 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11703 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11704 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11705 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
11706 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
11707 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
11708 { } /* end */
11709};
11710
11711static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = {
11712 HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol),
11713 ALC262_HIPPO_MASTER_SWITCH,
11714 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
11715 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
11716 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
11717 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11718 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11719 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
11720 { } /* end */
11721};
11722
11723/* additional init verbs for Benq laptops */
11724static const struct hda_verb alc262_EAPD_verbs[] = {
11725 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11726 {0x20, AC_VERB_SET_PROC_COEF, 0x3070},
11727 {}
11728};
11729
11730static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = {
11731 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11732 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
11733
11734 {0x20, AC_VERB_SET_COEF_INDEX, 0x07},
11735 {0x20, AC_VERB_SET_PROC_COEF, 0x3050},
11736 {}
11737};
11738
11739/* Samsung Q1 Ultra Vista model setup */
11740static const struct snd_kcontrol_new alc262_ultra_mixer[] = {
11741 HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT),
11742 HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT),
11743 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
11744 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
11745 HDA_CODEC_VOLUME("Mic Boost Volume", 0x19, 0, HDA_INPUT),
11746 HDA_CODEC_VOLUME("Headphone Mic Boost Volume", 0x15, 0, HDA_INPUT),
11747 { } /* end */
11748};
11749
11750static const struct hda_verb alc262_ultra_verbs[] = {
11751 /* output mixer */
11752 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11753 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11754 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11755 /* speaker */
11756 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
11757 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11758 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11759 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
11760 /* HP */
11761 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
11762 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
11763 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11764 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
11765 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
11766 /* internal mic */
11767 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
11768 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11769 /* ADC, choose mic */
11770 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11771 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11772 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
11773 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11774 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11775 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11776 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11777 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11778 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
11779 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(8)},
11780 {}
11781};
11782
11783/* mute/unmute internal speaker according to the hp jack and mute state */
11784static void alc262_ultra_automute(struct hda_codec *codec)
11785{
11786 struct alc_spec *spec = codec->spec;
11787 unsigned int mute;
11788
11789 mute = 0;
11790 /* auto-mute only when HP is used as HP */
11791 if (!spec->cur_mux[0]) {
11792 spec->jack_present = snd_hda_jack_detect(codec, 0x15);
11793 if (spec->jack_present)
11794 mute = HDA_AMP_MUTE;
11795 }
11796 /* mute/unmute internal speaker */
11797 snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0,
11798 HDA_AMP_MUTE, mute);
11799 /* mute/unmute HP */
11800 snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0,
11801 HDA_AMP_MUTE, mute ? 0 : HDA_AMP_MUTE);
11802}
11803
11804/* unsolicited event for HP jack sensing */
11805static void alc262_ultra_unsol_event(struct hda_codec *codec,
11806 unsigned int res)
11807{
11808 if ((res >> 26) != ALC880_HP_EVENT)
11809 return;
11810 alc262_ultra_automute(codec);
11811}
11812
11813static const struct hda_input_mux alc262_ultra_capture_source = {
11814 .num_items = 2,
11815 .items = {
11816 { "Mic", 0x1 },
11817 { "Headphone", 0x7 },
11818 },
11819};
11820
11821static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol,
11822 struct snd_ctl_elem_value *ucontrol)
11823{
11824 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
11825 struct alc_spec *spec = codec->spec;
11826 int ret;
11827
11828 ret = alc_mux_enum_put(kcontrol, ucontrol);
11829 if (!ret)
11830 return 0;
11831 /* reprogram the HP pin as mic or HP according to the input source */
11832 snd_hda_codec_write_cache(codec, 0x15, 0,
11833 AC_VERB_SET_PIN_WIDGET_CONTROL,
11834 spec->cur_mux[0] ? PIN_VREF80 : PIN_HP);
11835 alc262_ultra_automute(codec); /* mute/unmute HP */
11836 return ret;
11837}
11838
11839static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = {
11840 HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT),
11841 HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT),
11842 {
11843 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
11844 .name = "Capture Source",
11845 .info = alc_mux_enum_info,
11846 .get = alc_mux_enum_get,
11847 .put = alc262_ultra_mux_enum_put,
11848 },
11849 {
11850 .iface = NID_MAPPING,
11851 .name = "Capture Source",
11852 .private_value = 0x15,
11853 },
11854 { } /* end */
11855};
11856
11857/* We use two mixers depending on the output pin; 0x16 is a mono output 4160/* We use two mixers depending on the output pin; 0x16 is a mono output
11858 * and thus it's bound with a different mixer. 4161 * and thus it's bound with a different mixer.
11859 * This function returns which mixer amp should be used. 4162 * This function returns which mixer amp should be used.
@@ -11963,261 +4266,6 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec,
11963 return 0; 4266 return 0;
11964} 4267}
11965 4268
11966static const struct hda_verb alc262_HP_BPC_init_verbs[] = {
11967 /*
11968 * Unmute ADC0-2 and set the default input to mic-in
11969 */
11970 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
11971 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11972 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
11973 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11974 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
11975 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
11976
11977 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
11978 * mixer widget
11979 * Note: PASD motherboards uses the Line In 2 as the input for
11980 * front panel mic (mic 2)
11981 */
11982 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
11983 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
11984 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
11985 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
11986 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
11987 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
11988 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
11989 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
11990
11991 /*
11992 * Set up output mixers (0x0c - 0x0e)
11993 */
11994 /* set vol=0 to output mixers */
11995 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11996 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11997 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
11998
11999 /* set up input amps for analog loopback */
12000 /* Amp Indices: DAC = 0, mixer = 1 */
12001 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12002 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12003 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12004 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12005 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12006 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12007
12008 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12009 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12010 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
12011
12012 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12013 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12014
12015 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12016 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12017
12018 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12019 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12020 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12021 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12022 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12023
12024 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12025 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12026 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12027 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12028 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12029 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12030
12031
12032 /* FIXME: use matrix-type input source selection */
12033 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 0b, 12 */
12034 /* Input mixer1: only unmute Mic */
12035 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12036 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12037 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12038 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12039 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12040 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12041 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12042 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12043 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12044 /* Input mixer2 */
12045 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12046 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12047 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12048 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12049 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12050 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12051 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12052 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12053 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12054 /* Input mixer3 */
12055 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12056 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8))},
12057 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))},
12058 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))},
12059 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))},
12060 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x05 << 8))},
12061 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x06 << 8))},
12062 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x07 << 8))},
12063 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x08 << 8))},
12064
12065 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12066
12067 { }
12068};
12069
12070static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = {
12071 /*
12072 * Unmute ADC0-2 and set the default input to mic-in
12073 */
12074 {0x07, AC_VERB_SET_CONNECT_SEL, 0x00},
12075 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12076 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
12077 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12078 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
12079 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12080
12081 /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback
12082 * mixer widget
12083 * Note: PASD motherboards uses the Line In 2 as the input for front
12084 * panel mic (mic 2)
12085 */
12086 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
12087 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
12088 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12089 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
12090 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
12091 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
12092 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
12093 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
12094 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
12095 /*
12096 * Set up output mixers (0x0c - 0x0e)
12097 */
12098 /* set vol=0 to output mixers */
12099 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12100 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12101 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12102
12103 /* set up input amps for analog loopback */
12104 /* Amp Indices: DAC = 0, mixer = 1 */
12105 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12106 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12107 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12108 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12109 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12110 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
12111
12112
12113 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP */
12114 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Mono */
12115 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* rear MIC */
12116 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line in */
12117 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12118 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Line out */
12119 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD in */
12120
12121 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12122 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12123
12124 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
12125 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
12126
12127 /* {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 }, */
12128 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12129 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12130 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x7023 },
12131 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12132 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0x7000 },
12133
12134 /* FIXME: use matrix-type input source selection */
12135 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
12136 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
12137 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, /*rear MIC*/
12138 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))}, /*Line in*/
12139 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))}, /*F MIC*/
12140 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))}, /*Front*/
12141 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /*CD*/
12142 /* {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12143 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))}, /*HP*/
12144 /* Input mixer2 */
12145 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12146 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12147 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12148 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12149 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12150 /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12151 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12152 /* Input mixer3 */
12153 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))},
12154 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8))},
12155 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8))},
12156 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x03 << 8))},
12157 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))},
12158 /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x06 << 8))}, */
12159 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x07 << 8))},
12160
12161 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12162
12163 { }
12164};
12165
12166static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = {
12167
12168 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */
12169 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
12170 {0x14, AC_VERB_SET_CONNECT_SEL, 0x01},
12171
12172 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */
12173 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */
12174 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12175 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) },
12176
12177 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */
12178 {0x15, AC_VERB_SET_CONNECT_SEL, 0x00},
12179 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
12180 {}
12181};
12182
12183/*
12184 * Pin config fixes
12185 */
12186enum {
12187 PINFIX_FSC_H270,
12188 PINFIX_HP_Z200,
12189};
12190
12191static const struct alc_fixup alc262_fixups[] = {
12192 [PINFIX_FSC_H270] = {
12193 .type = ALC_FIXUP_PINS,
12194 .v.pins = (const struct alc_pincfg[]) {
12195 { 0x14, 0x99130110 }, /* speaker */
12196 { 0x15, 0x0221142f }, /* front HP */
12197 { 0x1b, 0x0121141f }, /* rear HP */
12198 { }
12199 }
12200 },
12201 [PINFIX_HP_Z200] = {
12202 .type = ALC_FIXUP_PINS,
12203 .v.pins = (const struct alc_pincfg[]) {
12204 { 0x16, 0x99130120 }, /* internal speaker */
12205 { }
12206 }
12207 },
12208};
12209
12210static const struct snd_pci_quirk alc262_fixup_tbl[] = {
12211 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", PINFIX_HP_Z200),
12212 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
12213 {}
12214};
12215
12216
12217#ifdef CONFIG_SND_HDA_POWER_SAVE
12218#define alc262_loopbacks alc880_loopbacks
12219#endif
12220
12221/* 4269/*
12222 * BIOS auto configuration 4270 * BIOS auto configuration
12223 */ 4271 */
@@ -12266,6 +4314,43 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
12266 return 1; 4314 return 1;
12267} 4315}
12268 4316
4317/*
4318 * Pin config fixes
4319 */
4320enum {
4321 PINFIX_FSC_H270,
4322 PINFIX_HP_Z200,
4323};
4324
4325static const struct alc_fixup alc262_fixups[] = {
4326 [PINFIX_FSC_H270] = {
4327 .type = ALC_FIXUP_PINS,
4328 .v.pins = (const struct alc_pincfg[]) {
4329 { 0x14, 0x99130110 }, /* speaker */
4330 { 0x15, 0x0221142f }, /* front HP */
4331 { 0x1b, 0x0121141f }, /* rear HP */
4332 { }
4333 }
4334 },
4335 [PINFIX_HP_Z200] = {
4336 .type = ALC_FIXUP_PINS,
4337 .v.pins = (const struct alc_pincfg[]) {
4338 { 0x16, 0x99130120 }, /* internal speaker */
4339 { }
4340 }
4341 },
4342};
4343
4344static const struct snd_pci_quirk alc262_fixup_tbl[] = {
4345 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200", PINFIX_HP_Z200),
4346 SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270),
4347 {}
4348};
4349
4350
4351#ifdef CONFIG_SND_HDA_POWER_SAVE
4352#define alc262_loopbacks alc880_loopbacks
4353#endif
12269 4354
12270/* init callback for auto-configuration model -- overriding the default init */ 4355/* init callback for auto-configuration model -- overriding the default init */
12271static void alc262_auto_init(struct hda_codec *codec) 4356static void alc262_auto_init(struct hda_codec *codec)
@@ -12281,321 +4366,10 @@ static void alc262_auto_init(struct hda_codec *codec)
12281} 4366}
12282 4367
12283/* 4368/*
12284 * configuration and preset
12285 */ 4369 */
12286static const char * const alc262_models[ALC262_MODEL_LAST] = { 4370#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
12287 [ALC262_BASIC] = "basic", 4371#include "alc262_quirks.c"
12288 [ALC262_HIPPO] = "hippo",
12289 [ALC262_HIPPO_1] = "hippo_1",
12290 [ALC262_FUJITSU] = "fujitsu",
12291 [ALC262_HP_BPC] = "hp-bpc",
12292 [ALC262_HP_BPC_D7000_WL]= "hp-bpc-d7000",
12293 [ALC262_HP_TC_T5735] = "hp-tc-t5735",
12294 [ALC262_HP_RP5700] = "hp-rp5700",
12295 [ALC262_BENQ_ED8] = "benq",
12296 [ALC262_BENQ_T31] = "benq-t31",
12297 [ALC262_SONY_ASSAMD] = "sony-assamd",
12298 [ALC262_TOSHIBA_S06] = "toshiba-s06",
12299 [ALC262_TOSHIBA_RX1] = "toshiba-rx1",
12300 [ALC262_ULTRA] = "ultra",
12301 [ALC262_LENOVO_3000] = "lenovo-3000",
12302 [ALC262_NEC] = "nec",
12303 [ALC262_TYAN] = "tyan",
12304 [ALC262_AUTO] = "auto",
12305};
12306
12307static const struct snd_pci_quirk alc262_cfg_tbl[] = {
12308 SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO),
12309 SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC),
12310 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series",
12311 ALC262_HP_BPC),
12312 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series",
12313 ALC262_HP_BPC),
12314 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series",
12315 ALC262_HP_BPC),
12316 SND_PCI_QUIRK(0x103c, 0x170b, "HP Z200",
12317 ALC262_AUTO),
12318 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series",
12319 ALC262_HP_BPC),
12320 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL),
12321 SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF),
12322 SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL),
12323 SND_PCI_QUIRK(0x103c, 0x2803, "HP D7000", ALC262_HP_BPC_D7000_WF),
12324 SND_PCI_QUIRK(0x103c, 0x2804, "HP D7000", ALC262_HP_BPC_D7000_WL),
12325 SND_PCI_QUIRK(0x103c, 0x2805, "HP D7000", ALC262_HP_BPC_D7000_WF),
12326 SND_PCI_QUIRK(0x103c, 0x2806, "HP D7000", ALC262_HP_BPC_D7000_WL),
12327 SND_PCI_QUIRK(0x103c, 0x2807, "HP D7000", ALC262_HP_BPC_D7000_WF),
12328 SND_PCI_QUIRK(0x103c, 0x280c, "HP xw4400", ALC262_HP_BPC),
12329 SND_PCI_QUIRK(0x103c, 0x3014, "HP xw6400", ALC262_HP_BPC),
12330 SND_PCI_QUIRK(0x103c, 0x3015, "HP xw8400", ALC262_HP_BPC),
12331 SND_PCI_QUIRK(0x103c, 0x302f, "HP Thin Client T5735",
12332 ALC262_HP_TC_T5735),
12333 SND_PCI_QUIRK(0x103c, 0x2817, "HP RP5700", ALC262_HP_RP5700),
12334 SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12335 SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO),
12336 SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD),
12337 SND_PCI_QUIRK(0x104d, 0x9016, "Sony VAIO", ALC262_AUTO), /* dig-only */
12338 SND_PCI_QUIRK(0x104d, 0x9025, "Sony VAIO Z21MN", ALC262_TOSHIBA_S06),
12339 SND_PCI_QUIRK(0x104d, 0x9035, "Sony VAIO VGN-FW170J", ALC262_AUTO),
12340 SND_PCI_QUIRK(0x104d, 0x9047, "Sony VAIO Type G", ALC262_AUTO),
12341#if 0 /* disable the quirk since model=auto works better in recent versions */
12342 SND_PCI_QUIRK_MASK(0x104d, 0xff00, 0x9000, "Sony VAIO",
12343 ALC262_SONY_ASSAMD),
12344#endif 4372#endif
12345 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1",
12346 ALC262_TOSHIBA_RX1),
12347 SND_PCI_QUIRK(0x1179, 0xff7b, "Toshiba S06", ALC262_TOSHIBA_S06),
12348 SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU),
12349 SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU),
12350 SND_PCI_QUIRK(0x10f1, 0x2915, "Tyan Thunder n6650W", ALC262_TYAN),
12351 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc032, "Samsung Q1",
12352 ALC262_ULTRA),
12353 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO),
12354 SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000),
12355 SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8),
12356 SND_PCI_QUIRK(0x17ff, 0x058d, "Benq T31-16", ALC262_BENQ_T31),
12357 SND_PCI_QUIRK(0x17ff, 0x058f, "Benq Hippo", ALC262_HIPPO_1),
12358 {}
12359};
12360
12361static const struct alc_config_preset alc262_presets[] = {
12362 [ALC262_BASIC] = {
12363 .mixers = { alc262_base_mixer },
12364 .init_verbs = { alc262_init_verbs },
12365 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12366 .dac_nids = alc262_dac_nids,
12367 .hp_nid = 0x03,
12368 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12369 .channel_mode = alc262_modes,
12370 .input_mux = &alc262_capture_source,
12371 },
12372 [ALC262_HIPPO] = {
12373 .mixers = { alc262_hippo_mixer },
12374 .init_verbs = { alc262_init_verbs, alc_hp15_unsol_verbs},
12375 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12376 .dac_nids = alc262_dac_nids,
12377 .hp_nid = 0x03,
12378 .dig_out_nid = ALC262_DIGOUT_NID,
12379 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12380 .channel_mode = alc262_modes,
12381 .input_mux = &alc262_capture_source,
12382 .unsol_event = alc_sku_unsol_event,
12383 .setup = alc262_hippo_setup,
12384 .init_hook = alc_inithook,
12385 },
12386 [ALC262_HIPPO_1] = {
12387 .mixers = { alc262_hippo1_mixer },
12388 .init_verbs = { alc262_init_verbs, alc262_hippo1_unsol_verbs},
12389 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12390 .dac_nids = alc262_dac_nids,
12391 .hp_nid = 0x02,
12392 .dig_out_nid = ALC262_DIGOUT_NID,
12393 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12394 .channel_mode = alc262_modes,
12395 .input_mux = &alc262_capture_source,
12396 .unsol_event = alc_sku_unsol_event,
12397 .setup = alc262_hippo1_setup,
12398 .init_hook = alc_inithook,
12399 },
12400 [ALC262_FUJITSU] = {
12401 .mixers = { alc262_fujitsu_mixer },
12402 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12403 alc262_fujitsu_unsol_verbs },
12404 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12405 .dac_nids = alc262_dac_nids,
12406 .hp_nid = 0x03,
12407 .dig_out_nid = ALC262_DIGOUT_NID,
12408 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12409 .channel_mode = alc262_modes,
12410 .input_mux = &alc262_fujitsu_capture_source,
12411 .unsol_event = alc_sku_unsol_event,
12412 .setup = alc262_fujitsu_setup,
12413 .init_hook = alc_inithook,
12414 },
12415 [ALC262_HP_BPC] = {
12416 .mixers = { alc262_HP_BPC_mixer },
12417 .init_verbs = { alc262_HP_BPC_init_verbs },
12418 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12419 .dac_nids = alc262_dac_nids,
12420 .hp_nid = 0x03,
12421 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12422 .channel_mode = alc262_modes,
12423 .input_mux = &alc262_HP_capture_source,
12424 .unsol_event = alc_sku_unsol_event,
12425 .setup = alc262_hp_bpc_setup,
12426 .init_hook = alc_inithook,
12427 },
12428 [ALC262_HP_BPC_D7000_WF] = {
12429 .mixers = { alc262_HP_BPC_WildWest_mixer },
12430 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12431 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12432 .dac_nids = alc262_dac_nids,
12433 .hp_nid = 0x03,
12434 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12435 .channel_mode = alc262_modes,
12436 .input_mux = &alc262_HP_D7000_capture_source,
12437 .unsol_event = alc_sku_unsol_event,
12438 .setup = alc262_hp_wildwest_setup,
12439 .init_hook = alc_inithook,
12440 },
12441 [ALC262_HP_BPC_D7000_WL] = {
12442 .mixers = { alc262_HP_BPC_WildWest_mixer,
12443 alc262_HP_BPC_WildWest_option_mixer },
12444 .init_verbs = { alc262_HP_BPC_WildWest_init_verbs },
12445 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12446 .dac_nids = alc262_dac_nids,
12447 .hp_nid = 0x03,
12448 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12449 .channel_mode = alc262_modes,
12450 .input_mux = &alc262_HP_D7000_capture_source,
12451 .unsol_event = alc_sku_unsol_event,
12452 .setup = alc262_hp_wildwest_setup,
12453 .init_hook = alc_inithook,
12454 },
12455 [ALC262_HP_TC_T5735] = {
12456 .mixers = { alc262_hp_t5735_mixer },
12457 .init_verbs = { alc262_init_verbs, alc262_hp_t5735_verbs },
12458 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12459 .dac_nids = alc262_dac_nids,
12460 .hp_nid = 0x03,
12461 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12462 .channel_mode = alc262_modes,
12463 .input_mux = &alc262_capture_source,
12464 .unsol_event = alc_sku_unsol_event,
12465 .setup = alc262_hp_t5735_setup,
12466 .init_hook = alc_inithook,
12467 },
12468 [ALC262_HP_RP5700] = {
12469 .mixers = { alc262_hp_rp5700_mixer },
12470 .init_verbs = { alc262_init_verbs, alc262_hp_rp5700_verbs },
12471 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12472 .dac_nids = alc262_dac_nids,
12473 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12474 .channel_mode = alc262_modes,
12475 .input_mux = &alc262_hp_rp5700_capture_source,
12476 },
12477 [ALC262_BENQ_ED8] = {
12478 .mixers = { alc262_base_mixer },
12479 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs },
12480 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12481 .dac_nids = alc262_dac_nids,
12482 .hp_nid = 0x03,
12483 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12484 .channel_mode = alc262_modes,
12485 .input_mux = &alc262_capture_source,
12486 },
12487 [ALC262_SONY_ASSAMD] = {
12488 .mixers = { alc262_sony_mixer },
12489 .init_verbs = { alc262_init_verbs, alc262_sony_unsol_verbs},
12490 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12491 .dac_nids = alc262_dac_nids,
12492 .hp_nid = 0x02,
12493 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12494 .channel_mode = alc262_modes,
12495 .input_mux = &alc262_capture_source,
12496 .unsol_event = alc_sku_unsol_event,
12497 .setup = alc262_hippo_setup,
12498 .init_hook = alc_inithook,
12499 },
12500 [ALC262_BENQ_T31] = {
12501 .mixers = { alc262_benq_t31_mixer },
12502 .init_verbs = { alc262_init_verbs, alc262_benq_t31_EAPD_verbs,
12503 alc_hp15_unsol_verbs },
12504 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12505 .dac_nids = alc262_dac_nids,
12506 .hp_nid = 0x03,
12507 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12508 .channel_mode = alc262_modes,
12509 .input_mux = &alc262_capture_source,
12510 .unsol_event = alc_sku_unsol_event,
12511 .setup = alc262_hippo_setup,
12512 .init_hook = alc_inithook,
12513 },
12514 [ALC262_ULTRA] = {
12515 .mixers = { alc262_ultra_mixer },
12516 .cap_mixer = alc262_ultra_capture_mixer,
12517 .init_verbs = { alc262_ultra_verbs },
12518 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12519 .dac_nids = alc262_dac_nids,
12520 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12521 .channel_mode = alc262_modes,
12522 .input_mux = &alc262_ultra_capture_source,
12523 .adc_nids = alc262_adc_nids, /* ADC0 */
12524 .capsrc_nids = alc262_capsrc_nids,
12525 .num_adc_nids = 1, /* single ADC */
12526 .unsol_event = alc262_ultra_unsol_event,
12527 .init_hook = alc262_ultra_automute,
12528 },
12529 [ALC262_LENOVO_3000] = {
12530 .mixers = { alc262_lenovo_3000_mixer },
12531 .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs,
12532 alc262_lenovo_3000_unsol_verbs,
12533 alc262_lenovo_3000_init_verbs },
12534 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12535 .dac_nids = alc262_dac_nids,
12536 .hp_nid = 0x03,
12537 .dig_out_nid = ALC262_DIGOUT_NID,
12538 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12539 .channel_mode = alc262_modes,
12540 .input_mux = &alc262_fujitsu_capture_source,
12541 .unsol_event = alc_sku_unsol_event,
12542 .setup = alc262_lenovo_3000_setup,
12543 .init_hook = alc_inithook,
12544 },
12545 [ALC262_NEC] = {
12546 .mixers = { alc262_nec_mixer },
12547 .init_verbs = { alc262_nec_verbs },
12548 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12549 .dac_nids = alc262_dac_nids,
12550 .hp_nid = 0x03,
12551 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12552 .channel_mode = alc262_modes,
12553 .input_mux = &alc262_capture_source,
12554 },
12555 [ALC262_TOSHIBA_S06] = {
12556 .mixers = { alc262_toshiba_s06_mixer },
12557 .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs,
12558 alc262_eapd_verbs },
12559 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12560 .capsrc_nids = alc262_dmic_capsrc_nids,
12561 .dac_nids = alc262_dac_nids,
12562 .adc_nids = alc262_dmic_adc_nids, /* ADC0 */
12563 .num_adc_nids = 1, /* single ADC */
12564 .dig_out_nid = ALC262_DIGOUT_NID,
12565 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12566 .channel_mode = alc262_modes,
12567 .unsol_event = alc_sku_unsol_event,
12568 .setup = alc262_toshiba_s06_setup,
12569 .init_hook = alc_inithook,
12570 },
12571 [ALC262_TOSHIBA_RX1] = {
12572 .mixers = { alc262_toshiba_rx1_mixer },
12573 .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs },
12574 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12575 .dac_nids = alc262_dac_nids,
12576 .hp_nid = 0x03,
12577 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12578 .channel_mode = alc262_modes,
12579 .input_mux = &alc262_capture_source,
12580 .unsol_event = alc_sku_unsol_event,
12581 .setup = alc262_hippo_setup,
12582 .init_hook = alc_inithook,
12583 },
12584 [ALC262_TYAN] = {
12585 .mixers = { alc262_tyan_mixer },
12586 .init_verbs = { alc262_init_verbs, alc262_tyan_verbs},
12587 .num_dacs = ARRAY_SIZE(alc262_dac_nids),
12588 .dac_nids = alc262_dac_nids,
12589 .hp_nid = 0x02,
12590 .dig_out_nid = ALC262_DIGOUT_NID,
12591 .num_channel_mode = ARRAY_SIZE(alc262_modes),
12592 .channel_mode = alc262_modes,
12593 .input_mux = &alc262_capture_source,
12594 .unsol_event = alc_sku_unsol_event,
12595 .setup = alc262_tyan_setup,
12596 .init_hook = alc_hp_automute,
12597 },
12598};
12599 4373
12600static int patch_alc262(struct hda_codec *codec) 4374static int patch_alc262(struct hda_codec *codec)
12601{ 4375{
@@ -12627,33 +4401,35 @@ static int patch_alc262(struct hda_codec *codec)
12627 4401
12628 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 4402 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
12629 4403
12630 board_config = snd_hda_check_board_config(codec, ALC262_MODEL_LAST, 4404 board_config = alc_board_config(codec, ALC262_MODEL_LAST,
12631 alc262_models, 4405 alc262_models, alc262_cfg_tbl);
12632 alc262_cfg_tbl);
12633 4406
12634 if (board_config < 0) { 4407 if (board_config < 0) {
12635 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 4408 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
12636 codec->chip_name); 4409 codec->chip_name);
12637 board_config = ALC262_AUTO; 4410 board_config = ALC_MODEL_AUTO;
12638 } 4411 }
12639 4412
12640 if (board_config == ALC262_AUTO) { 4413 if (board_config == ALC_MODEL_AUTO) {
12641 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups); 4414 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups);
12642 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 4415 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
12643 } 4416 }
12644 4417
12645 if (board_config == ALC262_AUTO) { 4418 if (board_config == ALC_MODEL_AUTO) {
12646 /* automatic parse from the BIOS config */ 4419 /* automatic parse from the BIOS config */
12647 err = alc262_parse_auto_config(codec); 4420 err = alc262_parse_auto_config(codec);
12648 if (err < 0) { 4421 if (err < 0) {
12649 alc_free(codec); 4422 alc_free(codec);
12650 return err; 4423 return err;
12651 } else if (!err) { 4424 }
4425#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4426 else if (!err) {
12652 printk(KERN_INFO 4427 printk(KERN_INFO
12653 "hda_codec: Cannot set up configuration " 4428 "hda_codec: Cannot set up configuration "
12654 "from BIOS. Using base mode...\n"); 4429 "from BIOS. Using base mode...\n");
12655 board_config = ALC262_BASIC; 4430 board_config = ALC262_BASIC;
12656 } 4431 }
4432#endif
12657 } 4433 }
12658 4434
12659 if (!spec->no_analog && has_cdefine_beep(codec)) { 4435 if (!spec->no_analog && has_cdefine_beep(codec)) {
@@ -12664,7 +4440,7 @@ static int patch_alc262(struct hda_codec *codec)
12664 } 4440 }
12665 } 4441 }
12666 4442
12667 if (board_config != ALC262_AUTO) 4443 if (board_config != ALC_MODEL_AUTO)
12668 setup_preset(codec, &alc262_presets[board_config]); 4444 setup_preset(codec, &alc262_presets[board_config]);
12669 4445
12670 if (!spec->adc_nids && spec->input_mux) { 4446 if (!spec->adc_nids && spec->input_mux) {
@@ -12682,7 +4458,7 @@ static int patch_alc262(struct hda_codec *codec)
12682 spec->vmaster_nid = 0x0c; 4458 spec->vmaster_nid = 0x0c;
12683 4459
12684 codec->patch_ops = alc_patch_ops; 4460 codec->patch_ops = alc_patch_ops;
12685 if (board_config == ALC262_AUTO) 4461 if (board_config == ALC_MODEL_AUTO)
12686 spec->init_hook = alc262_auto_init; 4462 spec->init_hook = alc262_auto_init;
12687 spec->shutup = alc_eapd_shutup; 4463 spec->shutup = alc_eapd_shutup;
12688 4464
@@ -12696,432 +4472,8 @@ static int patch_alc262(struct hda_codec *codec)
12696} 4472}
12697 4473
12698/* 4474/*
12699 * ALC268 channel source setting (2 channel) 4475 * ALC268
12700 */
12701#define ALC268_DIGOUT_NID ALC880_DIGOUT_NID
12702#define alc268_modes alc260_modes
12703
12704static const hda_nid_t alc268_dac_nids[2] = {
12705 /* front, hp */
12706 0x02, 0x03
12707};
12708
12709static const hda_nid_t alc268_adc_nids[2] = {
12710 /* ADC0-1 */
12711 0x08, 0x07
12712};
12713
12714static const hda_nid_t alc268_adc_nids_alt[1] = {
12715 /* ADC0 */
12716 0x08
12717};
12718
12719static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 };
12720
12721static const struct snd_kcontrol_new alc268_base_mixer[] = {
12722 /* output mixer control */
12723 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12724 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12725 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12726 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12727 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12728 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
12729 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
12730 { }
12731};
12732
12733static const struct snd_kcontrol_new alc268_toshiba_mixer[] = {
12734 /* output mixer control */
12735 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12736 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12737 ALC262_HIPPO_MASTER_SWITCH,
12738 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12739 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
12740 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
12741 { }
12742};
12743
12744/* bind Beep switches of both NID 0x0f and 0x10 */
12745static const struct hda_bind_ctls alc268_bind_beep_sw = {
12746 .ops = &snd_hda_bind_sw,
12747 .values = {
12748 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
12749 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
12750 0
12751 },
12752};
12753
12754static const struct snd_kcontrol_new alc268_beep_mixer[] = {
12755 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
12756 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
12757 { }
12758};
12759
12760static const struct hda_verb alc268_eapd_verbs[] = {
12761 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
12762 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
12763 { }
12764};
12765
12766/* Toshiba specific */
12767static const struct hda_verb alc268_toshiba_verbs[] = {
12768 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12769 { } /* end */
12770};
12771
12772/* Acer specific */
12773/* bind volumes of both NID 0x02 and 0x03 */
12774static const struct hda_bind_ctls alc268_acer_bind_master_vol = {
12775 .ops = &snd_hda_bind_vol,
12776 .values = {
12777 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
12778 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
12779 0
12780 },
12781};
12782
12783static void alc268_acer_setup(struct hda_codec *codec)
12784{
12785 struct alc_spec *spec = codec->spec;
12786
12787 spec->autocfg.hp_pins[0] = 0x14;
12788 spec->autocfg.speaker_pins[0] = 0x15;
12789 spec->automute = 1;
12790 spec->automute_mode = ALC_AUTOMUTE_AMP;
12791}
12792
12793#define alc268_acer_master_sw_get alc262_hp_master_sw_get
12794#define alc268_acer_master_sw_put alc262_hp_master_sw_put
12795
12796static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = {
12797 /* output mixer control */
12798 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12799 {
12800 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12801 .name = "Master Playback Switch",
12802 .subdevice = HDA_SUBDEV_NID_FLAG | 0x15,
12803 .info = snd_ctl_boolean_mono_info,
12804 .get = alc268_acer_master_sw_get,
12805 .put = alc268_acer_master_sw_put,
12806 },
12807 HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT),
12808 { }
12809};
12810
12811static const struct snd_kcontrol_new alc268_acer_mixer[] = {
12812 /* output mixer control */
12813 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12814 {
12815 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12816 .name = "Master Playback Switch",
12817 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12818 .info = snd_ctl_boolean_mono_info,
12819 .get = alc268_acer_master_sw_get,
12820 .put = alc268_acer_master_sw_put,
12821 },
12822 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12823 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12824 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
12825 { }
12826};
12827
12828static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = {
12829 /* output mixer control */
12830 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
12831 {
12832 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
12833 .name = "Master Playback Switch",
12834 .subdevice = HDA_SUBDEV_NID_FLAG | 0x14,
12835 .info = snd_ctl_boolean_mono_info,
12836 .get = alc268_acer_master_sw_get,
12837 .put = alc268_acer_master_sw_put,
12838 },
12839 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12840 HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT),
12841 { }
12842};
12843
12844static const struct hda_verb alc268_acer_aspire_one_verbs[] = {
12845 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12846 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12847 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12848 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
12849 {0x23, AC_VERB_SET_CONNECT_SEL, 0x06},
12850 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017},
12851 { }
12852};
12853
12854static const struct hda_verb alc268_acer_verbs[] = {
12855 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */
12856 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
12857 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12858 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
12859 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12860 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
12861 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12862 { }
12863};
12864
12865/* unsolicited event for HP jack sensing */
12866#define alc268_toshiba_setup alc262_hippo_setup
12867
12868static void alc268_acer_lc_setup(struct hda_codec *codec)
12869{
12870 struct alc_spec *spec = codec->spec;
12871 spec->autocfg.hp_pins[0] = 0x15;
12872 spec->autocfg.speaker_pins[0] = 0x14;
12873 spec->automute = 1;
12874 spec->automute_mode = ALC_AUTOMUTE_AMP;
12875 spec->ext_mic_pin = 0x18;
12876 spec->int_mic_pin = 0x12;
12877 spec->auto_mic = 1;
12878}
12879
12880static const struct snd_kcontrol_new alc268_dell_mixer[] = {
12881 /* output mixer control */
12882 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
12883 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12884 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
12885 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12886 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12887 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12888 { }
12889};
12890
12891static const struct hda_verb alc268_dell_verbs[] = {
12892 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12893 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
12894 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12895 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12896 { }
12897};
12898
12899/* mute/unmute internal speaker according to the hp jack and mute state */
12900static void alc268_dell_setup(struct hda_codec *codec)
12901{
12902 struct alc_spec *spec = codec->spec;
12903
12904 spec->autocfg.hp_pins[0] = 0x15;
12905 spec->autocfg.speaker_pins[0] = 0x14;
12906 spec->ext_mic_pin = 0x18;
12907 spec->int_mic_pin = 0x19;
12908 spec->auto_mic = 1;
12909 spec->automute = 1;
12910 spec->automute_mode = ALC_AUTOMUTE_PIN;
12911}
12912
12913static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = {
12914 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT),
12915 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
12916 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT),
12917 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
12918 HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT),
12919 HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT),
12920 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
12921 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
12922 { }
12923};
12924
12925static const struct hda_verb alc267_quanta_il1_verbs[] = {
12926 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
12927 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
12928 { }
12929};
12930
12931static void alc267_quanta_il1_setup(struct hda_codec *codec)
12932{
12933 struct alc_spec *spec = codec->spec;
12934 spec->autocfg.hp_pins[0] = 0x15;
12935 spec->autocfg.speaker_pins[0] = 0x14;
12936 spec->ext_mic_pin = 0x18;
12937 spec->int_mic_pin = 0x19;
12938 spec->auto_mic = 1;
12939 spec->automute = 1;
12940 spec->automute_mode = ALC_AUTOMUTE_PIN;
12941}
12942
12943/*
12944 * generic initialization of ADC, input mixers and output mixers
12945 */ 4476 */
12946static const struct hda_verb alc268_base_init_verbs[] = {
12947 /* Unmute DAC0-1 and set vol = 0 */
12948 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12949 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12950
12951 /*
12952 * Set up output mixers (0x0c - 0x0e)
12953 */
12954 /* set vol=0 to output mixers */
12955 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12956 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00},
12957
12958 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12959 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12960
12961 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12962 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0},
12963 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40},
12964 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12965 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
12966 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12967 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12968 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
12969
12970 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12971 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12972 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12973 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12974 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
12975
12976 /* set PCBEEP vol = 0, mute connections */
12977 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
12978 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12979 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
12980
12981 /* Unmute Selector 23h,24h and set the default input to mic-in */
12982
12983 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
12984 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12985 {0x24, AC_VERB_SET_CONNECT_SEL, 0x00},
12986 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
12987
12988 { }
12989};
12990
12991/* only for model=test */
12992#ifdef CONFIG_SND_DEBUG
12993/*
12994 * generic initialization of ADC, input mixers and output mixers
12995 */
12996static const struct hda_verb alc268_volume_init_verbs[] = {
12997 /* set output DAC */
12998 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
12999 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
13000
13001 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13002 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24},
13003 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13004 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13005 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20},
13006
13007 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13008 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13009 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13010
13011 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13012 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
13013 { }
13014};
13015#endif /* CONFIG_SND_DEBUG */
13016
13017/* set PCBEEP vol = 0, mute connections */
13018static const struct hda_verb alc268_beep_init_verbs[] = {
13019 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
13020 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13021 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
13022 { }
13023};
13024
13025static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = {
13026 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13027 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13028 { } /* end */
13029};
13030
13031static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = {
13032 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13033 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13034 _DEFINE_CAPSRC(1),
13035 { } /* end */
13036};
13037
13038static const struct snd_kcontrol_new alc268_capture_mixer[] = {
13039 HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13040 HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT),
13041 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT),
13042 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x24, 0x0, HDA_OUTPUT),
13043 _DEFINE_CAPSRC(2),
13044 { } /* end */
13045};
13046
13047static const struct hda_input_mux alc268_capture_source = {
13048 .num_items = 4,
13049 .items = {
13050 { "Mic", 0x0 },
13051 { "Front Mic", 0x1 },
13052 { "Line", 0x2 },
13053 { "CD", 0x3 },
13054 },
13055};
13056
13057static const struct hda_input_mux alc268_acer_capture_source = {
13058 .num_items = 3,
13059 .items = {
13060 { "Mic", 0x0 },
13061 { "Internal Mic", 0x1 },
13062 { "Line", 0x2 },
13063 },
13064};
13065
13066static const struct hda_input_mux alc268_acer_dmic_capture_source = {
13067 .num_items = 3,
13068 .items = {
13069 { "Mic", 0x0 },
13070 { "Internal Mic", 0x6 },
13071 { "Line", 0x2 },
13072 },
13073};
13074
13075#ifdef CONFIG_SND_DEBUG
13076static const struct snd_kcontrol_new alc268_test_mixer[] = {
13077 /* Volume widgets */
13078 HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13079 HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13080 HDA_BIND_MUTE_MONO("Mono sum Playback Switch", 0x0e, 1, 2, HDA_INPUT),
13081 HDA_BIND_MUTE("LINE-OUT sum Playback Switch", 0x0f, 2, HDA_INPUT),
13082 HDA_BIND_MUTE("HP-OUT sum Playback Switch", 0x10, 2, HDA_INPUT),
13083 HDA_BIND_MUTE("LINE-OUT Playback Switch", 0x14, 2, HDA_OUTPUT),
13084 HDA_BIND_MUTE("HP-OUT Playback Switch", 0x15, 2, HDA_OUTPUT),
13085 HDA_BIND_MUTE("Mono Playback Switch", 0x16, 2, HDA_OUTPUT),
13086 HDA_CODEC_VOLUME("MIC1 Capture Volume", 0x18, 0x0, HDA_INPUT),
13087 HDA_BIND_MUTE("MIC1 Capture Switch", 0x18, 2, HDA_OUTPUT),
13088 HDA_CODEC_VOLUME("MIC2 Capture Volume", 0x19, 0x0, HDA_INPUT),
13089 HDA_CODEC_VOLUME("LINE1 Capture Volume", 0x1a, 0x0, HDA_INPUT),
13090 HDA_BIND_MUTE("LINE1 Capture Switch", 0x1a, 2, HDA_OUTPUT),
13091 /* The below appears problematic on some hardwares */
13092 /*HDA_CODEC_VOLUME("PCBEEP Playback Volume", 0x1d, 0x0, HDA_INPUT),*/
13093 HDA_CODEC_VOLUME("PCM-IN1 Capture Volume", 0x23, 0x0, HDA_OUTPUT),
13094 HDA_BIND_MUTE("PCM-IN1 Capture Switch", 0x23, 2, HDA_OUTPUT),
13095 HDA_CODEC_VOLUME("PCM-IN2 Capture Volume", 0x24, 0x0, HDA_OUTPUT),
13096 HDA_BIND_MUTE("PCM-IN2 Capture Switch", 0x24, 2, HDA_OUTPUT),
13097
13098 /* Modes for retasking pin widgets */
13099 ALC_PIN_MODE("LINE-OUT pin mode", 0x14, ALC_PIN_DIR_INOUT),
13100 ALC_PIN_MODE("HP-OUT pin mode", 0x15, ALC_PIN_DIR_INOUT),
13101 ALC_PIN_MODE("MIC1 pin mode", 0x18, ALC_PIN_DIR_INOUT),
13102 ALC_PIN_MODE("LINE1 pin mode", 0x1a, ALC_PIN_DIR_INOUT),
13103
13104 /* Controls for GPIO pins, assuming they are configured as outputs */
13105 ALC_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01),
13106 ALC_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02),
13107 ALC_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04),
13108 ALC_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08),
13109
13110 /* Switches to allow the digital SPDIF output pin to be enabled.
13111 * The ALC268 does not have an SPDIF input.
13112 */
13113 ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x06, 0x01),
13114
13115 /* A switch allowing EAPD to be enabled. Some laptops seem to use
13116 * this output to turn on an external amplifier.
13117 */
13118 ALC_EAPD_CTRL_SWITCH("LINE-OUT EAPD Enable Switch", 0x0f, 0x02),
13119 ALC_EAPD_CTRL_SWITCH("HP-OUT EAPD Enable Switch", 0x10, 0x02),
13120
13121 { } /* end */
13122};
13123#endif
13124
13125/* create input playback/capture controls for the given pin */ 4477/* create input playback/capture controls for the given pin */
13126static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 4478static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
13127 const char *ctlname, int idx) 4479 const char *ctlname, int idx)
@@ -13320,6 +4672,30 @@ static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec)
13320 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2); 4672 AC_VERB_SET_AMP_GAIN_MUTE, dac_vol2);
13321} 4673}
13322 4674
4675/* bind Beep switches of both NID 0x0f and 0x10 */
4676static const struct hda_bind_ctls alc268_bind_beep_sw = {
4677 .ops = &snd_hda_bind_sw,
4678 .values = {
4679 HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT),
4680 HDA_COMPOSE_AMP_VAL(0x10, 3, 1, HDA_INPUT),
4681 0
4682 },
4683};
4684
4685static const struct snd_kcontrol_new alc268_beep_mixer[] = {
4686 HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT),
4687 HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw),
4688 { }
4689};
4690
4691/* set PCBEEP vol = 0, mute connections */
4692static const struct hda_verb alc268_beep_init_verbs[] = {
4693 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4694 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4695 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4696 { }
4697};
4698
13323/* 4699/*
13324 * BIOS auto configuration 4700 * BIOS auto configuration
13325 */ 4701 */
@@ -13388,215 +4764,10 @@ static void alc268_auto_init(struct hda_codec *codec)
13388} 4764}
13389 4765
13390/* 4766/*
13391 * configuration and preset
13392 */ 4767 */
13393static const char * const alc268_models[ALC268_MODEL_LAST] = { 4768#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
13394 [ALC267_QUANTA_IL1] = "quanta-il1", 4769#include "alc268_quirks.c"
13395 [ALC268_3ST] = "3stack",
13396 [ALC268_TOSHIBA] = "toshiba",
13397 [ALC268_ACER] = "acer",
13398 [ALC268_ACER_DMIC] = "acer-dmic",
13399 [ALC268_ACER_ASPIRE_ONE] = "acer-aspire",
13400 [ALC268_DELL] = "dell",
13401 [ALC268_ZEPTO] = "zepto",
13402#ifdef CONFIG_SND_DEBUG
13403 [ALC268_TEST] = "test",
13404#endif
13405 [ALC268_AUTO] = "auto",
13406};
13407
13408static const struct snd_pci_quirk alc268_cfg_tbl[] = {
13409 SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER),
13410 SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER),
13411 SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER),
13412 SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER),
13413 SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER),
13414 SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
13415 ALC268_ACER_ASPIRE_ONE),
13416 SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
13417 SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO),
13418 SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0,
13419 "Dell Inspiron Mini9/Vostro A90", ALC268_DELL),
13420 /* almost compatible with toshiba but with optional digital outs;
13421 * auto-probing seems working fine
13422 */
13423 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP TX25xx series",
13424 ALC268_AUTO),
13425 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
13426 SND_PCI_QUIRK(0x1170, 0x0040, "ZEPTO", ALC268_ZEPTO),
13427 SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA),
13428 SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1),
13429 {}
13430};
13431
13432/* Toshiba laptops have no unique PCI SSID but only codec SSID */
13433static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = {
13434 SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO),
13435 SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO),
13436 SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05",
13437 ALC268_TOSHIBA),
13438 {}
13439};
13440
13441static const struct alc_config_preset alc268_presets[] = {
13442 [ALC267_QUANTA_IL1] = {
13443 .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer,
13444 alc268_capture_nosrc_mixer },
13445 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13446 alc267_quanta_il1_verbs },
13447 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13448 .dac_nids = alc268_dac_nids,
13449 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13450 .adc_nids = alc268_adc_nids_alt,
13451 .hp_nid = 0x03,
13452 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13453 .channel_mode = alc268_modes,
13454 .unsol_event = alc_sku_unsol_event,
13455 .setup = alc267_quanta_il1_setup,
13456 .init_hook = alc_inithook,
13457 },
13458 [ALC268_3ST] = {
13459 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13460 alc268_beep_mixer },
13461 .init_verbs = { alc268_base_init_verbs },
13462 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13463 .dac_nids = alc268_dac_nids,
13464 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13465 .adc_nids = alc268_adc_nids_alt,
13466 .capsrc_nids = alc268_capsrc_nids,
13467 .hp_nid = 0x03,
13468 .dig_out_nid = ALC268_DIGOUT_NID,
13469 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13470 .channel_mode = alc268_modes,
13471 .input_mux = &alc268_capture_source,
13472 },
13473 [ALC268_TOSHIBA] = {
13474 .mixers = { alc268_toshiba_mixer, alc268_capture_alt_mixer,
13475 alc268_beep_mixer },
13476 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13477 alc268_toshiba_verbs },
13478 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13479 .dac_nids = alc268_dac_nids,
13480 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13481 .adc_nids = alc268_adc_nids_alt,
13482 .capsrc_nids = alc268_capsrc_nids,
13483 .hp_nid = 0x03,
13484 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13485 .channel_mode = alc268_modes,
13486 .input_mux = &alc268_capture_source,
13487 .unsol_event = alc_sku_unsol_event,
13488 .setup = alc268_toshiba_setup,
13489 .init_hook = alc_inithook,
13490 },
13491 [ALC268_ACER] = {
13492 .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer,
13493 alc268_beep_mixer },
13494 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13495 alc268_acer_verbs },
13496 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13497 .dac_nids = alc268_dac_nids,
13498 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13499 .adc_nids = alc268_adc_nids_alt,
13500 .capsrc_nids = alc268_capsrc_nids,
13501 .hp_nid = 0x02,
13502 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13503 .channel_mode = alc268_modes,
13504 .input_mux = &alc268_acer_capture_source,
13505 .unsol_event = alc_sku_unsol_event,
13506 .setup = alc268_acer_setup,
13507 .init_hook = alc_inithook,
13508 },
13509 [ALC268_ACER_DMIC] = {
13510 .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer,
13511 alc268_beep_mixer },
13512 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13513 alc268_acer_verbs },
13514 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13515 .dac_nids = alc268_dac_nids,
13516 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13517 .adc_nids = alc268_adc_nids_alt,
13518 .capsrc_nids = alc268_capsrc_nids,
13519 .hp_nid = 0x02,
13520 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13521 .channel_mode = alc268_modes,
13522 .input_mux = &alc268_acer_dmic_capture_source,
13523 .unsol_event = alc_sku_unsol_event,
13524 .setup = alc268_acer_setup,
13525 .init_hook = alc_inithook,
13526 },
13527 [ALC268_ACER_ASPIRE_ONE] = {
13528 .mixers = { alc268_acer_aspire_one_mixer,
13529 alc268_beep_mixer,
13530 alc268_capture_nosrc_mixer },
13531 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13532 alc268_acer_aspire_one_verbs },
13533 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13534 .dac_nids = alc268_dac_nids,
13535 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13536 .adc_nids = alc268_adc_nids_alt,
13537 .capsrc_nids = alc268_capsrc_nids,
13538 .hp_nid = 0x03,
13539 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13540 .channel_mode = alc268_modes,
13541 .unsol_event = alc_sku_unsol_event,
13542 .setup = alc268_acer_lc_setup,
13543 .init_hook = alc_inithook,
13544 },
13545 [ALC268_DELL] = {
13546 .mixers = { alc268_dell_mixer, alc268_beep_mixer,
13547 alc268_capture_nosrc_mixer },
13548 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13549 alc268_dell_verbs },
13550 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13551 .dac_nids = alc268_dac_nids,
13552 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13553 .adc_nids = alc268_adc_nids_alt,
13554 .capsrc_nids = alc268_capsrc_nids,
13555 .hp_nid = 0x02,
13556 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13557 .channel_mode = alc268_modes,
13558 .unsol_event = alc_sku_unsol_event,
13559 .setup = alc268_dell_setup,
13560 .init_hook = alc_inithook,
13561 },
13562 [ALC268_ZEPTO] = {
13563 .mixers = { alc268_base_mixer, alc268_capture_alt_mixer,
13564 alc268_beep_mixer },
13565 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13566 alc268_toshiba_verbs },
13567 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13568 .dac_nids = alc268_dac_nids,
13569 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13570 .adc_nids = alc268_adc_nids_alt,
13571 .capsrc_nids = alc268_capsrc_nids,
13572 .hp_nid = 0x03,
13573 .dig_out_nid = ALC268_DIGOUT_NID,
13574 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13575 .channel_mode = alc268_modes,
13576 .input_mux = &alc268_capture_source,
13577 .unsol_event = alc_sku_unsol_event,
13578 .setup = alc268_toshiba_setup,
13579 .init_hook = alc_inithook,
13580 },
13581#ifdef CONFIG_SND_DEBUG
13582 [ALC268_TEST] = {
13583 .mixers = { alc268_test_mixer, alc268_capture_mixer },
13584 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs,
13585 alc268_volume_init_verbs,
13586 alc268_beep_init_verbs },
13587 .num_dacs = ARRAY_SIZE(alc268_dac_nids),
13588 .dac_nids = alc268_dac_nids,
13589 .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt),
13590 .adc_nids = alc268_adc_nids_alt,
13591 .capsrc_nids = alc268_capsrc_nids,
13592 .hp_nid = 0x03,
13593 .dig_out_nid = ALC268_DIGOUT_NID,
13594 .num_channel_mode = ARRAY_SIZE(alc268_modes),
13595 .channel_mode = alc268_modes,
13596 .input_mux = &alc268_capture_source,
13597 },
13598#endif 4770#endif
13599};
13600 4771
13601static int patch_alc268(struct hda_codec *codec) 4772static int patch_alc268(struct hda_codec *codec)
13602{ 4773{
@@ -13612,35 +4783,37 @@ static int patch_alc268(struct hda_codec *codec)
13612 4783
13613 /* ALC268 has no aa-loopback mixer */ 4784 /* ALC268 has no aa-loopback mixer */
13614 4785
13615 board_config = snd_hda_check_board_config(codec, ALC268_MODEL_LAST, 4786 board_config = alc_board_config(codec, ALC268_MODEL_LAST,
13616 alc268_models, 4787 alc268_models, alc268_cfg_tbl);
13617 alc268_cfg_tbl);
13618 4788
13619 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) 4789 if (board_config < 0)
13620 board_config = snd_hda_check_board_codec_sid_config(codec, 4790 board_config = alc_board_codec_sid_config(codec,
13621 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl); 4791 ALC268_MODEL_LAST, alc268_models, alc268_ssid_cfg_tbl);
13622 4792
13623 if (board_config < 0 || board_config >= ALC268_MODEL_LAST) { 4793 if (board_config < 0) {
13624 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 4794 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
13625 codec->chip_name); 4795 codec->chip_name);
13626 board_config = ALC268_AUTO; 4796 board_config = ALC_MODEL_AUTO;
13627 } 4797 }
13628 4798
13629 if (board_config == ALC268_AUTO) { 4799 if (board_config == ALC_MODEL_AUTO) {
13630 /* automatic parse from the BIOS config */ 4800 /* automatic parse from the BIOS config */
13631 err = alc268_parse_auto_config(codec); 4801 err = alc268_parse_auto_config(codec);
13632 if (err < 0) { 4802 if (err < 0) {
13633 alc_free(codec); 4803 alc_free(codec);
13634 return err; 4804 return err;
13635 } else if (!err) { 4805 }
4806#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
4807 else if (!err) {
13636 printk(KERN_INFO 4808 printk(KERN_INFO
13637 "hda_codec: Cannot set up configuration " 4809 "hda_codec: Cannot set up configuration "
13638 "from BIOS. Using base mode...\n"); 4810 "from BIOS. Using base mode...\n");
13639 board_config = ALC268_3ST; 4811 board_config = ALC268_3ST;
13640 } 4812 }
4813#endif
13641 } 4814 }
13642 4815
13643 if (board_config != ALC268_AUTO) 4816 if (board_config != ALC_MODEL_AUTO)
13644 setup_preset(codec, &alc268_presets[board_config]); 4817 setup_preset(codec, &alc268_presets[board_config]);
13645 4818
13646 has_beep = 0; 4819 has_beep = 0;
@@ -13678,7 +4851,7 @@ static int patch_alc268(struct hda_codec *codec)
13678 spec->vmaster_nid = 0x02; 4851 spec->vmaster_nid = 0x02;
13679 4852
13680 codec->patch_ops = alc_patch_ops; 4853 codec->patch_ops = alc_patch_ops;
13681 if (board_config == ALC268_AUTO) 4854 if (board_config == ALC_MODEL_AUTO)
13682 spec->init_hook = alc268_auto_init; 4855 spec->init_hook = alc268_auto_init;
13683 spec->shutup = alc_eapd_shutup; 4856 spec->shutup = alc_eapd_shutup;
13684 4857
@@ -13688,469 +4861,8 @@ static int patch_alc268(struct hda_codec *codec)
13688} 4861}
13689 4862
13690/* 4863/*
13691 * ALC269 channel source setting (2 channel) 4864 * ALC269
13692 */ 4865 */
13693#define ALC269_DIGOUT_NID ALC880_DIGOUT_NID
13694
13695#define alc269_dac_nids alc260_dac_nids
13696
13697static const hda_nid_t alc269_adc_nids[1] = {
13698 /* ADC1 */
13699 0x08,
13700};
13701
13702static const hda_nid_t alc269_capsrc_nids[1] = {
13703 0x23,
13704};
13705
13706static const hda_nid_t alc269vb_adc_nids[1] = {
13707 /* ADC1 */
13708 0x09,
13709};
13710
13711static const hda_nid_t alc269vb_capsrc_nids[1] = {
13712 0x22,
13713};
13714
13715#define alc269_modes alc260_modes
13716#define alc269_capture_source alc880_lg_lw_capture_source
13717
13718static const struct snd_kcontrol_new alc269_base_mixer[] = {
13719 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13720 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13721 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
13722 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
13723 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13724 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13725 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13726 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13727 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13728 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
13729 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13730 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x16, 2, 0x0, HDA_OUTPUT),
13731 { } /* end */
13732};
13733
13734static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = {
13735 /* output mixer control */
13736 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13737 {
13738 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13739 .name = "Master Playback Switch",
13740 .subdevice = HDA_SUBDEV_AMP_FLAG,
13741 .info = snd_hda_mixer_amp_switch_info,
13742 .get = snd_hda_mixer_amp_switch_get,
13743 .put = alc268_acer_master_sw_put,
13744 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13745 },
13746 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13747 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13748 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13749 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13750 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13751 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13752 { }
13753};
13754
13755static const struct snd_kcontrol_new alc269_lifebook_mixer[] = {
13756 /* output mixer control */
13757 HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol),
13758 {
13759 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
13760 .name = "Master Playback Switch",
13761 .subdevice = HDA_SUBDEV_AMP_FLAG,
13762 .info = snd_hda_mixer_amp_switch_info,
13763 .get = snd_hda_mixer_amp_switch_get,
13764 .put = alc268_acer_master_sw_put,
13765 .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
13766 },
13767 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
13768 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
13769 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13770 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT),
13771 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT),
13772 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13773 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x0b, 0x03, HDA_INPUT),
13774 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x0b, 0x03, HDA_INPUT),
13775 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x1b, 0, HDA_INPUT),
13776 { }
13777};
13778
13779static const struct snd_kcontrol_new alc269_laptop_mixer[] = {
13780 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13781 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13782 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
13783 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13784 { } /* end */
13785};
13786
13787static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = {
13788 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
13789 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13790 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
13791 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
13792 { } /* end */
13793};
13794
13795static const struct snd_kcontrol_new alc269_asus_mixer[] = {
13796 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
13797 HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT),
13798 { } /* end */
13799};
13800
13801/* capture mixer elements */
13802static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = {
13803 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13804 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13805 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13806 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13807 { } /* end */
13808};
13809
13810static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = {
13811 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
13812 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
13813 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13814 { } /* end */
13815};
13816
13817static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = {
13818 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13819 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13820 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13821 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
13822 { } /* end */
13823};
13824
13825static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = {
13826 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
13827 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
13828 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
13829 { } /* end */
13830};
13831
13832/* FSC amilo */
13833#define alc269_fujitsu_mixer alc269_laptop_mixer
13834
13835static const struct hda_verb alc269_quanta_fl1_verbs[] = {
13836 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13837 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13838 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13839 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13840 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13841 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13842 { }
13843};
13844
13845static const struct hda_verb alc269_lifebook_verbs[] = {
13846 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13847 {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01},
13848 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13849 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13850 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13851 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
13852 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
13853 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
13854 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13855 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13856 { }
13857};
13858
13859/* toggle speaker-output according to the hp-jack state */
13860static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec)
13861{
13862 alc_hp_automute(codec);
13863
13864 snd_hda_codec_write(codec, 0x20, 0,
13865 AC_VERB_SET_COEF_INDEX, 0x0c);
13866 snd_hda_codec_write(codec, 0x20, 0,
13867 AC_VERB_SET_PROC_COEF, 0x680);
13868
13869 snd_hda_codec_write(codec, 0x20, 0,
13870 AC_VERB_SET_COEF_INDEX, 0x0c);
13871 snd_hda_codec_write(codec, 0x20, 0,
13872 AC_VERB_SET_PROC_COEF, 0x480);
13873}
13874
13875#define alc269_lifebook_speaker_automute \
13876 alc269_quanta_fl1_speaker_automute
13877
13878static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec)
13879{
13880 unsigned int present_laptop;
13881 unsigned int present_dock;
13882
13883 present_laptop = snd_hda_jack_detect(codec, 0x18);
13884 present_dock = snd_hda_jack_detect(codec, 0x1b);
13885
13886 /* Laptop mic port overrides dock mic port, design decision */
13887 if (present_dock)
13888 snd_hda_codec_write(codec, 0x23, 0,
13889 AC_VERB_SET_CONNECT_SEL, 0x3);
13890 if (present_laptop)
13891 snd_hda_codec_write(codec, 0x23, 0,
13892 AC_VERB_SET_CONNECT_SEL, 0x0);
13893 if (!present_dock && !present_laptop)
13894 snd_hda_codec_write(codec, 0x23, 0,
13895 AC_VERB_SET_CONNECT_SEL, 0x1);
13896}
13897
13898static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec,
13899 unsigned int res)
13900{
13901 switch (res >> 26) {
13902 case ALC880_HP_EVENT:
13903 alc269_quanta_fl1_speaker_automute(codec);
13904 break;
13905 case ALC880_MIC_EVENT:
13906 alc_mic_automute(codec);
13907 break;
13908 }
13909}
13910
13911static void alc269_lifebook_unsol_event(struct hda_codec *codec,
13912 unsigned int res)
13913{
13914 if ((res >> 26) == ALC880_HP_EVENT)
13915 alc269_lifebook_speaker_automute(codec);
13916 if ((res >> 26) == ALC880_MIC_EVENT)
13917 alc269_lifebook_mic_autoswitch(codec);
13918}
13919
13920static void alc269_quanta_fl1_setup(struct hda_codec *codec)
13921{
13922 struct alc_spec *spec = codec->spec;
13923 spec->autocfg.hp_pins[0] = 0x15;
13924 spec->autocfg.speaker_pins[0] = 0x14;
13925 spec->automute_mixer_nid[0] = 0x0c;
13926 spec->automute = 1;
13927 spec->automute_mode = ALC_AUTOMUTE_MIXER;
13928 spec->ext_mic_pin = 0x18;
13929 spec->int_mic_pin = 0x19;
13930 spec->auto_mic = 1;
13931}
13932
13933static void alc269_quanta_fl1_init_hook(struct hda_codec *codec)
13934{
13935 alc269_quanta_fl1_speaker_automute(codec);
13936 alc_mic_automute(codec);
13937}
13938
13939static void alc269_lifebook_setup(struct hda_codec *codec)
13940{
13941 struct alc_spec *spec = codec->spec;
13942 spec->autocfg.hp_pins[0] = 0x15;
13943 spec->autocfg.hp_pins[1] = 0x1a;
13944 spec->autocfg.speaker_pins[0] = 0x14;
13945 spec->automute_mixer_nid[0] = 0x0c;
13946 spec->automute = 1;
13947 spec->automute_mode = ALC_AUTOMUTE_MIXER;
13948}
13949
13950static void alc269_lifebook_init_hook(struct hda_codec *codec)
13951{
13952 alc269_lifebook_speaker_automute(codec);
13953 alc269_lifebook_mic_autoswitch(codec);
13954}
13955
13956static const struct hda_verb alc269_laptop_dmic_init_verbs[] = {
13957 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13958 {0x23, AC_VERB_SET_CONNECT_SEL, 0x05},
13959 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13960 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13961 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13962 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13963 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13964 {}
13965};
13966
13967static const struct hda_verb alc269_laptop_amic_init_verbs[] = {
13968 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
13969 {0x23, AC_VERB_SET_CONNECT_SEL, 0x01},
13970 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13971 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, (0x701b | (0x00 << 8))},
13972 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13973 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13974 {}
13975};
13976
13977static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = {
13978 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13979 {0x22, AC_VERB_SET_CONNECT_SEL, 0x06},
13980 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13981 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13982 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13983 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13984 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13985 {}
13986};
13987
13988static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = {
13989 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01},
13990 {0x22, AC_VERB_SET_CONNECT_SEL, 0x01},
13991 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 },
13992 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, (0x7019 | (0x00 << 8))},
13993 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
13994 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
13995 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
13996 {}
13997};
13998
13999static const struct hda_verb alc271_acer_dmic_verbs[] = {
14000 {0x20, AC_VERB_SET_COEF_INDEX, 0x0d},
14001 {0x20, AC_VERB_SET_PROC_COEF, 0x4000},
14002 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14003 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14004 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14005 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14006 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00},
14007 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
14008 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
14009 {0x22, AC_VERB_SET_CONNECT_SEL, 6},
14010 { }
14011};
14012
14013static void alc269_laptop_amic_setup(struct hda_codec *codec)
14014{
14015 struct alc_spec *spec = codec->spec;
14016 spec->autocfg.hp_pins[0] = 0x15;
14017 spec->autocfg.speaker_pins[0] = 0x14;
14018 spec->automute_mixer_nid[0] = 0x0c;
14019 spec->automute = 1;
14020 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14021 spec->ext_mic_pin = 0x18;
14022 spec->int_mic_pin = 0x19;
14023 spec->auto_mic = 1;
14024}
14025
14026static void alc269_laptop_dmic_setup(struct hda_codec *codec)
14027{
14028 struct alc_spec *spec = codec->spec;
14029 spec->autocfg.hp_pins[0] = 0x15;
14030 spec->autocfg.speaker_pins[0] = 0x14;
14031 spec->automute_mixer_nid[0] = 0x0c;
14032 spec->automute = 1;
14033 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14034 spec->ext_mic_pin = 0x18;
14035 spec->int_mic_pin = 0x12;
14036 spec->auto_mic = 1;
14037}
14038
14039static void alc269vb_laptop_amic_setup(struct hda_codec *codec)
14040{
14041 struct alc_spec *spec = codec->spec;
14042 spec->autocfg.hp_pins[0] = 0x21;
14043 spec->autocfg.speaker_pins[0] = 0x14;
14044 spec->automute_mixer_nid[0] = 0x0c;
14045 spec->automute = 1;
14046 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14047 spec->ext_mic_pin = 0x18;
14048 spec->int_mic_pin = 0x19;
14049 spec->auto_mic = 1;
14050}
14051
14052static void alc269vb_laptop_dmic_setup(struct hda_codec *codec)
14053{
14054 struct alc_spec *spec = codec->spec;
14055 spec->autocfg.hp_pins[0] = 0x21;
14056 spec->autocfg.speaker_pins[0] = 0x14;
14057 spec->automute_mixer_nid[0] = 0x0c;
14058 spec->automute = 1;
14059 spec->automute_mode = ALC_AUTOMUTE_MIXER;
14060 spec->ext_mic_pin = 0x18;
14061 spec->int_mic_pin = 0x12;
14062 spec->auto_mic = 1;
14063}
14064
14065/*
14066 * generic initialization of ADC, input mixers and output mixers
14067 */
14068static const struct hda_verb alc269_init_verbs[] = {
14069 /*
14070 * Unmute ADC0 and set the default input to mic-in
14071 */
14072 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14073
14074 /*
14075 * Set up output mixers (0x02 - 0x03)
14076 */
14077 /* set vol=0 to output mixers */
14078 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14079 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14080
14081 /* set up input amps for analog loopback */
14082 /* Amp Indices: DAC = 0, mixer = 1 */
14083 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14084 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14085 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14086 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14087 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14088 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14089
14090 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14091 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14092 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14093 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14094 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14095 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14096 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14097
14098 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14099 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14100
14101 /* FIXME: use Mux-type input source selection */
14102 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14103 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14104 {0x23, AC_VERB_SET_CONNECT_SEL, 0x00},
14105
14106 /* set EAPD */
14107 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14108 { }
14109};
14110
14111static const struct hda_verb alc269vb_init_verbs[] = {
14112 /*
14113 * Unmute ADC0 and set the default input to mic-in
14114 */
14115 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14116
14117 /*
14118 * Set up output mixers (0x02 - 0x03)
14119 */
14120 /* set vol=0 to output mixers */
14121 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14122 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
14123
14124 /* set up input amps for analog loopback */
14125 /* Amp Indices: DAC = 0, mixer = 1 */
14126 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14127 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14128 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14129 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14130 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
14131 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
14132
14133 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14134 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
14135 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
14136 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14137 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
14138 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14139 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
14140
14141 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14142 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
14143
14144 /* FIXME: use Mux-type input source selection */
14145 /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */
14146 /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */
14147 {0x22, AC_VERB_SET_CONNECT_SEL, 0x00},
14148
14149 /* set EAPD */
14150 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
14151 { }
14152};
14153
14154#define alc269_auto_create_multi_out_ctls \ 4866#define alc269_auto_create_multi_out_ctls \
14155 alc268_auto_create_multi_out_ctls 4867 alc268_auto_create_multi_out_ctls
14156 4868
@@ -14438,203 +5150,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
14438}; 5150};
14439 5151
14440 5152
14441/*
14442 * configuration and preset
14443 */
14444static const char * const alc269_models[ALC269_MODEL_LAST] = {
14445 [ALC269_BASIC] = "basic",
14446 [ALC269_QUANTA_FL1] = "quanta",
14447 [ALC269_AMIC] = "laptop-amic",
14448 [ALC269_DMIC] = "laptop-dmic",
14449 [ALC269_FUJITSU] = "fujitsu",
14450 [ALC269_LIFEBOOK] = "lifebook",
14451 [ALC269_AUTO] = "auto",
14452};
14453
14454static const struct snd_pci_quirk alc269_cfg_tbl[] = {
14455 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1),
14456 SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER),
14457 SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A",
14458 ALC269_AMIC),
14459 SND_PCI_QUIRK(0x1043, 0x1013, "ASUS N61Da", ALC269VB_AMIC),
14460 SND_PCI_QUIRK(0x1043, 0x1113, "ASUS N63Jn", ALC269VB_AMIC),
14461 SND_PCI_QUIRK(0x1043, 0x1143, "ASUS B53f", ALC269VB_AMIC),
14462 SND_PCI_QUIRK(0x1043, 0x1133, "ASUS UJ20ft", ALC269_AMIC),
14463 SND_PCI_QUIRK(0x1043, 0x1183, "ASUS K72DR", ALC269VB_AMIC),
14464 SND_PCI_QUIRK(0x1043, 0x11b3, "ASUS K52DR", ALC269VB_AMIC),
14465 SND_PCI_QUIRK(0x1043, 0x11e3, "ASUS U33Jc", ALC269VB_AMIC),
14466 SND_PCI_QUIRK(0x1043, 0x1273, "ASUS UL80Jt", ALC269VB_AMIC),
14467 SND_PCI_QUIRK(0x1043, 0x1283, "ASUS U53Jc", ALC269_AMIC),
14468 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS N82JV", ALC269VB_AMIC),
14469 SND_PCI_QUIRK(0x1043, 0x12d3, "ASUS N61Jv", ALC269_AMIC),
14470 SND_PCI_QUIRK(0x1043, 0x13a3, "ASUS UL30Vt", ALC269_AMIC),
14471 SND_PCI_QUIRK(0x1043, 0x1373, "ASUS G73JX", ALC269_AMIC),
14472 SND_PCI_QUIRK(0x1043, 0x1383, "ASUS UJ30Jc", ALC269_AMIC),
14473 SND_PCI_QUIRK(0x1043, 0x13d3, "ASUS N61JA", ALC269_AMIC),
14474 SND_PCI_QUIRK(0x1043, 0x1413, "ASUS UL50", ALC269_AMIC),
14475 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS UL30", ALC269_AMIC),
14476 SND_PCI_QUIRK(0x1043, 0x1453, "ASUS M60Jv", ALC269_AMIC),
14477 SND_PCI_QUIRK(0x1043, 0x1483, "ASUS UL80", ALC269_AMIC),
14478 SND_PCI_QUIRK(0x1043, 0x14f3, "ASUS F83Vf", ALC269_AMIC),
14479 SND_PCI_QUIRK(0x1043, 0x14e3, "ASUS UL20", ALC269_AMIC),
14480 SND_PCI_QUIRK(0x1043, 0x1513, "ASUS UX30", ALC269_AMIC),
14481 SND_PCI_QUIRK(0x1043, 0x1593, "ASUS N51Vn", ALC269_AMIC),
14482 SND_PCI_QUIRK(0x1043, 0x15a3, "ASUS N60Jv", ALC269_AMIC),
14483 SND_PCI_QUIRK(0x1043, 0x15b3, "ASUS N60Dp", ALC269_AMIC),
14484 SND_PCI_QUIRK(0x1043, 0x15c3, "ASUS N70De", ALC269_AMIC),
14485 SND_PCI_QUIRK(0x1043, 0x15e3, "ASUS F83T", ALC269_AMIC),
14486 SND_PCI_QUIRK(0x1043, 0x1643, "ASUS M60J", ALC269_AMIC),
14487 SND_PCI_QUIRK(0x1043, 0x1653, "ASUS U50", ALC269_AMIC),
14488 SND_PCI_QUIRK(0x1043, 0x1693, "ASUS F50N", ALC269_AMIC),
14489 SND_PCI_QUIRK(0x1043, 0x16a3, "ASUS F5Q", ALC269_AMIC),
14490 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_DMIC),
14491 SND_PCI_QUIRK(0x1043, 0x1723, "ASUS P80", ALC269_AMIC),
14492 SND_PCI_QUIRK(0x1043, 0x1743, "ASUS U80", ALC269_AMIC),
14493 SND_PCI_QUIRK(0x1043, 0x1773, "ASUS U20A", ALC269_AMIC),
14494 SND_PCI_QUIRK(0x1043, 0x1883, "ASUS F81Se", ALC269_AMIC),
14495 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901",
14496 ALC269_DMIC),
14497 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101",
14498 ALC269_DMIC),
14499 SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC),
14500 SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC),
14501 SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO),
14502 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK),
14503 SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC),
14504 SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU),
14505 SND_PCI_QUIRK(0x17aa, 0x3be9, "Quanta Wistron", ALC269_AMIC),
14506 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_AMIC),
14507 SND_PCI_QUIRK(0x17ff, 0x059a, "Quanta EL3", ALC269_DMIC),
14508 SND_PCI_QUIRK(0x17ff, 0x059b, "Quanta JR1", ALC269_DMIC),
14509 {}
14510};
14511
14512static const struct alc_config_preset alc269_presets[] = {
14513 [ALC269_BASIC] = {
14514 .mixers = { alc269_base_mixer },
14515 .init_verbs = { alc269_init_verbs },
14516 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14517 .dac_nids = alc269_dac_nids,
14518 .hp_nid = 0x03,
14519 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14520 .channel_mode = alc269_modes,
14521 .input_mux = &alc269_capture_source,
14522 },
14523 [ALC269_QUANTA_FL1] = {
14524 .mixers = { alc269_quanta_fl1_mixer },
14525 .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs },
14526 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14527 .dac_nids = alc269_dac_nids,
14528 .hp_nid = 0x03,
14529 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14530 .channel_mode = alc269_modes,
14531 .input_mux = &alc269_capture_source,
14532 .unsol_event = alc269_quanta_fl1_unsol_event,
14533 .setup = alc269_quanta_fl1_setup,
14534 .init_hook = alc269_quanta_fl1_init_hook,
14535 },
14536 [ALC269_AMIC] = {
14537 .mixers = { alc269_laptop_mixer },
14538 .cap_mixer = alc269_laptop_analog_capture_mixer,
14539 .init_verbs = { alc269_init_verbs,
14540 alc269_laptop_amic_init_verbs },
14541 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14542 .dac_nids = alc269_dac_nids,
14543 .hp_nid = 0x03,
14544 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14545 .channel_mode = alc269_modes,
14546 .unsol_event = alc_sku_unsol_event,
14547 .setup = alc269_laptop_amic_setup,
14548 .init_hook = alc_inithook,
14549 },
14550 [ALC269_DMIC] = {
14551 .mixers = { alc269_laptop_mixer },
14552 .cap_mixer = alc269_laptop_digital_capture_mixer,
14553 .init_verbs = { alc269_init_verbs,
14554 alc269_laptop_dmic_init_verbs },
14555 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14556 .dac_nids = alc269_dac_nids,
14557 .hp_nid = 0x03,
14558 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14559 .channel_mode = alc269_modes,
14560 .unsol_event = alc_sku_unsol_event,
14561 .setup = alc269_laptop_dmic_setup,
14562 .init_hook = alc_inithook,
14563 },
14564 [ALC269VB_AMIC] = {
14565 .mixers = { alc269vb_laptop_mixer },
14566 .cap_mixer = alc269vb_laptop_analog_capture_mixer,
14567 .init_verbs = { alc269vb_init_verbs,
14568 alc269vb_laptop_amic_init_verbs },
14569 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14570 .dac_nids = alc269_dac_nids,
14571 .hp_nid = 0x03,
14572 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14573 .channel_mode = alc269_modes,
14574 .unsol_event = alc_sku_unsol_event,
14575 .setup = alc269vb_laptop_amic_setup,
14576 .init_hook = alc_inithook,
14577 },
14578 [ALC269VB_DMIC] = {
14579 .mixers = { alc269vb_laptop_mixer },
14580 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14581 .init_verbs = { alc269vb_init_verbs,
14582 alc269vb_laptop_dmic_init_verbs },
14583 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14584 .dac_nids = alc269_dac_nids,
14585 .hp_nid = 0x03,
14586 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14587 .channel_mode = alc269_modes,
14588 .unsol_event = alc_sku_unsol_event,
14589 .setup = alc269vb_laptop_dmic_setup,
14590 .init_hook = alc_inithook,
14591 },
14592 [ALC269_FUJITSU] = {
14593 .mixers = { alc269_fujitsu_mixer },
14594 .cap_mixer = alc269_laptop_digital_capture_mixer,
14595 .init_verbs = { alc269_init_verbs,
14596 alc269_laptop_dmic_init_verbs },
14597 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14598 .dac_nids = alc269_dac_nids,
14599 .hp_nid = 0x03,
14600 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14601 .channel_mode = alc269_modes,
14602 .unsol_event = alc_sku_unsol_event,
14603 .setup = alc269_laptop_dmic_setup,
14604 .init_hook = alc_inithook,
14605 },
14606 [ALC269_LIFEBOOK] = {
14607 .mixers = { alc269_lifebook_mixer },
14608 .init_verbs = { alc269_init_verbs, alc269_lifebook_verbs },
14609 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14610 .dac_nids = alc269_dac_nids,
14611 .hp_nid = 0x03,
14612 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14613 .channel_mode = alc269_modes,
14614 .input_mux = &alc269_capture_source,
14615 .unsol_event = alc269_lifebook_unsol_event,
14616 .setup = alc269_lifebook_setup,
14617 .init_hook = alc269_lifebook_init_hook,
14618 },
14619 [ALC271_ACER] = {
14620 .mixers = { alc269_asus_mixer },
14621 .cap_mixer = alc269vb_laptop_digital_capture_mixer,
14622 .init_verbs = { alc269_init_verbs, alc271_acer_dmic_verbs },
14623 .num_dacs = ARRAY_SIZE(alc269_dac_nids),
14624 .dac_nids = alc269_dac_nids,
14625 .adc_nids = alc262_dmic_adc_nids,
14626 .num_adc_nids = ARRAY_SIZE(alc262_dmic_adc_nids),
14627 .capsrc_nids = alc262_dmic_capsrc_nids,
14628 .num_channel_mode = ARRAY_SIZE(alc269_modes),
14629 .channel_mode = alc269_modes,
14630 .input_mux = &alc269_capture_source,
14631 .dig_out_nid = ALC880_DIGOUT_NID,
14632 .unsol_event = alc_sku_unsol_event,
14633 .setup = alc269vb_laptop_dmic_setup,
14634 .init_hook = alc_inithook,
14635 },
14636};
14637
14638static int alc269_fill_coef(struct hda_codec *codec) 5153static int alc269_fill_coef(struct hda_codec *codec)
14639{ 5154{
14640 int val; 5155 int val;
@@ -14677,6 +5192,12 @@ static int alc269_fill_coef(struct hda_codec *codec)
14677 return 0; 5192 return 0;
14678} 5193}
14679 5194
5195/*
5196 */
5197#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5198#include "alc269_quirks.c"
5199#endif
5200
14680static int patch_alc269(struct hda_codec *codec) 5201static int patch_alc269(struct hda_codec *codec)
14681{ 5202{
14682 struct alc_spec *spec; 5203 struct alc_spec *spec;
@@ -14726,33 +5247,35 @@ static int patch_alc269(struct hda_codec *codec)
14726 alc269_fill_coef(codec); 5247 alc269_fill_coef(codec);
14727 } 5248 }
14728 5249
14729 board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, 5250 board_config = alc_board_config(codec, ALC269_MODEL_LAST,
14730 alc269_models, 5251 alc269_models, alc269_cfg_tbl);
14731 alc269_cfg_tbl);
14732 5252
14733 if (board_config < 0) { 5253 if (board_config < 0) {
14734 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5254 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
14735 codec->chip_name); 5255 codec->chip_name);
14736 board_config = ALC269_AUTO; 5256 board_config = ALC_MODEL_AUTO;
14737 } 5257 }
14738 5258
14739 if (board_config == ALC269_AUTO) { 5259 if (board_config == ALC_MODEL_AUTO) {
14740 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups); 5260 alc_pick_fixup(codec, NULL, alc269_fixup_tbl, alc269_fixups);
14741 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 5261 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
14742 } 5262 }
14743 5263
14744 if (board_config == ALC269_AUTO) { 5264 if (board_config == ALC_MODEL_AUTO) {
14745 /* automatic parse from the BIOS config */ 5265 /* automatic parse from the BIOS config */
14746 err = alc269_parse_auto_config(codec); 5266 err = alc269_parse_auto_config(codec);
14747 if (err < 0) { 5267 if (err < 0) {
14748 alc_free(codec); 5268 alc_free(codec);
14749 return err; 5269 return err;
14750 } else if (!err) { 5270 }
5271#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5272 else if (!err) {
14751 printk(KERN_INFO 5273 printk(KERN_INFO
14752 "hda_codec: Cannot set up configuration " 5274 "hda_codec: Cannot set up configuration "
14753 "from BIOS. Using base mode...\n"); 5275 "from BIOS. Using base mode...\n");
14754 board_config = ALC269_BASIC; 5276 board_config = ALC269_BASIC;
14755 } 5277 }
5278#endif
14756 } 5279 }
14757 5280
14758 if (has_cdefine_beep(codec)) { 5281 if (has_cdefine_beep(codec)) {
@@ -14763,9 +5286,10 @@ static int patch_alc269(struct hda_codec *codec)
14763 } 5286 }
14764 } 5287 }
14765 5288
14766 if (board_config != ALC269_AUTO) 5289 if (board_config != ALC_MODEL_AUTO)
14767 setup_preset(codec, &alc269_presets[board_config]); 5290 setup_preset(codec, &alc269_presets[board_config]);
14768 5291
5292#if 0
14769 if (board_config == ALC269_QUANTA_FL1) { 5293 if (board_config == ALC269_QUANTA_FL1) {
14770 /* Due to a hardware problem on Lenovo Ideadpad, we need to 5294 /* Due to a hardware problem on Lenovo Ideadpad, we need to
14771 * fix the sample rate of analog I/O to 44.1kHz 5295 * fix the sample rate of analog I/O to 44.1kHz
@@ -14773,6 +5297,7 @@ static int patch_alc269(struct hda_codec *codec)
14773 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback; 5297 spec->stream_analog_playback = &alc269_44k_pcm_analog_playback;
14774 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture; 5298 spec->stream_analog_capture = &alc269_44k_pcm_analog_capture;
14775 } 5299 }
5300#endif
14776 5301
14777 if (!spec->adc_nids) { /* wasn't filled automatically? use default */ 5302 if (!spec->adc_nids) { /* wasn't filled automatically? use default */
14778 alc_auto_fill_adc_caps(codec); 5303 alc_auto_fill_adc_caps(codec);
@@ -14793,7 +5318,7 @@ static int patch_alc269(struct hda_codec *codec)
14793#ifdef SND_HDA_NEEDS_RESUME 5318#ifdef SND_HDA_NEEDS_RESUME
14794 codec->patch_ops.resume = alc269_resume; 5319 codec->patch_ops.resume = alc269_resume;
14795#endif 5320#endif
14796 if (board_config == ALC269_AUTO) 5321 if (board_config == ALC_MODEL_AUTO)
14797 spec->init_hook = alc269_auto_init; 5322 spec->init_hook = alc269_auto_init;
14798 spec->shutup = alc269_shutup; 5323 spec->shutup = alc269_shutup;
14799 5324
@@ -14809,564 +5334,8 @@ static int patch_alc269(struct hda_codec *codec)
14809} 5334}
14810 5335
14811/* 5336/*
14812 * ALC861 channel source setting (2/6 channel selection for 3-stack) 5337 * ALC861
14813 */
14814
14815/*
14816 * set the path ways for 2 channel output
14817 * need to set the codec line out and mic 1 pin widgets to inputs
14818 */ 5338 */
14819static const struct hda_verb alc861_threestack_ch2_init[] = {
14820 /* set pin widget 1Ah (line in) for input */
14821 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14822 /* set pin widget 18h (mic1/2) for input, for mic also enable
14823 * the vref
14824 */
14825 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14826
14827 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14828#if 0
14829 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14830 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14831#endif
14832 { } /* end */
14833};
14834/*
14835 * 6ch mode
14836 * need to set the codec line out and mic 1 pin widgets to outputs
14837 */
14838static const struct hda_verb alc861_threestack_ch6_init[] = {
14839 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14840 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14841 /* set pin widget 18h (mic1) for output (CLFE)*/
14842 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14843
14844 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14845 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14846
14847 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14848#if 0
14849 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14850 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14851#endif
14852 { } /* end */
14853};
14854
14855static const struct hda_channel_mode alc861_threestack_modes[2] = {
14856 { 2, alc861_threestack_ch2_init },
14857 { 6, alc861_threestack_ch6_init },
14858};
14859/* Set mic1 as input and unmute the mixer */
14860static const struct hda_verb alc861_uniwill_m31_ch2_init[] = {
14861 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14862 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14863 { } /* end */
14864};
14865/* Set mic1 as output and mute mixer */
14866static const struct hda_verb alc861_uniwill_m31_ch4_init[] = {
14867 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14868 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14869 { } /* end */
14870};
14871
14872static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = {
14873 { 2, alc861_uniwill_m31_ch2_init },
14874 { 4, alc861_uniwill_m31_ch4_init },
14875};
14876
14877/* Set mic1 and line-in as input and unmute the mixer */
14878static const struct hda_verb alc861_asus_ch2_init[] = {
14879 /* set pin widget 1Ah (line in) for input */
14880 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
14881 /* set pin widget 18h (mic1/2) for input, for mic also enable
14882 * the vref
14883 */
14884 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
14885
14886 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c },
14887#if 0
14888 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/
14889 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x02 << 8)) }, /*line-in*/
14890#endif
14891 { } /* end */
14892};
14893/* Set mic1 nad line-in as output and mute mixer */
14894static const struct hda_verb alc861_asus_ch6_init[] = {
14895 /* set pin widget 1Ah (line in) for output (Back Surround)*/
14896 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14897 /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14898 /* set pin widget 18h (mic1) for output (CLFE)*/
14899 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
14900 /* { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */
14901 { 0x0c, AC_VERB_SET_CONNECT_SEL, 0x00 },
14902 { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00 },
14903
14904 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
14905#if 0
14906 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/
14907 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8)) }, /*line in*/
14908#endif
14909 { } /* end */
14910};
14911
14912static const struct hda_channel_mode alc861_asus_modes[2] = {
14913 { 2, alc861_asus_ch2_init },
14914 { 6, alc861_asus_ch6_init },
14915};
14916
14917/* patch-ALC861 */
14918
14919static const struct snd_kcontrol_new alc861_base_mixer[] = {
14920 /* output mixer control */
14921 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14922 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14923 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14924 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14925 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
14926
14927 /*Input mixer control */
14928 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14929 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14930 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14931 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14932 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14933 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14934 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14935 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14936 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14937 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
14938
14939 { } /* end */
14940};
14941
14942static const struct snd_kcontrol_new alc861_3ST_mixer[] = {
14943 /* output mixer control */
14944 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14945 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14946 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14947 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14948 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14949
14950 /* Input mixer control */
14951 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14952 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14953 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14954 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14955 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14956 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14957 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14958 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14959 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
14960 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
14961
14962 {
14963 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
14964 .name = "Channel Mode",
14965 .info = alc_ch_mode_info,
14966 .get = alc_ch_mode_get,
14967 .put = alc_ch_mode_put,
14968 .private_value = ARRAY_SIZE(alc861_threestack_modes),
14969 },
14970 { } /* end */
14971};
14972
14973static const struct snd_kcontrol_new alc861_toshiba_mixer[] = {
14974 /* output mixer control */
14975 HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14976 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14977 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14978
14979 { } /* end */
14980};
14981
14982static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = {
14983 /* output mixer control */
14984 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
14985 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
14986 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
14987 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
14988 /*HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT), */
14989
14990 /* Input mixer control */
14991 /* HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
14992 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT), */
14993 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
14994 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
14995 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
14996 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
14997 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
14998 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
14999 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15000 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT),
15001
15002 {
15003 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15004 .name = "Channel Mode",
15005 .info = alc_ch_mode_info,
15006 .get = alc_ch_mode_get,
15007 .put = alc_ch_mode_put,
15008 .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes),
15009 },
15010 { } /* end */
15011};
15012
15013static const struct snd_kcontrol_new alc861_asus_mixer[] = {
15014 /* output mixer control */
15015 HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT),
15016 HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT),
15017 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x05, 1, 0x0, HDA_OUTPUT),
15018 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x05, 2, 0x0, HDA_OUTPUT),
15019 HDA_CODEC_MUTE("Side Playback Switch", 0x04, 0x0, HDA_OUTPUT),
15020
15021 /* Input mixer control */
15022 HDA_CODEC_VOLUME("Input Playback Volume", 0x15, 0x0, HDA_OUTPUT),
15023 HDA_CODEC_MUTE("Input Playback Switch", 0x15, 0x0, HDA_OUTPUT),
15024 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15025 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15026 HDA_CODEC_VOLUME("Line Playback Volume", 0x15, 0x02, HDA_INPUT),
15027 HDA_CODEC_MUTE("Line Playback Switch", 0x15, 0x02, HDA_INPUT),
15028 HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT),
15029 HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT),
15030 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT),
15031 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT),
15032
15033 {
15034 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15035 .name = "Channel Mode",
15036 .info = alc_ch_mode_info,
15037 .get = alc_ch_mode_get,
15038 .put = alc_ch_mode_put,
15039 .private_value = ARRAY_SIZE(alc861_asus_modes),
15040 },
15041 { }
15042};
15043
15044/* additional mixer */
15045static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = {
15046 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT),
15047 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT),
15048 { }
15049};
15050
15051/*
15052 * generic initialization of ADC, input mixers and output mixers
15053 */
15054static const struct hda_verb alc861_base_init_verbs[] = {
15055 /*
15056 * Unmute ADC0 and set the default input to mic-in
15057 */
15058 /* port-A for surround (rear panel) */
15059 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15060 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x00 },
15061 /* port-B for mic-in (rear panel) with vref */
15062 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15063 /* port-C for line-in (rear panel) */
15064 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15065 /* port-D for Front */
15066 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15067 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15068 /* port-E for HP out (front panel) */
15069 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15070 /* route front PCM to HP */
15071 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15072 /* port-F for mic-in (front panel) with vref */
15073 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15074 /* port-G for CLFE (rear panel) */
15075 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15076 { 0x1f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15077 /* port-H for side (rear panel) */
15078 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15079 { 0x20, AC_VERB_SET_CONNECT_SEL, 0x00 },
15080 /* CD-in */
15081 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15082 /* route front mic to ADC1*/
15083 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15084 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15085
15086 /* Unmute DAC0~3 & spdif out*/
15087 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15088 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15089 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15090 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15091 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15092
15093 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15094 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15095 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15096 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15097 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15098
15099 /* Unmute Stereo Mixer 15 */
15100 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15101 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15102 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15103 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15104
15105 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15106 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15107 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15108 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15109 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15110 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15111 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15112 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15113 /* hp used DAC 3 (Front) */
15114 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15115 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15116
15117 { }
15118};
15119
15120static const struct hda_verb alc861_threestack_init_verbs[] = {
15121 /*
15122 * Unmute ADC0 and set the default input to mic-in
15123 */
15124 /* port-A for surround (rear panel) */
15125 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15126 /* port-B for mic-in (rear panel) with vref */
15127 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15128 /* port-C for line-in (rear panel) */
15129 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15130 /* port-D for Front */
15131 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15132 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15133 /* port-E for HP out (front panel) */
15134 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
15135 /* route front PCM to HP */
15136 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15137 /* port-F for mic-in (front panel) with vref */
15138 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15139 /* port-G for CLFE (rear panel) */
15140 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15141 /* port-H for side (rear panel) */
15142 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15143 /* CD-in */
15144 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15145 /* route front mic to ADC1*/
15146 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15147 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15148 /* Unmute DAC0~3 & spdif out*/
15149 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15150 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15151 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15152 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15153 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15154
15155 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15156 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15157 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15158 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15159 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15160
15161 /* Unmute Stereo Mixer 15 */
15162 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15163 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15164 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15165 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15166
15167 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15168 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15169 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15170 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15171 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15172 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15173 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15174 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15175 /* hp used DAC 3 (Front) */
15176 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15177 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15178 { }
15179};
15180
15181static const struct hda_verb alc861_uniwill_m31_init_verbs[] = {
15182 /*
15183 * Unmute ADC0 and set the default input to mic-in
15184 */
15185 /* port-A for surround (rear panel) */
15186 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15187 /* port-B for mic-in (rear panel) with vref */
15188 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15189 /* port-C for line-in (rear panel) */
15190 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15191 /* port-D for Front */
15192 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15193 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15194 /* port-E for HP out (front panel) */
15195 /* this has to be set to VREF80 */
15196 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15197 /* route front PCM to HP */
15198 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15199 /* port-F for mic-in (front panel) with vref */
15200 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15201 /* port-G for CLFE (rear panel) */
15202 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15203 /* port-H for side (rear panel) */
15204 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15205 /* CD-in */
15206 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15207 /* route front mic to ADC1*/
15208 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15209 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15210 /* Unmute DAC0~3 & spdif out*/
15211 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15212 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15213 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15214 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15215 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15216
15217 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15218 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15219 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15220 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15221 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15222
15223 /* Unmute Stereo Mixer 15 */
15224 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15225 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15226 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15227 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15228
15229 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15230 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15231 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15232 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15233 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15234 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15235 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15236 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15237 /* hp used DAC 3 (Front) */
15238 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15239 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15240 { }
15241};
15242
15243static const struct hda_verb alc861_asus_init_verbs[] = {
15244 /*
15245 * Unmute ADC0 and set the default input to mic-in
15246 */
15247 /* port-A for surround (rear panel)
15248 * according to codec#0 this is the HP jack
15249 */
15250 { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */
15251 /* route front PCM to HP */
15252 { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 },
15253 /* port-B for mic-in (rear panel) with vref */
15254 { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15255 /* port-C for line-in (rear panel) */
15256 { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15257 /* port-D for Front */
15258 { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15259 { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 },
15260 /* port-E for HP out (front panel) */
15261 /* this has to be set to VREF80 */
15262 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15263 /* route front PCM to HP */
15264 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 },
15265 /* port-F for mic-in (front panel) with vref */
15266 { 0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
15267 /* port-G for CLFE (rear panel) */
15268 { 0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15269 /* port-H for side (rear panel) */
15270 { 0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
15271 /* CD-in */
15272 { 0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
15273 /* route front mic to ADC1*/
15274 {0x08, AC_VERB_SET_CONNECT_SEL, 0x00},
15275 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15276 /* Unmute DAC0~3 & spdif out*/
15277 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15278 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15279 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15280 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15281 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
15282 /* Unmute Mixer 14 (mic) 1c (Line in)*/
15283 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15284 {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15285 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15286 {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15287
15288 /* Unmute Stereo Mixer 15 */
15289 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15290 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15291 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15292 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */
15293
15294 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15295 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15296 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15297 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15298 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15299 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15300 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
15301 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
15302 /* hp used DAC 3 (Front) */
15303 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},
15304 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
15305 { }
15306};
15307
15308/* additional init verbs for ASUS laptops */
15309static const struct hda_verb alc861_asus_laptop_init_verbs[] = {
15310 { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */
15311 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */
15312 { }
15313};
15314
15315static const struct hda_verb alc861_toshiba_init_verbs[] = {
15316 {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
15317
15318 { }
15319};
15320
15321/* toggle speaker-output according to the hp-jack state */
15322static void alc861_toshiba_automute(struct hda_codec *codec)
15323{
15324 unsigned int present = snd_hda_jack_detect(codec, 0x0f);
15325
15326 snd_hda_codec_amp_stereo(codec, 0x16, HDA_INPUT, 0,
15327 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
15328 snd_hda_codec_amp_stereo(codec, 0x1a, HDA_INPUT, 3,
15329 HDA_AMP_MUTE, present ? 0 : HDA_AMP_MUTE);
15330}
15331
15332static void alc861_toshiba_unsol_event(struct hda_codec *codec,
15333 unsigned int res)
15334{
15335 if ((res >> 26) == ALC880_HP_EVENT)
15336 alc861_toshiba_automute(codec);
15337}
15338
15339#define ALC861_DIGOUT_NID 0x07
15340
15341static const struct hda_channel_mode alc861_8ch_modes[1] = {
15342 { 8, NULL }
15343};
15344
15345static const hda_nid_t alc861_dac_nids[4] = {
15346 /* front, surround, clfe, side */
15347 0x03, 0x06, 0x05, 0x04
15348};
15349
15350static const hda_nid_t alc660_dac_nids[3] = {
15351 /* front, clfe, surround */
15352 0x03, 0x05, 0x06
15353};
15354
15355static const hda_nid_t alc861_adc_nids[1] = {
15356 /* ADC0-2 */
15357 0x08,
15358};
15359
15360static const struct hda_input_mux alc861_capture_source = {
15361 .num_items = 5,
15362 .items = {
15363 { "Mic", 0x0 },
15364 { "Front Mic", 0x3 },
15365 { "Line", 0x1 },
15366 { "CD", 0x4 },
15367 { "Mixer", 0x5 },
15368 },
15369};
15370 5339
15371static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin) 5340static hda_nid_t alc861_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
15372{ 5341{
@@ -15607,152 +5576,6 @@ static const struct hda_amp_list alc861_loopbacks[] = {
15607#endif 5576#endif
15608 5577
15609 5578
15610/*
15611 * configuration and preset
15612 */
15613static const char * const alc861_models[ALC861_MODEL_LAST] = {
15614 [ALC861_3ST] = "3stack",
15615 [ALC660_3ST] = "3stack-660",
15616 [ALC861_3ST_DIG] = "3stack-dig",
15617 [ALC861_6ST_DIG] = "6stack-dig",
15618 [ALC861_UNIWILL_M31] = "uniwill-m31",
15619 [ALC861_TOSHIBA] = "toshiba",
15620 [ALC861_ASUS] = "asus",
15621 [ALC861_ASUS_LAPTOP] = "asus-laptop",
15622 [ALC861_AUTO] = "auto",
15623};
15624
15625static const struct snd_pci_quirk alc861_cfg_tbl[] = {
15626 SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST),
15627 SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15628 SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP),
15629 SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS),
15630 SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP),
15631 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS P1-AH2", ALC861_3ST_DIG),
15632 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA),
15633 /* FIXME: the entry below breaks Toshiba A100 (model=auto works!)
15634 * Any other models that need this preset?
15635 */
15636 /* SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), */
15637 SND_PCI_QUIRK(0x1462, 0x7254, "HP dx2200 (MSI MS-7254)", ALC861_3ST),
15638 SND_PCI_QUIRK(0x1462, 0x7297, "HP dx2250 (MSI MS-7297)", ALC861_3ST),
15639 SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31),
15640 SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31),
15641 SND_PCI_QUIRK(0x1584, 0x9075, "Airis Praxis N1212", ALC861_ASUS_LAPTOP),
15642 /* FIXME: the below seems conflict */
15643 /* SND_PCI_QUIRK(0x1584, 0x9075, "Uniwill", ALC861_UNIWILL_M31), */
15644 SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST),
15645 SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST),
15646 {}
15647};
15648
15649static const struct alc_config_preset alc861_presets[] = {
15650 [ALC861_3ST] = {
15651 .mixers = { alc861_3ST_mixer },
15652 .init_verbs = { alc861_threestack_init_verbs },
15653 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15654 .dac_nids = alc861_dac_nids,
15655 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15656 .channel_mode = alc861_threestack_modes,
15657 .need_dac_fix = 1,
15658 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15659 .adc_nids = alc861_adc_nids,
15660 .input_mux = &alc861_capture_source,
15661 },
15662 [ALC861_3ST_DIG] = {
15663 .mixers = { alc861_base_mixer },
15664 .init_verbs = { alc861_threestack_init_verbs },
15665 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15666 .dac_nids = alc861_dac_nids,
15667 .dig_out_nid = ALC861_DIGOUT_NID,
15668 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15669 .channel_mode = alc861_threestack_modes,
15670 .need_dac_fix = 1,
15671 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15672 .adc_nids = alc861_adc_nids,
15673 .input_mux = &alc861_capture_source,
15674 },
15675 [ALC861_6ST_DIG] = {
15676 .mixers = { alc861_base_mixer },
15677 .init_verbs = { alc861_base_init_verbs },
15678 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15679 .dac_nids = alc861_dac_nids,
15680 .dig_out_nid = ALC861_DIGOUT_NID,
15681 .num_channel_mode = ARRAY_SIZE(alc861_8ch_modes),
15682 .channel_mode = alc861_8ch_modes,
15683 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15684 .adc_nids = alc861_adc_nids,
15685 .input_mux = &alc861_capture_source,
15686 },
15687 [ALC660_3ST] = {
15688 .mixers = { alc861_3ST_mixer },
15689 .init_verbs = { alc861_threestack_init_verbs },
15690 .num_dacs = ARRAY_SIZE(alc660_dac_nids),
15691 .dac_nids = alc660_dac_nids,
15692 .num_channel_mode = ARRAY_SIZE(alc861_threestack_modes),
15693 .channel_mode = alc861_threestack_modes,
15694 .need_dac_fix = 1,
15695 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15696 .adc_nids = alc861_adc_nids,
15697 .input_mux = &alc861_capture_source,
15698 },
15699 [ALC861_UNIWILL_M31] = {
15700 .mixers = { alc861_uniwill_m31_mixer },
15701 .init_verbs = { alc861_uniwill_m31_init_verbs },
15702 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15703 .dac_nids = alc861_dac_nids,
15704 .dig_out_nid = ALC861_DIGOUT_NID,
15705 .num_channel_mode = ARRAY_SIZE(alc861_uniwill_m31_modes),
15706 .channel_mode = alc861_uniwill_m31_modes,
15707 .need_dac_fix = 1,
15708 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15709 .adc_nids = alc861_adc_nids,
15710 .input_mux = &alc861_capture_source,
15711 },
15712 [ALC861_TOSHIBA] = {
15713 .mixers = { alc861_toshiba_mixer },
15714 .init_verbs = { alc861_base_init_verbs,
15715 alc861_toshiba_init_verbs },
15716 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15717 .dac_nids = alc861_dac_nids,
15718 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15719 .channel_mode = alc883_3ST_2ch_modes,
15720 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15721 .adc_nids = alc861_adc_nids,
15722 .input_mux = &alc861_capture_source,
15723 .unsol_event = alc861_toshiba_unsol_event,
15724 .init_hook = alc861_toshiba_automute,
15725 },
15726 [ALC861_ASUS] = {
15727 .mixers = { alc861_asus_mixer },
15728 .init_verbs = { alc861_asus_init_verbs },
15729 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15730 .dac_nids = alc861_dac_nids,
15731 .dig_out_nid = ALC861_DIGOUT_NID,
15732 .num_channel_mode = ARRAY_SIZE(alc861_asus_modes),
15733 .channel_mode = alc861_asus_modes,
15734 .need_dac_fix = 1,
15735 .hp_nid = 0x06,
15736 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15737 .adc_nids = alc861_adc_nids,
15738 .input_mux = &alc861_capture_source,
15739 },
15740 [ALC861_ASUS_LAPTOP] = {
15741 .mixers = { alc861_toshiba_mixer, alc861_asus_laptop_mixer },
15742 .init_verbs = { alc861_asus_init_verbs,
15743 alc861_asus_laptop_init_verbs },
15744 .num_dacs = ARRAY_SIZE(alc861_dac_nids),
15745 .dac_nids = alc861_dac_nids,
15746 .dig_out_nid = ALC861_DIGOUT_NID,
15747 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes),
15748 .channel_mode = alc883_3ST_2ch_modes,
15749 .need_dac_fix = 1,
15750 .num_adc_nids = ARRAY_SIZE(alc861_adc_nids),
15751 .adc_nids = alc861_adc_nids,
15752 .input_mux = &alc861_capture_source,
15753 },
15754};
15755
15756/* Pin config fixes */ 5579/* Pin config fixes */
15757enum { 5580enum {
15758 PINFIX_FSC_AMILO_PI1505, 5581 PINFIX_FSC_AMILO_PI1505,
@@ -15774,6 +5597,12 @@ static const struct snd_pci_quirk alc861_fixup_tbl[] = {
15774 {} 5597 {}
15775}; 5598};
15776 5599
5600/*
5601 */
5602#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5603#include "alc861_quirks.c"
5604#endif
5605
15777static int patch_alc861(struct hda_codec *codec) 5606static int patch_alc861(struct hda_codec *codec)
15778{ 5607{
15779 struct alc_spec *spec; 5608 struct alc_spec *spec;
@@ -15788,33 +5617,35 @@ static int patch_alc861(struct hda_codec *codec)
15788 5617
15789 spec->mixer_nid = 0x15; 5618 spec->mixer_nid = 0x15;
15790 5619
15791 board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, 5620 board_config = alc_board_config(codec, ALC861_MODEL_LAST,
15792 alc861_models, 5621 alc861_models, alc861_cfg_tbl);
15793 alc861_cfg_tbl);
15794 5622
15795 if (board_config < 0) { 5623 if (board_config < 0) {
15796 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5624 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
15797 codec->chip_name); 5625 codec->chip_name);
15798 board_config = ALC861_AUTO; 5626 board_config = ALC_MODEL_AUTO;
15799 } 5627 }
15800 5628
15801 if (board_config == ALC861_AUTO) { 5629 if (board_config == ALC_MODEL_AUTO) {
15802 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups); 5630 alc_pick_fixup(codec, NULL, alc861_fixup_tbl, alc861_fixups);
15803 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 5631 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
15804 } 5632 }
15805 5633
15806 if (board_config == ALC861_AUTO) { 5634 if (board_config == ALC_MODEL_AUTO) {
15807 /* automatic parse from the BIOS config */ 5635 /* automatic parse from the BIOS config */
15808 err = alc861_parse_auto_config(codec); 5636 err = alc861_parse_auto_config(codec);
15809 if (err < 0) { 5637 if (err < 0) {
15810 alc_free(codec); 5638 alc_free(codec);
15811 return err; 5639 return err;
15812 } else if (!err) { 5640 }
5641#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5642 else if (!err) {
15813 printk(KERN_INFO 5643 printk(KERN_INFO
15814 "hda_codec: Cannot set up configuration " 5644 "hda_codec: Cannot set up configuration "
15815 "from BIOS. Using base mode...\n"); 5645 "from BIOS. Using base mode...\n");
15816 board_config = ALC861_3ST_DIG; 5646 board_config = ALC861_3ST_DIG;
15817 } 5647 }
5648#endif
15818 } 5649 }
15819 5650
15820 err = snd_hda_attach_beep_device(codec, 0x23); 5651 err = snd_hda_attach_beep_device(codec, 0x23);
@@ -15823,7 +5654,7 @@ static int patch_alc861(struct hda_codec *codec)
15823 return err; 5654 return err;
15824 } 5655 }
15825 5656
15826 if (board_config != ALC861_AUTO) 5657 if (board_config != ALC_MODEL_AUTO)
15827 setup_preset(codec, &alc861_presets[board_config]); 5658 setup_preset(codec, &alc861_presets[board_config]);
15828 5659
15829 if (!spec->adc_nids) { 5660 if (!spec->adc_nids) {
@@ -15841,7 +5672,7 @@ static int patch_alc861(struct hda_codec *codec)
15841 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 5672 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
15842 5673
15843 codec->patch_ops = alc_patch_ops; 5674 codec->patch_ops = alc_patch_ops;
15844 if (board_config == ALC861_AUTO) { 5675 if (board_config == ALC_MODEL_AUTO) {
15845 spec->init_hook = alc861_auto_init; 5676 spec->init_hook = alc861_auto_init;
15846#ifdef CONFIG_SND_HDA_POWER_SAVE 5677#ifdef CONFIG_SND_HDA_POWER_SAVE
15847 spec->power_hook = alc_power_eapd; 5678 spec->power_hook = alc_power_eapd;
@@ -15862,604 +5693,19 @@ static int patch_alc861(struct hda_codec *codec)
15862 * 5693 *
15863 * In addition, an independent DAC 5694 * In addition, an independent DAC
15864 */ 5695 */
15865#define ALC861VD_DIGOUT_NID 0x06
15866
15867static const hda_nid_t alc861vd_dac_nids[4] = {
15868 /* front, surr, clfe, side surr */
15869 0x02, 0x03, 0x04, 0x05
15870};
15871
15872/* dac_nids for ALC660vd are in a different order - according to
15873 * Realtek's driver.
15874 * This should probably result in a different mixer for 6stack models
15875 * of ALC660vd codecs, but for now there is only 3stack mixer
15876 * - and it is the same as in 861vd.
15877 * adc_nids in ALC660vd are (is) the same as in 861vd
15878 */
15879static const hda_nid_t alc660vd_dac_nids[3] = {
15880 /* front, rear, clfe, rear_surr */
15881 0x02, 0x04, 0x03
15882};
15883
15884static const hda_nid_t alc861vd_adc_nids[1] = {
15885 /* ADC0 */
15886 0x09,
15887};
15888
15889static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 };
15890
15891/* input MUX */
15892/* FIXME: should be a matrix-type input source selection */
15893static const struct hda_input_mux alc861vd_capture_source = {
15894 .num_items = 4,
15895 .items = {
15896 { "Mic", 0x0 },
15897 { "Front Mic", 0x1 },
15898 { "Line", 0x2 },
15899 { "CD", 0x4 },
15900 },
15901};
15902
15903static const struct hda_input_mux alc861vd_dallas_capture_source = {
15904 .num_items = 2,
15905 .items = {
15906 { "Mic", 0x0 },
15907 { "Internal Mic", 0x1 },
15908 },
15909};
15910
15911static const struct hda_input_mux alc861vd_hp_capture_source = {
15912 .num_items = 2,
15913 .items = {
15914 { "Front Mic", 0x0 },
15915 { "ATAPI Mic", 0x1 },
15916 },
15917};
15918
15919/*
15920 * 2ch mode
15921 */
15922static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = {
15923 { 2, NULL }
15924};
15925
15926/*
15927 * 6ch mode
15928 */
15929static const struct hda_verb alc861vd_6stack_ch6_init[] = {
15930 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
15931 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15932 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15933 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15934 { } /* end */
15935};
15936
15937/*
15938 * 8ch mode
15939 */
15940static const struct hda_verb alc861vd_6stack_ch8_init[] = {
15941 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15942 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15943 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15944 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
15945 { } /* end */
15946};
15947
15948static const struct hda_channel_mode alc861vd_6stack_modes[2] = {
15949 { 6, alc861vd_6stack_ch6_init },
15950 { 8, alc861vd_6stack_ch8_init },
15951};
15952
15953static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = {
15954 {
15955 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
15956 .name = "Channel Mode",
15957 .info = alc_ch_mode_info,
15958 .get = alc_ch_mode_get,
15959 .put = alc_ch_mode_put,
15960 },
15961 { } /* end */
15962};
15963
15964/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
15965 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
15966 */
15967static const struct snd_kcontrol_new alc861vd_6st_mixer[] = {
15968 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
15969 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
15970
15971 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
15972 HDA_BIND_MUTE("Surround Playback Switch", 0x0d, 2, HDA_INPUT),
15973
15974 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0,
15975 HDA_OUTPUT),
15976 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0,
15977 HDA_OUTPUT),
15978 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0e, 1, 2, HDA_INPUT),
15979 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 2, HDA_INPUT),
15980
15981 HDA_CODEC_VOLUME("Side Playback Volume", 0x05, 0x0, HDA_OUTPUT),
15982 HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT),
15983
15984 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
15985
15986 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
15987 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
15988 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
15989
15990 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
15991 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
15992 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
15993
15994 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
15995 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
15996
15997 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
15998 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
15999
16000 { } /* end */
16001};
16002
16003static const struct snd_kcontrol_new alc861vd_3st_mixer[] = {
16004 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16005 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16006
16007 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16008
16009 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16010 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16011 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16012
16013 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16014 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16015 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16016
16017 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16018 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16019
16020 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16021 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16022
16023 { } /* end */
16024};
16025
16026static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = {
16027 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16028 /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/
16029 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
16030
16031 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16032
16033 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16034 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16035 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16036
16037 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x19, 0, HDA_INPUT),
16038 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16039 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16040
16041 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16042 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16043
16044 { } /* end */
16045};
16046
16047/* Pin assignment: Speaker=0x14, HP = 0x15,
16048 * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d
16049 */
16050static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = {
16051 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16052 HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT),
16053 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16054 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16055 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16056 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16057 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16058 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
16059 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16060 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16061 { } /* end */
16062};
16063
16064/* Pin assignment: Speaker=0x14, Line-out = 0x15,
16065 * Front Mic=0x18, ATAPI Mic = 0x19,
16066 */
16067static const struct snd_kcontrol_new alc861vd_hp_mixer[] = {
16068 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16069 HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),
16070 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16071 HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT),
16072 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16073 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16074 HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16075 HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16076
16077 { } /* end */
16078};
16079
16080/*
16081 * generic initialization of ADC, input mixers and output mixers
16082 */
16083static const struct hda_verb alc861vd_volume_init_verbs[] = {
16084 /*
16085 * Unmute ADC0 and set the default input to mic-in
16086 */
16087 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16088 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16089
16090 /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of
16091 * the analog-loopback mixer widget
16092 */
16093 /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */
16094 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16095 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16096 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16097 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16098 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16099
16100 /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */
16101 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16102 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16103 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)},
16104 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)},
16105
16106 /*
16107 * Set up output mixers (0x02 - 0x05)
16108 */
16109 /* set vol=0 to output mixers */
16110 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16111 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16112 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16113 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16114
16115 /* set up input amps for analog loopback */
16116 /* Amp Indices: DAC = 0, mixer = 1 */
16117 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16118 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16119 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16120 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16121 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16122 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16123 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16124 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16125
16126 { }
16127};
16128
16129/*
16130 * 3-stack pin configuration:
16131 * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b
16132 */
16133static const struct hda_verb alc861vd_3stack_init_verbs[] = {
16134 /*
16135 * Set pin mode and muting
16136 */
16137 /* set front pin widgets 0x14 for output */
16138 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16139 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16140 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16141
16142 /* Mic (rear) pin: input vref at 80% */
16143 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16144 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16145 /* Front Mic pin: input vref at 80% */
16146 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16147 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16148 /* Line In pin: input */
16149 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16150 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16151 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16152 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16153 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16154 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16155 /* CD pin widget for input */
16156 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16157
16158 { }
16159};
16160
16161/*
16162 * 6-stack pin configuration:
16163 */
16164static const struct hda_verb alc861vd_6stack_init_verbs[] = {
16165 /*
16166 * Set pin mode and muting
16167 */
16168 /* set front pin widgets 0x14 for output */
16169 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16170 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16171 {0x14, AC_VERB_SET_CONNECT_SEL, 0x00},
16172
16173 /* Rear Pin: output 1 (0x0d) */
16174 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16175 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16176 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
16177 /* CLFE Pin: output 2 (0x0e) */
16178 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16179 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16180 {0x16, AC_VERB_SET_CONNECT_SEL, 0x02},
16181 /* Side Pin: output 3 (0x0f) */
16182 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16183 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16184 {0x17, AC_VERB_SET_CONNECT_SEL, 0x03},
16185
16186 /* Mic (rear) pin: input vref at 80% */
16187 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16188 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16189 /* Front Mic pin: input vref at 80% */
16190 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
16191 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16192 /* Line In pin: input */
16193 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16194 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16195 /* Line-2 In: Headphone output (output 0 - 0x0c) */
16196 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
16197 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16198 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
16199 /* CD pin widget for input */
16200 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16201
16202 { }
16203};
16204
16205static const struct hda_verb alc861vd_eapd_verbs[] = {
16206 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16207 { }
16208};
16209
16210static const struct hda_verb alc660vd_eapd_verbs[] = {
16211 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
16212 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
16213 { }
16214};
16215
16216static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = {
16217 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16218 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16219 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
16220 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16221 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
16222 {}
16223};
16224
16225static void alc861vd_lenovo_setup(struct hda_codec *codec)
16226{
16227 struct alc_spec *spec = codec->spec;
16228 spec->autocfg.hp_pins[0] = 0x1b;
16229 spec->autocfg.speaker_pins[0] = 0x14;
16230 spec->automute = 1;
16231 spec->automute_mode = ALC_AUTOMUTE_AMP;
16232}
16233
16234static void alc861vd_lenovo_init_hook(struct hda_codec *codec)
16235{
16236 alc_hp_automute(codec);
16237 alc88x_simple_mic_automute(codec);
16238}
16239
16240static void alc861vd_lenovo_unsol_event(struct hda_codec *codec,
16241 unsigned int res)
16242{
16243 switch (res >> 26) {
16244 case ALC880_MIC_EVENT:
16245 alc88x_simple_mic_automute(codec);
16246 break;
16247 default:
16248 alc_sku_unsol_event(codec, res);
16249 break;
16250 }
16251}
16252
16253static const struct hda_verb alc861vd_dallas_verbs[] = {
16254 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16255 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16256 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16257 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
16258
16259 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16260 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
16261 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16262 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16263 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16264 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16265 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16266 {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
16267
16268 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16269 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16270 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16271 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16272 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16273 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16274 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
16275 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
16276
16277 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16278 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16279 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50},
16280 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
16281 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16282 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16283 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16284 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
16285
16286 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
16287 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
16288 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
16289 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
16290
16291 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
16292 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
16293 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
16294
16295 { } /* end */
16296};
16297
16298/* toggle speaker-output according to the hp-jack state */
16299static void alc861vd_dallas_setup(struct hda_codec *codec)
16300{
16301 struct alc_spec *spec = codec->spec;
16302
16303 spec->autocfg.hp_pins[0] = 0x15;
16304 spec->autocfg.speaker_pins[0] = 0x14;
16305 spec->automute = 1;
16306 spec->automute_mode = ALC_AUTOMUTE_AMP;
16307}
16308
16309#ifdef CONFIG_SND_HDA_POWER_SAVE 5696#ifdef CONFIG_SND_HDA_POWER_SAVE
16310#define alc861vd_loopbacks alc880_loopbacks 5697#define alc861vd_loopbacks alc880_loopbacks
16311#endif 5698#endif
16312 5699
16313/* 5700/*
16314 * configuration and preset
16315 */
16316static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = {
16317 [ALC660VD_3ST] = "3stack-660",
16318 [ALC660VD_3ST_DIG] = "3stack-660-digout",
16319 [ALC660VD_ASUS_V1S] = "asus-v1s",
16320 [ALC861VD_3ST] = "3stack",
16321 [ALC861VD_3ST_DIG] = "3stack-digout",
16322 [ALC861VD_6ST_DIG] = "6stack-digout",
16323 [ALC861VD_LENOVO] = "lenovo",
16324 [ALC861VD_DALLAS] = "dallas",
16325 [ALC861VD_HP] = "hp",
16326 [ALC861VD_AUTO] = "auto",
16327};
16328
16329static const struct snd_pci_quirk alc861vd_cfg_tbl[] = {
16330 SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST),
16331 SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP),
16332 SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST),
16333 /*SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST),*/ /* auto */
16334 SND_PCI_QUIRK(0x1043, 0x1633, "Asus V1Sn", ALC660VD_ASUS_V1S),
16335 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG),
16336 SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST),
16337 SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO),
16338 /*SND_PCI_QUIRK(0x1179, 0xff00, "DALLAS", ALC861VD_DALLAS),*/ /*lenovo*/
16339 SND_PCI_QUIRK(0x1179, 0xff01, "Toshiba A135", ALC861VD_LENOVO),
16340 SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO),
16341 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS),
16342 SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG),
16343 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", ALC861VD_LENOVO),
16344 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG),
16345 {}
16346};
16347
16348static const struct alc_config_preset alc861vd_presets[] = {
16349 [ALC660VD_3ST] = {
16350 .mixers = { alc861vd_3st_mixer },
16351 .init_verbs = { alc861vd_volume_init_verbs,
16352 alc861vd_3stack_init_verbs },
16353 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16354 .dac_nids = alc660vd_dac_nids,
16355 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16356 .channel_mode = alc861vd_3stack_2ch_modes,
16357 .input_mux = &alc861vd_capture_source,
16358 },
16359 [ALC660VD_3ST_DIG] = {
16360 .mixers = { alc861vd_3st_mixer },
16361 .init_verbs = { alc861vd_volume_init_verbs,
16362 alc861vd_3stack_init_verbs },
16363 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16364 .dac_nids = alc660vd_dac_nids,
16365 .dig_out_nid = ALC861VD_DIGOUT_NID,
16366 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16367 .channel_mode = alc861vd_3stack_2ch_modes,
16368 .input_mux = &alc861vd_capture_source,
16369 },
16370 [ALC861VD_3ST] = {
16371 .mixers = { alc861vd_3st_mixer },
16372 .init_verbs = { alc861vd_volume_init_verbs,
16373 alc861vd_3stack_init_verbs },
16374 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16375 .dac_nids = alc861vd_dac_nids,
16376 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16377 .channel_mode = alc861vd_3stack_2ch_modes,
16378 .input_mux = &alc861vd_capture_source,
16379 },
16380 [ALC861VD_3ST_DIG] = {
16381 .mixers = { alc861vd_3st_mixer },
16382 .init_verbs = { alc861vd_volume_init_verbs,
16383 alc861vd_3stack_init_verbs },
16384 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16385 .dac_nids = alc861vd_dac_nids,
16386 .dig_out_nid = ALC861VD_DIGOUT_NID,
16387 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16388 .channel_mode = alc861vd_3stack_2ch_modes,
16389 .input_mux = &alc861vd_capture_source,
16390 },
16391 [ALC861VD_6ST_DIG] = {
16392 .mixers = { alc861vd_6st_mixer, alc861vd_chmode_mixer },
16393 .init_verbs = { alc861vd_volume_init_verbs,
16394 alc861vd_6stack_init_verbs },
16395 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16396 .dac_nids = alc861vd_dac_nids,
16397 .dig_out_nid = ALC861VD_DIGOUT_NID,
16398 .num_channel_mode = ARRAY_SIZE(alc861vd_6stack_modes),
16399 .channel_mode = alc861vd_6stack_modes,
16400 .input_mux = &alc861vd_capture_source,
16401 },
16402 [ALC861VD_LENOVO] = {
16403 .mixers = { alc861vd_lenovo_mixer },
16404 .init_verbs = { alc861vd_volume_init_verbs,
16405 alc861vd_3stack_init_verbs,
16406 alc861vd_eapd_verbs,
16407 alc861vd_lenovo_unsol_verbs },
16408 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16409 .dac_nids = alc660vd_dac_nids,
16410 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16411 .channel_mode = alc861vd_3stack_2ch_modes,
16412 .input_mux = &alc861vd_capture_source,
16413 .unsol_event = alc861vd_lenovo_unsol_event,
16414 .setup = alc861vd_lenovo_setup,
16415 .init_hook = alc861vd_lenovo_init_hook,
16416 },
16417 [ALC861VD_DALLAS] = {
16418 .mixers = { alc861vd_dallas_mixer },
16419 .init_verbs = { alc861vd_dallas_verbs },
16420 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16421 .dac_nids = alc861vd_dac_nids,
16422 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16423 .channel_mode = alc861vd_3stack_2ch_modes,
16424 .input_mux = &alc861vd_dallas_capture_source,
16425 .unsol_event = alc_sku_unsol_event,
16426 .setup = alc861vd_dallas_setup,
16427 .init_hook = alc_hp_automute,
16428 },
16429 [ALC861VD_HP] = {
16430 .mixers = { alc861vd_hp_mixer },
16431 .init_verbs = { alc861vd_dallas_verbs, alc861vd_eapd_verbs },
16432 .num_dacs = ARRAY_SIZE(alc861vd_dac_nids),
16433 .dac_nids = alc861vd_dac_nids,
16434 .dig_out_nid = ALC861VD_DIGOUT_NID,
16435 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16436 .channel_mode = alc861vd_3stack_2ch_modes,
16437 .input_mux = &alc861vd_hp_capture_source,
16438 .unsol_event = alc_sku_unsol_event,
16439 .setup = alc861vd_dallas_setup,
16440 .init_hook = alc_hp_automute,
16441 },
16442 [ALC660VD_ASUS_V1S] = {
16443 .mixers = { alc861vd_lenovo_mixer },
16444 .init_verbs = { alc861vd_volume_init_verbs,
16445 alc861vd_3stack_init_verbs,
16446 alc861vd_eapd_verbs,
16447 alc861vd_lenovo_unsol_verbs },
16448 .num_dacs = ARRAY_SIZE(alc660vd_dac_nids),
16449 .dac_nids = alc660vd_dac_nids,
16450 .dig_out_nid = ALC861VD_DIGOUT_NID,
16451 .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes),
16452 .channel_mode = alc861vd_3stack_2ch_modes,
16453 .input_mux = &alc861vd_capture_source,
16454 .unsol_event = alc861vd_lenovo_unsol_event,
16455 .setup = alc861vd_lenovo_setup,
16456 .init_hook = alc861vd_lenovo_init_hook,
16457 },
16458};
16459
16460/*
16461 * BIOS auto configuration 5701 * BIOS auto configuration
16462 */ 5702 */
5703#define alc861vd_is_fixed_pin(nid) ((nid) >= 0x14 && (nid) <= 0x17)
5704#define alc861vd_fixed_pin_idx(nid) ((nid) - 0x14)
5705#define alc861vd_is_multi_pin(nid) ((nid) >= 0x18)
5706#define alc861vd_multi_pin_idx(nid) ((nid) - 0x18)
5707#define alc861vd_idx_to_dac(nid) ((nid) + 0x02)
5708#define alc861vd_dac_to_idx(nid) ((nid) - 0x02)
16463#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02) 5709#define alc861vd_idx_to_mixer_vol(nid) ((nid) + 0x02)
16464#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c) 5710#define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c)
16465 5711
@@ -16482,10 +5728,10 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec,
16482 if (!spec->multiout.dac_nids[i]) 5728 if (!spec->multiout.dac_nids[i])
16483 continue; 5729 continue;
16484 nid_v = alc861vd_idx_to_mixer_vol( 5730 nid_v = alc861vd_idx_to_mixer_vol(
16485 alc880_dac_to_idx( 5731 alc861vd_dac_to_idx(
16486 spec->multiout.dac_nids[i])); 5732 spec->multiout.dac_nids[i]));
16487 nid_s = alc861vd_idx_to_mixer_switch( 5733 nid_s = alc861vd_idx_to_mixer_switch(
16488 alc880_dac_to_idx( 5734 alc861vd_dac_to_idx(
16489 spec->multiout.dac_nids[i])); 5735 spec->multiout.dac_nids[i]));
16490 5736
16491 name = alc_get_line_out_pfx(spec, i, true, &index); 5737 name = alc_get_line_out_pfx(spec, i, true, &index);
@@ -16545,8 +5791,8 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16545 if (!pin) 5791 if (!pin)
16546 return 0; 5792 return 0;
16547 5793
16548 if (alc880_is_fixed_pin(pin)) { 5794 if (alc861vd_is_fixed_pin(pin)) {
16549 nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); 5795 nid_v = alc861vd_idx_to_dac(alc861vd_fixed_pin_idx(pin));
16550 /* specify the DAC as the extra output */ 5796 /* specify the DAC as the extra output */
16551 if (!spec->multiout.hp_nid) 5797 if (!spec->multiout.hp_nid)
16552 spec->multiout.hp_nid = nid_v; 5798 spec->multiout.hp_nid = nid_v;
@@ -16554,9 +5800,9 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16554 spec->multiout.extra_out_nid[0] = nid_v; 5800 spec->multiout.extra_out_nid[0] = nid_v;
16555 /* control HP volume/switch on the output mixer amp */ 5801 /* control HP volume/switch on the output mixer amp */
16556 nid_v = alc861vd_idx_to_mixer_vol( 5802 nid_v = alc861vd_idx_to_mixer_vol(
16557 alc880_fixed_pin_idx(pin)); 5803 alc861vd_fixed_pin_idx(pin));
16558 nid_s = alc861vd_idx_to_mixer_switch( 5804 nid_s = alc861vd_idx_to_mixer_switch(
16559 alc880_fixed_pin_idx(pin)); 5805 alc861vd_fixed_pin_idx(pin));
16560 5806
16561 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx, 5807 err = add_pb_vol_ctrl(spec, ALC_CTL_WIDGET_VOL, pfx,
16562 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); 5808 HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT));
@@ -16566,7 +5812,7 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec,
16566 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); 5812 HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT));
16567 if (err < 0) 5813 if (err < 0)
16568 return err; 5814 return err;
16569 } else if (alc880_is_multi_pin(pin)) { 5815 } else if (alc861vd_is_multi_pin(pin)) {
16570 /* set manual connection */ 5816 /* set manual connection */
16571 /* we have only a switch on HP-out PIN */ 5817 /* we have only a switch on HP-out PIN */
16572 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, 5818 err = add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
@@ -16672,6 +5918,18 @@ static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
16672 {} 5918 {}
16673}; 5919};
16674 5920
5921static const struct hda_verb alc660vd_eapd_verbs[] = {
5922 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
5923 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
5924 { }
5925};
5926
5927/*
5928 */
5929#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5930#include "alc861vd_quirks.c"
5931#endif
5932
16675static int patch_alc861vd(struct hda_codec *codec) 5933static int patch_alc861vd(struct hda_codec *codec)
16676{ 5934{
16677 struct alc_spec *spec; 5935 struct alc_spec *spec;
@@ -16685,33 +5943,35 @@ static int patch_alc861vd(struct hda_codec *codec)
16685 5943
16686 spec->mixer_nid = 0x0b; 5944 spec->mixer_nid = 0x0b;
16687 5945
16688 board_config = snd_hda_check_board_config(codec, ALC861VD_MODEL_LAST, 5946 board_config = alc_board_config(codec, ALC861VD_MODEL_LAST,
16689 alc861vd_models, 5947 alc861vd_models, alc861vd_cfg_tbl);
16690 alc861vd_cfg_tbl);
16691 5948
16692 if (board_config < 0 || board_config >= ALC861VD_MODEL_LAST) { 5949 if (board_config < 0) {
16693 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 5950 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
16694 codec->chip_name); 5951 codec->chip_name);
16695 board_config = ALC861VD_AUTO; 5952 board_config = ALC_MODEL_AUTO;
16696 } 5953 }
16697 5954
16698 if (board_config == ALC861VD_AUTO) { 5955 if (board_config == ALC_MODEL_AUTO) {
16699 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups); 5956 alc_pick_fixup(codec, NULL, alc861vd_fixup_tbl, alc861vd_fixups);
16700 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 5957 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
16701 } 5958 }
16702 5959
16703 if (board_config == ALC861VD_AUTO) { 5960 if (board_config == ALC_MODEL_AUTO) {
16704 /* automatic parse from the BIOS config */ 5961 /* automatic parse from the BIOS config */
16705 err = alc861vd_parse_auto_config(codec); 5962 err = alc861vd_parse_auto_config(codec);
16706 if (err < 0) { 5963 if (err < 0) {
16707 alc_free(codec); 5964 alc_free(codec);
16708 return err; 5965 return err;
16709 } else if (!err) { 5966 }
5967#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
5968 else if (!err) {
16710 printk(KERN_INFO 5969 printk(KERN_INFO
16711 "hda_codec: Cannot set up configuration " 5970 "hda_codec: Cannot set up configuration "
16712 "from BIOS. Using base mode...\n"); 5971 "from BIOS. Using base mode...\n");
16713 board_config = ALC861VD_3ST; 5972 board_config = ALC861VD_3ST;
16714 } 5973 }
5974#endif
16715 } 5975 }
16716 5976
16717 err = snd_hda_attach_beep_device(codec, 0x23); 5977 err = snd_hda_attach_beep_device(codec, 0x23);
@@ -16720,7 +5980,7 @@ static int patch_alc861vd(struct hda_codec *codec)
16720 return err; 5980 return err;
16721 } 5981 }
16722 5982
16723 if (board_config != ALC861VD_AUTO) 5983 if (board_config != ALC_MODEL_AUTO)
16724 setup_preset(codec, &alc861vd_presets[board_config]); 5984 setup_preset(codec, &alc861vd_presets[board_config]);
16725 5985
16726 if (codec->vendor_id == 0x10ec0660) { 5986 if (codec->vendor_id == 0x10ec0660) {
@@ -16743,7 +6003,7 @@ static int patch_alc861vd(struct hda_codec *codec)
16743 6003
16744 codec->patch_ops = alc_patch_ops; 6004 codec->patch_ops = alc_patch_ops;
16745 6005
16746 if (board_config == ALC861VD_AUTO) 6006 if (board_config == ALC_MODEL_AUTO)
16747 spec->init_hook = alc861vd_auto_init; 6007 spec->init_hook = alc861vd_auto_init;
16748 spec->shutup = alc_eapd_shutup; 6008 spec->shutup = alc_eapd_shutup;
16749#ifdef CONFIG_SND_HDA_POWER_SAVE 6009#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -16765,1913 +6025,14 @@ static int patch_alc861vd(struct hda_codec *codec)
16765 * In addition, an independent DAC for the multi-playback (not used in this 6025 * In addition, an independent DAC for the multi-playback (not used in this
16766 * driver yet). 6026 * driver yet).
16767 */ 6027 */
16768#define ALC662_DIGOUT_NID 0x06
16769#define ALC662_DIGIN_NID 0x0a
16770
16771static const hda_nid_t alc662_dac_nids[3] = {
16772 /* front, rear, clfe */
16773 0x02, 0x03, 0x04
16774};
16775
16776static const hda_nid_t alc272_dac_nids[2] = {
16777 0x02, 0x03
16778};
16779
16780static const hda_nid_t alc662_adc_nids[2] = {
16781 /* ADC1-2 */
16782 0x09, 0x08
16783};
16784
16785static const hda_nid_t alc272_adc_nids[1] = {
16786 /* ADC1-2 */
16787 0x08,
16788};
16789
16790static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 };
16791static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 };
16792
16793
16794/* input MUX */
16795/* FIXME: should be a matrix-type input source selection */
16796static const struct hda_input_mux alc662_capture_source = {
16797 .num_items = 4,
16798 .items = {
16799 { "Mic", 0x0 },
16800 { "Front Mic", 0x1 },
16801 { "Line", 0x2 },
16802 { "CD", 0x4 },
16803 },
16804};
16805
16806static const struct hda_input_mux alc662_lenovo_101e_capture_source = {
16807 .num_items = 2,
16808 .items = {
16809 { "Mic", 0x1 },
16810 { "Line", 0x2 },
16811 },
16812};
16813
16814static const struct hda_input_mux alc663_capture_source = {
16815 .num_items = 3,
16816 .items = {
16817 { "Mic", 0x0 },
16818 { "Front Mic", 0x1 },
16819 { "Line", 0x2 },
16820 },
16821};
16822
16823#if 0 /* set to 1 for testing other input sources below */
16824static const struct hda_input_mux alc272_nc10_capture_source = {
16825 .num_items = 16,
16826 .items = {
16827 { "Autoselect Mic", 0x0 },
16828 { "Internal Mic", 0x1 },
16829 { "In-0x02", 0x2 },
16830 { "In-0x03", 0x3 },
16831 { "In-0x04", 0x4 },
16832 { "In-0x05", 0x5 },
16833 { "In-0x06", 0x6 },
16834 { "In-0x07", 0x7 },
16835 { "In-0x08", 0x8 },
16836 { "In-0x09", 0x9 },
16837 { "In-0x0a", 0x0a },
16838 { "In-0x0b", 0x0b },
16839 { "In-0x0c", 0x0c },
16840 { "In-0x0d", 0x0d },
16841 { "In-0x0e", 0x0e },
16842 { "In-0x0f", 0x0f },
16843 },
16844};
16845#endif
16846
16847/*
16848 * 2ch mode
16849 */
16850static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = {
16851 { 2, NULL }
16852};
16853
16854/*
16855 * 2ch mode
16856 */
16857static const struct hda_verb alc662_3ST_ch2_init[] = {
16858 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
16859 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16860 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
16861 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
16862 { } /* end */
16863};
16864
16865/*
16866 * 6ch mode
16867 */
16868static const struct hda_verb alc662_3ST_ch6_init[] = {
16869 { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16870 { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16871 { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 },
16872 { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16873 { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
16874 { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 },
16875 { } /* end */
16876};
16877
16878static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = {
16879 { 2, alc662_3ST_ch2_init },
16880 { 6, alc662_3ST_ch6_init },
16881};
16882
16883/*
16884 * 2ch mode
16885 */
16886static const struct hda_verb alc662_sixstack_ch6_init[] = {
16887 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16888 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 },
16889 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16890 { } /* end */
16891};
16892
16893/*
16894 * 6ch mode
16895 */
16896static const struct hda_verb alc662_sixstack_ch8_init[] = {
16897 { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16898 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16899 { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
16900 { } /* end */
16901};
16902
16903static const struct hda_channel_mode alc662_5stack_modes[2] = {
16904 { 2, alc662_sixstack_ch6_init },
16905 { 6, alc662_sixstack_ch8_init },
16906};
16907
16908/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17
16909 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b
16910 */
16911
16912static const struct snd_kcontrol_new alc662_base_mixer[] = {
16913 /* output mixer control */
16914 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
16915 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
16916 HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT),
16917 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
16918 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16919 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
16920 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16921 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
16922 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16923
16924 /*Input mixer control */
16925 HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT),
16926 HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT),
16927 HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT),
16928 HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT),
16929 HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT),
16930 HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT),
16931 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT),
16932 HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT),
16933 { } /* end */
16934};
16935
16936static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = {
16937 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16938 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
16939 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16940 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16941 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16942 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16943 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16944 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16945 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16946 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16947 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16948 { } /* end */
16949};
16950
16951static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = {
16952 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16953 HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT),
16954 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16955 HDA_CODEC_MUTE("Surround Playback Switch", 0x0d, 0x0, HDA_INPUT),
16956 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
16957 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
16958 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x0e, 1, 0x0, HDA_INPUT),
16959 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x0e, 2, 0x0, HDA_INPUT),
16960 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16961 HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT),
16962 HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT),
16963 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16964 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16965 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16966 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16967 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16968 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16969 { } /* end */
16970};
16971
16972static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = {
16973 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16974 HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT),
16975 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT),
16976 HDA_BIND_MUTE("Speaker Playback Switch", 0x03, 2, HDA_INPUT),
16977 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
16978 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
16979 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
16980 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16981 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16982 { } /* end */
16983};
16984
16985static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = {
16986 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
16987 ALC262_HIPPO_MASTER_SWITCH,
16988
16989 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
16990 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
16991 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
16992
16993 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
16994 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
16995 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
16996 { } /* end */
16997};
16998
16999static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = {
17000 ALC262_HIPPO_MASTER_SWITCH,
17001 HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17002 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17003 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT),
17004 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT),
17005 HDA_BIND_MUTE("MuteCtrl Playback Switch", 0x0c, 2, HDA_INPUT),
17006 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17007 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17008 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17009 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17010 { } /* end */
17011};
17012
17013static const struct hda_bind_ctls alc663_asus_bind_master_vol = {
17014 .ops = &snd_hda_bind_vol,
17015 .values = {
17016 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17017 HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT),
17018 0
17019 },
17020};
17021
17022static const struct hda_bind_ctls alc663_asus_one_bind_switch = {
17023 .ops = &snd_hda_bind_sw,
17024 .values = {
17025 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17026 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17027 0
17028 },
17029};
17030
17031static const struct snd_kcontrol_new alc663_m51va_mixer[] = {
17032 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17033 HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch),
17034 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17035 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17036 { } /* end */
17037};
17038
17039static const struct hda_bind_ctls alc663_asus_tree_bind_switch = {
17040 .ops = &snd_hda_bind_sw,
17041 .values = {
17042 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17043 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17044 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17045 0
17046 },
17047};
17048
17049static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = {
17050 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17051 HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch),
17052 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17053 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17054 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17055 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17056
17057 { } /* end */
17058};
17059
17060static const struct hda_bind_ctls alc663_asus_four_bind_switch = {
17061 .ops = &snd_hda_bind_sw,
17062 .values = {
17063 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17064 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17065 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17066 0
17067 },
17068};
17069
17070static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = {
17071 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17072 HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch),
17073 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17074 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17075 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17076 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17077 { } /* end */
17078};
17079
17080static const struct snd_kcontrol_new alc662_1bjd_mixer[] = {
17081 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17082 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17083 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17084 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17085 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17086 HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17087 HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17088 { } /* end */
17089};
17090
17091static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = {
17092 .ops = &snd_hda_bind_vol,
17093 .values = {
17094 HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT),
17095 HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT),
17096 0
17097 },
17098};
17099
17100static const struct hda_bind_ctls alc663_asus_two_bind_switch = {
17101 .ops = &snd_hda_bind_sw,
17102 .values = {
17103 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17104 HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT),
17105 0
17106 },
17107};
17108
17109static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = {
17110 HDA_BIND_VOL("Master Playback Volume",
17111 &alc663_asus_two_bind_master_vol),
17112 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17113 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17114 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17115 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17116 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17117 { } /* end */
17118};
17119
17120static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = {
17121 HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol),
17122 HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch),
17123 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17124 HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17125 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17126 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17127 { } /* end */
17128};
17129
17130static const struct snd_kcontrol_new alc663_g71v_mixer[] = {
17131 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17132 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17133 HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17134 HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17135 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17136
17137 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17138 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17139 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17140 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17141 { } /* end */
17142};
17143
17144static const struct snd_kcontrol_new alc663_g50v_mixer[] = {
17145 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17146 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17147 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17148
17149 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17150 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17151 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17152 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17153 HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT),
17154 HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT),
17155 { } /* end */
17156};
17157
17158static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = {
17159 .ops = &snd_hda_bind_sw,
17160 .values = {
17161 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17162 HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT),
17163 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17164 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
17165 HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
17166 0
17167 },
17168};
17169
17170static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = {
17171 .ops = &snd_hda_bind_sw,
17172 .values = {
17173 HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT),
17174 HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_OUTPUT),
17175 0
17176 },
17177};
17178
17179static const struct snd_kcontrol_new alc663_mode7_mixer[] = {
17180 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17181 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17182 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17183 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
17184 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17185 HDA_CODEC_VOLUME("IntMic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17186 HDA_CODEC_MUTE("IntMic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17187 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17188 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17189 { } /* end */
17190};
17191
17192static const struct snd_kcontrol_new alc663_mode8_mixer[] = {
17193 HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch),
17194 HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol),
17195 HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch),
17196 HDA_CODEC_MUTE("Headphone1 Playback Switch", 0x15, 0x0, HDA_OUTPUT),
17197 HDA_CODEC_MUTE("Headphone2 Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17198 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17199 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17200 { } /* end */
17201};
17202
17203
17204static const struct snd_kcontrol_new alc662_chmode_mixer[] = {
17205 {
17206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
17207 .name = "Channel Mode",
17208 .info = alc_ch_mode_info,
17209 .get = alc_ch_mode_get,
17210 .put = alc_ch_mode_put,
17211 },
17212 { } /* end */
17213};
17214
17215static const struct hda_verb alc662_init_verbs[] = {
17216 /* ADC: mute amp left and right */
17217 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17218 {0x09, AC_VERB_SET_CONNECT_SEL, 0x00},
17219
17220 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17221 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17222 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17223 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17224 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17225 {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17226
17227 /* Front Pin: output 0 (0x0c) */
17228 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17229 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17230
17231 /* Rear Pin: output 1 (0x0d) */
17232 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17233 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17234
17235 /* CLFE Pin: output 2 (0x0e) */
17236 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17237 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17238
17239 /* Mic (rear) pin: input vref at 80% */
17240 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17241 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17242 /* Front Mic pin: input vref at 80% */
17243 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
17244 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17245 /* Line In pin: input */
17246 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17247 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
17248 /* Line-2 In: Headphone output (output 0 - 0x0c) */
17249 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17250 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17251 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00},
17252 /* CD pin widget for input */
17253 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17254
17255 /* FIXME: use matrix-type input source selection */
17256 /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */
17257 /* Input mixer */
17258 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17259 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
17260
17261 { }
17262};
17263
17264static const struct hda_verb alc662_eapd_init_verbs[] = {
17265 /* always trun on EAPD */
17266 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
17267 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
17268 { }
17269};
17270
17271static const struct hda_verb alc662_sue_init_verbs[] = {
17272 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17273 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17274 {}
17275};
17276
17277static const struct hda_verb alc662_eeepc_sue_init_verbs[] = {
17278 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17279 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17280 {}
17281};
17282
17283/* Set Unsolicited Event*/
17284static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = {
17285 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17286 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17287 {}
17288};
17289
17290static const struct hda_verb alc663_m51va_init_verbs[] = {
17291 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17292 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17293 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17294 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17295 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17296 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17297 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17298 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17299 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17300 {}
17301};
17302
17303static const struct hda_verb alc663_21jd_amic_init_verbs[] = {
17304 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17305 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17306 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17307 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17308 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17309 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17310 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17311 {}
17312};
17313
17314static const struct hda_verb alc662_1bjd_amic_init_verbs[] = {
17315 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17316 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17317 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17318 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17319 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17320 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17321 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17322 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17323 {}
17324};
17325
17326static const struct hda_verb alc663_15jd_amic_init_verbs[] = {
17327 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17328 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17329 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17330 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17331 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17332 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17333 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17334 {}
17335};
17336
17337static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = {
17338 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17339 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17340 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17341 {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17342 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17343 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17344 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */
17345 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17346 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17347 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17348 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17349 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17350 {}
17351};
17352
17353static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = {
17354 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17355 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17356 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17357 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17358 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17359 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17360 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17361 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17362 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
17363 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17364 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17365 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17366 {}
17367};
17368
17369static const struct hda_verb alc663_g71v_init_verbs[] = {
17370 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17371 /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */
17372 /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */
17373
17374 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17375 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17376 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17377
17378 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT},
17379 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_MIC_EVENT},
17380 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT},
17381 {}
17382};
17383
17384static const struct hda_verb alc663_g50v_init_verbs[] = {
17385 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17386 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17387 {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */
17388
17389 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17390 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17391 {}
17392};
17393
17394static const struct hda_verb alc662_ecs_init_verbs[] = {
17395 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f},
17396 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17397 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17398 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17399 {}
17400};
17401
17402static const struct hda_verb alc272_dell_zm1_init_verbs[] = {
17403 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17404 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17405 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17406 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17407 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17408 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17409 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17410 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17411 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17412 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17413 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17414 {}
17415};
17416
17417static const struct hda_verb alc272_dell_init_verbs[] = {
17418 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17419 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17420 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17421 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17422 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17423 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17424 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17425 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17426 {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17427 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17428 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17429 {}
17430};
17431
17432static const struct hda_verb alc663_mode7_init_verbs[] = {
17433 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17434 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17435 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17436 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17437 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17438 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17439 {0x1b, AC_VERB_SET_CONNECT_SEL, 0x01},
17440 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17441 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17442 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17443 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17444 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17445 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17446 {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17447 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17448 {}
17449};
17450
17451static const struct hda_verb alc663_mode8_init_verbs[] = {
17452 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17453 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17454 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17455 {0x15, AC_VERB_SET_CONNECT_SEL, 0x01},
17456 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17457 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
17458 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17459 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
17460 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
17461 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
17462 {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */
17463 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
17464 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)},
17465 {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17466 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT},
17467 {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT},
17468 {}
17469};
17470
17471static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = {
17472 HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT),
17473 HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT),
17474 { } /* end */
17475};
17476
17477static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = {
17478 HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT),
17479 HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT),
17480 { } /* end */
17481};
17482
17483static void alc662_lenovo_101e_setup(struct hda_codec *codec)
17484{
17485 struct alc_spec *spec = codec->spec;
17486
17487 spec->autocfg.hp_pins[0] = 0x1b;
17488 spec->autocfg.line_out_pins[0] = 0x14;
17489 spec->autocfg.speaker_pins[0] = 0x15;
17490 spec->automute = 1;
17491 spec->detect_line = 1;
17492 spec->automute_lines = 1;
17493 spec->automute_mode = ALC_AUTOMUTE_AMP;
17494}
17495
17496static void alc662_eeepc_setup(struct hda_codec *codec)
17497{
17498 struct alc_spec *spec = codec->spec;
17499
17500 alc262_hippo1_setup(codec);
17501 spec->ext_mic_pin = 0x18;
17502 spec->int_mic_pin = 0x19;
17503 spec->auto_mic = 1;
17504}
17505
17506static void alc662_eeepc_ep20_setup(struct hda_codec *codec)
17507{
17508 struct alc_spec *spec = codec->spec;
17509
17510 spec->autocfg.hp_pins[0] = 0x14;
17511 spec->autocfg.speaker_pins[0] = 0x1b;
17512 spec->automute = 1;
17513 spec->automute_mode = ALC_AUTOMUTE_AMP;
17514}
17515
17516static void alc663_m51va_setup(struct hda_codec *codec)
17517{
17518 struct alc_spec *spec = codec->spec;
17519 spec->autocfg.hp_pins[0] = 0x21;
17520 spec->autocfg.speaker_pins[0] = 0x14;
17521 spec->automute_mixer_nid[0] = 0x0c;
17522 spec->automute = 1;
17523 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17524 spec->ext_mic_pin = 0x18;
17525 spec->int_mic_pin = 0x12;
17526 spec->auto_mic = 1;
17527}
17528
17529/* ***************** Mode1 ******************************/
17530static void alc663_mode1_setup(struct hda_codec *codec)
17531{
17532 struct alc_spec *spec = codec->spec;
17533 spec->autocfg.hp_pins[0] = 0x21;
17534 spec->autocfg.speaker_pins[0] = 0x14;
17535 spec->automute_mixer_nid[0] = 0x0c;
17536 spec->automute = 1;
17537 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17538 spec->ext_mic_pin = 0x18;
17539 spec->int_mic_pin = 0x19;
17540 spec->auto_mic = 1;
17541}
17542
17543/* ***************** Mode2 ******************************/
17544static void alc662_mode2_setup(struct hda_codec *codec)
17545{
17546 struct alc_spec *spec = codec->spec;
17547 spec->autocfg.hp_pins[0] = 0x1b;
17548 spec->autocfg.speaker_pins[0] = 0x14;
17549 spec->automute = 1;
17550 spec->automute_mode = ALC_AUTOMUTE_PIN;
17551 spec->ext_mic_pin = 0x18;
17552 spec->int_mic_pin = 0x19;
17553 spec->auto_mic = 1;
17554}
17555
17556/* ***************** Mode3 ******************************/
17557static void alc663_mode3_setup(struct hda_codec *codec)
17558{
17559 struct alc_spec *spec = codec->spec;
17560 spec->autocfg.hp_pins[0] = 0x21;
17561 spec->autocfg.hp_pins[0] = 0x15;
17562 spec->autocfg.speaker_pins[0] = 0x14;
17563 spec->automute = 1;
17564 spec->automute_mode = ALC_AUTOMUTE_PIN;
17565 spec->ext_mic_pin = 0x18;
17566 spec->int_mic_pin = 0x19;
17567 spec->auto_mic = 1;
17568}
17569
17570/* ***************** Mode4 ******************************/
17571static void alc663_mode4_setup(struct hda_codec *codec)
17572{
17573 struct alc_spec *spec = codec->spec;
17574 spec->autocfg.hp_pins[0] = 0x21;
17575 spec->autocfg.speaker_pins[0] = 0x14;
17576 spec->autocfg.speaker_pins[1] = 0x16;
17577 spec->automute_mixer_nid[0] = 0x0c;
17578 spec->automute_mixer_nid[1] = 0x0e;
17579 spec->automute = 1;
17580 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17581 spec->ext_mic_pin = 0x18;
17582 spec->int_mic_pin = 0x19;
17583 spec->auto_mic = 1;
17584}
17585
17586/* ***************** Mode5 ******************************/
17587static void alc663_mode5_setup(struct hda_codec *codec)
17588{
17589 struct alc_spec *spec = codec->spec;
17590 spec->autocfg.hp_pins[0] = 0x15;
17591 spec->autocfg.speaker_pins[0] = 0x14;
17592 spec->autocfg.speaker_pins[1] = 0x16;
17593 spec->automute_mixer_nid[0] = 0x0c;
17594 spec->automute_mixer_nid[1] = 0x0e;
17595 spec->automute = 1;
17596 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17597 spec->ext_mic_pin = 0x18;
17598 spec->int_mic_pin = 0x19;
17599 spec->auto_mic = 1;
17600}
17601
17602/* ***************** Mode6 ******************************/
17603static void alc663_mode6_setup(struct hda_codec *codec)
17604{
17605 struct alc_spec *spec = codec->spec;
17606 spec->autocfg.hp_pins[0] = 0x1b;
17607 spec->autocfg.hp_pins[0] = 0x15;
17608 spec->autocfg.speaker_pins[0] = 0x14;
17609 spec->automute_mixer_nid[0] = 0x0c;
17610 spec->automute = 1;
17611 spec->automute_mode = ALC_AUTOMUTE_MIXER;
17612 spec->ext_mic_pin = 0x18;
17613 spec->int_mic_pin = 0x19;
17614 spec->auto_mic = 1;
17615}
17616
17617/* ***************** Mode7 ******************************/
17618static void alc663_mode7_setup(struct hda_codec *codec)
17619{
17620 struct alc_spec *spec = codec->spec;
17621 spec->autocfg.hp_pins[0] = 0x1b;
17622 spec->autocfg.hp_pins[0] = 0x21;
17623 spec->autocfg.speaker_pins[0] = 0x14;
17624 spec->autocfg.speaker_pins[0] = 0x17;
17625 spec->automute = 1;
17626 spec->automute_mode = ALC_AUTOMUTE_PIN;
17627 spec->ext_mic_pin = 0x18;
17628 spec->int_mic_pin = 0x19;
17629 spec->auto_mic = 1;
17630}
17631
17632/* ***************** Mode8 ******************************/
17633static void alc663_mode8_setup(struct hda_codec *codec)
17634{
17635 struct alc_spec *spec = codec->spec;
17636 spec->autocfg.hp_pins[0] = 0x21;
17637 spec->autocfg.hp_pins[1] = 0x15;
17638 spec->autocfg.speaker_pins[0] = 0x14;
17639 spec->autocfg.speaker_pins[0] = 0x17;
17640 spec->automute = 1;
17641 spec->automute_mode = ALC_AUTOMUTE_PIN;
17642 spec->ext_mic_pin = 0x18;
17643 spec->int_mic_pin = 0x12;
17644 spec->auto_mic = 1;
17645}
17646
17647static void alc663_g71v_setup(struct hda_codec *codec)
17648{
17649 struct alc_spec *spec = codec->spec;
17650 spec->autocfg.hp_pins[0] = 0x21;
17651 spec->autocfg.line_out_pins[0] = 0x15;
17652 spec->autocfg.speaker_pins[0] = 0x14;
17653 spec->automute = 1;
17654 spec->automute_mode = ALC_AUTOMUTE_AMP;
17655 spec->detect_line = 1;
17656 spec->automute_lines = 1;
17657 spec->ext_mic_pin = 0x18;
17658 spec->int_mic_pin = 0x12;
17659 spec->auto_mic = 1;
17660}
17661
17662#define alc663_g50v_setup alc663_m51va_setup
17663
17664static const struct snd_kcontrol_new alc662_ecs_mixer[] = {
17665 HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17666 ALC262_HIPPO_MASTER_SWITCH,
17667
17668 HDA_CODEC_VOLUME("Mic/LineIn Boost Volume", 0x18, 0, HDA_INPUT),
17669 HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT),
17670 HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT),
17671
17672 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17673 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17674 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17675 { } /* end */
17676};
17677
17678static const struct snd_kcontrol_new alc272_nc10_mixer[] = {
17679 /* Master Playback automatically created from Speaker and Headphone */
17680 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT),
17681 HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT),
17682 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
17683 HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT),
17684
17685 HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT),
17686 HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT),
17687 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
17688
17689 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT),
17690 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT),
17691 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT),
17692 { } /* end */
17693};
17694
17695#ifdef CONFIG_SND_HDA_POWER_SAVE 6028#ifdef CONFIG_SND_HDA_POWER_SAVE
17696#define alc662_loopbacks alc880_loopbacks 6029#define alc662_loopbacks alc880_loopbacks
17697#endif 6030#endif
17698 6031
17699
17700/*
17701 * configuration and preset
17702 */
17703static const char * const alc662_models[ALC662_MODEL_LAST] = {
17704 [ALC662_3ST_2ch_DIG] = "3stack-dig",
17705 [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig",
17706 [ALC662_3ST_6ch] = "3stack-6ch",
17707 [ALC662_5ST_DIG] = "5stack-dig",
17708 [ALC662_LENOVO_101E] = "lenovo-101e",
17709 [ALC662_ASUS_EEEPC_P701] = "eeepc-p701",
17710 [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20",
17711 [ALC662_ECS] = "ecs",
17712 [ALC663_ASUS_M51VA] = "m51va",
17713 [ALC663_ASUS_G71V] = "g71v",
17714 [ALC663_ASUS_H13] = "h13",
17715 [ALC663_ASUS_G50V] = "g50v",
17716 [ALC663_ASUS_MODE1] = "asus-mode1",
17717 [ALC662_ASUS_MODE2] = "asus-mode2",
17718 [ALC663_ASUS_MODE3] = "asus-mode3",
17719 [ALC663_ASUS_MODE4] = "asus-mode4",
17720 [ALC663_ASUS_MODE5] = "asus-mode5",
17721 [ALC663_ASUS_MODE6] = "asus-mode6",
17722 [ALC663_ASUS_MODE7] = "asus-mode7",
17723 [ALC663_ASUS_MODE8] = "asus-mode8",
17724 [ALC272_DELL] = "dell",
17725 [ALC272_DELL_ZM1] = "dell-zm1",
17726 [ALC272_SAMSUNG_NC10] = "samsung-nc10",
17727 [ALC662_AUTO] = "auto",
17728};
17729
17730static const struct snd_pci_quirk alc662_cfg_tbl[] = {
17731 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS),
17732 SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL),
17733 SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1),
17734 SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1),
17735 SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3),
17736 SND_PCI_QUIRK(0x1043, 0x1173, "ASUS K73Jn", ALC663_ASUS_MODE1),
17737 SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3),
17738 SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1),
17739 SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2),
17740 SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1),
17741 SND_PCI_QUIRK(0x1043, 0x1303, "ASUS G60J", ALC663_ASUS_MODE1),
17742 SND_PCI_QUIRK(0x1043, 0x1333, "ASUS G60Jx", ALC663_ASUS_MODE1),
17743 SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2),
17744 SND_PCI_QUIRK(0x1043, 0x13e3, "ASUS N71JA", ALC663_ASUS_MODE7),
17745 SND_PCI_QUIRK(0x1043, 0x1463, "ASUS N71", ALC663_ASUS_MODE7),
17746 SND_PCI_QUIRK(0x1043, 0x14d3, "ASUS G72", ALC663_ASUS_MODE8),
17747 SND_PCI_QUIRK(0x1043, 0x1563, "ASUS N90", ALC663_ASUS_MODE3),
17748 SND_PCI_QUIRK(0x1043, 0x15d3, "ASUS N50SF F50SF", ALC663_ASUS_MODE1),
17749 SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2),
17750 SND_PCI_QUIRK(0x1043, 0x16f3, "ASUS K40C K50C", ALC662_ASUS_MODE2),
17751 SND_PCI_QUIRK(0x1043, 0x1733, "ASUS N81De", ALC663_ASUS_MODE1),
17752 SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2),
17753 SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6),
17754 SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6),
17755 SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2),
17756 SND_PCI_QUIRK(0x1043, 0x1793, "ASUS F50GX", ALC663_ASUS_MODE1),
17757 SND_PCI_QUIRK(0x1043, 0x17b3, "ASUS F70SL", ALC663_ASUS_MODE3),
17758 SND_PCI_QUIRK(0x1043, 0x17c3, "ASUS UX20", ALC663_ASUS_M51VA),
17759 SND_PCI_QUIRK(0x1043, 0x17f3, "ASUS X58LE", ALC662_ASUS_MODE2),
17760 SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2),
17761 SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5),
17762 SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6),
17763 SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2),
17764 SND_PCI_QUIRK(0x1043, 0x1853, "ASUS F50Z", ALC663_ASUS_MODE1),
17765 SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2),
17766 SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2),
17767 SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA),
17768 /*SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1),*/
17769 SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3),
17770 SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3),
17771 SND_PCI_QUIRK(0x1043, 0x18b3, "ASUS N80Vc", ALC663_ASUS_MODE1),
17772 SND_PCI_QUIRK(0x1043, 0x18c3, "ASUS VX5", ALC663_ASUS_MODE1),
17773 SND_PCI_QUIRK(0x1043, 0x18d3, "ASUS N81Te", ALC663_ASUS_MODE1),
17774 SND_PCI_QUIRK(0x1043, 0x18f3, "ASUS N505Tp", ALC663_ASUS_MODE1),
17775 SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1),
17776 SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2),
17777 SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2),
17778 SND_PCI_QUIRK(0x1043, 0x1943, "ASUS Vx3V", ALC663_ASUS_MODE1),
17779 SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1),
17780 SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3),
17781 SND_PCI_QUIRK(0x1043, 0x1983, "ASUS N5051A", ALC663_ASUS_MODE1),
17782 SND_PCI_QUIRK(0x1043, 0x1993, "ASUS N20", ALC663_ASUS_MODE1),
17783 SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS G50V", ALC663_ASUS_G50V),
17784 /*SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1),*/
17785 SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1),
17786 SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2),
17787 SND_PCI_QUIRK(0x1043, 0x19d3, "ASUS NB", ALC663_ASUS_M51VA),
17788 SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1),
17789 SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4),
17790 SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG),
17791 SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701),
17792 SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20),
17793 SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS),
17794 SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K",
17795 ALC662_3ST_6ch_DIG),
17796 SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO),
17797 SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10),
17798 SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L",
17799 ALC662_3ST_6ch_DIG),
17800 SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13),
17801 SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG),
17802 SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA),
17803 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E),
17804 SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0",
17805 ALC662_3ST_6ch_DIG),
17806 SND_PCI_QUIRK_MASK(0x1854, 0xf000, 0x2000, "ASUS H13-200x",
17807 ALC663_ASUS_H13),
17808 SND_PCI_QUIRK(0x1991, 0x5628, "Ordissimo EVE", ALC662_LENOVO_101E),
17809 {}
17810};
17811
17812static const struct alc_config_preset alc662_presets[] = {
17813 [ALC662_3ST_2ch_DIG] = {
17814 .mixers = { alc662_3ST_2ch_mixer },
17815 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
17816 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17817 .dac_nids = alc662_dac_nids,
17818 .dig_out_nid = ALC662_DIGOUT_NID,
17819 .dig_in_nid = ALC662_DIGIN_NID,
17820 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17821 .channel_mode = alc662_3ST_2ch_modes,
17822 .input_mux = &alc662_capture_source,
17823 },
17824 [ALC662_3ST_6ch_DIG] = {
17825 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
17826 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
17827 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17828 .dac_nids = alc662_dac_nids,
17829 .dig_out_nid = ALC662_DIGOUT_NID,
17830 .dig_in_nid = ALC662_DIGIN_NID,
17831 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17832 .channel_mode = alc662_3ST_6ch_modes,
17833 .need_dac_fix = 1,
17834 .input_mux = &alc662_capture_source,
17835 },
17836 [ALC662_3ST_6ch] = {
17837 .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer },
17838 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
17839 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17840 .dac_nids = alc662_dac_nids,
17841 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17842 .channel_mode = alc662_3ST_6ch_modes,
17843 .need_dac_fix = 1,
17844 .input_mux = &alc662_capture_source,
17845 },
17846 [ALC662_5ST_DIG] = {
17847 .mixers = { alc662_base_mixer, alc662_chmode_mixer },
17848 .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs },
17849 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17850 .dac_nids = alc662_dac_nids,
17851 .dig_out_nid = ALC662_DIGOUT_NID,
17852 .dig_in_nid = ALC662_DIGIN_NID,
17853 .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes),
17854 .channel_mode = alc662_5stack_modes,
17855 .input_mux = &alc662_capture_source,
17856 },
17857 [ALC662_LENOVO_101E] = {
17858 .mixers = { alc662_lenovo_101e_mixer },
17859 .init_verbs = { alc662_init_verbs,
17860 alc662_eapd_init_verbs,
17861 alc662_sue_init_verbs },
17862 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17863 .dac_nids = alc662_dac_nids,
17864 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17865 .channel_mode = alc662_3ST_2ch_modes,
17866 .input_mux = &alc662_lenovo_101e_capture_source,
17867 .unsol_event = alc_sku_unsol_event,
17868 .setup = alc662_lenovo_101e_setup,
17869 .init_hook = alc_inithook,
17870 },
17871 [ALC662_ASUS_EEEPC_P701] = {
17872 .mixers = { alc662_eeepc_p701_mixer },
17873 .init_verbs = { alc662_init_verbs,
17874 alc662_eapd_init_verbs,
17875 alc662_eeepc_sue_init_verbs },
17876 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17877 .dac_nids = alc662_dac_nids,
17878 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17879 .channel_mode = alc662_3ST_2ch_modes,
17880 .unsol_event = alc_sku_unsol_event,
17881 .setup = alc662_eeepc_setup,
17882 .init_hook = alc_inithook,
17883 },
17884 [ALC662_ASUS_EEEPC_EP20] = {
17885 .mixers = { alc662_eeepc_ep20_mixer,
17886 alc662_chmode_mixer },
17887 .init_verbs = { alc662_init_verbs,
17888 alc662_eapd_init_verbs,
17889 alc662_eeepc_ep20_sue_init_verbs },
17890 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17891 .dac_nids = alc662_dac_nids,
17892 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17893 .channel_mode = alc662_3ST_6ch_modes,
17894 .input_mux = &alc662_lenovo_101e_capture_source,
17895 .unsol_event = alc_sku_unsol_event,
17896 .setup = alc662_eeepc_ep20_setup,
17897 .init_hook = alc_inithook,
17898 },
17899 [ALC662_ECS] = {
17900 .mixers = { alc662_ecs_mixer },
17901 .init_verbs = { alc662_init_verbs,
17902 alc662_eapd_init_verbs,
17903 alc662_ecs_init_verbs },
17904 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17905 .dac_nids = alc662_dac_nids,
17906 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17907 .channel_mode = alc662_3ST_2ch_modes,
17908 .unsol_event = alc_sku_unsol_event,
17909 .setup = alc662_eeepc_setup,
17910 .init_hook = alc_inithook,
17911 },
17912 [ALC663_ASUS_M51VA] = {
17913 .mixers = { alc663_m51va_mixer },
17914 .init_verbs = { alc662_init_verbs,
17915 alc662_eapd_init_verbs,
17916 alc663_m51va_init_verbs },
17917 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17918 .dac_nids = alc662_dac_nids,
17919 .dig_out_nid = ALC662_DIGOUT_NID,
17920 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17921 .channel_mode = alc662_3ST_2ch_modes,
17922 .unsol_event = alc_sku_unsol_event,
17923 .setup = alc663_m51va_setup,
17924 .init_hook = alc_inithook,
17925 },
17926 [ALC663_ASUS_G71V] = {
17927 .mixers = { alc663_g71v_mixer },
17928 .init_verbs = { alc662_init_verbs,
17929 alc662_eapd_init_verbs,
17930 alc663_g71v_init_verbs },
17931 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17932 .dac_nids = alc662_dac_nids,
17933 .dig_out_nid = ALC662_DIGOUT_NID,
17934 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17935 .channel_mode = alc662_3ST_2ch_modes,
17936 .unsol_event = alc_sku_unsol_event,
17937 .setup = alc663_g71v_setup,
17938 .init_hook = alc_inithook,
17939 },
17940 [ALC663_ASUS_H13] = {
17941 .mixers = { alc663_m51va_mixer },
17942 .init_verbs = { alc662_init_verbs,
17943 alc662_eapd_init_verbs,
17944 alc663_m51va_init_verbs },
17945 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17946 .dac_nids = alc662_dac_nids,
17947 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17948 .channel_mode = alc662_3ST_2ch_modes,
17949 .setup = alc663_m51va_setup,
17950 .unsol_event = alc_sku_unsol_event,
17951 .init_hook = alc_inithook,
17952 },
17953 [ALC663_ASUS_G50V] = {
17954 .mixers = { alc663_g50v_mixer },
17955 .init_verbs = { alc662_init_verbs,
17956 alc662_eapd_init_verbs,
17957 alc663_g50v_init_verbs },
17958 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17959 .dac_nids = alc662_dac_nids,
17960 .dig_out_nid = ALC662_DIGOUT_NID,
17961 .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes),
17962 .channel_mode = alc662_3ST_6ch_modes,
17963 .input_mux = &alc663_capture_source,
17964 .unsol_event = alc_sku_unsol_event,
17965 .setup = alc663_g50v_setup,
17966 .init_hook = alc_inithook,
17967 },
17968 [ALC663_ASUS_MODE1] = {
17969 .mixers = { alc663_m51va_mixer },
17970 .cap_mixer = alc662_auto_capture_mixer,
17971 .init_verbs = { alc662_init_verbs,
17972 alc662_eapd_init_verbs,
17973 alc663_21jd_amic_init_verbs },
17974 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17975 .hp_nid = 0x03,
17976 .dac_nids = alc662_dac_nids,
17977 .dig_out_nid = ALC662_DIGOUT_NID,
17978 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17979 .channel_mode = alc662_3ST_2ch_modes,
17980 .unsol_event = alc_sku_unsol_event,
17981 .setup = alc663_mode1_setup,
17982 .init_hook = alc_inithook,
17983 },
17984 [ALC662_ASUS_MODE2] = {
17985 .mixers = { alc662_1bjd_mixer },
17986 .cap_mixer = alc662_auto_capture_mixer,
17987 .init_verbs = { alc662_init_verbs,
17988 alc662_eapd_init_verbs,
17989 alc662_1bjd_amic_init_verbs },
17990 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
17991 .dac_nids = alc662_dac_nids,
17992 .dig_out_nid = ALC662_DIGOUT_NID,
17993 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
17994 .channel_mode = alc662_3ST_2ch_modes,
17995 .unsol_event = alc_sku_unsol_event,
17996 .setup = alc662_mode2_setup,
17997 .init_hook = alc_inithook,
17998 },
17999 [ALC663_ASUS_MODE3] = {
18000 .mixers = { alc663_two_hp_m1_mixer },
18001 .cap_mixer = alc662_auto_capture_mixer,
18002 .init_verbs = { alc662_init_verbs,
18003 alc662_eapd_init_verbs,
18004 alc663_two_hp_amic_m1_init_verbs },
18005 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18006 .hp_nid = 0x03,
18007 .dac_nids = alc662_dac_nids,
18008 .dig_out_nid = ALC662_DIGOUT_NID,
18009 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18010 .channel_mode = alc662_3ST_2ch_modes,
18011 .unsol_event = alc_sku_unsol_event,
18012 .setup = alc663_mode3_setup,
18013 .init_hook = alc_inithook,
18014 },
18015 [ALC663_ASUS_MODE4] = {
18016 .mixers = { alc663_asus_21jd_clfe_mixer },
18017 .cap_mixer = alc662_auto_capture_mixer,
18018 .init_verbs = { alc662_init_verbs,
18019 alc662_eapd_init_verbs,
18020 alc663_21jd_amic_init_verbs},
18021 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18022 .hp_nid = 0x03,
18023 .dac_nids = alc662_dac_nids,
18024 .dig_out_nid = ALC662_DIGOUT_NID,
18025 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18026 .channel_mode = alc662_3ST_2ch_modes,
18027 .unsol_event = alc_sku_unsol_event,
18028 .setup = alc663_mode4_setup,
18029 .init_hook = alc_inithook,
18030 },
18031 [ALC663_ASUS_MODE5] = {
18032 .mixers = { alc663_asus_15jd_clfe_mixer },
18033 .cap_mixer = alc662_auto_capture_mixer,
18034 .init_verbs = { alc662_init_verbs,
18035 alc662_eapd_init_verbs,
18036 alc663_15jd_amic_init_verbs },
18037 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18038 .hp_nid = 0x03,
18039 .dac_nids = alc662_dac_nids,
18040 .dig_out_nid = ALC662_DIGOUT_NID,
18041 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18042 .channel_mode = alc662_3ST_2ch_modes,
18043 .unsol_event = alc_sku_unsol_event,
18044 .setup = alc663_mode5_setup,
18045 .init_hook = alc_inithook,
18046 },
18047 [ALC663_ASUS_MODE6] = {
18048 .mixers = { alc663_two_hp_m2_mixer },
18049 .cap_mixer = alc662_auto_capture_mixer,
18050 .init_verbs = { alc662_init_verbs,
18051 alc662_eapd_init_verbs,
18052 alc663_two_hp_amic_m2_init_verbs },
18053 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18054 .hp_nid = 0x03,
18055 .dac_nids = alc662_dac_nids,
18056 .dig_out_nid = ALC662_DIGOUT_NID,
18057 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18058 .channel_mode = alc662_3ST_2ch_modes,
18059 .unsol_event = alc_sku_unsol_event,
18060 .setup = alc663_mode6_setup,
18061 .init_hook = alc_inithook,
18062 },
18063 [ALC663_ASUS_MODE7] = {
18064 .mixers = { alc663_mode7_mixer },
18065 .cap_mixer = alc662_auto_capture_mixer,
18066 .init_verbs = { alc662_init_verbs,
18067 alc662_eapd_init_verbs,
18068 alc663_mode7_init_verbs },
18069 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18070 .hp_nid = 0x03,
18071 .dac_nids = alc662_dac_nids,
18072 .dig_out_nid = ALC662_DIGOUT_NID,
18073 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18074 .channel_mode = alc662_3ST_2ch_modes,
18075 .unsol_event = alc_sku_unsol_event,
18076 .setup = alc663_mode7_setup,
18077 .init_hook = alc_inithook,
18078 },
18079 [ALC663_ASUS_MODE8] = {
18080 .mixers = { alc663_mode8_mixer },
18081 .cap_mixer = alc662_auto_capture_mixer,
18082 .init_verbs = { alc662_init_verbs,
18083 alc662_eapd_init_verbs,
18084 alc663_mode8_init_verbs },
18085 .num_dacs = ARRAY_SIZE(alc662_dac_nids),
18086 .hp_nid = 0x03,
18087 .dac_nids = alc662_dac_nids,
18088 .dig_out_nid = ALC662_DIGOUT_NID,
18089 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18090 .channel_mode = alc662_3ST_2ch_modes,
18091 .unsol_event = alc_sku_unsol_event,
18092 .setup = alc663_mode8_setup,
18093 .init_hook = alc_inithook,
18094 },
18095 [ALC272_DELL] = {
18096 .mixers = { alc663_m51va_mixer },
18097 .cap_mixer = alc272_auto_capture_mixer,
18098 .init_verbs = { alc662_init_verbs,
18099 alc662_eapd_init_verbs,
18100 alc272_dell_init_verbs },
18101 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18102 .dac_nids = alc272_dac_nids,
18103 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18104 .adc_nids = alc272_adc_nids,
18105 .num_adc_nids = ARRAY_SIZE(alc272_adc_nids),
18106 .capsrc_nids = alc272_capsrc_nids,
18107 .channel_mode = alc662_3ST_2ch_modes,
18108 .unsol_event = alc_sku_unsol_event,
18109 .setup = alc663_m51va_setup,
18110 .init_hook = alc_inithook,
18111 },
18112 [ALC272_DELL_ZM1] = {
18113 .mixers = { alc663_m51va_mixer },
18114 .cap_mixer = alc662_auto_capture_mixer,
18115 .init_verbs = { alc662_init_verbs,
18116 alc662_eapd_init_verbs,
18117 alc272_dell_zm1_init_verbs },
18118 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18119 .dac_nids = alc272_dac_nids,
18120 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18121 .adc_nids = alc662_adc_nids,
18122 .num_adc_nids = 1,
18123 .capsrc_nids = alc662_capsrc_nids,
18124 .channel_mode = alc662_3ST_2ch_modes,
18125 .unsol_event = alc_sku_unsol_event,
18126 .setup = alc663_m51va_setup,
18127 .init_hook = alc_inithook,
18128 },
18129 [ALC272_SAMSUNG_NC10] = {
18130 .mixers = { alc272_nc10_mixer },
18131 .init_verbs = { alc662_init_verbs,
18132 alc662_eapd_init_verbs,
18133 alc663_21jd_amic_init_verbs },
18134 .num_dacs = ARRAY_SIZE(alc272_dac_nids),
18135 .dac_nids = alc272_dac_nids,
18136 .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes),
18137 .channel_mode = alc662_3ST_2ch_modes,
18138 /*.input_mux = &alc272_nc10_capture_source,*/
18139 .unsol_event = alc_sku_unsol_event,
18140 .setup = alc663_mode4_setup,
18141 .init_hook = alc_inithook,
18142 },
18143};
18144
18145
18146/* 6032/*
18147 * BIOS auto configuration 6033 * BIOS auto configuration
18148 */ 6034 */
18149 6035
18150/* convert from MIX nid to DAC */
18151static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid)
18152{
18153 hda_nid_t list[5];
18154 int i, num;
18155
18156 num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list));
18157 for (i = 0; i < num; i++) {
18158 if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT)
18159 return list[i];
18160 }
18161 return 0;
18162}
18163
18164/* go down to the selector widget before the mixer */
18165static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin)
18166{
18167 hda_nid_t srcs[5];
18168 int num = snd_hda_get_connections(codec, pin, srcs,
18169 ARRAY_SIZE(srcs));
18170 if (num != 1 ||
18171 get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL)
18172 return pin;
18173 return srcs[0];
18174}
18175
18176/* get MIX nid connected to the given pin targeted to DAC */
18177static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin,
18178 hda_nid_t dac)
18179{
18180 hda_nid_t mix[5];
18181 int i, num;
18182
18183 pin = alc_go_down_to_selector(codec, pin);
18184 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18185 for (i = 0; i < num; i++) {
18186 if (alc_auto_mix_to_dac(codec, mix[i]) == dac)
18187 return mix[i];
18188 }
18189 return 0;
18190}
18191
18192/* select the connection from pin to DAC if needed */
18193static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin,
18194 hda_nid_t dac)
18195{
18196 hda_nid_t mix[5];
18197 int i, num;
18198
18199 pin = alc_go_down_to_selector(codec, pin);
18200 num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix));
18201 if (num < 2)
18202 return 0;
18203 for (i = 0; i < num; i++) {
18204 if (alc_auto_mix_to_dac(codec, mix[i]) == dac) {
18205 snd_hda_codec_update_cache(codec, pin, 0,
18206 AC_VERB_SET_CONNECT_SEL, i);
18207 return 0;
18208 }
18209 }
18210 return 0;
18211}
18212
18213/* look for an empty DAC slot */
18214static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin)
18215{
18216 struct alc_spec *spec = codec->spec;
18217 hda_nid_t srcs[5];
18218 int i, num;
18219
18220 pin = alc_go_down_to_selector(codec, pin);
18221 num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs));
18222 for (i = 0; i < num; i++) {
18223 hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]);
18224 if (!nid)
18225 continue;
18226 if (found_in_nid_list(nid, spec->multiout.dac_nids,
18227 spec->multiout.num_dacs))
18228 continue;
18229 if (spec->multiout.hp_nid == nid)
18230 continue;
18231 if (found_in_nid_list(nid, spec->multiout.extra_out_nid,
18232 ARRAY_SIZE(spec->multiout.extra_out_nid)))
18233 continue;
18234 return nid;
18235 }
18236 return 0;
18237}
18238
18239static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
18240{
18241 hda_nid_t sel = alc_go_down_to_selector(codec, pin);
18242 if (snd_hda_get_conn_list(codec, sel, NULL) == 1)
18243 return alc_auto_look_for_dac(codec, pin);
18244 return 0;
18245}
18246
18247/* fill in the dac_nids table from the parsed pin configuration */
18248static int alc_auto_fill_dac_nids(struct hda_codec *codec)
18249{
18250 struct alc_spec *spec = codec->spec;
18251 const struct auto_pin_cfg *cfg = &spec->autocfg;
18252 bool redone = false;
18253 int i;
18254
18255 again:
18256 spec->multiout.num_dacs = 0;
18257 spec->multiout.hp_nid = 0;
18258 spec->multiout.extra_out_nid[0] = 0;
18259 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
18260 spec->multiout.dac_nids = spec->private_dac_nids;
18261
18262 /* fill hard-wired DACs first */
18263 if (!redone) {
18264 for (i = 0; i < cfg->line_outs; i++)
18265 spec->private_dac_nids[i] =
18266 get_dac_if_single(codec, cfg->line_out_pins[i]);
18267 if (cfg->hp_outs)
18268 spec->multiout.hp_nid =
18269 get_dac_if_single(codec, cfg->hp_pins[0]);
18270 if (cfg->speaker_outs)
18271 spec->multiout.extra_out_nid[0] =
18272 get_dac_if_single(codec, cfg->speaker_pins[0]);
18273 }
18274
18275 for (i = 0; i < cfg->line_outs; i++) {
18276 hda_nid_t pin = cfg->line_out_pins[i];
18277 if (spec->private_dac_nids[i])
18278 continue;
18279 spec->private_dac_nids[i] = alc_auto_look_for_dac(codec, pin);
18280 if (!spec->private_dac_nids[i] && !redone) {
18281 /* if we can't find primary DACs, re-probe without
18282 * checking the hard-wired DACs
18283 */
18284 redone = true;
18285 goto again;
18286 }
18287 }
18288
18289 for (i = 0; i < cfg->line_outs; i++) {
18290 if (spec->private_dac_nids[i])
18291 spec->multiout.num_dacs++;
18292 else
18293 memmove(spec->private_dac_nids + i,
18294 spec->private_dac_nids + i + 1,
18295 sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
18296 }
18297
18298 if (cfg->hp_outs && !spec->multiout.hp_nid)
18299 spec->multiout.hp_nid =
18300 alc_auto_look_for_dac(codec, cfg->hp_pins[0]);
18301 if (cfg->speaker_outs && !spec->multiout.extra_out_nid[0])
18302 spec->multiout.extra_out_nid[0] =
18303 alc_auto_look_for_dac(codec, cfg->speaker_pins[0]);
18304
18305 return 0;
18306}
18307
18308static int alc_auto_add_vol_ctl(struct hda_codec *codec,
18309 const char *pfx, int cidx,
18310 hda_nid_t nid, unsigned int chs)
18311{
18312 return __add_pb_vol_ctrl(codec->spec, ALC_CTL_WIDGET_VOL, pfx, cidx,
18313 HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
18314}
18315
18316#define alc_auto_add_stereo_vol(codec, pfx, cidx, nid) \
18317 alc_auto_add_vol_ctl(codec, pfx, cidx, nid, 3)
18318
18319/* create a mute-switch for the given mixer widget;
18320 * if it has multiple sources (e.g. DAC and loopback), create a bind-mute
18321 */
18322static int alc_auto_add_sw_ctl(struct hda_codec *codec,
18323 const char *pfx, int cidx,
18324 hda_nid_t nid, unsigned int chs)
18325{
18326 int type;
18327 unsigned long val;
18328 if (snd_hda_get_conn_list(codec, nid, NULL) == 1) {
18329 type = ALC_CTL_WIDGET_MUTE;
18330 val = HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT);
18331 } else {
18332 type = ALC_CTL_BIND_MUTE;
18333 val = HDA_COMPOSE_AMP_VAL(nid, chs, 2, HDA_INPUT);
18334 }
18335 return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val);
18336}
18337
18338#define alc_auto_add_stereo_sw(codec, pfx, cidx, nid) \
18339 alc_auto_add_sw_ctl(codec, pfx, cidx, nid, 3)
18340
18341/* add playback controls from the parsed DAC table */
18342static int alc_auto_create_multi_out_ctls(struct hda_codec *codec,
18343 const struct auto_pin_cfg *cfg)
18344{
18345 struct alc_spec *spec = codec->spec;
18346 hda_nid_t nid, mix, pin;
18347 int i, err, noutputs;
18348
18349 noutputs = cfg->line_outs;
18350 if (spec->multi_ios > 0)
18351 noutputs += spec->multi_ios;
18352
18353 for (i = 0; i < noutputs; i++) {
18354 const char *name;
18355 int index;
18356 nid = spec->multiout.dac_nids[i];
18357 if (!nid)
18358 continue;
18359 if (i >= cfg->line_outs)
18360 pin = spec->multi_io[i - 1].pin;
18361 else
18362 pin = cfg->line_out_pins[i];
18363 mix = alc_auto_dac_to_mix(codec, pin, nid);
18364 if (!mix)
18365 continue;
18366 name = alc_get_line_out_pfx(spec, i, true, &index);
18367 if (!name) {
18368 /* Center/LFE */
18369 err = alc_auto_add_vol_ctl(codec, "Center", 0, nid, 1);
18370 if (err < 0)
18371 return err;
18372 err = alc_auto_add_vol_ctl(codec, "LFE", 0, nid, 2);
18373 if (err < 0)
18374 return err;
18375 err = alc_auto_add_sw_ctl(codec, "Center", 0, mix, 1);
18376 if (err < 0)
18377 return err;
18378 err = alc_auto_add_sw_ctl(codec, "LFE", 0, mix, 2);
18379 if (err < 0)
18380 return err;
18381 } else {
18382 err = alc_auto_add_stereo_vol(codec, name, index, nid);
18383 if (err < 0)
18384 return err;
18385 err = alc_auto_add_stereo_sw(codec, name, index, mix);
18386 if (err < 0)
18387 return err;
18388 }
18389 }
18390 return 0;
18391}
18392
18393/* add playback controls for speaker and HP outputs */
18394static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin,
18395 hda_nid_t dac, const char *pfx)
18396{
18397 struct alc_spec *spec = codec->spec;
18398 hda_nid_t mix;
18399 int err;
18400
18401 if (!pin)
18402 return 0;
18403 if (!dac) {
18404 /* the corresponding DAC is already occupied */
18405 if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP))
18406 return 0; /* no way */
18407 /* create a switch only */
18408 return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx,
18409 HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT));
18410 }
18411
18412 mix = alc_auto_dac_to_mix(codec, pin, dac);
18413 if (!mix)
18414 return 0;
18415 err = alc_auto_add_stereo_vol(codec, pfx, 0, dac);
18416 if (err < 0)
18417 return err;
18418 err = alc_auto_add_stereo_sw(codec, pfx, 0, mix);
18419 if (err < 0)
18420 return err;
18421 return 0;
18422}
18423
18424static int alc_auto_create_hp_out(struct hda_codec *codec)
18425{
18426 struct alc_spec *spec = codec->spec;
18427 return alc_auto_create_extra_out(codec, spec->autocfg.hp_pins[0],
18428 spec->multiout.hp_nid,
18429 "Headphone");
18430}
18431
18432static int alc_auto_create_speaker_out(struct hda_codec *codec)
18433{
18434 struct alc_spec *spec = codec->spec;
18435 return alc_auto_create_extra_out(codec, spec->autocfg.speaker_pins[0],
18436 spec->multiout.extra_out_nid[0],
18437 "Speaker");
18438}
18439
18440static void alc_auto_set_output_and_unmute(struct hda_codec *codec,
18441 hda_nid_t nid, int pin_type,
18442 hda_nid_t dac)
18443{
18444 int i, num;
18445 hda_nid_t mix = 0;
18446 hda_nid_t srcs[HDA_MAX_CONNECTIONS];
18447
18448 alc_set_pin_output(codec, nid, pin_type);
18449 nid = alc_go_down_to_selector(codec, nid);
18450 num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs));
18451 for (i = 0; i < num; i++) {
18452 if (alc_auto_mix_to_dac(codec, srcs[i]) != dac)
18453 continue;
18454 mix = srcs[i];
18455 break;
18456 }
18457 if (!mix)
18458 return;
18459
18460 /* need the manual connection? */
18461 if (num > 1)
18462 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i);
18463 /* unmute mixer widget inputs */
18464 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
18465 AMP_IN_UNMUTE(0));
18466 snd_hda_codec_write(codec, mix, 0, AC_VERB_SET_AMP_GAIN_MUTE,
18467 AMP_IN_UNMUTE(1));
18468 /* initialize volume */
18469 if (query_amp_caps(codec, dac, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
18470 nid = dac;
18471 else if (query_amp_caps(codec, mix, HDA_OUTPUT) & AC_AMPCAP_NUM_STEPS)
18472 nid = mix;
18473 else
18474 return;
18475 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
18476 AMP_OUT_ZERO);
18477}
18478
18479static void alc_auto_init_multi_out(struct hda_codec *codec)
18480{
18481 struct alc_spec *spec = codec->spec;
18482 int pin_type = get_pin_type(spec->autocfg.line_out_type);
18483 int i;
18484
18485 for (i = 0; i <= HDA_SIDE; i++) {
18486 hda_nid_t nid = spec->autocfg.line_out_pins[i];
18487 if (nid)
18488 alc_auto_set_output_and_unmute(codec, nid, pin_type,
18489 spec->multiout.dac_nids[i]);
18490 }
18491}
18492
18493static void alc_auto_init_extra_out(struct hda_codec *codec)
18494{
18495 struct alc_spec *spec = codec->spec;
18496 hda_nid_t pin;
18497
18498 pin = spec->autocfg.hp_pins[0];
18499 if (pin)
18500 alc_auto_set_output_and_unmute(codec, pin, PIN_HP,
18501 spec->multiout.hp_nid);
18502 pin = spec->autocfg.speaker_pins[0];
18503 if (pin)
18504 alc_auto_set_output_and_unmute(codec, pin, PIN_OUT,
18505 spec->multiout.extra_out_nid[0]);
18506}
18507
18508/*
18509 * multi-io helper
18510 */
18511static int alc_auto_fill_multi_ios(struct hda_codec *codec,
18512 unsigned int location)
18513{
18514 struct alc_spec *spec = codec->spec;
18515 struct auto_pin_cfg *cfg = &spec->autocfg;
18516 int type, i, num_pins = 0;
18517
18518 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
18519 for (i = 0; i < cfg->num_inputs; i++) {
18520 hda_nid_t nid = cfg->inputs[i].pin;
18521 hda_nid_t dac;
18522 unsigned int defcfg, caps;
18523 if (cfg->inputs[i].type != type)
18524 continue;
18525 defcfg = snd_hda_codec_get_pincfg(codec, nid);
18526 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
18527 continue;
18528 if (location && get_defcfg_location(defcfg) != location)
18529 continue;
18530 caps = snd_hda_query_pin_caps(codec, nid);
18531 if (!(caps & AC_PINCAP_OUT))
18532 continue;
18533 dac = alc_auto_look_for_dac(codec, nid);
18534 if (!dac)
18535 continue;
18536 spec->multi_io[num_pins].pin = nid;
18537 spec->multi_io[num_pins].dac = dac;
18538 num_pins++;
18539 spec->private_dac_nids[spec->multiout.num_dacs++] = dac;
18540 }
18541 }
18542 spec->multiout.num_dacs = 1;
18543 if (num_pins < 2)
18544 return 0;
18545 return num_pins;
18546}
18547
18548static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol,
18549 struct snd_ctl_elem_info *uinfo)
18550{
18551 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
18552 struct alc_spec *spec = codec->spec;
18553
18554 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
18555 uinfo->count = 1;
18556 uinfo->value.enumerated.items = spec->multi_ios + 1;
18557 if (uinfo->value.enumerated.item > spec->multi_ios)
18558 uinfo->value.enumerated.item = spec->multi_ios;
18559 sprintf(uinfo->value.enumerated.name, "%dch",
18560 (uinfo->value.enumerated.item + 1) * 2);
18561 return 0;
18562}
18563
18564static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol,
18565 struct snd_ctl_elem_value *ucontrol)
18566{
18567 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
18568 struct alc_spec *spec = codec->spec;
18569 ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2;
18570 return 0;
18571}
18572
18573static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output)
18574{
18575 struct alc_spec *spec = codec->spec;
18576 hda_nid_t nid = spec->multi_io[idx].pin;
18577
18578 if (!spec->multi_io[idx].ctl_in)
18579 spec->multi_io[idx].ctl_in =
18580 snd_hda_codec_read(codec, nid, 0,
18581 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
18582 if (output) {
18583 snd_hda_codec_update_cache(codec, nid, 0,
18584 AC_VERB_SET_PIN_WIDGET_CONTROL,
18585 PIN_OUT);
18586 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
18587 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
18588 HDA_AMP_MUTE, 0);
18589 alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac);
18590 } else {
18591 if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)
18592 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
18593 HDA_AMP_MUTE, HDA_AMP_MUTE);
18594 snd_hda_codec_update_cache(codec, nid, 0,
18595 AC_VERB_SET_PIN_WIDGET_CONTROL,
18596 spec->multi_io[idx].ctl_in);
18597 }
18598 return 0;
18599}
18600
18601static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol,
18602 struct snd_ctl_elem_value *ucontrol)
18603{
18604 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
18605 struct alc_spec *spec = codec->spec;
18606 int i, ch;
18607
18608 ch = ucontrol->value.enumerated.item[0];
18609 if (ch < 0 || ch > spec->multi_ios)
18610 return -EINVAL;
18611 if (ch == (spec->ext_channel_count - 1) / 2)
18612 return 0;
18613 spec->ext_channel_count = (ch + 1) * 2;
18614 for (i = 0; i < spec->multi_ios; i++)
18615 alc_set_multi_io(codec, i, i < ch);
18616 spec->multiout.max_channels = spec->ext_channel_count;
18617 return 1;
18618}
18619
18620static const struct snd_kcontrol_new alc_auto_channel_mode_enum = {
18621 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
18622 .name = "Channel Mode",
18623 .info = alc_auto_ch_mode_info,
18624 .get = alc_auto_ch_mode_get,
18625 .put = alc_auto_ch_mode_put,
18626};
18627
18628static int alc_auto_add_multi_channel_mode(struct hda_codec *codec,
18629 int (*fill_dac)(struct hda_codec *))
18630{
18631 struct alc_spec *spec = codec->spec;
18632 struct auto_pin_cfg *cfg = &spec->autocfg;
18633 unsigned int location, defcfg;
18634 int num_pins;
18635
18636 if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && cfg->hp_outs == 1) {
18637 /* use HP as primary out */
18638 cfg->speaker_outs = cfg->line_outs;
18639 memcpy(cfg->speaker_pins, cfg->line_out_pins,
18640 sizeof(cfg->speaker_pins));
18641 cfg->line_outs = cfg->hp_outs;
18642 memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
18643 cfg->hp_outs = 0;
18644 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
18645 cfg->line_out_type = AUTO_PIN_HP_OUT;
18646 if (fill_dac)
18647 fill_dac(codec);
18648 }
18649 if (cfg->line_outs != 1 ||
18650 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
18651 return 0;
18652
18653 defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]);
18654 location = get_defcfg_location(defcfg);
18655
18656 num_pins = alc_auto_fill_multi_ios(codec, location);
18657 if (num_pins > 0) {
18658 struct snd_kcontrol_new *knew;
18659
18660 knew = alc_kcontrol_new(spec);
18661 if (!knew)
18662 return -ENOMEM;
18663 *knew = alc_auto_channel_mode_enum;
18664 knew->name = kstrdup("Channel Mode", GFP_KERNEL);
18665 if (!knew->name)
18666 return -ENOMEM;
18667
18668 spec->multi_ios = num_pins;
18669 spec->ext_channel_count = 2;
18670 spec->multiout.num_dacs = num_pins + 1;
18671 }
18672 return 0;
18673}
18674
18675static int alc662_parse_auto_config(struct hda_codec *codec) 6036static int alc662_parse_auto_config(struct hda_codec *codec)
18676{ 6037{
18677 struct alc_spec *spec = codec->spec; 6038 struct alc_spec *spec = codec->spec;
@@ -18816,6 +6177,12 @@ static const struct alc_model_fixup alc662_fixup_models[] = {
18816}; 6177};
18817 6178
18818 6179
6180/*
6181 */
6182#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
6183#include "alc662_quirks.c"
6184#endif
6185
18819static int patch_alc662(struct hda_codec *codec) 6186static int patch_alc662(struct hda_codec *codec)
18820{ 6187{
18821 struct alc_spec *spec; 6188 struct alc_spec *spec;
@@ -18844,16 +6211,15 @@ static int patch_alc662(struct hda_codec *codec)
18844 else if (coef == 0x4011) 6211 else if (coef == 0x4011)
18845 alc_codec_rename(codec, "ALC656"); 6212 alc_codec_rename(codec, "ALC656");
18846 6213
18847 board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, 6214 board_config = alc_board_config(codec, ALC662_MODEL_LAST,
18848 alc662_models, 6215 alc662_models, alc662_cfg_tbl);
18849 alc662_cfg_tbl);
18850 if (board_config < 0) { 6216 if (board_config < 0) {
18851 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 6217 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
18852 codec->chip_name); 6218 codec->chip_name);
18853 board_config = ALC662_AUTO; 6219 board_config = ALC_MODEL_AUTO;
18854 } 6220 }
18855 6221
18856 if (board_config == ALC662_AUTO) { 6222 if (board_config == ALC_MODEL_AUTO) {
18857 alc_pick_fixup(codec, alc662_fixup_models, 6223 alc_pick_fixup(codec, alc662_fixup_models,
18858 alc662_fixup_tbl, alc662_fixups); 6224 alc662_fixup_tbl, alc662_fixups);
18859 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 6225 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
@@ -18862,12 +6228,15 @@ static int patch_alc662(struct hda_codec *codec)
18862 if (err < 0) { 6228 if (err < 0) {
18863 alc_free(codec); 6229 alc_free(codec);
18864 return err; 6230 return err;
18865 } else if (!err) { 6231 }
6232#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
6233 else if (!err) {
18866 printk(KERN_INFO 6234 printk(KERN_INFO
18867 "hda_codec: Cannot set up configuration " 6235 "hda_codec: Cannot set up configuration "
18868 "from BIOS. Using base mode...\n"); 6236 "from BIOS. Using base mode...\n");
18869 board_config = ALC662_3ST_2ch_DIG; 6237 board_config = ALC662_3ST_2ch_DIG;
18870 } 6238 }
6239#endif
18871 } 6240 }
18872 6241
18873 if (has_cdefine_beep(codec)) { 6242 if (has_cdefine_beep(codec)) {
@@ -18878,7 +6247,7 @@ static int patch_alc662(struct hda_codec *codec)
18878 } 6247 }
18879 } 6248 }
18880 6249
18881 if (board_config != ALC662_AUTO) 6250 if (board_config != ALC_MODEL_AUTO)
18882 setup_preset(codec, &alc662_presets[board_config]); 6251 setup_preset(codec, &alc662_presets[board_config]);
18883 6252
18884 if (!spec->adc_nids) { 6253 if (!spec->adc_nids) {
@@ -18910,7 +6279,7 @@ static int patch_alc662(struct hda_codec *codec)
18910 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); 6279 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
18911 6280
18912 codec->patch_ops = alc_patch_ops; 6281 codec->patch_ops = alc_patch_ops;
18913 if (board_config == ALC662_AUTO) 6282 if (board_config == ALC_MODEL_AUTO)
18914 spec->init_hook = alc662_auto_init; 6283 spec->init_hook = alc662_auto_init;
18915 spec->shutup = alc_eapd_shutup; 6284 spec->shutup = alc_eapd_shutup;
18916 6285
@@ -18953,187 +6322,6 @@ static int patch_alc899(struct hda_codec *codec)
18953/* 6322/*
18954 * ALC680 support 6323 * ALC680 support
18955 */ 6324 */
18956#define ALC680_DIGIN_NID ALC880_DIGIN_NID
18957#define ALC680_DIGOUT_NID ALC880_DIGOUT_NID
18958#define alc680_modes alc260_modes
18959
18960static const hda_nid_t alc680_dac_nids[3] = {
18961 /* Lout1, Lout2, hp */
18962 0x02, 0x03, 0x04
18963};
18964
18965static const hda_nid_t alc680_adc_nids[3] = {
18966 /* ADC0-2 */
18967 /* DMIC, MIC, Line-in*/
18968 0x07, 0x08, 0x09
18969};
18970
18971/*
18972 * Analog capture ADC cgange
18973 */
18974static hda_nid_t alc680_get_cur_adc(struct hda_codec *codec)
18975{
18976 static hda_nid_t pins[] = {0x18, 0x19};
18977 static hda_nid_t adcs[] = {0x08, 0x09};
18978 int i;
18979
18980 for (i = 0; i < ARRAY_SIZE(pins); i++) {
18981 if (!is_jack_detectable(codec, pins[i]))
18982 continue;
18983 if (snd_hda_jack_detect(codec, pins[i]))
18984 return adcs[i];
18985 }
18986 return 0x07;
18987}
18988
18989static void alc680_rec_autoswitch(struct hda_codec *codec)
18990{
18991 struct alc_spec *spec = codec->spec;
18992 hda_nid_t nid = alc680_get_cur_adc(codec);
18993 if (spec->cur_adc && nid != spec->cur_adc) {
18994 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
18995 spec->cur_adc = nid;
18996 snd_hda_codec_setup_stream(codec, nid,
18997 spec->cur_adc_stream_tag, 0,
18998 spec->cur_adc_format);
18999 }
19000}
19001
19002static int alc680_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
19003 struct hda_codec *codec,
19004 unsigned int stream_tag,
19005 unsigned int format,
19006 struct snd_pcm_substream *substream)
19007{
19008 struct alc_spec *spec = codec->spec;
19009 hda_nid_t nid = alc680_get_cur_adc(codec);
19010
19011 spec->cur_adc = nid;
19012 spec->cur_adc_stream_tag = stream_tag;
19013 spec->cur_adc_format = format;
19014 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
19015 return 0;
19016}
19017
19018static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
19019 struct hda_codec *codec,
19020 struct snd_pcm_substream *substream)
19021{
19022 struct alc_spec *spec = codec->spec;
19023 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
19024 spec->cur_adc = 0;
19025 return 0;
19026}
19027
19028static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = {
19029 .substreams = 1, /* can be overridden */
19030 .channels_min = 2,
19031 .channels_max = 2,
19032 /* NID is set in alc_build_pcms */
19033 .ops = {
19034 .prepare = alc680_capture_pcm_prepare,
19035 .cleanup = alc680_capture_pcm_cleanup
19036 },
19037};
19038
19039static const struct snd_kcontrol_new alc680_base_mixer[] = {
19040 /* output mixer control */
19041 HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT),
19042 HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT),
19043 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT),
19044 HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT),
19045 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x12, 0, HDA_INPUT),
19046 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT),
19047 HDA_CODEC_VOLUME("Line In Boost Volume", 0x19, 0, HDA_INPUT),
19048 { }
19049};
19050
19051static const struct hda_bind_ctls alc680_bind_cap_vol = {
19052 .ops = &snd_hda_bind_vol,
19053 .values = {
19054 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19055 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19056 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19057 0
19058 },
19059};
19060
19061static const struct hda_bind_ctls alc680_bind_cap_switch = {
19062 .ops = &snd_hda_bind_sw,
19063 .values = {
19064 HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT),
19065 HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT),
19066 HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT),
19067 0
19068 },
19069};
19070
19071static const struct snd_kcontrol_new alc680_master_capture_mixer[] = {
19072 HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol),
19073 HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch),
19074 { } /* end */
19075};
19076
19077/*
19078 * generic initialization of ADC, input mixers and output mixers
19079 */
19080static const struct hda_verb alc680_init_verbs[] = {
19081 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19082 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19083 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
19084
19085 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19086 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19087 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
19088 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
19089 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
19090 {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
19091
19092 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19093 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19094 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19095 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19096 {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
19097
19098 {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN},
19099 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19100 {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN},
19101
19102 { }
19103};
19104
19105/* toggle speaker-output according to the hp-jack state */
19106static void alc680_base_setup(struct hda_codec *codec)
19107{
19108 struct alc_spec *spec = codec->spec;
19109
19110 spec->autocfg.hp_pins[0] = 0x16;
19111 spec->autocfg.speaker_pins[0] = 0x14;
19112 spec->autocfg.speaker_pins[1] = 0x15;
19113 spec->autocfg.num_inputs = 2;
19114 spec->autocfg.inputs[0].pin = 0x18;
19115 spec->autocfg.inputs[0].type = AUTO_PIN_MIC;
19116 spec->autocfg.inputs[1].pin = 0x19;
19117 spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN;
19118 spec->automute = 1;
19119 spec->automute_mode = ALC_AUTOMUTE_AMP;
19120}
19121
19122static void alc680_unsol_event(struct hda_codec *codec,
19123 unsigned int res)
19124{
19125 if ((res >> 26) == ALC880_HP_EVENT)
19126 alc_hp_automute(codec);
19127 if ((res >> 26) == ALC880_MIC_EVENT)
19128 alc680_rec_autoswitch(codec);
19129}
19130
19131static void alc680_inithook(struct hda_codec *codec)
19132{
19133 alc_hp_automute(codec);
19134 alc680_rec_autoswitch(codec);
19135}
19136
19137/* create input playback/capture controls for the given pin */ 6325/* create input playback/capture controls for the given pin */
19138static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid, 6326static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid,
19139 const char *ctlname, int idx) 6327 const char *ctlname, int idx)
@@ -19300,34 +6488,10 @@ static void alc680_auto_init(struct hda_codec *codec)
19300} 6488}
19301 6489
19302/* 6490/*
19303 * configuration and preset
19304 */ 6491 */
19305static const char * const alc680_models[ALC680_MODEL_LAST] = { 6492#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
19306 [ALC680_BASE] = "base", 6493#include "alc680_quirks.c"
19307 [ALC680_AUTO] = "auto", 6494#endif
19308};
19309
19310static const struct snd_pci_quirk alc680_cfg_tbl[] = {
19311 SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE),
19312 {}
19313};
19314
19315static const struct alc_config_preset alc680_presets[] = {
19316 [ALC680_BASE] = {
19317 .mixers = { alc680_base_mixer },
19318 .cap_mixer = alc680_master_capture_mixer,
19319 .init_verbs = { alc680_init_verbs },
19320 .num_dacs = ARRAY_SIZE(alc680_dac_nids),
19321 .dac_nids = alc680_dac_nids,
19322 .dig_out_nid = ALC680_DIGOUT_NID,
19323 .num_channel_mode = ARRAY_SIZE(alc680_modes),
19324 .channel_mode = alc680_modes,
19325 .unsol_event = alc680_unsol_event,
19326 .setup = alc680_base_setup,
19327 .init_hook = alc680_inithook,
19328
19329 },
19330};
19331 6495
19332static int patch_alc680(struct hda_codec *codec) 6496static int patch_alc680(struct hda_codec *codec)
19333{ 6497{
@@ -19343,33 +6507,37 @@ static int patch_alc680(struct hda_codec *codec)
19343 6507
19344 /* ALC680 has no aa-loopback mixer */ 6508 /* ALC680 has no aa-loopback mixer */
19345 6509
19346 board_config = snd_hda_check_board_config(codec, ALC680_MODEL_LAST, 6510 board_config = alc_board_config(codec, ALC680_MODEL_LAST,
19347 alc680_models, 6511 alc680_models, alc680_cfg_tbl);
19348 alc680_cfg_tbl);
19349 6512
19350 if (board_config < 0 || board_config >= ALC680_MODEL_LAST) { 6513 if (board_config < 0) {
19351 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 6514 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
19352 codec->chip_name); 6515 codec->chip_name);
19353 board_config = ALC680_AUTO; 6516 board_config = ALC_MODEL_AUTO;
19354 } 6517 }
19355 6518
19356 if (board_config == ALC680_AUTO) { 6519 if (board_config == ALC_MODEL_AUTO) {
19357 /* automatic parse from the BIOS config */ 6520 /* automatic parse from the BIOS config */
19358 err = alc680_parse_auto_config(codec); 6521 err = alc680_parse_auto_config(codec);
19359 if (err < 0) { 6522 if (err < 0) {
19360 alc_free(codec); 6523 alc_free(codec);
19361 return err; 6524 return err;
19362 } else if (!err) { 6525 }
6526#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
6527 else if (!err) {
19363 printk(KERN_INFO 6528 printk(KERN_INFO
19364 "hda_codec: Cannot set up configuration " 6529 "hda_codec: Cannot set up configuration "
19365 "from BIOS. Using base mode...\n"); 6530 "from BIOS. Using base mode...\n");
19366 board_config = ALC680_BASE; 6531 board_config = ALC680_BASE;
19367 } 6532 }
6533#endif
19368 } 6534 }
19369 6535
19370 if (board_config != ALC680_AUTO) { 6536 if (board_config != ALC_MODEL_AUTO) {
19371 setup_preset(codec, &alc680_presets[board_config]); 6537 setup_preset(codec, &alc680_presets[board_config]);
6538#ifdef CONFIG_SND_HDA_ENABLE_REALTEK_QUIRKS
19372 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture; 6539 spec->stream_analog_capture = &alc680_pcm_analog_auto_capture;
6540#endif
19373 } 6541 }
19374 6542
19375 if (!spec->adc_nids) { 6543 if (!spec->adc_nids) {
@@ -19384,7 +6552,7 @@ static int patch_alc680(struct hda_codec *codec)
19384 spec->vmaster_nid = 0x02; 6552 spec->vmaster_nid = 0x02;
19385 6553
19386 codec->patch_ops = alc_patch_ops; 6554 codec->patch_ops = alc_patch_ops;
19387 if (board_config == ALC680_AUTO) 6555 if (board_config == ALC_MODEL_AUTO)
19388 spec->init_hook = alc680_auto_init; 6556 spec->init_hook = alc680_auto_init;
19389 6557
19390 return 0; 6558 return 0;